Changeset 3950236 in opengl-game
- Timestamp:
- Apr 19, 2020, 3:39:41 AM (5 years ago)
- Branches:
- feature/imgui-sdl, master, points-test
- Children:
- 7297892
- Parents:
- 1f81ecc
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
vulkan-game.cpp
r1f81ecc r3950236 779 779 } 780 780 781 if (leftLaserIdx != -1) { 782 updateLaserTarget(leftLaserIdx); 783 } 784 if (rightLaserIdx != -1) { 785 updateLaserTarget(rightLaserIdx); 786 } 787 781 788 for (SceneObject<AsteroidVertex, SSBO_Asteroid>& asteroid : this->asteroidObjects) { 782 789 if (!asteroid.ssbo.deleted) { … … 1552 1559 {{-width / 2, 0.0f, 0.0f }, {0.0f, 0.0f }}, 1553 1560 {{ width / 2, 0.0f, 0.0f }, {1.0f, 0.0f }}, 1554 {{ width / 2, 0.0f, -length + width / 2}, {1.0f, 0.51f}},1561 {{ width / 2, 0.0f, -length + width / 2}, {1.0f, 0.51f}}, 1555 1562 {{-width / 2, 0.0f, -length + width / 2}, {0.0f, 0.51f}}, 1556 1563 {{ width / 2, 0.0f, -length, }, {1.0f, 1.0f }}, … … 1580 1587 float zAxisRotation = -atan2(glm::dot(glm::cross(normal, laserToCam), glm::normalize(ray)), glm::dot(normal, laserToCam)); 1581 1588 1589 laser.targetAsteroid = nullptr; 1590 1582 1591 laser.model_base = 1583 1592 rotate(mat4(1.0f), zAxisRotation, vec3(0.0f, 0.0f, 1.0f)); … … 1621 1630 1622 1631 laser.modified = true; 1632 } 1633 1634 void VulkanGame::updateLaserTarget(size_t index) { 1635 SceneObject<LaserVertex, SSBO_Laser>& laser = this->laserObjects[index]; 1636 1637 // TODO: A lot of the values calculated here can be calculated once and saved when the laser is created, 1638 // and then re-used here 1639 1640 vec3 start = vec3(laser.model_transform * vec4(0.0f, 0.0f, 0.0f, 1.0f)); 1641 vec3 end = vec3(laser.model_transform * vec4(0.0f, 0.0f, laser.vertices[6].pos.z, 1.0f)); 1642 1643 vec3 intersection(0.0f), closestIntersection(0.0f); 1644 SceneObject<AsteroidVertex, SSBO_Asteroid>* closestAsteroid = nullptr; 1645 unsigned int closestAsteroidIndex = -1; 1646 1647 for (int i = 0; i < this->asteroidObjects.size(); i++) { 1648 if (!this->asteroidObjects[i].ssbo.deleted && 1649 this->getLaserAndAsteroidIntersection(this->asteroidObjects[i], start, end, intersection)) { 1650 // TODO: Implement a more generic algorithm for testing the closest object by getting the distance between the points 1651 // TODO: Also check which intersection is close to the start of the laser. This would make the algorithm work 1652 // regardless of which way -Z is pointing 1653 if (closestAsteroid == nullptr || intersection.z > closestIntersection.z) { 1654 // TODO: At this point, find the real intersection of the laser with one of the asteroid's sides 1655 closestAsteroid = &asteroidObjects[i]; 1656 closestIntersection = intersection; 1657 closestAsteroidIndex = i; 1658 } 1659 } 1660 } 1661 1662 float width = laser.vertices[0].pos.x - laser.vertices[1].pos.x; 1663 1664 if (laser.targetAsteroid != closestAsteroid) { 1665 laser.targetAsteroid = closestAsteroid; 1666 } 1667 1668 // Make the laser go past the end of the screen if it doesn't hit anything 1669 float length = closestAsteroid == nullptr ? 5.24f : glm::length(closestIntersection - start); 1670 1671 laser.vertices[4].pos.z = -length + width / 2; 1672 laser.vertices[5].pos.z = -length + width / 2; 1673 laser.vertices[6].pos.z = -length; 1674 laser.vertices[7].pos.z = -length; 1675 1676 // TODO: Consider if I want to set a flag and do this update in in updateScene() instead 1677 updateObjectVertices(this->laserPipeline, laser, index); 1678 } 1679 1680 // TODO: Determine if I should pass start and end by reference or value since they don't get changed 1681 // Probably use const reference 1682 bool VulkanGame::getLaserAndAsteroidIntersection(SceneObject<AsteroidVertex, SSBO_Asteroid>& asteroid, 1683 vec3& start, vec3& end, vec3& intersection) { 1684 /* 1685 ### LINE EQUATIONS ### 1686 x = x1 + u * (x2 - x1) 1687 y = y1 + u * (y2 - y1) 1688 z = z1 + u * (z2 - z1) 1689 1690 ### SPHERE EQUATION ### 1691 (x - x3)^2 + (y - y3)^2 + (z - z3)^2 = r^2 1692 1693 ### QUADRATIC EQUATION TO SOLVE ### 1694 a*u^2 + b*u + c = 0 1695 WHERE THE CONSTANTS ARE 1696 a = (x2 - x1)^2 + (y2 - y1)^2 + (z2 - z1)^2 1697 b = 2*( (x2 - x1)*(x1 - x3) + (y2 - y1)*(y1 - y3) + (z2 - z1)*(z1 - z3) ) 1698 c = x3^2 + y3^2 + z3^2 + x1^2 + y1^2 + z1^2 - 2(x3*x1 + y3*y1 + z3*z1) - r^2 1699 1700 u = (-b +- sqrt(b^2 - 4*a*c)) / 2a 1701 1702 If the value under the root is >= 0, we got an intersection 1703 If the value > 0, there are two solutions. Take the one closer to 0, since that's the 1704 one closer to the laser start point 1705 */ 1706 1707 vec3& center = asteroid.center; 1708 1709 float a = pow(end.x - start.x, 2) + pow(end.y - start.y, 2) + pow(end.z - start.z, 2); 1710 float b = 2 * ((start.x - end.x) * (start.x - center.x) + (end.y - start.y) * (start.y - center.y) + 1711 (end.z - start.z) * (start.z - center.z)); 1712 float c = pow(center.x, 2) + pow(center.y, 2) + pow(center.z, 2) + pow(start.x, 2) + pow(start.y, 2) + 1713 pow(start.z, 2) - 2 * (center.x * start.x + center.y * start.y + center.z * start.z) - 1714 pow(asteroid.radius, 2); 1715 float discriminant = pow(b, 2) - 4 * a * c; 1716 1717 if (discriminant >= 0.0f) { 1718 // In this case, the negative root will always give the point closer to the laser start point 1719 float u = (-b - sqrt(discriminant)) / (2 * a); 1720 1721 // Check that the intersection is within the line segment corresponding to the laser 1722 if (0.0f <= u && u <= 1.0f) { 1723 intersection = start + u * (end - start); 1724 return true; 1725 } 1726 } 1727 1728 return false; 1623 1729 } 1624 1730 -
vulkan-game.hpp
r1f81ecc r3950236 96 96 vec3 center; // currently only matters for asteroids 97 97 float radius; // currently only matters for asteroids 98 SceneObject<AsteroidVertex, SSBO_Asteroid>* targetAsteroid; // currently only used for lasers 98 99 }; 99 100 … … 271 272 void addLaser(vec3 start, vec3 end, vec3 color, float width); 272 273 void translateLaser(size_t index, const vec3& translation); 274 void updateLaserTarget(size_t index); 275 bool getLaserAndAsteroidIntersection(SceneObject<AsteroidVertex, SSBO_Asteroid>& asteroid, 276 vec3& start, vec3& end, vec3& intersection); 273 277 274 278 // TODO: Since addObject() returns a reference to the new object now,
Note:
See TracChangeset
for help on using the changeset viewer.