[DEV] remove mathematic
This commit is contained in:
parent
572d64845c
commit
247f3e6c11
@ -9,6 +9,7 @@
|
|||||||
#include <ephysics/constraint/Joint.h>
|
#include <ephysics/constraint/Joint.h>
|
||||||
#include <ephysics/collision/shapes/CollisionShape.h>
|
#include <ephysics/collision/shapes/CollisionShape.h>
|
||||||
#include <ephysics/engine/DynamicsWorld.h>
|
#include <ephysics/engine/DynamicsWorld.h>
|
||||||
|
#include <ephysics/debug.hpp>
|
||||||
|
|
||||||
// We want to use the ReactPhysics3D namespace
|
// We want to use the ReactPhysics3D namespace
|
||||||
using namespace reactphysics3d;
|
using namespace reactphysics3d;
|
||||||
@ -310,7 +311,9 @@ void RigidBody::updateBroadPhaseState() const {
|
|||||||
|
|
||||||
// Recompute the world-space AABB of the collision shape
|
// Recompute the world-space AABB of the collision shape
|
||||||
AABB aabb;
|
AABB aabb;
|
||||||
|
EPHY_ERROR(" : " << aabb.getMin() << " " << aabb.getMax());
|
||||||
shape->getCollisionShape()->computeAABB(aabb, m_transform *shape->getLocalToBodyTransform());
|
shape->getCollisionShape()->computeAABB(aabb, m_transform *shape->getLocalToBodyTransform());
|
||||||
|
EPHY_ERROR(" : " << aabb.getMin() << " " << aabb.getMax());
|
||||||
|
|
||||||
// Update the broad-phase state for the proxy collision shape
|
// Update the broad-phase state for the proxy collision shape
|
||||||
m_world.m_collisionDetection.updateProxyCollisionShape(shape, aabb, displacement);
|
m_world.m_collisionDetection.updateProxyCollisionShape(shape, aabb, displacement);
|
||||||
|
@ -123,20 +123,17 @@ void BroadPhaseAlgorithm::removeProxyCollisionShape(ProxyShape* proxyShape) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Notify the broad-phase that a collision shape has moved and need to be updated
|
// Notify the broad-phase that a collision shape has moved and need to be updated
|
||||||
void BroadPhaseAlgorithm::updateProxyCollisionShape(ProxyShape* proxyShape, const AABB& aabb,
|
void BroadPhaseAlgorithm::updateProxyCollisionShape(ProxyShape* _proxyShape,
|
||||||
const vec3& displacement, bool forceReinsert) {
|
const AABB& _aabb,
|
||||||
|
const vec3& _displacement,
|
||||||
int32_t broadPhaseID = proxyShape->m_broadPhaseID;
|
bool _forceReinsert) {
|
||||||
|
int32_t broadPhaseID = _proxyShape->m_broadPhaseID;
|
||||||
assert(broadPhaseID >= 0);
|
assert(broadPhaseID >= 0);
|
||||||
|
|
||||||
// Update the dynamic AABB tree according to the movement of the collision shape
|
// Update the dynamic AABB tree according to the movement of the collision shape
|
||||||
bool hasBeenReInserted = m_dynamicAABBTree.updateObject(broadPhaseID, aabb, displacement, forceReinsert);
|
bool hasBeenReInserted = m_dynamicAABBTree.updateObject(broadPhaseID, _aabb, _displacement, _forceReinsert);
|
||||||
|
|
||||||
// If the collision shape has moved out of its fat AABB (and therefore has been reinserted
|
// If the collision shape has moved out of its fat AABB (and therefore has been reinserted
|
||||||
// int32_to the tree).
|
// int32_to the tree).
|
||||||
if (hasBeenReInserted) {
|
if (hasBeenReInserted) {
|
||||||
|
|
||||||
// Add the collision shape int32_to the array of shapes that have moved (or have been created)
|
// Add the collision shape int32_to the array of shapes that have moved (or have been created)
|
||||||
// during the last simulation step
|
// during the last simulation step
|
||||||
addMovedCollisionShape(broadPhaseID);
|
addMovedCollisionShape(broadPhaseID);
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <ephysics/collision/broadphase/BroadPhaseAlgorithm.h>
|
#include <ephysics/collision/broadphase/BroadPhaseAlgorithm.h>
|
||||||
#include <ephysics/memory/Stack.h>
|
#include <ephysics/memory/Stack.h>
|
||||||
#include <ephysics/engine/Profiler.h>
|
#include <ephysics/engine/Profiler.h>
|
||||||
|
#include <ephysics/debug.hpp>
|
||||||
|
|
||||||
using namespace reactphysics3d;
|
using namespace reactphysics3d;
|
||||||
|
|
||||||
@ -62,12 +63,9 @@ void DynamicAABBTree::reset() {
|
|||||||
|
|
||||||
// Allocate and return a new node in the tree
|
// Allocate and return a new node in the tree
|
||||||
int32_t DynamicAABBTree::allocateNode() {
|
int32_t DynamicAABBTree::allocateNode() {
|
||||||
|
|
||||||
// If there is no more allocated node to use
|
// If there is no more allocated node to use
|
||||||
if (m_freeNodeID == TreeNode::NULL_TREE_NODE) {
|
if (m_freeNodeID == TreeNode::NULL_TREE_NODE) {
|
||||||
|
|
||||||
assert(m_numberNodes == m_numberAllocatedNodes);
|
assert(m_numberNodes == m_numberAllocatedNodes);
|
||||||
|
|
||||||
// Allocate more nodes in the tree
|
// Allocate more nodes in the tree
|
||||||
m_numberAllocatedNodes *= 2;
|
m_numberAllocatedNodes *= 2;
|
||||||
TreeNode* oldNodes = m_nodes;
|
TreeNode* oldNodes = m_nodes;
|
||||||
@ -75,7 +73,6 @@ int32_t DynamicAABBTree::allocateNode() {
|
|||||||
assert(m_nodes);
|
assert(m_nodes);
|
||||||
memcpy(m_nodes, oldNodes, m_numberNodes * sizeof(TreeNode));
|
memcpy(m_nodes, oldNodes, m_numberNodes * sizeof(TreeNode));
|
||||||
free(oldNodes);
|
free(oldNodes);
|
||||||
|
|
||||||
// Initialize the allocated nodes
|
// Initialize the allocated nodes
|
||||||
for (int32_t i=m_numberNodes; i<m_numberAllocatedNodes - 1; i++) {
|
for (int32_t i=m_numberNodes; i<m_numberAllocatedNodes - 1; i++) {
|
||||||
m_nodes[i].nextNodeID = i + 1;
|
m_nodes[i].nextNodeID = i + 1;
|
||||||
@ -85,26 +82,24 @@ int32_t DynamicAABBTree::allocateNode() {
|
|||||||
m_nodes[m_numberAllocatedNodes - 1].height = -1;
|
m_nodes[m_numberAllocatedNodes - 1].height = -1;
|
||||||
m_freeNodeID = m_numberNodes;
|
m_freeNodeID = m_numberNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the next free node
|
// Get the next free node
|
||||||
int32_t freeNodeID = m_freeNodeID;
|
int32_t freeNodeID = m_freeNodeID;
|
||||||
m_freeNodeID = m_nodes[freeNodeID].nextNodeID;
|
m_freeNodeID = m_nodes[freeNodeID].nextNodeID;
|
||||||
m_nodes[freeNodeID].parentID = TreeNode::NULL_TREE_NODE;
|
m_nodes[freeNodeID].parentID = TreeNode::NULL_TREE_NODE;
|
||||||
m_nodes[freeNodeID].height = 0;
|
m_nodes[freeNodeID].height = 0;
|
||||||
m_numberNodes++;
|
m_numberNodes++;
|
||||||
|
|
||||||
return freeNodeID;
|
return freeNodeID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release a node
|
// Release a node
|
||||||
void DynamicAABBTree::releaseNode(int32_t nodeID) {
|
void DynamicAABBTree::releaseNode(int32_t _nodeID) {
|
||||||
|
|
||||||
assert(m_numberNodes > 0);
|
assert(m_numberNodes > 0);
|
||||||
assert(nodeID >= 0 && nodeID < m_numberAllocatedNodes);
|
assert(_nodeID >= 0 && _nodeID < m_numberAllocatedNodes);
|
||||||
assert(m_nodes[nodeID].height >= 0);
|
assert(m_nodes[_nodeID].height >= 0);
|
||||||
m_nodes[nodeID].nextNodeID = m_freeNodeID;
|
m_nodes[_nodeID].nextNodeID = m_freeNodeID;
|
||||||
m_nodes[nodeID].height = -1;
|
m_nodes[_nodeID].height = -1;
|
||||||
m_freeNodeID = nodeID;
|
m_freeNodeID = _nodeID;
|
||||||
m_numberNodes--;
|
m_numberNodes--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,37 +107,38 @@ void DynamicAABBTree::releaseNode(int32_t nodeID) {
|
|||||||
int32_t DynamicAABBTree::addObjectInternal(const AABB& aabb) {
|
int32_t DynamicAABBTree::addObjectInternal(const AABB& aabb) {
|
||||||
|
|
||||||
// Get the next available node (or allocate new ones if necessary)
|
// Get the next available node (or allocate new ones if necessary)
|
||||||
int32_t nodeID = allocateNode();
|
int32_t _nodeID = allocateNode();
|
||||||
|
|
||||||
// Create the fat aabb to use in the tree
|
// Create the fat aabb to use in the tree
|
||||||
const vec3 gap(m_extraAABBGap, m_extraAABBGap, m_extraAABBGap);
|
const vec3 gap(m_extraAABBGap, m_extraAABBGap, m_extraAABBGap);
|
||||||
m_nodes[nodeID].aabb.setMin(aabb.getMin() - gap);
|
m_nodes[_nodeID].aabb.setMin(aabb.getMin() - gap);
|
||||||
m_nodes[nodeID].aabb.setMax(aabb.getMax() + gap);
|
m_nodes[_nodeID].aabb.setMax(aabb.getMax() + gap);
|
||||||
|
|
||||||
// Set the height of the node in the tree
|
// Set the height of the node in the tree
|
||||||
m_nodes[nodeID].height = 0;
|
m_nodes[_nodeID].height = 0;
|
||||||
|
|
||||||
// Insert the new leaf node in the tree
|
// Insert the new leaf node in the tree
|
||||||
insertLeafNode(nodeID);
|
insertLeafNode(_nodeID);
|
||||||
assert(m_nodes[nodeID].isLeaf());
|
assert(m_nodes[_nodeID].isLeaf());
|
||||||
|
|
||||||
assert(nodeID >= 0);
|
assert(_nodeID >= 0);
|
||||||
|
|
||||||
// Return the Id of the node
|
// Return the Id of the node
|
||||||
return nodeID;
|
return _nodeID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove an object from the tree
|
// Remove an object from the tree
|
||||||
void DynamicAABBTree::removeObject(int32_t nodeID) {
|
void DynamicAABBTree::removeObject(int32_t _nodeID) {
|
||||||
|
|
||||||
assert(nodeID >= 0 && nodeID < m_numberAllocatedNodes);
|
assert(_nodeID >= 0 && _nodeID < m_numberAllocatedNodes);
|
||||||
assert(m_nodes[nodeID].isLeaf());
|
assert(m_nodes[_nodeID].isLeaf());
|
||||||
|
|
||||||
// Remove the node from the tree
|
// Remove the node from the tree
|
||||||
removeLeafNode(nodeID);
|
removeLeafNode(_nodeID);
|
||||||
releaseNode(nodeID);
|
releaseNode(_nodeID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Update the dynamic tree after an object has moved.
|
// Update the dynamic tree after an object has moved.
|
||||||
/// If the new AABB of the object that has moved is still inside its fat AABB, then
|
/// If the new AABB of the object that has moved is still inside its fat AABB, then
|
||||||
/// nothing is done. Otherwise, the corresponding node is removed and reinserted int32_to the tree.
|
/// nothing is done. Otherwise, the corresponding node is removed and reinserted int32_to the tree.
|
||||||
@ -150,49 +146,56 @@ void DynamicAABBTree::removeObject(int32_t nodeID) {
|
|||||||
/// argument is the linear velocity of the AABB multiplied by the elapsed time between two
|
/// argument is the linear velocity of the AABB multiplied by the elapsed time between two
|
||||||
/// frames. If the "forceReinsert" parameter is true, we force a removal and reinsertion of the node
|
/// frames. If the "forceReinsert" parameter is true, we force a removal and reinsertion of the node
|
||||||
/// (this can be useful if the shape AABB has become much smaller than the previous one for instance).
|
/// (this can be useful if the shape AABB has become much smaller than the previous one for instance).
|
||||||
bool DynamicAABBTree::updateObject(int32_t nodeID, const AABB& newAABB, const vec3& displacement, bool forceReinsert) {
|
bool DynamicAABBTree::updateObject(int32_t _nodeID, const AABB& _newAABB, const vec3& _displacement, bool _forceReinsert) {
|
||||||
|
|
||||||
PROFILE("DynamicAABBTree::updateObject()");
|
PROFILE("DynamicAABBTree::updateObject()");
|
||||||
|
|
||||||
assert(nodeID >= 0 && nodeID < m_numberAllocatedNodes);
|
assert(_nodeID >= 0 && _nodeID < m_numberAllocatedNodes);
|
||||||
assert(m_nodes[nodeID].isLeaf());
|
assert(m_nodes[_nodeID].isLeaf());
|
||||||
assert(m_nodes[nodeID].height >= 0);
|
assert(m_nodes[_nodeID].height >= 0);
|
||||||
|
|
||||||
|
EPHY_INFO(" compare : " << m_nodes[_nodeID].aabb.m_minCoordinates << " " << m_nodes[_nodeID].aabb.m_maxCoordinates);
|
||||||
|
EPHY_INFO(" : " << _newAABB.m_minCoordinates << " " << _newAABB.m_maxCoordinates);
|
||||||
// If the new AABB is still inside the fat AABB of the node
|
// If the new AABB is still inside the fat AABB of the node
|
||||||
if (!forceReinsert && m_nodes[nodeID].aabb.contains(newAABB)) {
|
if ( _forceReinsert == false
|
||||||
|
&& m_nodes[_nodeID].aabb.contains(_newAABB)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the new AABB is outside the fat AABB, we remove the corresponding node
|
// If the new AABB is outside the fat AABB, we remove the corresponding node
|
||||||
removeLeafNode(nodeID);
|
removeLeafNode(_nodeID);
|
||||||
|
|
||||||
// Compute the fat AABB by inflating the AABB with a constant gap
|
// Compute the fat AABB by inflating the AABB with a constant gap
|
||||||
m_nodes[nodeID].aabb = newAABB;
|
m_nodes[_nodeID].aabb = _newAABB;
|
||||||
const vec3 gap(m_extraAABBGap, m_extraAABBGap, m_extraAABBGap);
|
const vec3 gap(m_extraAABBGap, m_extraAABBGap, m_extraAABBGap);
|
||||||
m_nodes[nodeID].aabb.m_minCoordinates -= gap;
|
m_nodes[_nodeID].aabb.m_minCoordinates -= gap;
|
||||||
m_nodes[nodeID].aabb.m_maxCoordinates += gap;
|
m_nodes[_nodeID].aabb.m_maxCoordinates += gap;
|
||||||
|
|
||||||
// Inflate the fat AABB in direction of the linear motion of the AABB
|
// Inflate the fat AABB in direction of the linear motion of the AABB
|
||||||
if (displacement.x() < 0.0f) {
|
if (_displacement.x() < 0.0f) {
|
||||||
m_nodes[nodeID].aabb.m_minCoordinates.setX(m_nodes[nodeID].aabb.m_minCoordinates.x() + DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER *displacement.x());
|
m_nodes[_nodeID].aabb.m_minCoordinates.setX(m_nodes[_nodeID].aabb.m_minCoordinates.x() + DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER *_displacement.x());
|
||||||
} else {
|
} else {
|
||||||
m_nodes[nodeID].aabb.m_maxCoordinates.setY(m_nodes[nodeID].aabb.m_maxCoordinates.x() + DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER *displacement.x());
|
m_nodes[_nodeID].aabb.m_maxCoordinates.setX(m_nodes[_nodeID].aabb.m_maxCoordinates.x() + DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER *_displacement.x());
|
||||||
}
|
}
|
||||||
if (displacement.y() < 0.0f) {
|
if (_displacement.y() < 0.0f) {
|
||||||
m_nodes[nodeID].aabb.m_minCoordinates.setY(m_nodes[nodeID].aabb.m_minCoordinates.y() + DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER *displacement.y());
|
m_nodes[_nodeID].aabb.m_minCoordinates.setY(m_nodes[_nodeID].aabb.m_minCoordinates.y() + DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER *_displacement.y());
|
||||||
} else {
|
} else {
|
||||||
m_nodes[nodeID].aabb.m_maxCoordinates.setY(m_nodes[nodeID].aabb.m_maxCoordinates.y() + DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER *displacement.y());
|
m_nodes[_nodeID].aabb.m_maxCoordinates.setY(m_nodes[_nodeID].aabb.m_maxCoordinates.y() + DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER *_displacement.y());
|
||||||
}
|
}
|
||||||
if (displacement.z() < 0.0f) {
|
if (_displacement.z() < 0.0f) {
|
||||||
m_nodes[nodeID].aabb.m_minCoordinates.setZ(m_nodes[nodeID].aabb.m_minCoordinates.z() + DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER *displacement.z());
|
m_nodes[_nodeID].aabb.m_minCoordinates.setZ(m_nodes[_nodeID].aabb.m_minCoordinates.z() + DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER *_displacement.z());
|
||||||
} else {
|
} else {
|
||||||
m_nodes[nodeID].aabb.m_maxCoordinates.setZ(m_nodes[nodeID].aabb.m_maxCoordinates.z() + DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER *displacement.z());
|
m_nodes[_nodeID].aabb.m_maxCoordinates.setZ(m_nodes[_nodeID].aabb.m_maxCoordinates.z() + DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER *_displacement.z());
|
||||||
}
|
}
|
||||||
|
EPHY_ERROR(" compare : " << m_nodes[_nodeID].aabb.m_minCoordinates << " " << m_nodes[_nodeID].aabb.m_maxCoordinates);
|
||||||
assert(m_nodes[nodeID].aabb.contains(newAABB));
|
EPHY_ERROR(" : " << _newAABB.m_minCoordinates << " " << _newAABB.m_maxCoordinates);
|
||||||
|
if (m_nodes[_nodeID].aabb.contains(_newAABB) == false) {
|
||||||
|
//EPHY_CRITICAL("ERROR");
|
||||||
|
}
|
||||||
|
assert(m_nodes[_nodeID].aabb.contains(_newAABB));
|
||||||
|
|
||||||
// Reinsert the node int32_to the tree
|
// Reinsert the node int32_to the tree
|
||||||
insertLeafNode(nodeID);
|
insertLeafNode(_nodeID);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -200,11 +203,11 @@ bool DynamicAABBTree::updateObject(int32_t nodeID, const AABB& newAABB, const ve
|
|||||||
// Insert a leaf node in the tree. The process of inserting a new leaf node
|
// Insert a leaf node in the tree. The process of inserting a new leaf node
|
||||||
// in the dynamic tree is described in the book "Introduction to Game Physics
|
// in the dynamic tree is described in the book "Introduction to Game Physics
|
||||||
// with Box2D" by Ian Parberry.
|
// with Box2D" by Ian Parberry.
|
||||||
void DynamicAABBTree::insertLeafNode(int32_t nodeID) {
|
void DynamicAABBTree::insertLeafNode(int32_t _nodeID) {
|
||||||
|
|
||||||
// If the tree is empty
|
// If the tree is empty
|
||||||
if (m_rootNodeID == TreeNode::NULL_TREE_NODE) {
|
if (m_rootNodeID == TreeNode::NULL_TREE_NODE) {
|
||||||
m_rootNodeID = nodeID;
|
m_rootNodeID = _nodeID;
|
||||||
m_nodes[m_rootNodeID].parentID = TreeNode::NULL_TREE_NODE;
|
m_nodes[m_rootNodeID].parentID = TreeNode::NULL_TREE_NODE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -212,7 +215,7 @@ void DynamicAABBTree::insertLeafNode(int32_t nodeID) {
|
|||||||
assert(m_rootNodeID != TreeNode::NULL_TREE_NODE);
|
assert(m_rootNodeID != TreeNode::NULL_TREE_NODE);
|
||||||
|
|
||||||
// Find the best sibling node for the new node
|
// Find the best sibling node for the new node
|
||||||
AABB newNodeAABB = m_nodes[nodeID].aabb;
|
AABB newNodeAABB = m_nodes[_nodeID].aabb;
|
||||||
int32_t currentNodeID = m_rootNodeID;
|
int32_t currentNodeID = m_rootNodeID;
|
||||||
while (!m_nodes[currentNodeID].isLeaf()) {
|
while (!m_nodes[currentNodeID].isLeaf()) {
|
||||||
|
|
||||||
@ -288,26 +291,26 @@ void DynamicAABBTree::insertLeafNode(int32_t nodeID) {
|
|||||||
m_nodes[oldParentNode].children[1] = newParentNode;
|
m_nodes[oldParentNode].children[1] = newParentNode;
|
||||||
}
|
}
|
||||||
m_nodes[newParentNode].children[0] = siblingNode;
|
m_nodes[newParentNode].children[0] = siblingNode;
|
||||||
m_nodes[newParentNode].children[1] = nodeID;
|
m_nodes[newParentNode].children[1] = _nodeID;
|
||||||
m_nodes[siblingNode].parentID = newParentNode;
|
m_nodes[siblingNode].parentID = newParentNode;
|
||||||
m_nodes[nodeID].parentID = newParentNode;
|
m_nodes[_nodeID].parentID = newParentNode;
|
||||||
}
|
}
|
||||||
else { // If the sibling node was the root node
|
else { // If the sibling node was the root node
|
||||||
m_nodes[newParentNode].children[0] = siblingNode;
|
m_nodes[newParentNode].children[0] = siblingNode;
|
||||||
m_nodes[newParentNode].children[1] = nodeID;
|
m_nodes[newParentNode].children[1] = _nodeID;
|
||||||
m_nodes[siblingNode].parentID = newParentNode;
|
m_nodes[siblingNode].parentID = newParentNode;
|
||||||
m_nodes[nodeID].parentID = newParentNode;
|
m_nodes[_nodeID].parentID = newParentNode;
|
||||||
m_rootNodeID = newParentNode;
|
m_rootNodeID = newParentNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move up in the tree to change the AABBs that have changed
|
// Move up in the tree to change the AABBs that have changed
|
||||||
currentNodeID = m_nodes[nodeID].parentID;
|
currentNodeID = m_nodes[_nodeID].parentID;
|
||||||
assert(!m_nodes[currentNodeID].isLeaf());
|
assert(!m_nodes[currentNodeID].isLeaf());
|
||||||
while (currentNodeID != TreeNode::NULL_TREE_NODE) {
|
while (currentNodeID != TreeNode::NULL_TREE_NODE) {
|
||||||
|
|
||||||
// Balance the sub-tree of the current node if it is not balanced
|
// Balance the sub-tree of the current node if it is not balanced
|
||||||
currentNodeID = balanceSubTreeAtNode(currentNodeID);
|
currentNodeID = balanceSubTreeAtNode(currentNodeID);
|
||||||
assert(m_nodes[nodeID].isLeaf());
|
assert(m_nodes[_nodeID].isLeaf());
|
||||||
|
|
||||||
assert(!m_nodes[currentNodeID].isLeaf());
|
assert(!m_nodes[currentNodeID].isLeaf());
|
||||||
int32_t leftChild = m_nodes[currentNodeID].children[0];
|
int32_t leftChild = m_nodes[currentNodeID].children[0];
|
||||||
@ -326,25 +329,25 @@ void DynamicAABBTree::insertLeafNode(int32_t nodeID) {
|
|||||||
currentNodeID = m_nodes[currentNodeID].parentID;
|
currentNodeID = m_nodes[currentNodeID].parentID;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(m_nodes[nodeID].isLeaf());
|
assert(m_nodes[_nodeID].isLeaf());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove a leaf node from the tree
|
// Remove a leaf node from the tree
|
||||||
void DynamicAABBTree::removeLeafNode(int32_t nodeID) {
|
void DynamicAABBTree::removeLeafNode(int32_t _nodeID) {
|
||||||
|
|
||||||
assert(nodeID >= 0 && nodeID < m_numberAllocatedNodes);
|
assert(_nodeID >= 0 && _nodeID < m_numberAllocatedNodes);
|
||||||
assert(m_nodes[nodeID].isLeaf());
|
assert(m_nodes[_nodeID].isLeaf());
|
||||||
|
|
||||||
// If we are removing the root node (root node is a leaf in this case)
|
// If we are removing the root node (root node is a leaf in this case)
|
||||||
if (m_rootNodeID == nodeID) {
|
if (m_rootNodeID == _nodeID) {
|
||||||
m_rootNodeID = TreeNode::NULL_TREE_NODE;
|
m_rootNodeID = TreeNode::NULL_TREE_NODE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t parentNodeID = m_nodes[nodeID].parentID;
|
int32_t parentNodeID = m_nodes[_nodeID].parentID;
|
||||||
int32_t grandParentNodeID = m_nodes[parentNodeID].parentID;
|
int32_t grandParentNodeID = m_nodes[parentNodeID].parentID;
|
||||||
int32_t siblingNodeID;
|
int32_t siblingNodeID;
|
||||||
if (m_nodes[parentNodeID].children[0] == nodeID) {
|
if (m_nodes[parentNodeID].children[0] == _nodeID) {
|
||||||
siblingNodeID = m_nodes[parentNodeID].children[1];
|
siblingNodeID = m_nodes[parentNodeID].children[1];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -401,17 +404,17 @@ void DynamicAABBTree::removeLeafNode(int32_t nodeID) {
|
|||||||
// Balance the sub-tree of a given node using left or right rotations.
|
// Balance the sub-tree of a given node using left or right rotations.
|
||||||
/// The rotation schemes are described in the book "Introduction to Game Physics
|
/// The rotation schemes are described in the book "Introduction to Game Physics
|
||||||
/// with Box2D" by Ian Parberry. This method returns the new root node ID.
|
/// with Box2D" by Ian Parberry. This method returns the new root node ID.
|
||||||
int32_t DynamicAABBTree::balanceSubTreeAtNode(int32_t nodeID) {
|
int32_t DynamicAABBTree::balanceSubTreeAtNode(int32_t _nodeID) {
|
||||||
|
|
||||||
assert(nodeID != TreeNode::NULL_TREE_NODE);
|
assert(_nodeID != TreeNode::NULL_TREE_NODE);
|
||||||
|
|
||||||
TreeNode* nodeA = m_nodes + nodeID;
|
TreeNode* nodeA = m_nodes + _nodeID;
|
||||||
|
|
||||||
// If the node is a leaf or the height of A's sub-tree is less than 2
|
// If the node is a leaf or the height of A's sub-tree is less than 2
|
||||||
if (nodeA->isLeaf() || nodeA->height < 2) {
|
if (nodeA->isLeaf() || nodeA->height < 2) {
|
||||||
|
|
||||||
// Do not perform any rotation
|
// Do not perform any rotation
|
||||||
return nodeID;
|
return _nodeID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the two children nodes
|
// Get the two children nodes
|
||||||
@ -437,17 +440,17 @@ int32_t DynamicAABBTree::balanceSubTreeAtNode(int32_t nodeID) {
|
|||||||
TreeNode* nodeF = m_nodes + nodeFID;
|
TreeNode* nodeF = m_nodes + nodeFID;
|
||||||
TreeNode* nodeG = m_nodes + nodeGID;
|
TreeNode* nodeG = m_nodes + nodeGID;
|
||||||
|
|
||||||
nodeC->children[0] = nodeID;
|
nodeC->children[0] = _nodeID;
|
||||||
nodeC->parentID = nodeA->parentID;
|
nodeC->parentID = nodeA->parentID;
|
||||||
nodeA->parentID = nodeCID;
|
nodeA->parentID = nodeCID;
|
||||||
|
|
||||||
if (nodeC->parentID != TreeNode::NULL_TREE_NODE) {
|
if (nodeC->parentID != TreeNode::NULL_TREE_NODE) {
|
||||||
|
|
||||||
if (m_nodes[nodeC->parentID].children[0] == nodeID) {
|
if (m_nodes[nodeC->parentID].children[0] == _nodeID) {
|
||||||
m_nodes[nodeC->parentID].children[0] = nodeCID;
|
m_nodes[nodeC->parentID].children[0] = nodeCID;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert(m_nodes[nodeC->parentID].children[1] == nodeID);
|
assert(m_nodes[nodeC->parentID].children[1] == _nodeID);
|
||||||
m_nodes[nodeC->parentID].children[1] = nodeCID;
|
m_nodes[nodeC->parentID].children[1] = nodeCID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -463,7 +466,7 @@ int32_t DynamicAABBTree::balanceSubTreeAtNode(int32_t nodeID) {
|
|||||||
|
|
||||||
nodeC->children[1] = nodeFID;
|
nodeC->children[1] = nodeFID;
|
||||||
nodeA->children[1] = nodeGID;
|
nodeA->children[1] = nodeGID;
|
||||||
nodeG->parentID = nodeID;
|
nodeG->parentID = _nodeID;
|
||||||
|
|
||||||
// Recompute the AABB of node A and C
|
// Recompute the AABB of node A and C
|
||||||
nodeA->aabb.mergeTwoAABBs(nodeB->aabb, nodeG->aabb);
|
nodeA->aabb.mergeTwoAABBs(nodeB->aabb, nodeG->aabb);
|
||||||
@ -478,7 +481,7 @@ int32_t DynamicAABBTree::balanceSubTreeAtNode(int32_t nodeID) {
|
|||||||
else { // If the right node C was higher than left node B because of node G
|
else { // If the right node C was higher than left node B because of node G
|
||||||
nodeC->children[1] = nodeGID;
|
nodeC->children[1] = nodeGID;
|
||||||
nodeA->children[1] = nodeFID;
|
nodeA->children[1] = nodeFID;
|
||||||
nodeF->parentID = nodeID;
|
nodeF->parentID = _nodeID;
|
||||||
|
|
||||||
// Recompute the AABB of node A and C
|
// Recompute the AABB of node A and C
|
||||||
nodeA->aabb.mergeTwoAABBs(nodeB->aabb, nodeF->aabb);
|
nodeA->aabb.mergeTwoAABBs(nodeB->aabb, nodeF->aabb);
|
||||||
@ -507,17 +510,17 @@ int32_t DynamicAABBTree::balanceSubTreeAtNode(int32_t nodeID) {
|
|||||||
TreeNode* nodeF = m_nodes + nodeFID;
|
TreeNode* nodeF = m_nodes + nodeFID;
|
||||||
TreeNode* nodeG = m_nodes + nodeGID;
|
TreeNode* nodeG = m_nodes + nodeGID;
|
||||||
|
|
||||||
nodeB->children[0] = nodeID;
|
nodeB->children[0] = _nodeID;
|
||||||
nodeB->parentID = nodeA->parentID;
|
nodeB->parentID = nodeA->parentID;
|
||||||
nodeA->parentID = nodeBID;
|
nodeA->parentID = nodeBID;
|
||||||
|
|
||||||
if (nodeB->parentID != TreeNode::NULL_TREE_NODE) {
|
if (nodeB->parentID != TreeNode::NULL_TREE_NODE) {
|
||||||
|
|
||||||
if (m_nodes[nodeB->parentID].children[0] == nodeID) {
|
if (m_nodes[nodeB->parentID].children[0] == _nodeID) {
|
||||||
m_nodes[nodeB->parentID].children[0] = nodeBID;
|
m_nodes[nodeB->parentID].children[0] = nodeBID;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert(m_nodes[nodeB->parentID].children[1] == nodeID);
|
assert(m_nodes[nodeB->parentID].children[1] == _nodeID);
|
||||||
m_nodes[nodeB->parentID].children[1] = nodeBID;
|
m_nodes[nodeB->parentID].children[1] = nodeBID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -533,7 +536,7 @@ int32_t DynamicAABBTree::balanceSubTreeAtNode(int32_t nodeID) {
|
|||||||
|
|
||||||
nodeB->children[1] = nodeFID;
|
nodeB->children[1] = nodeFID;
|
||||||
nodeA->children[0] = nodeGID;
|
nodeA->children[0] = nodeGID;
|
||||||
nodeG->parentID = nodeID;
|
nodeG->parentID = _nodeID;
|
||||||
|
|
||||||
// Recompute the AABB of node A and B
|
// Recompute the AABB of node A and B
|
||||||
nodeA->aabb.mergeTwoAABBs(nodeC->aabb, nodeG->aabb);
|
nodeA->aabb.mergeTwoAABBs(nodeC->aabb, nodeG->aabb);
|
||||||
@ -548,7 +551,7 @@ int32_t DynamicAABBTree::balanceSubTreeAtNode(int32_t nodeID) {
|
|||||||
else { // If the left node B was higher than right node C because of node G
|
else { // If the left node B was higher than right node C because of node G
|
||||||
nodeB->children[1] = nodeGID;
|
nodeB->children[1] = nodeGID;
|
||||||
nodeA->children[0] = nodeFID;
|
nodeA->children[0] = nodeFID;
|
||||||
nodeF->parentID = nodeID;
|
nodeF->parentID = _nodeID;
|
||||||
|
|
||||||
// Recompute the AABB of node A and B
|
// Recompute the AABB of node A and B
|
||||||
nodeA->aabb.mergeTwoAABBs(nodeC->aabb, nodeF->aabb);
|
nodeA->aabb.mergeTwoAABBs(nodeC->aabb, nodeF->aabb);
|
||||||
@ -566,7 +569,7 @@ int32_t DynamicAABBTree::balanceSubTreeAtNode(int32_t nodeID) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the sub-tree is balanced, return the current root node
|
// If the sub-tree is balanced, return the current root node
|
||||||
return nodeID;
|
return _nodeID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Report all shapes overlapping with the AABB given in parameter.
|
/// Report all shapes overlapping with the AABB given in parameter.
|
||||||
@ -692,17 +695,17 @@ void DynamicAABBTree::check() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if the node structure is valid (for debugging purpose)
|
// Check if the node structure is valid (for debugging purpose)
|
||||||
void DynamicAABBTree::checkNode(int32_t nodeID) const {
|
void DynamicAABBTree::checkNode(int32_t _nodeID) const {
|
||||||
|
|
||||||
if (nodeID == TreeNode::NULL_TREE_NODE) return;
|
if (_nodeID == TreeNode::NULL_TREE_NODE) return;
|
||||||
|
|
||||||
// If it is the root
|
// If it is the root
|
||||||
if (nodeID == m_rootNodeID) {
|
if (_nodeID == m_rootNodeID) {
|
||||||
assert(m_nodes[nodeID].parentID == TreeNode::NULL_TREE_NODE);
|
assert(m_nodes[_nodeID].parentID == TreeNode::NULL_TREE_NODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the children nodes
|
// Get the children nodes
|
||||||
TreeNode* pNode = m_nodes + nodeID;
|
TreeNode* pNode = m_nodes + _nodeID;
|
||||||
assert(!pNode->isLeaf());
|
assert(!pNode->isLeaf());
|
||||||
int32_t leftChild = pNode->children[0];
|
int32_t leftChild = pNode->children[0];
|
||||||
int32_t rightChild = pNode->children[1];
|
int32_t rightChild = pNode->children[1];
|
||||||
@ -725,18 +728,18 @@ void DynamicAABBTree::checkNode(int32_t nodeID) const {
|
|||||||
assert(0 <= rightChild && rightChild < m_numberAllocatedNodes);
|
assert(0 <= rightChild && rightChild < m_numberAllocatedNodes);
|
||||||
|
|
||||||
// Check that the children nodes have the correct parent node
|
// Check that the children nodes have the correct parent node
|
||||||
assert(m_nodes[leftChild].parentID == nodeID);
|
assert(m_nodes[leftChild].parentID == _nodeID);
|
||||||
assert(m_nodes[rightChild].parentID == nodeID);
|
assert(m_nodes[rightChild].parentID == _nodeID);
|
||||||
|
|
||||||
// Check the height of node
|
// Check the height of node
|
||||||
int32_t height = 1 + std::max(m_nodes[leftChild].height, m_nodes[rightChild].height);
|
int32_t height = 1 + std::max(m_nodes[leftChild].height, m_nodes[rightChild].height);
|
||||||
assert(m_nodes[nodeID].height == height);
|
assert(m_nodes[_nodeID].height == height);
|
||||||
|
|
||||||
// Check the AABB of the node
|
// Check the AABB of the node
|
||||||
AABB aabb;
|
AABB aabb;
|
||||||
aabb.mergeTwoAABBs(m_nodes[leftChild].aabb, m_nodes[rightChild].aabb);
|
aabb.mergeTwoAABBs(m_nodes[leftChild].aabb, m_nodes[rightChild].aabb);
|
||||||
assert(aabb.getMin() == m_nodes[nodeID].aabb.getMin());
|
assert(aabb.getMin() == m_nodes[_nodeID].aabb.getMin());
|
||||||
assert(aabb.getMax() == m_nodes[nodeID].aabb.getMax());
|
assert(aabb.getMax() == m_nodes[_nodeID].aabb.getMax());
|
||||||
|
|
||||||
// Recursively check the children nodes
|
// Recursively check the children nodes
|
||||||
checkNode(leftChild);
|
checkNode(leftChild);
|
||||||
@ -750,9 +753,9 @@ int32_t DynamicAABBTree::computeHeight() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compute the height of a given node in the tree
|
// Compute the height of a given node in the tree
|
||||||
int32_t DynamicAABBTree::computeHeight(int32_t nodeID) {
|
int32_t DynamicAABBTree::computeHeight(int32_t _nodeID) {
|
||||||
assert(nodeID >= 0 && nodeID < m_numberAllocatedNodes);
|
assert(_nodeID >= 0 && _nodeID < m_numberAllocatedNodes);
|
||||||
TreeNode* node = m_nodes + nodeID;
|
TreeNode* node = m_nodes + _nodeID;
|
||||||
|
|
||||||
// If the node is a leaf, its height is zero
|
// If the node is a leaf, its height is zero
|
||||||
if (node->isLeaf()) {
|
if (node->isLeaf()) {
|
||||||
|
@ -13,30 +13,24 @@
|
|||||||
using namespace reactphysics3d;
|
using namespace reactphysics3d;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
// Constructor
|
AABB::AABB():
|
||||||
AABB::AABB() {
|
m_minCoordinates(0,0,0),
|
||||||
|
m_maxCoordinates(0,0,0) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructor
|
|
||||||
AABB::AABB(const vec3& minCoordinates, const vec3& maxCoordinates):
|
AABB::AABB(const vec3& minCoordinates, const vec3& maxCoordinates):
|
||||||
m_minCoordinates(minCoordinates),
|
m_minCoordinates(minCoordinates),
|
||||||
m_maxCoordinates(maxCoordinates) {
|
m_maxCoordinates(maxCoordinates) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy-constructor
|
|
||||||
AABB::AABB(const AABB& aabb):
|
AABB::AABB(const AABB& aabb):
|
||||||
m_minCoordinates(aabb.m_minCoordinates),
|
m_minCoordinates(aabb.m_minCoordinates),
|
||||||
m_maxCoordinates(aabb.m_maxCoordinates) {
|
m_maxCoordinates(aabb.m_maxCoordinates) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
|
||||||
AABB::~AABB() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Merge the AABB in parameter with the current one
|
// Merge the AABB in parameter with the current one
|
||||||
void AABB::mergeWithAABB(const AABB& aabb) {
|
void AABB::mergeWithAABB(const AABB& aabb) {
|
||||||
m_minCoordinates.setX(std::min(m_minCoordinates.x(), aabb.m_minCoordinates.x()));
|
m_minCoordinates.setX(std::min(m_minCoordinates.x(), aabb.m_minCoordinates.x()));
|
||||||
|
@ -43,9 +43,6 @@ class AABB {
|
|||||||
/// Copy-constructor
|
/// Copy-constructor
|
||||||
AABB(const AABB& aabb);
|
AABB(const AABB& aabb);
|
||||||
|
|
||||||
/// Destructor
|
|
||||||
~AABB();
|
|
||||||
|
|
||||||
/// Return the center point
|
/// Return the center point
|
||||||
vec3 getCenter() const;
|
vec3 getCenter() const;
|
||||||
|
|
||||||
|
@ -18,16 +18,12 @@ using namespace reactphysics3d;
|
|||||||
* @param extent The vector with the three extents of the box (in meters)
|
* @param extent The vector with the three extents of the box (in meters)
|
||||||
* @param margin The collision margin (in meters) around the collision shape
|
* @param margin The collision margin (in meters) around the collision shape
|
||||||
*/
|
*/
|
||||||
BoxShape::BoxShape(const vec3& extent, float margin)
|
BoxShape::BoxShape(const vec3& _extent, float _margin):
|
||||||
: ConvexShape(BOX, margin), m_extent(extent - vec3(margin, margin, margin)) {
|
ConvexShape(BOX, _margin),
|
||||||
assert(extent.x() > 0.0f && extent.x() > margin);
|
m_extent(_extent - vec3(_margin, _margin, _margin)) {
|
||||||
assert(extent.y() > 0.0f && extent.y() > margin);
|
assert(_extent.x() > 0.0f && _extent.x() > _margin);
|
||||||
assert(extent.z() > 0.0f && extent.z() > margin);
|
assert(_extent.y() > 0.0f && _extent.y() > _margin);
|
||||||
}
|
assert(_extent.z() > 0.0f && _extent.z() > _margin);
|
||||||
|
|
||||||
// Destructor
|
|
||||||
BoxShape::~BoxShape() {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the local inertia tensor of the collision shape
|
// Return the local inertia tensor of the collision shape
|
||||||
|
@ -32,14 +32,8 @@ namespace reactphysics3d {
|
|||||||
class BoxShape : public ConvexShape {
|
class BoxShape : public ConvexShape {
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
|
||||||
|
|
||||||
/// Extent sizes of the box in the x, y and z direction
|
/// Extent sizes of the box in the x, y and z direction
|
||||||
vec3 m_extent;
|
vec3 m_extent;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
|
||||||
|
|
||||||
/// Private copy-constructor
|
/// Private copy-constructor
|
||||||
BoxShape(const BoxShape& shape);
|
BoxShape(const BoxShape& shape);
|
||||||
|
|
||||||
@ -60,14 +54,11 @@ class BoxShape : public ConvexShape {
|
|||||||
virtual size_t getSizeInBytes() const;
|
virtual size_t getSizeInBytes() const;
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
BoxShape(const vec3& extent, float margin = OBJECT_MARGIN);
|
BoxShape(const vec3& extent, float margin = OBJECT_MARGIN);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
virtual ~BoxShape();
|
virtual ~BoxShape() = default;
|
||||||
|
|
||||||
/// Return the extents of the box
|
/// Return the extents of the box
|
||||||
vec3 getExtent() const;
|
vec3 getExtent() const;
|
||||||
@ -76,7 +67,7 @@ class BoxShape : public ConvexShape {
|
|||||||
virtual void setLocalScaling(const vec3& scaling);
|
virtual void setLocalScaling(const vec3& scaling);
|
||||||
|
|
||||||
/// Return the local bounds of the shape in x, y and z directions
|
/// Return the local bounds of the shape in x, y and z directions
|
||||||
virtual void getLocalBounds(vec3& min, vec3& max) const;
|
virtual void getLocalBounds(vec3& _min, vec3& _max) const;
|
||||||
|
|
||||||
/// Return the local inertia tensor of the collision shape
|
/// Return the local inertia tensor of the collision shape
|
||||||
virtual void computeLocalInertiaTensor(etk::Matrix3x3& tensor, float mass) const;
|
virtual void computeLocalInertiaTensor(etk::Matrix3x3& tensor, float mass) const;
|
||||||
@ -104,13 +95,13 @@ inline void BoxShape::setLocalScaling(const vec3& scaling) {
|
|||||||
* @param min The minimum bounds of the shape in local-space coordinates
|
* @param min The minimum bounds of the shape in local-space coordinates
|
||||||
* @param max The maximum bounds of the shape in local-space coordinates
|
* @param max The maximum bounds of the shape in local-space coordinates
|
||||||
*/
|
*/
|
||||||
inline void BoxShape::getLocalBounds(vec3& min, vec3& max) const {
|
inline void BoxShape::getLocalBounds(vec3& _min, vec3& _max) const {
|
||||||
|
|
||||||
// Maximum bounds
|
// Maximum bounds
|
||||||
max = m_extent + vec3(m_margin, m_margin, m_margin);
|
_max = m_extent + vec3(m_margin, m_margin, m_margin);
|
||||||
|
|
||||||
// Minimum bounds
|
// Minimum bounds
|
||||||
min = -max;
|
_min = -_max;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the number of bytes used by the collision shape
|
// Return the number of bytes used by the collision shape
|
||||||
|
@ -14,13 +14,14 @@ using namespace reactphysics3d;
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
/**
|
/**
|
||||||
* @param radius The radius of the capsule (in meters)
|
* @param _radius The radius of the capsule (in meters)
|
||||||
* @param height The height of the capsule (in meters)
|
* @param _height The height of the capsule (in meters)
|
||||||
*/
|
*/
|
||||||
CapsuleShape::CapsuleShape(float radius, float height)
|
CapsuleShape::CapsuleShape(float _radius, float _height):
|
||||||
: ConvexShape(CAPSULE, radius), m_halfHeight(height * 0.5f) {
|
ConvexShape(CAPSULE, _radius),
|
||||||
assert(radius > 0.0f);
|
m_halfHeight(_height * 0.5f) {
|
||||||
assert(height > 0.0f);
|
assert(_radius > 0.0f);
|
||||||
|
assert(_height > 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
|
@ -24,16 +24,9 @@ namespace reactphysics3d {
|
|||||||
* capsule shape.
|
* capsule shape.
|
||||||
*/
|
*/
|
||||||
class CapsuleShape : public ConvexShape {
|
class CapsuleShape : public ConvexShape {
|
||||||
|
protected:
|
||||||
protected :
|
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
|
||||||
|
|
||||||
/// Half height of the capsule (height = distance between the centers of the two spheres)
|
/// Half height of the capsule (height = distance between the centers of the two spheres)
|
||||||
float m_halfHeight;
|
float m_halfHeight;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
|
||||||
|
|
||||||
/// Private copy-constructor
|
/// Private copy-constructor
|
||||||
CapsuleShape(const CapsuleShape& shape);
|
CapsuleShape(const CapsuleShape& shape);
|
||||||
|
|
||||||
@ -59,11 +52,8 @@ class CapsuleShape : public ConvexShape {
|
|||||||
virtual size_t getSizeInBytes() const;
|
virtual size_t getSizeInBytes() const;
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
CapsuleShape(float radius, float height);
|
CapsuleShape(float _radius, float _height);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
virtual ~CapsuleShape();
|
virtual ~CapsuleShape();
|
||||||
|
@ -12,12 +12,12 @@
|
|||||||
// We want to use the ReactPhysics3D namespace
|
// We want to use the ReactPhysics3D namespace
|
||||||
using namespace reactphysics3d;
|
using namespace reactphysics3d;
|
||||||
|
|
||||||
// Constructor
|
CollisionShape::CollisionShape(CollisionShapeType type) :
|
||||||
CollisionShape::CollisionShape(CollisionShapeType type) : m_type(type), m_scaling(1.0, 1.0, 1.0) {
|
m_type(type),
|
||||||
|
m_scaling(1.0f, 1.0f, 1.0f) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
|
||||||
CollisionShape::~CollisionShape() {
|
CollisionShape::~CollisionShape() {
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -33,18 +33,18 @@ void CollisionShape::computeAABB(AABB& aabb, const etk::Transform3D& transform)
|
|||||||
PROFILE("CollisionShape::computeAABB()");
|
PROFILE("CollisionShape::computeAABB()");
|
||||||
|
|
||||||
// Get the local bounds in x,y and z direction
|
// Get the local bounds in x,y and z direction
|
||||||
vec3 minBounds;
|
vec3 minBounds(0,0,0);
|
||||||
vec3 maxBounds;
|
vec3 maxBounds(0,0,0);
|
||||||
getLocalBounds(minBounds, maxBounds);
|
getLocalBounds(minBounds, maxBounds);
|
||||||
|
|
||||||
// Rotate the local bounds according to the orientation of the body
|
// Rotate the local bounds according to the orientation of the body
|
||||||
etk::Matrix3x3 worldAxis = transform.getOrientation().getMatrix().getAbsolute();
|
etk::Matrix3x3 worldAxis = transform.getOrientation().getMatrix().getAbsolute();
|
||||||
vec3 worldMinBounds(worldAxis.getColumn(0).dot(minBounds),
|
vec3 worldMinBounds(worldAxis.getColumn(0).dot(minBounds),
|
||||||
worldAxis.getColumn(1).dot(minBounds),
|
worldAxis.getColumn(1).dot(minBounds),
|
||||||
worldAxis.getColumn(2).dot(minBounds));
|
worldAxis.getColumn(2).dot(minBounds));
|
||||||
vec3 worldMaxBounds(worldAxis.getColumn(0).dot(maxBounds),
|
vec3 worldMaxBounds(worldAxis.getColumn(0).dot(maxBounds),
|
||||||
worldAxis.getColumn(1).dot(maxBounds),
|
worldAxis.getColumn(1).dot(maxBounds),
|
||||||
worldAxis.getColumn(2).dot(maxBounds));
|
worldAxis.getColumn(2).dot(maxBounds));
|
||||||
|
|
||||||
// Compute the minimum and maximum coordinates of the rotated extents
|
// Compute the minimum and maximum coordinates of the rotated extents
|
||||||
vec3 minCoordinates = transform.getPosition() + worldMinBounds;
|
vec3 minCoordinates = transform.getPosition() + worldMinBounds;
|
||||||
|
@ -33,74 +33,43 @@ class CollisionBody;
|
|||||||
* body that is used during the narrow-phase collision detection.
|
* body that is used during the narrow-phase collision detection.
|
||||||
*/
|
*/
|
||||||
class CollisionShape {
|
class CollisionShape {
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
CollisionShapeType m_type; //!< Type of the collision shape
|
||||||
// -------------------- Attributes -------------------- //
|
vec3 m_scaling; //!< Scaling vector of the collision shape
|
||||||
|
|
||||||
/// Type of the collision shape
|
|
||||||
CollisionShapeType m_type;
|
|
||||||
|
|
||||||
/// Scaling vector of the collision shape
|
|
||||||
vec3 m_scaling;
|
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
|
||||||
|
|
||||||
/// Private copy-constructor
|
/// Private copy-constructor
|
||||||
CollisionShape(const CollisionShape& shape);
|
CollisionShape(const CollisionShape& shape);
|
||||||
|
|
||||||
/// Private assignment operator
|
/// Private assignment operator
|
||||||
CollisionShape& operator=(const CollisionShape& shape);
|
CollisionShape& operator=(const CollisionShape& shape);
|
||||||
|
|
||||||
/// Return true if a point is inside the collision shape
|
/// Return true if a point is inside the collision shape
|
||||||
virtual bool testPointInside(const vec3& worldPoint, ProxyShape* proxyShape) const=0;
|
virtual bool testPointInside(const vec3& worldPoint, ProxyShape* proxyShape) const=0;
|
||||||
|
|
||||||
/// Raycast method with feedback information
|
/// Raycast method with feedback information
|
||||||
virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape) const=0;
|
virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape) const=0;
|
||||||
|
|
||||||
/// Return the number of bytes used by the collision shape
|
/// Return the number of bytes used by the collision shape
|
||||||
virtual size_t getSizeInBytes() const = 0;
|
virtual size_t getSizeInBytes() const = 0;
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
CollisionShape(CollisionShapeType type);
|
CollisionShape(CollisionShapeType type);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
virtual ~CollisionShape();
|
virtual ~CollisionShape();
|
||||||
|
|
||||||
/// Return the type of the collision shapes
|
/// Return the type of the collision shapes
|
||||||
CollisionShapeType getType() const;
|
CollisionShapeType getType() const;
|
||||||
|
|
||||||
/// Return true if the collision shape is convex, false if it is concave
|
/// Return true if the collision shape is convex, false if it is concave
|
||||||
virtual bool isConvex() const=0;
|
virtual bool isConvex() const=0;
|
||||||
|
|
||||||
/// Return the local bounds of the shape in x, y and z directions
|
/// Return the local bounds of the shape in x, y and z directions
|
||||||
virtual void getLocalBounds(vec3& min, vec3& max) const=0;
|
virtual void getLocalBounds(vec3& min, vec3& max) const=0;
|
||||||
|
|
||||||
/// Return the scaling vector of the collision shape
|
/// Return the scaling vector of the collision shape
|
||||||
vec3 getScaling() const;
|
vec3 getScaling() const;
|
||||||
|
|
||||||
/// Set the local scaling vector of the collision shape
|
/// Set the local scaling vector of the collision shape
|
||||||
virtual void setLocalScaling(const vec3& scaling);
|
virtual void setLocalScaling(const vec3& scaling);
|
||||||
|
|
||||||
/// Return the local inertia tensor of the collision shapes
|
/// Return the local inertia tensor of the collision shapes
|
||||||
virtual void computeLocalInertiaTensor(etk::Matrix3x3& tensor, float mass) const=0;
|
virtual void computeLocalInertiaTensor(etk::Matrix3x3& tensor, float mass) const=0;
|
||||||
|
|
||||||
/// Compute the world-space AABB of the collision shape given a transform
|
/// Compute the world-space AABB of the collision shape given a transform
|
||||||
virtual void computeAABB(AABB& aabb, const etk::Transform3D& transform) const;
|
virtual void computeAABB(AABB& aabb, const etk::Transform3D& transform) const;
|
||||||
|
|
||||||
/// Return true if the collision shape type is a convex shape
|
/// Return true if the collision shape type is a convex shape
|
||||||
static bool isConvex(CollisionShapeType shapeType);
|
static bool isConvex(CollisionShapeType shapeType);
|
||||||
|
|
||||||
/// Return the maximum number of contact manifolds in an overlapping pair given two shape types
|
/// Return the maximum number of contact manifolds in an overlapping pair given two shape types
|
||||||
static int32_t computeNbMaxContactManifolds(CollisionShapeType shapeType1,
|
static int32_t computeNbMaxContactManifolds(CollisionShapeType shapeType1,
|
||||||
CollisionShapeType shapeType2);
|
CollisionShapeType shapeType2);
|
||||||
|
|
||||||
// -------------------- Friendship -------------------- //
|
|
||||||
|
|
||||||
friend class ProxyShape;
|
friend class ProxyShape;
|
||||||
friend class CollisionWorld;
|
friend class CollisionWorld;
|
||||||
};
|
};
|
||||||
|
@ -16,31 +16,24 @@ namespace reactphysics3d {
|
|||||||
|
|
||||||
class ConcaveMeshShape;
|
class ConcaveMeshShape;
|
||||||
|
|
||||||
// class ConvexTriangleAABBOverlapCallback
|
|
||||||
class ConvexTriangleAABBOverlapCallback : public DynamicAABBTreeOverlapCallback {
|
class ConvexTriangleAABBOverlapCallback : public DynamicAABBTreeOverlapCallback {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
TriangleCallback& m_triangleTestCallback; //!<
|
||||||
TriangleCallback& m_triangleTestCallback;
|
const ConcaveMeshShape& m_concaveMeshShape; //!< Reference to the concave mesh shape
|
||||||
|
const DynamicAABBTree& m_dynamicAABBTree; //!< Reference to the Dynamic AABB tree
|
||||||
// Reference to the concave mesh shape
|
|
||||||
const ConcaveMeshShape& m_concaveMeshShape;
|
|
||||||
|
|
||||||
// Reference to the Dynamic AABB tree
|
|
||||||
const DynamicAABBTree& m_dynamicAABBTree;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
ConvexTriangleAABBOverlapCallback(TriangleCallback& triangleCallback, const ConcaveMeshShape& concaveShape,
|
ConvexTriangleAABBOverlapCallback(TriangleCallback& _triangleCallback,
|
||||||
const DynamicAABBTree& dynamicAABBTree)
|
const ConcaveMeshShape& _concaveShape,
|
||||||
: m_triangleTestCallback(triangleCallback), m_concaveMeshShape(concaveShape), m_dynamicAABBTree(dynamicAABBTree) {
|
const DynamicAABBTree& _dynamicAABBTree):
|
||||||
|
m_triangleTestCallback(_triangleCallback),
|
||||||
|
m_concaveMeshShape(_concaveShape),
|
||||||
|
m_dynamicAABBTree(_dynamicAABBTree) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when a overlapping node has been found during the call to
|
// Called when a overlapping node has been found during the call to
|
||||||
// DynamicAABBTree:reportAllShapesOverlappingWithAABB()
|
// DynamicAABBTree:reportAllShapesOverlappingWithAABB()
|
||||||
virtual void notifyOverlappingNode(int32_t nodeId);
|
virtual void notifyOverlappingNode(int32_t _nodeId);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,18 +18,15 @@ using namespace reactphysics3d;
|
|||||||
* @param height Height of the cone (in meters)
|
* @param height Height of the cone (in meters)
|
||||||
* @param margin Collision margin (in meters) around the collision shape
|
* @param margin Collision margin (in meters) around the collision shape
|
||||||
*/
|
*/
|
||||||
ConeShape::ConeShape(float radius, float height, float margin)
|
ConeShape::ConeShape(float radius, float height, float margin):
|
||||||
: ConvexShape(CONE, margin), mRadius(radius), m_halfHeight(height * 0.5f) {
|
ConvexShape(CONE, margin),
|
||||||
assert(mRadius > 0.0f);
|
m_radius(radius),
|
||||||
|
m_halfHeight(height * 0.5f) {
|
||||||
|
assert(m_radius > 0.0f);
|
||||||
assert(m_halfHeight > 0.0f);
|
assert(m_halfHeight > 0.0f);
|
||||||
|
|
||||||
// Compute the sine of the semi-angle at the apex point
|
// Compute the sine of the semi-angle at the apex point
|
||||||
mSinTheta = mRadius / (sqrt(mRadius * mRadius + height * height));
|
m_sinTheta = m_radius / (sqrt(m_radius * m_radius + height * height));
|
||||||
}
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
ConeShape::~ConeShape() {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a local support point in a given direction without the object margin
|
// Return a local support point in a given direction without the object margin
|
||||||
@ -37,7 +34,7 @@ vec3 ConeShape::getLocalSupportPointWithoutMargin(const vec3& direction,
|
|||||||
void** cachedCollisionData) const {
|
void** cachedCollisionData) const {
|
||||||
|
|
||||||
const vec3& v = direction;
|
const vec3& v = direction;
|
||||||
float sinThetaTimesLengthV = mSinTheta * v.length();
|
float sinThetaTimesLengthV = m_sinTheta * v.length();
|
||||||
vec3 supportPoint;
|
vec3 supportPoint;
|
||||||
|
|
||||||
if (v.y() > sinThetaTimesLengthV) {
|
if (v.y() > sinThetaTimesLengthV) {
|
||||||
@ -46,7 +43,7 @@ vec3 ConeShape::getLocalSupportPointWithoutMargin(const vec3& direction,
|
|||||||
else {
|
else {
|
||||||
float projectedLength = sqrt(v.x() * v.x() + v.z() * v.z());
|
float projectedLength = sqrt(v.x() * v.x() + v.z() * v.z());
|
||||||
if (projectedLength > MACHINE_EPSILON) {
|
if (projectedLength > MACHINE_EPSILON) {
|
||||||
float d = mRadius / projectedLength;
|
float d = m_radius / projectedLength;
|
||||||
supportPoint = vec3(v.x() * d, -m_halfHeight, v.z() * d);
|
supportPoint = vec3(v.x() * d, -m_halfHeight, v.z() * d);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -70,7 +67,7 @@ bool ConeShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* pr
|
|||||||
vec3 centerBase(0, -m_halfHeight, 0);
|
vec3 centerBase(0, -m_halfHeight, 0);
|
||||||
vec3 axis(0, float(-1.0), 0);
|
vec3 axis(0, float(-1.0), 0);
|
||||||
float heightSquare = float(4.0) * m_halfHeight * m_halfHeight;
|
float heightSquare = float(4.0) * m_halfHeight * m_halfHeight;
|
||||||
float cosThetaSquare = heightSquare / (heightSquare + mRadius * mRadius);
|
float cosThetaSquare = heightSquare / (heightSquare + m_radius * m_radius);
|
||||||
float factor = 1.0f - cosThetaSquare;
|
float factor = 1.0f - cosThetaSquare;
|
||||||
vec3 delta = ray.point1 - V;
|
vec3 delta = ray.point1 - V;
|
||||||
float c0 = -cosThetaSquare * delta.x() * delta.x() + factor * delta.y() * delta.y() -
|
float c0 = -cosThetaSquare * delta.x() * delta.x() + factor * delta.y() * delta.y() -
|
||||||
@ -148,7 +145,7 @@ bool ConeShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* pr
|
|||||||
// Only keep this int32_tersection if it is inside the cone radius
|
// Only keep this int32_tersection if it is inside the cone radius
|
||||||
localHitPoint[2] = ray.point1 + tHit[2] * r;
|
localHitPoint[2] = ray.point1 + tHit[2] * r;
|
||||||
|
|
||||||
if ((localHitPoint[2] - centerBase).length2() > mRadius * mRadius) {
|
if ((localHitPoint[2] - centerBase).length2() > m_radius * m_radius) {
|
||||||
tHit[2] = float(-1.0);
|
tHit[2] = float(-1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +172,7 @@ bool ConeShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* pr
|
|||||||
float h = float(2.0) * m_halfHeight;
|
float h = float(2.0) * m_halfHeight;
|
||||||
float value1 = (localHitPoint[hitIndex].x() * localHitPoint[hitIndex].x() +
|
float value1 = (localHitPoint[hitIndex].x() * localHitPoint[hitIndex].x() +
|
||||||
localHitPoint[hitIndex].z() * localHitPoint[hitIndex].z());
|
localHitPoint[hitIndex].z() * localHitPoint[hitIndex].z());
|
||||||
float rOverH = mRadius / h;
|
float rOverH = m_radius / h;
|
||||||
float value2 = 1.0f + rOverH * rOverH;
|
float value2 = 1.0f + rOverH * rOverH;
|
||||||
float factor = 1.0f / std::sqrt(value1 * value2);
|
float factor = 1.0f / std::sqrt(value1 * value2);
|
||||||
float x = localHitPoint[hitIndex].x() * factor;
|
float x = localHitPoint[hitIndex].x() * factor;
|
||||||
|
@ -29,22 +29,13 @@ namespace reactphysics3d {
|
|||||||
* default margin distance by not using the "margin" parameter in the constructor.
|
* default margin distance by not using the "margin" parameter in the constructor.
|
||||||
*/
|
*/
|
||||||
class ConeShape : public ConvexShape {
|
class ConeShape : public ConvexShape {
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
|
||||||
|
|
||||||
/// Radius of the base
|
/// Radius of the base
|
||||||
float mRadius;
|
float m_radius;
|
||||||
|
|
||||||
/// Half height of the cone
|
/// Half height of the cone
|
||||||
float m_halfHeight;
|
float m_halfHeight;
|
||||||
|
|
||||||
/// sine of the semi angle at the apex point
|
/// sine of the semi angle at the apex point
|
||||||
float mSinTheta;
|
float m_sinTheta;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
|
||||||
|
|
||||||
/// Private copy-constructor
|
/// Private copy-constructor
|
||||||
ConeShape(const ConeShape& shape);
|
ConeShape(const ConeShape& shape);
|
||||||
|
|
||||||
@ -69,10 +60,7 @@ class ConeShape : public ConvexShape {
|
|||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
ConeShape(float mRadius, float height, float margin = OBJECT_MARGIN);
|
ConeShape(float m_radius, float height, float margin = OBJECT_MARGIN);
|
||||||
|
|
||||||
/// Destructor
|
|
||||||
virtual ~ConeShape();
|
|
||||||
|
|
||||||
/// Return the radius
|
/// Return the radius
|
||||||
float getRadius() const;
|
float getRadius() const;
|
||||||
@ -95,7 +83,7 @@ class ConeShape : public ConvexShape {
|
|||||||
* @return Radius of the cone (in meters)
|
* @return Radius of the cone (in meters)
|
||||||
*/
|
*/
|
||||||
inline float ConeShape::getRadius() const {
|
inline float ConeShape::getRadius() const {
|
||||||
return mRadius;
|
return m_radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the height
|
// Return the height
|
||||||
@ -110,7 +98,7 @@ inline float ConeShape::getHeight() const {
|
|||||||
inline void ConeShape::setLocalScaling(const vec3& scaling) {
|
inline void ConeShape::setLocalScaling(const vec3& scaling) {
|
||||||
|
|
||||||
m_halfHeight = (m_halfHeight / m_scaling.y()) * scaling.y();
|
m_halfHeight = (m_halfHeight / m_scaling.y()) * scaling.y();
|
||||||
mRadius = (mRadius / m_scaling.x()) * scaling.x();
|
m_radius = (m_radius / m_scaling.x()) * scaling.x();
|
||||||
|
|
||||||
CollisionShape::setLocalScaling(scaling);
|
CollisionShape::setLocalScaling(scaling);
|
||||||
}
|
}
|
||||||
@ -128,7 +116,7 @@ inline size_t ConeShape::getSizeInBytes() const {
|
|||||||
inline void ConeShape::getLocalBounds(vec3& min, vec3& max) const {
|
inline void ConeShape::getLocalBounds(vec3& min, vec3& max) const {
|
||||||
|
|
||||||
// Maximum bounds
|
// Maximum bounds
|
||||||
max.setX(mRadius + m_margin);
|
max.setX(m_radius + m_margin);
|
||||||
max.setY(m_halfHeight + m_margin);
|
max.setY(m_halfHeight + m_margin);
|
||||||
max.setZ(max.x());
|
max.setZ(max.x());
|
||||||
|
|
||||||
@ -145,7 +133,7 @@ inline void ConeShape::getLocalBounds(vec3& min, vec3& max) const {
|
|||||||
* @param mass Mass to use to compute the inertia tensor of the collision shape
|
* @param mass Mass to use to compute the inertia tensor of the collision shape
|
||||||
*/
|
*/
|
||||||
inline void ConeShape::computeLocalInertiaTensor(etk::Matrix3x3& tensor, float mass) const {
|
inline void ConeShape::computeLocalInertiaTensor(etk::Matrix3x3& tensor, float mass) const {
|
||||||
float rSquare = mRadius * mRadius;
|
float rSquare = m_radius * m_radius;
|
||||||
float diagXZ = float(0.15) * mass * (rSquare + m_halfHeight);
|
float diagXZ = float(0.15) * mass * (rSquare + m_halfHeight);
|
||||||
tensor.setValue(diagXZ, 0.0, 0.0,
|
tensor.setValue(diagXZ, 0.0, 0.0,
|
||||||
0.0, float(0.3) * mass * rSquare,
|
0.0, float(0.3) * mass * rSquare,
|
||||||
@ -154,7 +142,7 @@ inline void ConeShape::computeLocalInertiaTensor(etk::Matrix3x3& tensor, float m
|
|||||||
|
|
||||||
// Return true if a point is inside the collision shape
|
// Return true if a point is inside the collision shape
|
||||||
inline bool ConeShape::testPointInside(const vec3& localPoint, ProxyShape* proxyShape) const {
|
inline bool ConeShape::testPointInside(const vec3& localPoint, ProxyShape* proxyShape) const {
|
||||||
const float radiusHeight = mRadius * (-localPoint.y() + m_halfHeight) /
|
const float radiusHeight = m_radius * (-localPoint.y() + m_halfHeight) /
|
||||||
(m_halfHeight * float(2.0));
|
(m_halfHeight * float(2.0));
|
||||||
return (localPoint.y() < m_halfHeight && localPoint.y() > -m_halfHeight) &&
|
return (localPoint.y() < m_halfHeight && localPoint.y() > -m_halfHeight) &&
|
||||||
(localPoint.x() * localPoint.x() + localPoint.z() * localPoint.z() < radiusHeight *radiusHeight);
|
(localPoint.x() * localPoint.x() + localPoint.z() * localPoint.z() < radiusHeight *radiusHeight);
|
||||||
|
@ -93,7 +93,7 @@ void HingeJoint::initBeforeSolve(const ConstraintSolverData& constraintSolverDat
|
|||||||
vec3 a2 = orientationBody2 * mHingeLocalAxisBody2;
|
vec3 a2 = orientationBody2 * mHingeLocalAxisBody2;
|
||||||
mA1.normalize();
|
mA1.normalize();
|
||||||
a2.normalize();
|
a2.normalize();
|
||||||
const vec3 b2 = a2.getOneUnitOrthogonalVector();
|
const vec3 b2 = a2.getOrthoVector();
|
||||||
const vec3 c2 = a2.cross(b2);
|
const vec3 c2 = a2.cross(b2);
|
||||||
mB2CrossA1 = b2.cross(mA1);
|
mB2CrossA1 = b2.cross(mA1);
|
||||||
mC2CrossA1 = c2.cross(mA1);
|
mC2CrossA1 = c2.cross(mA1);
|
||||||
@ -104,11 +104,11 @@ void HingeJoint::initBeforeSolve(const ConstraintSolverData& constraintSolverDat
|
|||||||
|
|
||||||
// Compute the inverse mass matrix K=JM^-1J^t for the 3 translation constraints (3x3 matrix)
|
// Compute the inverse mass matrix K=JM^-1J^t for the 3 translation constraints (3x3 matrix)
|
||||||
float inverseMassBodies = m_body1->m_massInverse + m_body2->m_massInverse;
|
float inverseMassBodies = m_body1->m_massInverse + m_body2->m_massInverse;
|
||||||
etk::Matrix3x3 massMatrix = Matrix3x3(inverseMassBodies, 0, 0,
|
etk::Matrix3x3 massMatrix = etk::Matrix3x3(inverseMassBodies, 0, 0,
|
||||||
0, inverseMassBodies, 0,
|
0, inverseMassBodies, 0,
|
||||||
0, 0, inverseMassBodies) +
|
0, 0, inverseMassBodies)
|
||||||
skewSymmetricMatrixU1 * m_i1 * skewSymmetricMatrixU1.getTranspose() +
|
+ skewSymmetricMatrixU1 * m_i1 * skewSymmetricMatrixU1.getTranspose()
|
||||||
skewSymmetricMatrixU2 * m_i2 * skewSymmetricMatrixU2.getTranspose();
|
+ skewSymmetricMatrixU2 * m_i2 * skewSymmetricMatrixU2.getTranspose();
|
||||||
m_inverseMassMatrixTranslation.setZero();
|
m_inverseMassMatrixTranslation.setZero();
|
||||||
if (m_body1->getType() == DYNAMIC || m_body2->getType() == DYNAMIC) {
|
if (m_body1->getType() == DYNAMIC || m_body2->getType() == DYNAMIC) {
|
||||||
m_inverseMassMatrixTranslation = massMatrix.getInverse();
|
m_inverseMassMatrixTranslation = massMatrix.getInverse();
|
||||||
@ -423,7 +423,7 @@ void HingeJoint::solvePositionConstraint(const ConstraintSolverData& constraintS
|
|||||||
vec3 a2 = q2 * mHingeLocalAxisBody2;
|
vec3 a2 = q2 * mHingeLocalAxisBody2;
|
||||||
mA1.normalize();
|
mA1.normalize();
|
||||||
a2.normalize();
|
a2.normalize();
|
||||||
const vec3 b2 = a2.getOneUnitOrthogonalVector();
|
const vec3 b2 = a2.getOrthoVector();
|
||||||
const vec3 c2 = a2.cross(b2);
|
const vec3 c2 = a2.cross(b2);
|
||||||
mB2CrossA1 = b2.cross(mA1);
|
mB2CrossA1 = b2.cross(mA1);
|
||||||
mC2CrossA1 = c2.cross(mA1);
|
mC2CrossA1 = c2.cross(mA1);
|
||||||
@ -436,11 +436,11 @@ void HingeJoint::solvePositionConstraint(const ConstraintSolverData& constraintS
|
|||||||
|
|
||||||
// Compute the matrix K=JM^-1J^t (3x3 matrix) for the 3 translation constraints
|
// Compute the matrix K=JM^-1J^t (3x3 matrix) for the 3 translation constraints
|
||||||
float inverseMassBodies = m_body1->m_massInverse + m_body2->m_massInverse;
|
float inverseMassBodies = m_body1->m_massInverse + m_body2->m_massInverse;
|
||||||
etk::Matrix3x3 massMatrix = Matrix3x3(inverseMassBodies, 0, 0,
|
etk::Matrix3x3 massMatrix = etk::Matrix3x3(inverseMassBodies, 0, 0,
|
||||||
0, inverseMassBodies, 0,
|
0, inverseMassBodies, 0,
|
||||||
0, 0, inverseMassBodies) +
|
0, 0, inverseMassBodies)
|
||||||
skewSymmetricMatrixU1 * m_i1 * skewSymmetricMatrixU1.getTranspose() +
|
+ skewSymmetricMatrixU1 * m_i1 * skewSymmetricMatrixU1.getTranspose()
|
||||||
skewSymmetricMatrixU2 * m_i2 * skewSymmetricMatrixU2.getTranspose();
|
+ skewSymmetricMatrixU2 * m_i2 * skewSymmetricMatrixU2.getTranspose();
|
||||||
m_inverseMassMatrixTranslation.setZero();
|
m_inverseMassMatrixTranslation.setZero();
|
||||||
if (m_body1->getType() == DYNAMIC || m_body2->getType() == DYNAMIC) {
|
if (m_body1->getType() == DYNAMIC || m_body2->getType() == DYNAMIC) {
|
||||||
m_inverseMassMatrixTranslation = massMatrix.getInverse();
|
m_inverseMassMatrixTranslation = massMatrix.getInverse();
|
||||||
@ -762,7 +762,7 @@ float HingeJoint::computeCurrentHingeAngle(const etk::Quaternion& orientationBod
|
|||||||
// axis is not pointing in the same direction as the hinge axis, we use the rotation -q which
|
// axis is not pointing in the same direction as the hinge axis, we use the rotation -q which
|
||||||
// has the same |sin(theta/2)| value but the value cos(theta/2) is sign inverted. Some details
|
// has the same |sin(theta/2)| value but the value cos(theta/2) is sign inverted. Some details
|
||||||
// about this trick is explained in the source code of OpenTissue (http://www.opentissue.org).
|
// about this trick is explained in the source code of OpenTissue (http://www.opentissue.org).
|
||||||
float cosHalfAngle = relativeRotation.w;
|
float cosHalfAngle = relativeRotation.w();
|
||||||
float sinHalfAngleAbs = relativeRotation.getVectorV().length();
|
float sinHalfAngleAbs = relativeRotation.getVectorV().length();
|
||||||
|
|
||||||
// Compute the dot product of the relative rotation axis and the hinge axis
|
// Compute the dot product of the relative rotation axis and the hinge axis
|
||||||
|
@ -76,7 +76,7 @@ void SliderJoint::initBeforeSolve(const ConstraintSolverData& constraintSolverDa
|
|||||||
// Compute the two orthogonal vectors to the slider axis in world-space
|
// Compute the two orthogonal vectors to the slider axis in world-space
|
||||||
mSliderAxisWorld = orientationBody1 * mSliderAxisBody1;
|
mSliderAxisWorld = orientationBody1 * mSliderAxisBody1;
|
||||||
mSliderAxisWorld.normalize();
|
mSliderAxisWorld.normalize();
|
||||||
mN1 = mSliderAxisWorld.getOneUnitOrthogonalVector();
|
mN1 = mSliderAxisWorld.getOrthoVector();
|
||||||
mN2 = mSliderAxisWorld.cross(mN1);
|
mN2 = mSliderAxisWorld.cross(mN1);
|
||||||
|
|
||||||
// Check if the limit constraints are violated or not
|
// Check if the limit constraints are violated or not
|
||||||
@ -128,8 +128,8 @@ void SliderJoint::initBeforeSolve(const ConstraintSolverData& constraintSolverDa
|
|||||||
mBTranslation.setZero();
|
mBTranslation.setZero();
|
||||||
float biasFactor = (BETA / constraintSolverData.timeStep);
|
float biasFactor = (BETA / constraintSolverData.timeStep);
|
||||||
if (m_positionCorrectionTechnique == BAUMGARTE_JOINTS) {
|
if (m_positionCorrectionTechnique == BAUMGARTE_JOINTS) {
|
||||||
mBTranslation.x() = u.dot(mN1);
|
mBTranslation.setX(u.dot(mN1));
|
||||||
mBTranslation.y() = u.dot(mN2);
|
mBTranslation.setY(u.dot(mN2));
|
||||||
mBTranslation *= biasFactor;
|
mBTranslation *= biasFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,7 +440,7 @@ void SliderJoint::solvePositionConstraint(const ConstraintSolverData& constraint
|
|||||||
// Compute the two orthogonal vectors to the slider axis in world-space
|
// Compute the two orthogonal vectors to the slider axis in world-space
|
||||||
mSliderAxisWorld = q1 * mSliderAxisBody1;
|
mSliderAxisWorld = q1 * mSliderAxisBody1;
|
||||||
mSliderAxisWorld.normalize();
|
mSliderAxisWorld.normalize();
|
||||||
mN1 = mSliderAxisWorld.getOneUnitOrthogonalVector();
|
mN1 = mSliderAxisWorld.getOrthoVector();
|
||||||
mN2 = mSliderAxisWorld.cross(mN1);
|
mN2 = mSliderAxisWorld.cross(mN1);
|
||||||
|
|
||||||
// Check if the limit constraints are violated or not
|
// Check if the limit constraints are violated or not
|
||||||
|
12
ephysics/debug.cpp
Normal file
12
ephysics/debug.cpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ephysics/debug.hpp>
|
||||||
|
|
||||||
|
int32_t ephysic::getLogId() {
|
||||||
|
static int32_t g_val = elog::registerInstance("ephysic");
|
||||||
|
return g_val;
|
||||||
|
}
|
37
ephysics/debug.hpp
Normal file
37
ephysics/debug.hpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <elog/log.hpp>
|
||||||
|
|
||||||
|
namespace ephysic {
|
||||||
|
int32_t getLogId();
|
||||||
|
};
|
||||||
|
#define EPHY_BASE(info,data) ELOG_BASE(ephysic::getLogId(),info,data)
|
||||||
|
|
||||||
|
#define EPHY_PRINT(data) EPHY_BASE(-1, data)
|
||||||
|
#define EPHY_CRITICAL(data) EPHY_BASE(1, data)
|
||||||
|
#define EPHY_ERROR(data) EPHY_BASE(2, data)
|
||||||
|
#define EPHY_WARNING(data) EPHY_BASE(3, data)
|
||||||
|
#define EPHY_INFO(data) EPHY_BASE(4, data)
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define EPHY_DEBUG(data) EPHY_BASE(5, data)
|
||||||
|
#define EPHY_VERBOSE(data) EPHY_BASE(6, data)
|
||||||
|
#define EPHY_TODO(data) EPHY_BASE(4, "TODO : " << data)
|
||||||
|
#else
|
||||||
|
#define EPHY_DEBUG(data) do { } while(false)
|
||||||
|
#define EPHY_VERBOSE(data) do { } while(false)
|
||||||
|
#define EPHY_TODO(data) do { } while(false)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define EPHY_ASSERT(cond,data) \
|
||||||
|
do { \
|
||||||
|
if (!(cond)) { \
|
||||||
|
EPHY_CRITICAL(data); \
|
||||||
|
assert(!#cond); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
@ -21,8 +21,8 @@ const float ContactSolver::SLOP= float(0.01);
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
ContactSolver::ContactSolver(const std::map<RigidBody*, uint32_t>& mapBodyToVelocityIndex)
|
ContactSolver::ContactSolver(const std::map<RigidBody*, uint32_t>& mapBodyToVelocityIndex)
|
||||||
:m_splitLinearVelocities(NULL), m_splitAngularVelocities(NULL),
|
:m_splitLinearVelocities(nullptr), m_splitAngularVelocities(nullptr),
|
||||||
mContactConstraints(NULL), mLinearVelocities(NULL), mAngularVelocities(NULL),
|
mContactConstraints(nullptr), mLinearVelocities(nullptr), mAngularVelocities(nullptr),
|
||||||
m_mapBodyToConstrainedVelocityIndex(mapBodyToVelocityIndex),
|
m_mapBodyToConstrainedVelocityIndex(mapBodyToVelocityIndex),
|
||||||
mIsWarmStartingActive(true), mIsSplitImpulseActive(true),
|
mIsWarmStartingActive(true), mIsSplitImpulseActive(true),
|
||||||
mIsSolveFrictionAtContactManifoldCenterActive(true) {
|
mIsSolveFrictionAtContactManifoldCenterActive(true) {
|
||||||
@ -39,11 +39,11 @@ void ContactSolver::initializeForIsland(float dt, Island* island) {
|
|||||||
|
|
||||||
PROFILE("ContactSolver::initializeForIsland()");
|
PROFILE("ContactSolver::initializeForIsland()");
|
||||||
|
|
||||||
assert(island != NULL);
|
assert(island != nullptr);
|
||||||
assert(island->getNbBodies() > 0);
|
assert(island->getNbBodies() > 0);
|
||||||
assert(island->getNbContactManifolds() > 0);
|
assert(island->getNbContactManifolds() > 0);
|
||||||
assert(m_splitLinearVelocities != NULL);
|
assert(m_splitLinearVelocities != nullptr);
|
||||||
assert(m_splitAngularVelocities != NULL);
|
assert(m_splitAngularVelocities != nullptr);
|
||||||
|
|
||||||
// Set the current time step
|
// Set the current time step
|
||||||
m_timeStep = dt;
|
m_timeStep = dt;
|
||||||
@ -51,7 +51,7 @@ void ContactSolver::initializeForIsland(float dt, Island* island) {
|
|||||||
m_numberContactManifolds = island->getNbContactManifolds();
|
m_numberContactManifolds = island->getNbContactManifolds();
|
||||||
|
|
||||||
mContactConstraints = new ContactManifoldSolver[m_numberContactManifolds];
|
mContactConstraints = new ContactManifoldSolver[m_numberContactManifolds];
|
||||||
assert(mContactConstraints != NULL);
|
assert(mContactConstraints != nullptr);
|
||||||
|
|
||||||
// For each contact manifold of the island
|
// For each contact manifold of the island
|
||||||
ContactManifold** contactManifolds = island->getContactManifold();
|
ContactManifold** contactManifolds = island->getContactManifold();
|
||||||
@ -66,8 +66,8 @@ void ContactSolver::initializeForIsland(float dt, Island* island) {
|
|||||||
// Get the two bodies of the contact
|
// Get the two bodies of the contact
|
||||||
RigidBody* body1 = static_cast<RigidBody*>(externalManifold->getContactPoint(0)->getBody1());
|
RigidBody* body1 = static_cast<RigidBody*>(externalManifold->getContactPoint(0)->getBody1());
|
||||||
RigidBody* body2 = static_cast<RigidBody*>(externalManifold->getContactPoint(0)->getBody2());
|
RigidBody* body2 = static_cast<RigidBody*>(externalManifold->getContactPoint(0)->getBody2());
|
||||||
assert(body1 != NULL);
|
assert(body1 != nullptr);
|
||||||
assert(body2 != NULL);
|
assert(body2 != nullptr);
|
||||||
|
|
||||||
// Get the position of the two bodies
|
// Get the position of the two bodies
|
||||||
const vec3& x1 = body1->m_centerOfMassWorld;
|
const vec3& x1 = body1->m_centerOfMassWorld;
|
||||||
@ -91,8 +91,8 @@ void ContactSolver::initializeForIsland(float dt, Island* island) {
|
|||||||
|
|
||||||
// If we solve the friction constraints at the center of the contact manifold
|
// If we solve the friction constraints at the center of the contact manifold
|
||||||
if (mIsSolveFrictionAtContactManifoldCenterActive) {
|
if (mIsSolveFrictionAtContactManifoldCenterActive) {
|
||||||
int32_ternalManifold.frictionPointBody1 = vec3::zero();
|
int32_ternalManifold.frictionPointBody1 = vec3(0.0f,0.0f,0.0f);
|
||||||
int32_ternalManifold.frictionPointBody2 = vec3::zero();
|
int32_ternalManifold.frictionPointBody2 = vec3(0.0f,0.0f,0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each contact point of the contact manifold
|
// For each contact point of the contact manifold
|
||||||
@ -119,7 +119,7 @@ void ContactSolver::initializeForIsland(float dt, Island* island) {
|
|||||||
contactPoint.penetrationImpulse = 0.0;
|
contactPoint.penetrationImpulse = 0.0;
|
||||||
contactPoint.friction1Impulse = 0.0;
|
contactPoint.friction1Impulse = 0.0;
|
||||||
contactPoint.friction2Impulse = 0.0;
|
contactPoint.friction2Impulse = 0.0;
|
||||||
contactPoint.rollingResistanceImpulse = vec3::zero();
|
contactPoint.rollingResistanceImpulse = vec3(0.0f,0.0f,0.0f);
|
||||||
|
|
||||||
// If we solve the friction constraints at the center of the contact manifold
|
// If we solve the friction constraints at the center of the contact manifold
|
||||||
if (mIsSolveFrictionAtContactManifoldCenterActive) {
|
if (mIsSolveFrictionAtContactManifoldCenterActive) {
|
||||||
@ -384,8 +384,8 @@ void ContactSolver::warmStart() {
|
|||||||
if (contactManifold.rollingResistanceFactor > 0) {
|
if (contactManifold.rollingResistanceFactor > 0) {
|
||||||
|
|
||||||
// Compute the impulse P = J^T * lambda
|
// Compute the impulse P = J^T * lambda
|
||||||
const Impulse impulseRollingResistance(vec3::zero(), -contactPoint.rollingResistanceImpulse,
|
const Impulse impulseRollingResistance(vec3(0.0f,0.0f,0.0f), -contactPoint.rollingResistanceImpulse,
|
||||||
vec3::zero(), contactPoint.rollingResistanceImpulse);
|
vec3(0.0f,0.0f,0.0f), contactPoint.rollingResistanceImpulse);
|
||||||
|
|
||||||
// Apply the impulses to the bodies of the constraint
|
// Apply the impulses to the bodies of the constraint
|
||||||
applyImpulse(impulseRollingResistance, contactManifold);
|
applyImpulse(impulseRollingResistance, contactManifold);
|
||||||
@ -398,7 +398,7 @@ void ContactSolver::warmStart() {
|
|||||||
contactPoint.penetrationImpulse = 0.0;
|
contactPoint.penetrationImpulse = 0.0;
|
||||||
contactPoint.friction1Impulse = 0.0;
|
contactPoint.friction1Impulse = 0.0;
|
||||||
contactPoint.friction2Impulse = 0.0;
|
contactPoint.friction2Impulse = 0.0;
|
||||||
contactPoint.rollingResistanceImpulse = vec3::zero();
|
contactPoint.rollingResistanceImpulse = vec3(0.0f,0.0f,0.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,8 +469,8 @@ void ContactSolver::warmStart() {
|
|||||||
// Compute the impulse P = J^T * lambda
|
// Compute the impulse P = J^T * lambda
|
||||||
angularImpulseBody1 = -contactManifold.rollingResistanceImpulse;
|
angularImpulseBody1 = -contactManifold.rollingResistanceImpulse;
|
||||||
angularImpulseBody2 = contactManifold.rollingResistanceImpulse;
|
angularImpulseBody2 = contactManifold.rollingResistanceImpulse;
|
||||||
const Impulse impulseRollingResistance(vec3::zero(), angularImpulseBody1,
|
const Impulse impulseRollingResistance(vec3(0.0f,0.0f,0.0f), angularImpulseBody1,
|
||||||
vec3::zero(), angularImpulseBody2);
|
vec3(0.0f,0.0f,0.0f), angularImpulseBody2);
|
||||||
|
|
||||||
// Apply the impulses to the bodies of the constraint
|
// Apply the impulses to the bodies of the constraint
|
||||||
applyImpulse(impulseRollingResistance, contactManifold);
|
applyImpulse(impulseRollingResistance, contactManifold);
|
||||||
@ -481,7 +481,7 @@ void ContactSolver::warmStart() {
|
|||||||
contactManifold.friction1Impulse = 0.0;
|
contactManifold.friction1Impulse = 0.0;
|
||||||
contactManifold.friction2Impulse = 0.0;
|
contactManifold.friction2Impulse = 0.0;
|
||||||
contactManifold.frictionTwistImpulse = 0.0;
|
contactManifold.frictionTwistImpulse = 0.0;
|
||||||
contactManifold.rollingResistanceImpulse = vec3::zero();
|
contactManifold.rollingResistanceImpulse = vec3(0.0f,0.0f,0.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -640,8 +640,8 @@ void ContactSolver::solve() {
|
|||||||
deltaLambdaRolling = contactPoint.rollingResistanceImpulse - lambdaTempRolling;
|
deltaLambdaRolling = contactPoint.rollingResistanceImpulse - lambdaTempRolling;
|
||||||
|
|
||||||
// Compute the impulse P=J^T * lambda
|
// Compute the impulse P=J^T * lambda
|
||||||
const Impulse impulseRolling(vec3::zero(), -deltaLambdaRolling,
|
const Impulse impulseRolling(vec3(0.0f,0.0f,0.0f), -deltaLambdaRolling,
|
||||||
vec3::zero(), deltaLambdaRolling);
|
vec3(0.0f,0.0f,0.0f), deltaLambdaRolling);
|
||||||
|
|
||||||
// Apply the impulses to the bodies of the constraint
|
// Apply the impulses to the bodies of the constraint
|
||||||
applyImpulse(impulseRolling, contactManifold);
|
applyImpulse(impulseRolling, contactManifold);
|
||||||
@ -742,15 +742,17 @@ void ContactSolver::solve() {
|
|||||||
vec3 deltaLambdaRolling = contactManifold.inverseRollingResistance * (-JvRolling);
|
vec3 deltaLambdaRolling = contactManifold.inverseRollingResistance * (-JvRolling);
|
||||||
float rollingLimit = contactManifold.rollingResistanceFactor * sumPenetrationImpulse;
|
float rollingLimit = contactManifold.rollingResistanceFactor * sumPenetrationImpulse;
|
||||||
vec3 lambdaTempRolling = contactManifold.rollingResistanceImpulse;
|
vec3 lambdaTempRolling = contactManifold.rollingResistanceImpulse;
|
||||||
contactManifold.rollingResistanceImpulse = clamp(contactManifold.rollingResistanceImpulse +
|
contactManifold.rollingResistanceImpulse = clamp(contactManifold.rollingResistanceImpulse + deltaLambdaRolling,
|
||||||
deltaLambdaRolling, rollingLimit);
|
rollingLimit);
|
||||||
deltaLambdaRolling = contactManifold.rollingResistanceImpulse - lambdaTempRolling;
|
deltaLambdaRolling = contactManifold.rollingResistanceImpulse - lambdaTempRolling;
|
||||||
|
|
||||||
// Compute the impulse P=J^T * lambda
|
// Compute the impulse P=J^T * lambda
|
||||||
angularImpulseBody1 = -deltaLambdaRolling;
|
angularImpulseBody1 = -deltaLambdaRolling;
|
||||||
angularImpulseBody2 = deltaLambdaRolling;
|
angularImpulseBody2 = deltaLambdaRolling;
|
||||||
const Impulse impulseRolling(vec3::zero(), angularImpulseBody1,
|
const Impulse impulseRolling(vec3(0.0f,0.0f,0.0f),
|
||||||
vec3::zero(), angularImpulseBody2);
|
angularImpulseBody1,
|
||||||
|
vec3(0.0f,0.0f,0.0f),
|
||||||
|
angularImpulseBody2);
|
||||||
|
|
||||||
// Apply the impulses to the bodies of the constraint
|
// Apply the impulses to the bodies of the constraint
|
||||||
applyImpulse(impulseRolling, contactManifold);
|
applyImpulse(impulseRolling, contactManifold);
|
||||||
@ -846,7 +848,7 @@ void ContactSolver::computeFrictionVectors(const vec3& deltaVelocity,
|
|||||||
else {
|
else {
|
||||||
|
|
||||||
// Get any orthogonal vector to the normal as the first friction vector
|
// Get any orthogonal vector to the normal as the first friction vector
|
||||||
contactPoint.frictionVector1 = contactPoint.normal.getOneUnitOrthogonalVector();
|
contactPoint.frictionVector1 = contactPoint.normal.getOrthoVector();
|
||||||
}
|
}
|
||||||
|
|
||||||
// The second friction vector is computed by the cross product of the firs
|
// The second friction vector is computed by the cross product of the firs
|
||||||
@ -876,7 +878,7 @@ void ContactSolver::computeFrictionVectors(const vec3& deltaVelocity,
|
|||||||
else {
|
else {
|
||||||
|
|
||||||
// Get any orthogonal vector to the normal as the first friction vector
|
// Get any orthogonal vector to the normal as the first friction vector
|
||||||
contact.frictionVector1 = contact.normal.getOneUnitOrthogonalVector();
|
contact.frictionVector1 = contact.normal.getOrthoVector();
|
||||||
}
|
}
|
||||||
|
|
||||||
// The second friction vector is computed by the cross product of the firs
|
// The second friction vector is computed by the cross product of the firs
|
||||||
@ -887,8 +889,8 @@ void ContactSolver::computeFrictionVectors(const vec3& deltaVelocity,
|
|||||||
// Clean up the constraint solver
|
// Clean up the constraint solver
|
||||||
void ContactSolver::cleanup() {
|
void ContactSolver::cleanup() {
|
||||||
|
|
||||||
if (mContactConstraints != NULL) {
|
if (mContactConstraints != nullptr) {
|
||||||
delete[] mContactConstraints;
|
delete[] mContactConstraints;
|
||||||
mContactConstraints = NULL;
|
mContactConstraints = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,11 @@ DynamicsWorld::DynamicsWorld(const vec3 &gravity)
|
|||||||
m_nbVelocitySolverIterations(DEFAULT_VELOCITY_SOLVER_NB_ITERATIONS),
|
m_nbVelocitySolverIterations(DEFAULT_VELOCITY_SOLVER_NB_ITERATIONS),
|
||||||
m_nbPositionSolverIterations(DEFAULT_POSITION_SOLVER_NB_ITERATIONS),
|
m_nbPositionSolverIterations(DEFAULT_POSITION_SOLVER_NB_ITERATIONS),
|
||||||
m_isSleepingEnabled(SPLEEPING_ENABLED), m_gravity(gravity),
|
m_isSleepingEnabled(SPLEEPING_ENABLED), m_gravity(gravity),
|
||||||
m_isGravityEnabled(true), m_constrainedLinearVelocities(NULL),
|
m_isGravityEnabled(true), m_constrainedLinearVelocities(nullptr),
|
||||||
m_constrainedAngularVelocities(NULL), m_splitLinearVelocities(NULL),
|
m_constrainedAngularVelocities(nullptr), m_splitLinearVelocities(nullptr),
|
||||||
m_splitAngularVelocities(NULL), m_constrainedPositions(NULL),
|
m_splitAngularVelocities(nullptr), m_constrainedPositions(nullptr),
|
||||||
m_constrainedOrientations(NULL), m_numberIslands(0),
|
m_constrainedOrientations(nullptr), m_numberIslands(0),
|
||||||
m_numberIslandsCapacity(0), m_islands(NULL), m_numberBodiesCapacity(0),
|
m_numberIslandsCapacity(0), m_islands(nullptr), m_numberBodiesCapacity(0),
|
||||||
m_sleepLinearVelocity(DEFAULT_SLEEP_LINEAR_VELOCITY),
|
m_sleepLinearVelocity(DEFAULT_SLEEP_LINEAR_VELOCITY),
|
||||||
m_sleepAngularVelocity(DEFAULT_SLEEP_ANGULAR_VELOCITY),
|
m_sleepAngularVelocity(DEFAULT_SLEEP_ANGULAR_VELOCITY),
|
||||||
m_timeBeforeSleep(DEFAULT_TIME_BEFORE_SLEEP) {
|
m_timeBeforeSleep(DEFAULT_TIME_BEFORE_SLEEP) {
|
||||||
@ -109,7 +109,7 @@ void DynamicsWorld::update(float timeStep) {
|
|||||||
m_timeStep = timeStep;
|
m_timeStep = timeStep;
|
||||||
|
|
||||||
// Notify the event listener about the beginning of an int32_ternal tick
|
// Notify the event listener about the beginning of an int32_ternal tick
|
||||||
if (m_eventListener != NULL) {
|
if (m_eventListener != nullptr) {
|
||||||
m_eventListener->beginInternalTick();
|
m_eventListener->beginInternalTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +145,7 @@ void DynamicsWorld::update(float timeStep) {
|
|||||||
if (m_isSleepingEnabled) updateSleepingBodies();
|
if (m_isSleepingEnabled) updateSleepingBodies();
|
||||||
|
|
||||||
// Notify the event listener about the end of an int32_ternal tick
|
// Notify the event listener about the end of an int32_ternal tick
|
||||||
if (m_eventListener != NULL) m_eventListener->endInternalTick();
|
if (m_eventListener != nullptr) m_eventListener->endInternalTick();
|
||||||
|
|
||||||
// Reset the external force and torque applied to the bodies
|
// Reset the external force and torque applied to the bodies
|
||||||
resetBodiesForceAndTorque();
|
resetBodiesForceAndTorque();
|
||||||
@ -185,9 +185,11 @@ void DynamicsWorld::int32_tegrateRigidBodiesPositions() {
|
|||||||
|
|
||||||
// Update the new constrained position and orientation of the body
|
// Update the new constrained position and orientation of the body
|
||||||
m_constrainedPositions[indexArray] = currentPosition + newLinVelocity * m_timeStep;
|
m_constrainedPositions[indexArray] = currentPosition + newLinVelocity * m_timeStep;
|
||||||
m_constrainedOrientations[indexArray] = currentOrientation +
|
m_constrainedOrientations[indexArray] = currentOrientation;
|
||||||
etk::Quaternion(0, newAngVelocity) *
|
m_constrainedOrientations[indexArray] += etk::Quaternion(0, newAngVelocity)
|
||||||
currentOrientation * 0.5f * m_timeStep;
|
* currentOrientation
|
||||||
|
* 0.5f
|
||||||
|
* m_timeStep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,12 +246,12 @@ void DynamicsWorld::initVelocityArrays() {
|
|||||||
m_constrainedAngularVelocities = new vec3[m_numberBodiesCapacity];
|
m_constrainedAngularVelocities = new vec3[m_numberBodiesCapacity];
|
||||||
m_constrainedPositions = new vec3[m_numberBodiesCapacity];
|
m_constrainedPositions = new vec3[m_numberBodiesCapacity];
|
||||||
m_constrainedOrientations = new etk::Quaternion[m_numberBodiesCapacity];
|
m_constrainedOrientations = new etk::Quaternion[m_numberBodiesCapacity];
|
||||||
assert(m_splitLinearVelocities != NULL);
|
assert(m_splitLinearVelocities != nullptr);
|
||||||
assert(m_splitAngularVelocities != NULL);
|
assert(m_splitAngularVelocities != nullptr);
|
||||||
assert(m_constrainedLinearVelocities != NULL);
|
assert(m_constrainedLinearVelocities != nullptr);
|
||||||
assert(m_constrainedAngularVelocities != NULL);
|
assert(m_constrainedAngularVelocities != nullptr);
|
||||||
assert(m_constrainedPositions != NULL);
|
assert(m_constrainedPositions != nullptr);
|
||||||
assert(m_constrainedOrientations != NULL);
|
assert(m_constrainedOrientations != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the velocities arrays
|
// Reset the velocities arrays
|
||||||
@ -297,11 +299,10 @@ void DynamicsWorld::int32_tegrateRigidBodiesVelocities() {
|
|||||||
assert(m_splitAngularVelocities[indexBody] == vec3(0, 0, 0));
|
assert(m_splitAngularVelocities[indexBody] == vec3(0, 0, 0));
|
||||||
|
|
||||||
// Integrate the external force to get the new velocity of the body
|
// Integrate the external force to get the new velocity of the body
|
||||||
m_constrainedLinearVelocities[indexBody] = bodies[b]->getLinearVelocity() +
|
m_constrainedLinearVelocities[indexBody] = bodies[b]->getLinearVelocity();
|
||||||
m_timeStep * bodies[b]->m_massInverse * bodies[b]->m_externalForce;
|
m_constrainedLinearVelocities[indexBody] += bodies[b]->m_massInverse * bodies[b]->m_externalForce * m_timeStep;
|
||||||
m_constrainedAngularVelocities[indexBody] = bodies[b]->getAngularVelocity() +
|
m_constrainedAngularVelocities[indexBody] = bodies[b]->getAngularVelocity();
|
||||||
m_timeStep * bodies[b]->getInertiaTensorInverseWorld() *
|
m_constrainedAngularVelocities[indexBody] += bodies[b]->getInertiaTensorInverseWorld() * bodies[b]->m_externalTorque * m_timeStep;
|
||||||
bodies[b]->m_externalTorque;
|
|
||||||
|
|
||||||
// If the gravity has to be applied to this rigid body
|
// If the gravity has to be applied to this rigid body
|
||||||
if (bodies[b]->isGravityEnabled() && m_isGravityEnabled) {
|
if (bodies[b]->isGravityEnabled() && m_isGravityEnabled) {
|
||||||
@ -436,7 +437,7 @@ RigidBody* DynamicsWorld::createRigidBody(const etk::Transform3D& transform) {
|
|||||||
// Create the rigid body
|
// Create the rigid body
|
||||||
RigidBody* rigidBody = new (m_memoryAllocator.allocate(sizeof(RigidBody))) RigidBody(transform,
|
RigidBody* rigidBody = new (m_memoryAllocator.allocate(sizeof(RigidBody))) RigidBody(transform,
|
||||||
*this, bodyID);
|
*this, bodyID);
|
||||||
assert(rigidBody != NULL);
|
assert(rigidBody != nullptr);
|
||||||
|
|
||||||
// Add the rigid body to the physics world
|
// Add the rigid body to the physics world
|
||||||
m_bodies.insert(rigidBody);
|
m_bodies.insert(rigidBody);
|
||||||
@ -460,7 +461,7 @@ void DynamicsWorld::destroyRigidBody(RigidBody* rigidBody) {
|
|||||||
|
|
||||||
// Destroy all the joints in which the rigid body to be destroyed is involved
|
// Destroy all the joints in which the rigid body to be destroyed is involved
|
||||||
JointListElement* element;
|
JointListElement* element;
|
||||||
for (element = rigidBody->m_jointsList; element != NULL; element = element->next) {
|
for (element = rigidBody->m_jointsList; element != nullptr; element = element->next) {
|
||||||
destroyJoint(element->joint);
|
destroyJoint(element->joint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -485,7 +486,7 @@ void DynamicsWorld::destroyRigidBody(RigidBody* rigidBody) {
|
|||||||
*/
|
*/
|
||||||
Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
|
Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
|
||||||
|
|
||||||
Joint* newJoint = NULL;
|
Joint* newJoint = nullptr;
|
||||||
|
|
||||||
// Allocate memory to create the new joint
|
// Allocate memory to create the new joint
|
||||||
switch(jointInfo.type) {
|
switch(jointInfo.type) {
|
||||||
@ -530,7 +531,7 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
assert(false);
|
assert(false);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -557,7 +558,7 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
|
|||||||
*/
|
*/
|
||||||
void DynamicsWorld::destroyJoint(Joint* joint) {
|
void DynamicsWorld::destroyJoint(Joint* joint) {
|
||||||
|
|
||||||
assert(joint != NULL);
|
assert(joint != nullptr);
|
||||||
|
|
||||||
// If the collision between the two bodies of the constraint was disabled
|
// If the collision between the two bodies of the constraint was disabled
|
||||||
if (!joint->isCollisionEnabled()) {
|
if (!joint->isCollisionEnabled()) {
|
||||||
@ -589,7 +590,7 @@ void DynamicsWorld::destroyJoint(Joint* joint) {
|
|||||||
// Add the joint to the list of joints of the two bodies involved in the joint
|
// Add the joint to the list of joints of the two bodies involved in the joint
|
||||||
void DynamicsWorld::addJointToBody(Joint* joint) {
|
void DynamicsWorld::addJointToBody(Joint* joint) {
|
||||||
|
|
||||||
assert(joint != NULL);
|
assert(joint != nullptr);
|
||||||
|
|
||||||
// Add the joint at the beginning of the linked list of joints of the first body
|
// Add the joint at the beginning of the linked list of joints of the first body
|
||||||
void* allocatedMemory1 = m_memoryAllocator.allocate(sizeof(JointListElement));
|
void* allocatedMemory1 = m_memoryAllocator.allocate(sizeof(JointListElement));
|
||||||
@ -698,7 +699,7 @@ void DynamicsWorld::computeIslands() {
|
|||||||
|
|
||||||
// For each contact manifold in which the current body is involded
|
// For each contact manifold in which the current body is involded
|
||||||
ContactManifoldListElement* contactElement;
|
ContactManifoldListElement* contactElement;
|
||||||
for (contactElement = bodyToVisit->m_contactManifoldsList; contactElement != NULL;
|
for (contactElement = bodyToVisit->m_contactManifoldsList; contactElement != nullptr;
|
||||||
contactElement = contactElement->next) {
|
contactElement = contactElement->next) {
|
||||||
|
|
||||||
ContactManifold* contactManifold = contactElement->contactManifold;
|
ContactManifold* contactManifold = contactElement->contactManifold;
|
||||||
@ -728,7 +729,7 @@ void DynamicsWorld::computeIslands() {
|
|||||||
|
|
||||||
// For each joint in which the current body is involved
|
// For each joint in which the current body is involved
|
||||||
JointListElement* jointElement;
|
JointListElement* jointElement;
|
||||||
for (jointElement = bodyToVisit->m_jointsList; jointElement != NULL;
|
for (jointElement = bodyToVisit->m_jointsList; jointElement != nullptr;
|
||||||
jointElement = jointElement->next) {
|
jointElement = jointElement->next) {
|
||||||
|
|
||||||
Joint* joint = jointElement->joint;
|
Joint* joint = jointElement->joint;
|
||||||
@ -904,7 +905,7 @@ void DynamicsWorld::testCollision(const CollisionBody* body,
|
|||||||
std::set<uint32_t> shapes1;
|
std::set<uint32_t> shapes1;
|
||||||
|
|
||||||
// For each shape of the body
|
// For each shape of the body
|
||||||
for (const ProxyShape* shape=body->getProxyShapesList(); shape != NULL;
|
for (const ProxyShape* shape=body->getProxyShapesList(); shape != nullptr;
|
||||||
shape = shape->getNext()) {
|
shape = shape->getNext()) {
|
||||||
shapes1.insert(shape->m_broadPhaseID);
|
shapes1.insert(shape->m_broadPhaseID);
|
||||||
}
|
}
|
||||||
@ -929,13 +930,13 @@ void DynamicsWorld::testCollision(const CollisionBody* body1,
|
|||||||
|
|
||||||
// Create the sets of shapes
|
// Create the sets of shapes
|
||||||
std::set<uint32_t> shapes1;
|
std::set<uint32_t> shapes1;
|
||||||
for (const ProxyShape* shape=body1->getProxyShapesList(); shape != NULL;
|
for (const ProxyShape* shape=body1->getProxyShapesList(); shape != nullptr;
|
||||||
shape = shape->getNext()) {
|
shape = shape->getNext()) {
|
||||||
shapes1.insert(shape->m_broadPhaseID);
|
shapes1.insert(shape->m_broadPhaseID);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<uint32_t> shapes2;
|
std::set<uint32_t> shapes2;
|
||||||
for (const ProxyShape* shape=body2->getProxyShapesList(); shape != NULL;
|
for (const ProxyShape* shape=body2->getProxyShapesList(); shape != nullptr;
|
||||||
shape = shape->getNext()) {
|
shape = shape->getNext()) {
|
||||||
shapes2.insert(shape->m_broadPhaseID);
|
shapes2.insert(shape->m_broadPhaseID);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
// Libraries
|
// Libraries
|
||||||
#include <ephysics/configuration.h>
|
#include <ephysics/configuration.h>
|
||||||
|
#include <etk/math/Vector3D.hpp>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
@ -28,6 +28,7 @@ def configure(target, my_module):
|
|||||||
my_module.add_extra_flags()
|
my_module.add_extra_flags()
|
||||||
# add the file to compile:
|
# add the file to compile:
|
||||||
my_module.add_src_file([
|
my_module.add_src_file([
|
||||||
|
'ephysics/debug.cpp',
|
||||||
'ephysics/memory/MemoryAllocator.cpp',
|
'ephysics/memory/MemoryAllocator.cpp',
|
||||||
'ephysics/constraint/Joint.cpp',
|
'ephysics/constraint/Joint.cpp',
|
||||||
'ephysics/constraint/HingeJoint.cpp',
|
'ephysics/constraint/HingeJoint.cpp',
|
||||||
@ -83,6 +84,7 @@ def configure(target, my_module):
|
|||||||
])
|
])
|
||||||
|
|
||||||
my_module.add_header_file([
|
my_module.add_header_file([
|
||||||
|
'ephysics/debug.hpp',
|
||||||
'ephysics/memory/MemoryAllocator.h',
|
'ephysics/memory/MemoryAllocator.h',
|
||||||
'ephysics/memory/Stack.h',
|
'ephysics/memory/Stack.h',
|
||||||
'ephysics/constraint/BallAndSocketJoint.h',
|
'ephysics/constraint/BallAndSocketJoint.h',
|
||||||
|
@ -228,10 +228,10 @@ class TestDynamicAABBTree : public Test {
|
|||||||
|
|
||||||
// ---- Update the object AABBs with the initial AABBs (no reinsertion) ----- //
|
// ---- Update the object AABBs with the initial AABBs (no reinsertion) ----- //
|
||||||
|
|
||||||
tree.updateObject(object1Id, aabb1, vec3::zero(), false);
|
tree.updateObject(object1Id, aabb1, vec3(0.0f,0.0f,0.0f)(), false);
|
||||||
tree.updateObject(object2Id, aabb2, vec3::zero(), false);
|
tree.updateObject(object2Id, aabb2, vec3(0.0f,0.0f,0.0f)(), false);
|
||||||
tree.updateObject(object3Id, aabb3, vec3::zero(), false);
|
tree.updateObject(object3Id, aabb3, vec3(0.0f,0.0f,0.0f)(), false);
|
||||||
tree.updateObject(object4Id, aabb4, vec3::zero(), false);
|
tree.updateObject(object4Id, aabb4, vec3(0.0f,0.0f,0.0f)(), false);
|
||||||
|
|
||||||
// AABB overlapping nothing
|
// AABB overlapping nothing
|
||||||
mOverlapCallback.reset();
|
mOverlapCallback.reset();
|
||||||
@ -275,10 +275,10 @@ class TestDynamicAABBTree : public Test {
|
|||||||
|
|
||||||
// ---- Update the object AABBs with the initial AABBs (with reinsertion) ----- //
|
// ---- Update the object AABBs with the initial AABBs (with reinsertion) ----- //
|
||||||
|
|
||||||
tree.updateObject(object1Id, aabb1, vec3::zero(), true);
|
tree.updateObject(object1Id, aabb1, vec3(0.0f,0.0f,0.0f)(), true);
|
||||||
tree.updateObject(object2Id, aabb2, vec3::zero(), true);
|
tree.updateObject(object2Id, aabb2, vec3(0.0f,0.0f,0.0f)(), true);
|
||||||
tree.updateObject(object3Id, aabb3, vec3::zero(), true);
|
tree.updateObject(object3Id, aabb3, vec3(0.0f,0.0f,0.0f)(), true);
|
||||||
tree.updateObject(object4Id, aabb4, vec3::zero(), true);
|
tree.updateObject(object4Id, aabb4, vec3(0.0f,0.0f,0.0f)(), true);
|
||||||
|
|
||||||
// AABB overlapping nothing
|
// AABB overlapping nothing
|
||||||
mOverlapCallback.reset();
|
mOverlapCallback.reset();
|
||||||
@ -323,10 +323,10 @@ class TestDynamicAABBTree : public Test {
|
|||||||
// ---- Move objects 2 and 3 ----- //
|
// ---- Move objects 2 and 3 ----- //
|
||||||
|
|
||||||
AABB newAABB2(vec3(-7, 10, -3), vec3(1, 13, 3));
|
AABB newAABB2(vec3(-7, 10, -3), vec3(1, 13, 3));
|
||||||
tree.updateObject(object2Id, newAABB2, vec3::zero());
|
tree.updateObject(object2Id, newAABB2, vec3(0.0f,0.0f,0.0f)());
|
||||||
|
|
||||||
AABB newAABB3(vec3(7, -6, -3), vec3(9, 1, 3));
|
AABB newAABB3(vec3(7, -6, -3), vec3(9, 1, 3));
|
||||||
tree.updateObject(object3Id, newAABB3, vec3::zero());
|
tree.updateObject(object3Id, newAABB3, vec3(0.0f,0.0f,0.0f)());
|
||||||
|
|
||||||
// AABB overlapping object 3
|
// AABB overlapping object 3
|
||||||
mOverlapCallback.reset();
|
mOverlapCallback.reset();
|
||||||
@ -414,10 +414,10 @@ class TestDynamicAABBTree : public Test {
|
|||||||
|
|
||||||
// ---- Update the object AABBs with the initial AABBs (no reinsertion) ----- //
|
// ---- Update the object AABBs with the initial AABBs (no reinsertion) ----- //
|
||||||
|
|
||||||
tree.updateObject(object1Id, aabb1, vec3::zero(), false);
|
tree.updateObject(object1Id, aabb1, vec3(0.0f,0.0f,0.0f)(), false);
|
||||||
tree.updateObject(object2Id, aabb2, vec3::zero(), false);
|
tree.updateObject(object2Id, aabb2, vec3(0.0f,0.0f,0.0f)(), false);
|
||||||
tree.updateObject(object3Id, aabb3, vec3::zero(), false);
|
tree.updateObject(object3Id, aabb3, vec3(0.0f,0.0f,0.0f)(), false);
|
||||||
tree.updateObject(object4Id, aabb4, vec3::zero(), false);
|
tree.updateObject(object4Id, aabb4, vec3(0.0f,0.0f,0.0f)(), false);
|
||||||
|
|
||||||
// Ray with no hits
|
// Ray with no hits
|
||||||
m_raycastCallback.reset();
|
m_raycastCallback.reset();
|
||||||
@ -453,10 +453,10 @@ class TestDynamicAABBTree : public Test {
|
|||||||
|
|
||||||
// ---- Update the object AABBs with the initial AABBs (with reinsertion) ----- //
|
// ---- Update the object AABBs with the initial AABBs (with reinsertion) ----- //
|
||||||
|
|
||||||
tree.updateObject(object1Id, aabb1, vec3::zero(), true);
|
tree.updateObject(object1Id, aabb1, vec3(0.0f,0.0f,0.0f)(), true);
|
||||||
tree.updateObject(object2Id, aabb2, vec3::zero(), true);
|
tree.updateObject(object2Id, aabb2, vec3(0.0f,0.0f,0.0f)(), true);
|
||||||
tree.updateObject(object3Id, aabb3, vec3::zero(), true);
|
tree.updateObject(object3Id, aabb3, vec3(0.0f,0.0f,0.0f)(), true);
|
||||||
tree.updateObject(object4Id, aabb4, vec3::zero(), true);
|
tree.updateObject(object4Id, aabb4, vec3(0.0f,0.0f,0.0f)(), true);
|
||||||
|
|
||||||
// Ray with no hits
|
// Ray with no hits
|
||||||
m_raycastCallback.reset();
|
m_raycastCallback.reset();
|
||||||
@ -493,10 +493,10 @@ class TestDynamicAABBTree : public Test {
|
|||||||
// ---- Move objects 2 and 3 ----- //
|
// ---- Move objects 2 and 3 ----- //
|
||||||
|
|
||||||
AABB newAABB2(vec3(-7, 10, -3), vec3(1, 13, 3));
|
AABB newAABB2(vec3(-7, 10, -3), vec3(1, 13, 3));
|
||||||
tree.updateObject(object2Id, newAABB2, vec3::zero());
|
tree.updateObject(object2Id, newAABB2, vec3(0.0f,0.0f,0.0f)());
|
||||||
|
|
||||||
AABB newAABB3(vec3(7, -6, -3), vec3(9, 1, 3));
|
AABB newAABB3(vec3(7, -6, -3), vec3(9, 1, 3));
|
||||||
tree.updateObject(object3Id, newAABB3, vec3::zero());
|
tree.updateObject(object3Id, newAABB3, vec3(0.0f,0.0f,0.0f)());
|
||||||
|
|
||||||
// Ray that hits object 1, 2
|
// Ray that hits object 1, 2
|
||||||
Ray ray5(vec3(-4, -5, 0), vec3(-4, 12, 0));
|
Ray ray5(vec3(-4, -5, 0), vec3(-4, 12, 0));
|
||||||
|
@ -177,7 +177,7 @@ void ConcaveMeshScene::renderSinglePass(Shader& shader, const openglframework::M
|
|||||||
void ConcaveMeshScene::reset() {
|
void ConcaveMeshScene::reset() {
|
||||||
|
|
||||||
// Reset the transform
|
// Reset the transform
|
||||||
rp3d::etk::Transform3D transform(rp3d::vec3::zero(), rp3d::etk::Quaternion::identity());
|
rp3d::etk::Transform3D transform(rp3d::vec3(0.0f,0.0f,0.0f)(), rp3d::etk::Quaternion::identity());
|
||||||
mConcaveMesh->resetTransform(transform);
|
mConcaveMesh->resetTransform(transform);
|
||||||
|
|
||||||
for (int32_t i=0; i<NB_BOXES_X; i++) {
|
for (int32_t i=0; i<NB_BOXES_X; i++) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user