diff --git a/trunk/unmanaged/ubODE-OpenSim/OPCODE/Makefile.am b/trunk/unmanaged/ubODE-OpenSim/OPCODE/Makefile.am index 1e82910d..a71147ee 100644 --- a/trunk/unmanaged/ubODE-OpenSim/OPCODE/Makefile.am +++ b/trunk/unmanaged/ubODE-OpenSim/OPCODE/Makefile.am @@ -21,7 +21,6 @@ libOPCODE_la_SOURCES = OPC_AABBCollider.cpp OPC_AABBCollider.h \ OPC_OBBCollider.cpp OPC_OBBCollider.h \ Opcode.cpp Opcode.h \ OPC_OptimizedTree.cpp OPC_OptimizedTree.h \ - OPC_Picking.cpp OPC_Picking.h \ OPC_PlanesCollider.cpp OPC_PlanesCollider.h \ OPC_RayCollider.cpp OPC_RayCollider.h \ OPC_SphereCollider.cpp OPC_SphereCollider.h \ diff --git a/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_AABBCollider.cpp b/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_AABBCollider.cpp index 14ad078c..14a7bf5d 100644 --- a/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_AABBCollider.cpp +++ b/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_AABBCollider.cpp @@ -320,70 +320,6 @@ void AABBCollider::_CollideNoPrimitiveTest(const AABBCollisionNode* node) } } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/** - * Recursive collision query for quantized AABB trees. - * \param node [in] current collision node - */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void AABBCollider::_Collide(const AABBQuantizedNode* node) -{ - // Dequantize box - const QuantizedAABB& Box = node->mAABB; - const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); - const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); - - // Perform AABB-AABB overlap test - if(!AABBAABBOverlap(Extents, Center)) return; - - TEST_BOX_IN_AABB(Center, Extents) - - if(node->IsLeaf()) - { - AABB_PRIM(node->GetPrimitive(), OPC_CONTACT) - } - else - { - _Collide(node->GetPos()); - - if(ContactFound()) return; - - _Collide(node->GetNeg()); - } -} - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/** - * Recursive collision query for quantized AABB trees, without primitive tests. - * \param node [in] current collision node - */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void AABBCollider::_CollideNoPrimitiveTest(const AABBQuantizedNode* node) -{ - // Dequantize box - const QuantizedAABB& Box = node->mAABB; - const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); - const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); - - // Perform AABB-AABB overlap test - if(!AABBAABBOverlap(Extents, Center)) return; - - TEST_BOX_IN_AABB(Center, Extents) - - if(node->IsLeaf()) - { - SET_CONTACT(node->GetPrimitive(), OPC_CONTACT) - } - else - { - _CollideNoPrimitiveTest(node->GetPos()); - - if(ContactFound()) return; - - _CollideNoPrimitiveTest(node->GetNeg()); - } -} - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for no-leaf AABB trees. @@ -393,17 +329,27 @@ void AABBCollider::_CollideNoPrimitiveTest(const AABBQuantizedNode* node) void AABBCollider::_Collide(const AABBNoLeafNode* node) { // Perform AABB-AABB overlap test - if(!AABBAABBOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) return; + if(!AABBAABBOverlap(node->mAABB.mExtents, node->mAABB.mCenter)) + return; TEST_BOX_IN_AABB(node->mAABB.mCenter, node->mAABB.mExtents) - if(node->HasPosLeaf()) { AABB_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } - else _Collide(node->GetPos()); + if(node->HasPosLeaf()) + { + AABB_PRIM(node->GetPosPrimitive(), OPC_CONTACT) + } + else + _Collide(node->GetPos()); - if(ContactFound()) return; + if(ContactFound()) + return; - if(node->HasNegLeaf()) { AABB_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } - else _Collide(node->GetNeg()); + if(node->HasNegLeaf()) + { + AABB_PRIM(node->GetNegPrimitive(), OPC_CONTACT) + } + else + _Collide(node->GetNeg()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -428,60 +374,6 @@ void AABBCollider::_CollideNoPrimitiveTest(const AABBNoLeafNode* node) else _CollideNoPrimitiveTest(node->GetNeg()); } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/** - * Recursive collision query for quantized no-leaf AABB trees. - * \param node [in] current collision node - */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void AABBCollider::_Collide(const AABBQuantizedNoLeafNode* node) -{ - // Dequantize box - const QuantizedAABB& Box = node->mAABB; - const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); - const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); - - // Perform AABB-AABB overlap test - if(!AABBAABBOverlap(Extents, Center)) return; - - TEST_BOX_IN_AABB(Center, Extents) - - if(node->HasPosLeaf()) { AABB_PRIM(node->GetPosPrimitive(), OPC_CONTACT) } - else _Collide(node->GetPos()); - - if(ContactFound()) return; - - if(node->HasNegLeaf()) { AABB_PRIM(node->GetNegPrimitive(), OPC_CONTACT) } - else _Collide(node->GetNeg()); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/** - * Recursive collision query for quantized no-leaf AABB trees, without primitive tests. - * \param node [in] current collision node - */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void AABBCollider::_CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node) -{ - // Dequantize box - const QuantizedAABB& Box = node->mAABB; - const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); - const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); - - // Perform AABB-AABB overlap test - if(!AABBAABBOverlap(Extents, Center)) return; - - TEST_BOX_IN_AABB(Center, Extents) - - if(node->HasPosLeaf()) { SET_CONTACT(node->GetPosPrimitive(), OPC_CONTACT) } - else _CollideNoPrimitiveTest(node->GetPos()); - - if(ContactFound()) return; - - if(node->HasNegLeaf()) { SET_CONTACT(node->GetNegPrimitive(), OPC_CONTACT) } - else _CollideNoPrimitiveTest(node->GetNeg()); -} - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive collision query for vanilla AABB trees. @@ -509,8 +401,6 @@ void AABBCollider::_Collide(const AABBTreeNode* node) } - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructor. diff --git a/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_BoxBoxOverlap.h b/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_BoxBoxOverlap.h index 2487bc69..4544e197 100644 --- a/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_BoxBoxOverlap.h +++ b/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_BoxBoxOverlap.h @@ -191,17 +191,20 @@ inline_ BOOL AABBCollider::AABBAABBOverlap(const Point& extents, const Point& ce return ((_mm_movemask_ps(ma) & 0x07) == 0); #else - float tx = mBox.mCenter.x - center.x; - float ex = extents.x + mBox.mExtents.x; - if (fabs(tx) > ex) return FALSE; + float t = mBox.mCenter.x - center.x; + float e = extents.x + mBox.mExtents.x; + if (fabs(t) > e) + return FALSE; - float ty = mBox.mCenter.y - center.y; - float ey = extents.y + mBox.mExtents.y; - if (fabs(ty) > ey) return FALSE; + t = mBox.mCenter.y - center.y; + e = extents.y + mBox.mExtents.y; + if (fabs(t) > e) + return FALSE; - float tz = mBox.mCenter.z - center.z; - float ez = extents.z + mBox.mExtents.z; - if (fabs(tz) > ez) return FALSE; + t = mBox.mCenter.z - center.z; + e = extents.z + mBox.mExtents.z; + if (fabs(t) > e) + return FALSE; return TRUE; #endif } diff --git a/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_Picking.cpp b/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_Picking.cpp deleted file mode 100644 index 0f4c6c32..00000000 --- a/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_Picking.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/* - * OPCODE - Optimized Collision Detection - * Copyright (C) 2001 Pierre Terdiman - * Homepage: http://www.codercorner.com/Opcode.htm - */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/** - * Contains code to perform "picking". - * \file OPC_Picking.cpp - * \author Pierre Terdiman - * \date March, 20, 2001 - */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Precompiled Header -#include "Stdafx.h" - -using namespace Opcode; - -#ifdef OPC_RAYHIT_CALLBACK - -/* - Possible RayCollider usages: - - boolean query (shadow feeler) - - closest hit - - all hits - - number of intersection (boolean) - -*/ - -bool Opcode::SetupAllHits(RayCollider& collider, CollisionFaces& contacts) -{ - struct Local - { - static void AllContacts(const CollisionFace& hit, void* user_data) - { - CollisionFaces* CF = (CollisionFaces*)user_data; - CF->AddFace(hit); - } - }; - - collider.SetFirstContact(false); - collider.SetHitCallback(Local::AllContacts); - collider.SetUserData(&contacts); - return true; -} - -bool Opcode::SetupClosestHit(RayCollider& collider, CollisionFace& closest_contact) -{ - struct Local - { - static void ClosestContact(const CollisionFace& hit, void* user_data) - { - CollisionFace* CF = (CollisionFace*)user_data; - if(hit.mDistancemDistance) *CF = hit; - } - }; - - collider.SetFirstContact(false); - collider.SetHitCallback(Local::ClosestContact); - collider.SetUserData(&closest_contact); - closest_contact.mDistance = MAX_FLOAT; - return true; -} - -bool Opcode::SetupShadowFeeler(RayCollider& collider) -{ - collider.SetFirstContact(true); - collider.SetHitCallback(null); - return true; -} - -bool Opcode::SetupInOutTest(RayCollider& collider) -{ - collider.SetFirstContact(false); - collider.SetHitCallback(null); - // Results with collider.GetNbIntersections() - return true; -} - -bool Opcode::Picking( -CollisionFace& picked_face, -const Ray& world_ray, const Model& model, const Matrix4x4* world, -float min_dist, float max_dist, const Point& view_point, CullModeCallback callback, void* user_data) -{ - struct Local - { - struct CullData - { - CollisionFace* Closest; - float MinLimit; - CullModeCallback Callback; - void* UserData; - Point ViewPoint; - const MeshInterface* IMesh; - }; - - // Called for each stabbed face - static void RenderCullingCallback(const CollisionFace& hit, void* user_data) - { - CullData* Data = (CullData*)user_data; - - // Discard face if we already have a closer hit - if(hit.mDistance>=Data->Closest->mDistance) return; - - // Discard face if hit point is smaller than min limit. This mainly happens when the face is in front - // of the near clip plane (or straddles it). If we keep the face nonetheless, the user can select an - // object that he may not even be able to see, which is very annoying. - if(hit.mDistance<=Data->MinLimit) return; - - // This is the index of currently stabbed triangle. - udword StabbedFaceIndex = hit.mFaceID; - - // We may keep it or not, depending on backface culling - bool KeepIt = true; - - // Catch *render* cull mode for this face - CullMode CM = (Data->Callback)(StabbedFaceIndex, Data->UserData); - - if(CM!=CULLMODE_NONE) // Don't even compute culling for double-sided triangles - { - // Compute backface culling for current face - - VertexPointers VP; - ConversionArea VC; - Data->IMesh->GetTriangle(VP, StabbedFaceIndex, VC); - if(VP.BackfaceCulling(Data->ViewPoint)) - { - if(CM==CULLMODE_CW) KeepIt = false; - } - else - { - if(CM==CULLMODE_CCW) KeepIt = false; - } - } - - if(KeepIt) *Data->Closest = hit; - } - }; - - RayCollider RC; - RC.SetMaxDist(max_dist); - RC.SetTemporalCoherence(false); - RC.SetCulling(false); // We need all faces since some of them can be double-sided - RC.SetFirstContact(false); - RC.SetHitCallback(Local::RenderCullingCallback); - - picked_face.mFaceID = INVALID_ID; - picked_face.mDistance = MAX_FLOAT; - picked_face.mU = 0.0f; - picked_face.mV = 0.0f; - - Local::CullData Data; - Data.Closest = &picked_face; - Data.MinLimit = min_dist; - Data.Callback = callback; - Data.UserData = user_data; - Data.ViewPoint = view_point; - Data.IMesh = model.GetMeshInterface(); - - if(world) - { - // Get matrices - Matrix4x4 InvWorld; - InvertPRMatrix(InvWorld, *world); - - // Compute camera position in mesh space - Data.ViewPoint *= InvWorld; - } - - RC.SetUserData(&Data); - if(RC.Collide(world_ray, model, world)) - { - return picked_face.mFaceID!=INVALID_ID; - } - return false; -} - -#endif diff --git a/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_Picking.h b/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_Picking.h deleted file mode 100644 index d22fa38a..00000000 --- a/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_Picking.h +++ /dev/null @@ -1,45 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/* - * OPCODE - Optimized Collision Detection - * Copyright (C) 2001 Pierre Terdiman - * Homepage: http://www.codercorner.com/Opcode.htm - */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/** - * Contains code to perform "picking". - * \file OPC_Picking.h - * \author Pierre Terdiman - * \date March, 20, 2001 - */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Include Guard -#ifndef __OPC_PICKING_H__ -#define __OPC_PICKING_H__ - -#ifdef OPC_RAYHIT_CALLBACK - - enum CullMode - { - CULLMODE_NONE = 0, - CULLMODE_CW = 1, - CULLMODE_CCW = 2 - }; - - typedef CullMode (*CullModeCallback)(udword triangle_index, void* user_data); - - OPCODE_API bool SetupAllHits (RayCollider& collider, CollisionFaces& contacts); - OPCODE_API bool SetupClosestHit (RayCollider& collider, CollisionFace& closest_contact); - OPCODE_API bool SetupShadowFeeler (RayCollider& collider); - OPCODE_API bool SetupInOutTest (RayCollider& collider); - - OPCODE_API bool Picking( - CollisionFace& picked_face, - const Ray& world_ray, const Model& model, const Matrix4x4* world, - float min_dist, float max_dist, const Point& view_point, CullModeCallback callback, void* user_data); -#endif - -#endif //__OPC_PICKING_H__ diff --git a/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_RayCollider.cpp b/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_RayCollider.cpp index 46f80f4e..4d7b8105 100644 --- a/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_RayCollider.cpp +++ b/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_RayCollider.cpp @@ -126,20 +126,6 @@ using namespace Opcode; /* In any case the contact has been found and recorded in mStabbedFace */ \ mStabbedFace.mFaceID = prim_index; -#ifdef OPC_RAYHIT_CALLBACK - - #define HANDLE_CONTACT(prim_index, flag) \ - SET_CONTACT(prim_index, flag) \ - \ - if(mHitCallback) (mHitCallback)(mStabbedFace, mUserData); - - #define UPDATE_CACHE \ - if(cache && GetContactStatus()) \ - { \ - *cache = mStabbedFace.mFaceID; \ - } -#else - #define HANDLE_CONTACT(prim_index, flag) \ SET_CONTACT(prim_index, flag) \ \ @@ -169,7 +155,6 @@ using namespace Opcode; if(Current) *cache = Current->mFaceID; \ else *cache = INVALID_ID; \ } -#endif #define SEGMENT_PRIM(prim_index, flag) \ /* Request vertices from the app */ \ @@ -180,7 +165,7 @@ using namespace Opcode; { \ /* Intersection point is valid if dist < segment's length */ \ /* We know dist>0 so we can use integers */ \ - if(IR(mStabbedFace.mDistance)GetNodes()); - else _RayStab(Tree->GetNodes()); + // Perform stabbing query + if(mMaxDist != MAX_FLOAT) + _SegmentStab(Tree->GetNodes()); + else + _RayStab(Tree->GetNodes()); // Update cache if needed UPDATE_CACHE return true; } - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Initializes a stabbing query : @@ -301,9 +282,9 @@ BOOL RayCollider::InitQuery(const Ray& world_ray, const Matrix4x4* world, udword mNbRayBVTests = 0; mNbRayPrimTests = 0; mNbIntersections = 0; -#ifndef OPC_RAYHIT_CALLBACK - if(mStabbedFaces) mStabbedFaces->Reset(); -#endif + + if(mStabbedFaces) + mStabbedFaces->Reset(); // Compute ray in local space // The (Origin/Dir) form is needed for the ray-triangle test anyway (even for segment tests) @@ -341,48 +322,16 @@ BOOL RayCollider::InitQuery(const Ray& world_ray, const Matrix4x4* world, udword // Test previously colliding primitives first if(TemporalCoherenceEnabled() && FirstContactEnabled() && face_id && *face_id!=INVALID_ID) { -#ifdef OLD_CODE -#ifndef OPC_RAYHIT_CALLBACK - if(!mClosestHit) -#endif - { - // Request vertices from the app - VertexPointers VP; - ConversionArea VC; - mIMesh->GetTriangle(VP, *face_id, VC); - // Perform ray-cached tri overlap test - if(RayTriOverlap(*VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) - { - // Intersection point is valid if: - // - distance is positive (else it can just be a face behind the orig point) - // - distance is smaller than a given max distance (useful for shadow feelers) -// if(mStabbedFace.mDistance>0.0f && mStabbedFace.mDistanceAddFace(mStabbedFace); -#endif - return TRUE; - } - } - } -#else - // New code // We handle both Segment/ray queries with the same segment code, and a possible infinite limit SEGMENT_PRIM(*face_id, OPC_TEMPORAL_CONTACT) // Return immediately if possible - if(GetContactStatus()) return TRUE; -#endif + if(GetContactStatus()) + return TRUE; } // Precompute data (moved after temporal coherence since only needed for ray-AABB) - if(IR(mMaxDist)!=IEEE_MAX_FLOAT) + if(mMaxDist != MAX_FLOAT) { // For Segment-AABB overlap mData = 0.5f * mDir * mMaxDist; @@ -470,36 +419,6 @@ void RayCollider::_SegmentStab(const AABBCollisionNode* node) } } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/** - * Recursive stabbing query for quantized AABB trees. - * \param node [in] current collision node - */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void RayCollider::_SegmentStab(const AABBQuantizedNode* node) -{ - // Dequantize box - const QuantizedAABB& Box = node->mAABB; - const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); - const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); - - // Perform Segment-AABB overlap test - if(!SegmentAABBOverlap(Center, Extents)) return; - - if(node->IsLeaf()) - { - SEGMENT_PRIM(node->GetPrimitive(), OPC_CONTACT) - } - else - { - _SegmentStab(node->GetPos()); - - if(ContactFound()) return; - - _SegmentStab(node->GetNeg()); - } -} - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive stabbing query for no-leaf AABB trees. @@ -526,36 +445,6 @@ void RayCollider::_SegmentStab(const AABBNoLeafNode* node) else _SegmentStab(node->GetNeg()); } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/** - * Recursive stabbing query for quantized no-leaf AABB trees. - * \param node [in] current collision node - */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void RayCollider::_SegmentStab(const AABBQuantizedNoLeafNode* node) -{ - // Dequantize box - const QuantizedAABB& Box = node->mAABB; - const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); - const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); - - // Perform Segment-AABB overlap test - if(!SegmentAABBOverlap(Center, Extents)) return; - - if(node->HasPosLeaf()) - { - SEGMENT_PRIM(node->GetPosPrimitive(), OPC_CONTACT) - } - else _SegmentStab(node->GetPos()); - - if(ContactFound()) return; - - if(node->HasNegLeaf()) - { - SEGMENT_PRIM(node->GetNegPrimitive(), OPC_CONTACT) - } - else _SegmentStab(node->GetNeg()); -} /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** @@ -608,36 +497,6 @@ void RayCollider::_RayStab(const AABBCollisionNode* node) } } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/** - * Recursive stabbing query for quantized AABB trees. - * \param node [in] current collision node - */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void RayCollider::_RayStab(const AABBQuantizedNode* node) -{ - // Dequantize box - const QuantizedAABB& Box = node->mAABB; - const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); - const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); - - // Perform Ray-AABB overlap test - if(!RayAABBOverlap(Center, Extents)) return; - - if(node->IsLeaf()) - { - RAY_PRIM(node->GetPrimitive(), OPC_CONTACT) - } - else - { - _RayStab(node->GetPos()); - - if(ContactFound()) return; - - _RayStab(node->GetNeg()); - } -} - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive stabbing query for no-leaf AABB trees. @@ -664,37 +523,6 @@ void RayCollider::_RayStab(const AABBNoLeafNode* node) else _RayStab(node->GetNeg()); } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/** - * Recursive stabbing query for quantized no-leaf AABB trees. - * \param node [in] current collision node - */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void RayCollider::_RayStab(const AABBQuantizedNoLeafNode* node) -{ - // Dequantize box - const QuantizedAABB& Box = node->mAABB; - const Point Center(float(Box.mCenter[0]) * mCenterCoeff.x, float(Box.mCenter[1]) * mCenterCoeff.y, float(Box.mCenter[2]) * mCenterCoeff.z); - const Point Extents(float(Box.mExtents[0]) * mExtentsCoeff.x, float(Box.mExtents[1]) * mExtentsCoeff.y, float(Box.mExtents[2]) * mExtentsCoeff.z); - - // Perform Ray-AABB overlap test - if(!RayAABBOverlap(Center, Extents)) return; - - if(node->HasPosLeaf()) - { - RAY_PRIM(node->GetPosPrimitive(), OPC_CONTACT) - } - else _RayStab(node->GetPos()); - - if(ContactFound()) return; - - if(node->HasNegLeaf()) - { - RAY_PRIM(node->GetNegPrimitive(), OPC_CONTACT) - } - else _RayStab(node->GetNeg()); -} - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Recursive stabbing query for vanilla AABB trees. diff --git a/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_RayCollider.h b/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_RayCollider.h index 4a8ab7e6..52c0f318 100644 --- a/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_RayCollider.h +++ b/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_RayCollider.h @@ -24,48 +24,49 @@ { public: //! Constructor - inline_ CollisionFace() {} + inline_ CollisionFace() {} //! Destructor - inline_ ~CollisionFace() {} + inline_ ~CollisionFace() {} - udword mFaceID; //!< Index of touched face - float mDistance; //!< Distance from collider to hitpoint - float mU, mV; //!< Impact barycentric coordinates + udword mFaceID; //!< Index of touched face + float mDistance; //!< Distance from collider to hitpoint + float mU, mV; //!< Impact barycentric coordinates }; class OPCODE_API CollisionFaces : public Container { public: //! Constructor - CollisionFaces() {} + CollisionFaces() {} //! Destructor - ~CollisionFaces() {} + ~CollisionFaces() {} - inline_ udword GetNbFaces() const { return GetNbEntries()>>2; } - inline_ const CollisionFace* GetFaces() const { return (const CollisionFace*)GetEntries(); } + inline_ udword GetNbFaces() const + { + return GetNbEntries() >> 2; + } + inline_ const CollisionFace* GetFaces() const + { + return (const CollisionFace*)GetEntries(); + } - inline_ void Reset() { Container::Reset(); } + inline_ void Reset() + { + Container::Reset(); + } - inline_ void AddFace(const CollisionFace& face) { Add(face.mFaceID).Add(face.mDistance).Add(face.mU).Add(face.mV); } + inline_ void AddFace(const CollisionFace& face) + { + Add(face.mFaceID).Add(face.mDistance).Add(face.mU).Add(face.mV); + } }; -#ifdef OPC_RAYHIT_CALLBACK - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /** - * User-callback, called by OPCODE to record a hit. - * \param hit [in] current hit - * \param user_data [in] user-defined data from SetCallback() - */ - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - typedef void (*HitCallback) (const CollisionFace& hit, void* user_data); -#endif - class OPCODE_API RayCollider : public Collider { public: // Constructor / Destructor - RayCollider(); - virtual ~RayCollider(); + RayCollider(); + virtual ~RayCollider(); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** @@ -81,12 +82,11 @@ * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - bool Collide(const Ray& world_ray, const Model& model, const Matrix4x4* world=null, udword* cache=null); + bool Collide(const Ray& world_ray, const Model& model, const Matrix4x4* world=null, udword* cache=null); // - bool Collide(const Ray& world_ray, const AABBTree* tree, Container& box_indices); + bool Collide(const Ray& world_ray, const AABBTree* tree, Container& box_indices); // Settings -#ifndef OPC_RAYHIT_CALLBACK /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Settings: enable or disable "closest hit" mode. @@ -96,8 +96,11 @@ * \see SetDestination(StabbedFaces* sf) */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - inline_ void SetClosestHit(bool flag) { mClosestHit = flag; } -#endif + inline_ void SetClosestHit(bool flag) + { + mClosestHit = flag; + } + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Settings: enable or disable backface culling. @@ -107,7 +110,10 @@ * \see SetDestination(StabbedFaces* sf) */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - inline_ void SetCulling(bool flag) { mCulling = flag; } + inline_ void SetCulling(bool flag) + { + mCulling = flag; + } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** @@ -118,12 +124,11 @@ * \see SetDestination(StabbedFaces* sf) */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - inline_ void SetMaxDist(float max_dist=MAX_FLOAT) { mMaxDist = max_dist; } + inline_ void SetMaxDist(float max_dist = MAX_FLOAT) + { + mMaxDist = max_dist; + } -#ifdef OPC_RAYHIT_CALLBACK - inline_ void SetHitCallback(HitCallback cb) { mHitCallback = cb; } - inline_ void SetUserData(void* user_data) { mUserData = user_data; } -#else /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Settings: sets the destination array for stabbed faces. @@ -133,8 +138,10 @@ * \see SetMaxDist(float max_dist) */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - inline_ void SetDestination(CollisionFaces* cf) { mStabbedFaces = cf; } -#endif + inline_ void SetDestination(CollisionFaces* cf) + { + mStabbedFaces = cf; + } // Stats /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** @@ -144,7 +151,10 @@ * \return the number of Ray-BV tests performed during last query */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - inline_ udword GetNbRayBVTests() const { return mNbRayBVTests; } + inline_ udword GetNbRayBVTests() const + { + return mNbRayBVTests; + } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** @@ -154,7 +164,10 @@ * \return the number of Ray-Triangle tests performed during last query */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - inline_ udword GetNbRayPrimTests() const { return mNbRayPrimTests; } + inline_ udword GetNbRayPrimTests() const + { + return mNbRayPrimTests; + } // In-out test /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -165,7 +178,10 @@ * \return the number of valid intersections during last query */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - inline_ udword GetNbIntersections() const { return mNbIntersections; } + inline_ udword GetNbIntersections() const + { + return mNbIntersections; + } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** @@ -177,48 +193,38 @@ protected: // Ray in local space - Point mOrigin; //!< Ray origin - Point mDir; //!< Ray direction (normalized) - Point mFDir; //!< fabsf(mDir) - Point mData, mData2; + Point mOrigin; //!< Ray origin + Point mDir; //!< Ray direction (normalized) + Point mFDir; //!< fabsf(mDir) + Point mData, mData2; // Stabbed faces - CollisionFace mStabbedFace; //!< Current stabbed face -#ifdef OPC_RAYHIT_CALLBACK - HitCallback mHitCallback; //!< Callback used to record a hit - void* mUserData; //!< User-defined data -#else - CollisionFaces* mStabbedFaces; //!< List of stabbed faces - bool mClosestHit; //!< Report closest hit only -#endif + CollisionFace mStabbedFace; //!< Current stabbed face + CollisionFaces* mStabbedFaces; //!< List of stabbed faces + bool mClosestHit; //!< Report closest hit only // Stats - udword mNbRayBVTests; //!< Number of Ray-BV tests - udword mNbRayPrimTests; //!< Number of Ray-Primitive tests + udword mNbRayBVTests; //!< Number of Ray-BV tests + udword mNbRayPrimTests; //!< Number of Ray-Primitive tests // In-out test - udword mNbIntersections; //!< Number of valid intersections + udword mNbIntersections; //!< Number of valid intersections // Dequantization coeffs - Point mCenterCoeff; - Point mExtentsCoeff; + Point mCenterCoeff; + Point mExtentsCoeff; // Settings - float mMaxDist; //!< Valid segment on the ray - - bool mCulling; //!< Stab culled faces or not + float mMaxDist; //!< Valid segment on the ray + bool mCulling; //!< Stab culled faces or not // Internal methods - void _SegmentStab(const AABBCollisionNode* node); - void _SegmentStab(const AABBNoLeafNode* node); - void _SegmentStab(const AABBQuantizedNode* node); - void _SegmentStab(const AABBQuantizedNoLeafNode* node); - void _SegmentStab(const AABBTreeNode* node, Container& box_indices); - void _RayStab(const AABBCollisionNode* node); - void _RayStab(const AABBNoLeafNode* node); - void _RayStab(const AABBQuantizedNode* node); - void _RayStab(const AABBQuantizedNoLeafNode* node); - void _RayStab(const AABBTreeNode* node, Container& box_indices); - // Overlap tests - inline_ BOOL RayAABBOverlap(const Point& center, const Point& extents); - inline_ BOOL SegmentAABBOverlap(const Point& center, const Point& extents); - inline_ BOOL RayTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2); + void _SegmentStab(const AABBCollisionNode* node); + void _SegmentStab(const AABBNoLeafNode* node); + void _SegmentStab(const AABBTreeNode* node, Container& box_indices); + void _RayStab(const AABBCollisionNode* node); + void _RayStab(const AABBNoLeafNode* node); + void _RayStab(const AABBTreeNode* node, Container& box_indices); + // Overlap tests + inline_ BOOL RayAABBOverlap(const Point& center, const Point& extents); + inline_ BOOL SegmentAABBOverlap(const Point& center, const Point& extents); + inline_ BOOL RayTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2); // Init methods - BOOL InitQuery(const Ray& world_ray, const Matrix4x4* world=null, udword* face_id=null); + BOOL InitQuery(const Ray& world_ray, const Matrix4x4* world=null, udword* face_id=null); }; #endif // __OPC_RAYCOLLIDER_H__ diff --git a/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_RayTriOverlap.h b/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_RayTriOverlap.h index 04110a1f..0b25aa62 100644 --- a/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_RayTriOverlap.h +++ b/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_RayTriOverlap.h @@ -23,10 +23,10 @@ inline_ BOOL RayCollider::RayTriOverlap(const Point& vert0, const Point& vert1, Point edge2 = vert2 - vert0; // Begin calculating determinant - also used to calculate U parameter - Point pvec = mDir^edge2; + Point pvec = mDir ^ edge2; // If determinant is near zero, ray lies in plane of triangle - float det = edge1|pvec; + float det = edge1 | pvec; if(mCulling) { @@ -62,7 +62,7 @@ inline_ BOOL RayCollider::RayTriOverlap(const Point& vert0, const Point& vert1, else { // the non-culling branch - if(FastFabs(det) <= LOCAL_EPSILON * FCMin2(edge1.SquareMagnitude(), edge2.SquareMagnitude())) return FALSE; + if(fabsf(det) <= LOCAL_EPSILON * FCMin2(edge1.SquareMagnitude(), edge2.SquareMagnitude())) return FALSE; float OneOverDet = 1.0f / det; // Calculate distance from vert0 to ray origin diff --git a/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_Settings.h b/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_Settings.h index 3600378f..cc08f4f3 100644 --- a/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_Settings.h +++ b/trunk/unmanaged/ubODE-OpenSim/OPCODE/OPC_Settings.h @@ -32,9 +32,6 @@ //! Discard negative pointer in vanilla trees #define OPC_NO_NEG_VANILLA_TREE - //! Use a callback in the ray collider - //#define OPC_RAYHIT_CALLBACK - // NB: no compilation flag to enable/disable stats since they're actually needed in the box/box overlap test #endif //__OPC_SETTINGS_H__ diff --git a/trunk/unmanaged/ubODE-OpenSim/OPCODE/Opcode.h b/trunk/unmanaged/ubODE-OpenSim/OPCODE/Opcode.h index 9cb9b7d4..7c091043 100644 --- a/trunk/unmanaged/ubODE-OpenSim/OPCODE/Opcode.h +++ b/trunk/unmanaged/ubODE-OpenSim/OPCODE/Opcode.h @@ -106,8 +106,6 @@ #include "OPC_LSSCollider.h" #include "OPC_PlanesCollider.h" // Usages - #include "OPC_Picking.h" - FUNCTION OPCODE_API bool InitOpcode(); FUNCTION OPCODE_API bool CloseOpcode(); diff --git a/trunk/unmanaged/ubODE-OpenSim/ode/src/collision_trimesh_plane.cpp b/trunk/unmanaged/ubODE-OpenSim/ode/src/collision_trimesh_plane.cpp index 49f4a65b..e30a67d2 100644 --- a/trunk/unmanaged/ubODE-OpenSim/ode/src/collision_trimesh_plane.cpp +++ b/trunk/unmanaged/ubODE-OpenSim/ode/src/collision_trimesh_plane.cpp @@ -62,7 +62,7 @@ int dCollideTrimeshPlane( dxGeom *o1, dxGeom *o2, int flags, dContactGeom* conta dReal alpha; dVector3 vertex; - dVector3 int_vertex; // Intermediate vertex for double precision mode. + //dVector3 int_vertex; // Intermediate vertex for double precision mode. const unsigned uiTLSKind = trimesh->getParentSpaceTLSKind(); dIASSERT(uiTLSKind == plane->getParentSpaceTLSKind()); // The colliding spaces must use matching cleanup method