Add PhysicsEffects to Extras. The build is only tested on Windows and Android.
The Android/NEON optimized version of Physics Effects is thanks to Graham Rhodes and Anthony Hamilton, See Issue 587
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
Applied Research Associates Inc. (c)2011
|
||||
|
||||
Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc.
|
||||
All rights reserved.
|
||||
|
||||
Physics Effects is open software; you can redistribute it and/or
|
||||
modify it under the terms of the BSD License.
|
||||
|
||||
Physics Effects is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the BSD License for more details.
|
||||
|
||||
A copy of the BSD License is distributed with
|
||||
Physics Effects under the filename: physics_effects_license.txt
|
||||
*/
|
||||
|
||||
#include "../../../include/physics_effects/low_level/collision/pfx_batched_ray_cast.h"
|
||||
#include "../../../include/physics_effects/base_level/base/pfx_perf_counter.h"
|
||||
|
||||
namespace sce {
|
||||
namespace PhysicsEffects {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// MULTIPLE THREADS
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// pfxCastRaysStartTaskEntry
|
||||
//
|
||||
/// The thread PfxTaskEntry function used to cast rays in parallel.
|
||||
//----------------------------------------------------------------------------
|
||||
void pfxCastRaysStartTaskEntry(PfxTaskArg *arg)
|
||||
{
|
||||
PfxRayCastParam ¶m = *((PfxRayCastParam*)arg->io);
|
||||
|
||||
PfxRayInput *rayInputs = (PfxRayInput*)arg->data[0];
|
||||
PfxRayOutput *rayOutputs = (PfxRayOutput*)arg->data[1];
|
||||
PfxUInt32 iFirstRay = arg->data[2];
|
||||
PfxUInt32 iEndRay = arg->data[3];
|
||||
|
||||
for(PfxUInt32 i = iFirstRay; i < iEndRay; i++)
|
||||
{
|
||||
pfxCastSingleRay(rayInputs[i], rayOutputs[i], param);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// pfxCastRays
|
||||
//
|
||||
/// Perform cast rays in parallel using a task manager.
|
||||
///
|
||||
/// @param rayInputs [in] Array of rays to cast
|
||||
/// @param rayOutputs [out] On return contains output of ray casts
|
||||
/// @param param Information about ray cast
|
||||
/// @param taskManager Pointer to the thread task manager to use
|
||||
//----------------------------------------------------------------------------
|
||||
void pfxCastRays(PfxRayInput *rayInputs,PfxRayOutput *rayOutputs,int numRays,
|
||||
PfxRayCastParam ¶m,PfxTaskManager *taskManager)
|
||||
{
|
||||
SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesX));
|
||||
SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesY));
|
||||
SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesZ));
|
||||
SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesXb));
|
||||
SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesYb));
|
||||
SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesZb));
|
||||
SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.offsetRigidStates));
|
||||
SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.offsetCollidables));
|
||||
|
||||
SCE_PFX_PUSH_MARKER("pfxCastRays");
|
||||
|
||||
PfxUInt32 maxBatchSize = numRays / (PfxUInt32)(taskManager->getNumTasks());
|
||||
PfxUInt32 iEnd = maxBatchSize, iStart = 0;
|
||||
int task = 0;
|
||||
taskManager->setTaskEntry((void*)pfxCastRaysStartTaskEntry);
|
||||
|
||||
for (task = 0; task < taskManager->getNumTasks() - 1; task++, iStart += maxBatchSize, iEnd += maxBatchSize)
|
||||
{
|
||||
taskManager->startTask(task, static_cast<void*>(¶m), (PfxUInt32)rayInputs, (PfxUInt32)rayOutputs, iStart, iEnd);
|
||||
}
|
||||
|
||||
// send final task
|
||||
iEnd = numRays;
|
||||
taskManager->startTask(taskManager->getNumTasks() - 1, static_cast<void*>(¶m), iStart, iEnd, 0, 0);
|
||||
|
||||
// wait for tasks to complete
|
||||
PfxUInt32 data1, data2, data3, data4;
|
||||
for (PfxUInt32 i = 0; i < taskManager->getNumTasks(); i++)
|
||||
taskManager->waitTask(task, data1, data2, data3, data4);
|
||||
|
||||
SCE_PFX_POP_MARKER();
|
||||
}
|
||||
|
||||
} //namespace PhysicsEffects
|
||||
} //namespace sce
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc.
|
||||
All rights reserved.
|
||||
|
||||
Physics Effects is open software; you can redistribute it and/or
|
||||
modify it under the terms of the BSD License.
|
||||
|
||||
Physics Effects is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the BSD License for more details.
|
||||
|
||||
A copy of the BSD License is distributed with
|
||||
Physics Effects under the filename: physics_effects_license.txt
|
||||
*/
|
||||
|
||||
#include "../../../include/physics_effects/low_level/collision/pfx_batched_ray_cast.h"
|
||||
|
||||
namespace sce {
|
||||
namespace PhysicsEffects {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// SINGLE THREAD
|
||||
|
||||
void pfxCastRaysStart(PfxRayInput *rayInputs,PfxRayOutput *rayOutputs,int numRays,PfxRayCastParam ¶m)
|
||||
{
|
||||
for(int i=0;i<numRays;i++) {
|
||||
pfxCastSingleRay(rayInputs[i],rayOutputs[i],param);
|
||||
}
|
||||
}
|
||||
|
||||
void pfxCastRays(PfxRayInput *rayInputs,PfxRayOutput *rayOutputs,int numRays,PfxRayCastParam ¶m)
|
||||
{
|
||||
SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesX));
|
||||
SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesY));
|
||||
SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesZ));
|
||||
SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesXb));
|
||||
SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesYb));
|
||||
SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesZb));
|
||||
SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.offsetRigidStates));
|
||||
SCE_PFX_ALWAYS_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.offsetCollidables));
|
||||
|
||||
pfxCastRaysStart(rayInputs,rayOutputs,numRays,param);
|
||||
}
|
||||
|
||||
} //namespace PhysicsEffects
|
||||
} //namespace sce
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
Applied Research Associates Inc. (c)2011
|
||||
|
||||
Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc.
|
||||
All rights reserved.
|
||||
|
||||
Physics Effects is open software; you can redistribute it and/or
|
||||
modify it under the terms of the BSD License.
|
||||
|
||||
Physics Effects is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the BSD License for more details.
|
||||
|
||||
A copy of the BSD License is distributed with
|
||||
Physics Effects under the filename: physics_effects_license.txt
|
||||
*/
|
||||
|
||||
#include "../../../include/physics_effects/base_level/base/pfx_perf_counter.h"
|
||||
#include "../../../include/physics_effects/base_level/collision/pfx_shape_iterator.h"
|
||||
#include "../../../include/physics_effects/low_level/collision/pfx_collision_detection.h"
|
||||
#include "../../base_level/broadphase/pfx_check_collidable.h"
|
||||
#include "../../base_level/collision/pfx_contact_cache.h"
|
||||
#include "pfx_detect_collision_func.h"
|
||||
|
||||
namespace sce {
|
||||
namespace PhysicsEffects {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// This function is implemented in pfx_collision_detection_single.cpp
|
||||
extern int pfxCheckParamOfDetectCollision(PfxDetectCollisionParam ¶m);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// MULTIPLE THREADS
|
||||
|
||||
#define SCE_PFX_CONTACT_THRESHOLD 0.0f
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// pfxDetectCollisionTaskEntry
|
||||
//
|
||||
/// The thread PfxTaskEntry function used to perform narrow phase collision
|
||||
/// detection in parallel.
|
||||
//----------------------------------------------------------------------------
|
||||
void pfxDetectCollisionTaskEntry(PfxTaskArg *arg)
|
||||
{
|
||||
PfxDetectCollisionParam ¶m = *((PfxDetectCollisionParam*)arg->io);
|
||||
|
||||
PfxUInt32 iFirstContactPair = arg->data[0];
|
||||
PfxUInt32 iEndContactPair = arg->data[1];
|
||||
|
||||
PfxConstraintPair *contactPairs = param.contactPairs;
|
||||
PfxContactManifold *offsetContactManifolds = param.offsetContactManifolds;
|
||||
PfxRigidState *offsetRigidStates = param.offsetRigidStates;
|
||||
PfxCollidable *offsetCollidables = param.offsetCollidables;
|
||||
PfxUInt32 numRigidBodies = param.numRigidBodies;
|
||||
|
||||
for(PfxUInt32 i = iFirstContactPair; i < iEndContactPair; i++)
|
||||
{
|
||||
const PfxBroadphasePair &pair = contactPairs[i];
|
||||
if(!pfxCheckCollidableInCollision(pair))
|
||||
continue;
|
||||
|
||||
PfxUInt32 iContact = pfxGetContactId(pair);
|
||||
PfxUInt32 iA = pfxGetObjectIdA(pair);
|
||||
PfxUInt32 iB = pfxGetObjectIdB(pair);
|
||||
|
||||
PfxContactManifold &contact = offsetContactManifolds[iContact];
|
||||
|
||||
SCE_PFX_ALWAYS_ASSERT(iA==contact.getRigidBodyIdA());
|
||||
SCE_PFX_ALWAYS_ASSERT(iB==contact.getRigidBodyIdB());
|
||||
|
||||
PfxRigidState &stateA = offsetRigidStates[iA];
|
||||
PfxRigidState &stateB = offsetRigidStates[iB];
|
||||
PfxCollidable &collA = offsetCollidables[iA];
|
||||
PfxCollidable &collB = offsetCollidables[iB];
|
||||
PfxTransform3 tA0(stateA.getOrientation(), stateA.getPosition());
|
||||
PfxTransform3 tB0(stateB.getOrientation(), stateB.getPosition());
|
||||
|
||||
PfxContactCache contactCache;
|
||||
|
||||
PfxShapeIterator itrShapeA(collA);
|
||||
for(PfxUInt32 j=0;j<collA.getNumShapes();j++,++itrShapeA)
|
||||
{
|
||||
const PfxShape &shapeA = *itrShapeA;
|
||||
PfxTransform3 offsetTrA = shapeA.getOffsetTransform();
|
||||
PfxTransform3 worldTrA = tA0 * offsetTrA;
|
||||
|
||||
PfxShapeIterator itrShapeB(collB);
|
||||
for(PfxUInt32 k=0;k<collB.getNumShapes();k++,++itrShapeB)
|
||||
{
|
||||
const PfxShape &shapeB = *itrShapeB;
|
||||
PfxTransform3 offsetTrB = shapeB.getOffsetTransform();
|
||||
PfxTransform3 worldTrB = tB0 * offsetTrB;
|
||||
|
||||
if( (shapeA.getContactFilterSelf()&shapeB.getContactFilterTarget()) &&
|
||||
(shapeA.getContactFilterTarget()&shapeB.getContactFilterSelf()) )
|
||||
{
|
||||
pfxGetDetectCollisionFunc(shapeA.getType(),shapeB.getType())(
|
||||
contactCache,
|
||||
shapeA,offsetTrA,worldTrA,j,
|
||||
shapeB,offsetTrB,worldTrB,k,
|
||||
SCE_PFX_CONTACT_THRESHOLD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int j=0;j<contactCache.getNumContacts();j++)
|
||||
{
|
||||
const PfxCachedContactPoint &cp = contactCache.getContactPoint(j);
|
||||
|
||||
contact.addContactPoint(
|
||||
cp.m_distance,
|
||||
cp.m_normal,
|
||||
cp.m_localPointA,
|
||||
cp.m_localPointB,
|
||||
cp.m_subData
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// pfxDetectCollision
|
||||
//
|
||||
/// Perform narrow phase collision detection in parallel using a task
|
||||
/// manager.
|
||||
///
|
||||
/// @param param Information about pairs that may be colliding
|
||||
/// @param taskManager Pointer to the thread task manager to use
|
||||
///
|
||||
/// @return SCE_PFX_OK if successful, otherwise, returns an error code.
|
||||
//----------------------------------------------------------------------------
|
||||
PfxInt32 pfxDetectCollision(PfxDetectCollisionParam ¶m, PfxTaskManager *taskManager)
|
||||
{
|
||||
PfxInt32 ret = pfxCheckParamOfDetectCollision(param);
|
||||
if(ret != SCE_PFX_OK)
|
||||
return ret;
|
||||
|
||||
SCE_PFX_PUSH_MARKER("pfxDetectCollision");
|
||||
|
||||
PfxUInt32 maxBatchSize = param.numContactPairs / (PfxUInt32)(taskManager->getNumTasks());
|
||||
PfxUInt32 iEnd = maxBatchSize, iStart = 0;
|
||||
int task = 0;
|
||||
taskManager->setTaskEntry((void*)pfxDetectCollisionTaskEntry);
|
||||
|
||||
for (task = 0; task < taskManager->getNumTasks() - 1; task++, iStart += maxBatchSize, iEnd += maxBatchSize)
|
||||
{
|
||||
taskManager->startTask(task, static_cast<void*>(¶m), iStart, iEnd, 0, 0);
|
||||
}
|
||||
|
||||
// send final task
|
||||
iEnd = param.numContactPairs;
|
||||
taskManager->startTask(taskManager->getNumTasks() - 1, static_cast<void*>(¶m), iStart, iEnd, 0, 0);
|
||||
|
||||
// wait for tasks to complete
|
||||
PfxUInt32 data1, data2, data3, data4;
|
||||
for (PfxUInt32 i = 0; i < taskManager->getNumTasks(); i++)
|
||||
taskManager->waitTask(task, data1, data2, data3, data4);
|
||||
|
||||
SCE_PFX_POP_MARKER();
|
||||
|
||||
return SCE_PFX_OK;
|
||||
}
|
||||
|
||||
} //namespace PhysicsEffects
|
||||
} //namespace sce
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc.
|
||||
All rights reserved.
|
||||
|
||||
Physics Effects is open software; you can redistribute it and/or
|
||||
modify it under the terms of the BSD License.
|
||||
|
||||
Physics Effects is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the BSD License for more details.
|
||||
|
||||
A copy of the BSD License is distributed with
|
||||
Physics Effects under the filename: physics_effects_license.txt
|
||||
*/
|
||||
|
||||
#include "../../../include/physics_effects/base_level/base/pfx_perf_counter.h"
|
||||
#include "../../../include/physics_effects/base_level/collision/pfx_shape_iterator.h"
|
||||
#include "../../../include/physics_effects/low_level/collision/pfx_collision_detection.h"
|
||||
#include "../../base_level/broadphase/pfx_check_collidable.h"
|
||||
#include "../../base_level/collision/pfx_contact_cache.h"
|
||||
#include "pfx_detect_collision_func.h"
|
||||
|
||||
namespace sce {
|
||||
namespace PhysicsEffects {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int pfxCheckParamOfDetectCollision(PfxDetectCollisionParam ¶m)
|
||||
{
|
||||
if(!param.contactPairs || !param.offsetContactManifolds || !param.offsetRigidStates|| !param.offsetCollidables ) return SCE_PFX_ERR_INVALID_VALUE;
|
||||
if(!SCE_PFX_PTR_IS_ALIGNED16(param.contactPairs) || !SCE_PFX_PTR_IS_ALIGNED16(param.offsetContactManifolds) ||
|
||||
!SCE_PFX_PTR_IS_ALIGNED16(param.offsetRigidStates) || !SCE_PFX_PTR_IS_ALIGNED16(param.offsetCollidables)) return SCE_PFX_ERR_INVALID_ALIGN;
|
||||
return SCE_PFX_OK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// SINGLE THREAD
|
||||
|
||||
#define SCE_PFX_CONTACT_THRESHOLD 0.0f
|
||||
|
||||
PfxInt32 pfxDetectCollision(PfxDetectCollisionParam ¶m)
|
||||
{
|
||||
PfxInt32 ret = pfxCheckParamOfDetectCollision(param);
|
||||
if(ret != SCE_PFX_OK)
|
||||
return ret;
|
||||
|
||||
SCE_PFX_PUSH_MARKER("pfxDetectCollision");
|
||||
|
||||
PfxConstraintPair *contactPairs = param.contactPairs;
|
||||
PfxUInt32 numContactPairs = param.numContactPairs;
|
||||
PfxContactManifold *offsetContactManifolds = param.offsetContactManifolds;
|
||||
PfxRigidState *offsetRigidStates = param.offsetRigidStates;
|
||||
PfxCollidable *offsetCollidables = param.offsetCollidables;
|
||||
PfxUInt32 numRigidBodies = param.numRigidBodies;
|
||||
|
||||
for(PfxUInt32 i=0;i<numContactPairs;i++) {
|
||||
const PfxBroadphasePair &pair = contactPairs[i];
|
||||
if(!pfxCheckCollidableInCollision(pair)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PfxUInt32 iContact = pfxGetContactId(pair);
|
||||
PfxUInt32 iA = pfxGetObjectIdA(pair);
|
||||
PfxUInt32 iB = pfxGetObjectIdB(pair);
|
||||
|
||||
PfxContactManifold &contact = offsetContactManifolds[iContact];
|
||||
|
||||
SCE_PFX_ALWAYS_ASSERT(iA==contact.getRigidBodyIdA());
|
||||
SCE_PFX_ALWAYS_ASSERT(iB==contact.getRigidBodyIdB());
|
||||
|
||||
PfxRigidState &stateA = offsetRigidStates[iA];
|
||||
PfxRigidState &stateB = offsetRigidStates[iB];
|
||||
PfxCollidable &collA = offsetCollidables[iA];
|
||||
PfxCollidable &collB = offsetCollidables[iB];
|
||||
PfxTransform3 tA0(stateA.getOrientation(), stateA.getPosition());
|
||||
PfxTransform3 tB0(stateB.getOrientation(), stateB.getPosition());
|
||||
|
||||
PfxContactCache contactCache;
|
||||
|
||||
PfxShapeIterator itrShapeA(collA);
|
||||
for(PfxUInt32 j=0;j<collA.getNumShapes();j++,++itrShapeA) {
|
||||
const PfxShape &shapeA = *itrShapeA;
|
||||
PfxTransform3 offsetTrA = shapeA.getOffsetTransform();
|
||||
PfxTransform3 worldTrA = tA0 * offsetTrA;
|
||||
|
||||
PfxShapeIterator itrShapeB(collB);
|
||||
for(PfxUInt32 k=0;k<collB.getNumShapes();k++,++itrShapeB) {
|
||||
const PfxShape &shapeB = *itrShapeB;
|
||||
PfxTransform3 offsetTrB = shapeB.getOffsetTransform();
|
||||
PfxTransform3 worldTrB = tB0 * offsetTrB;
|
||||
|
||||
if( (shapeA.getContactFilterSelf()&shapeB.getContactFilterTarget()) &&
|
||||
(shapeA.getContactFilterTarget()&shapeB.getContactFilterSelf()) ) {
|
||||
pfxGetDetectCollisionFunc(shapeA.getType(),shapeB.getType())(
|
||||
contactCache,
|
||||
shapeA,offsetTrA,worldTrA,j,
|
||||
shapeB,offsetTrB,worldTrB,k,
|
||||
SCE_PFX_CONTACT_THRESHOLD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int j=0;j<contactCache.getNumContacts();j++) {
|
||||
const PfxCachedContactPoint &cp = contactCache.getContactPoint(j);
|
||||
|
||||
contact.addContactPoint(
|
||||
cp.m_distance,
|
||||
cp.m_normal,
|
||||
cp.m_localPointA,
|
||||
cp.m_localPointB,
|
||||
cp.m_subData
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SCE_PFX_POP_MARKER();
|
||||
|
||||
(void) numRigidBodies;
|
||||
|
||||
return SCE_PFX_OK;
|
||||
}
|
||||
|
||||
} //namespace PhysicsEffects
|
||||
} //namespace sce
|
||||
@@ -0,0 +1,449 @@
|
||||
/*
|
||||
Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc.
|
||||
All rights reserved.
|
||||
|
||||
Physics Effects is open software; you can redistribute it and/or
|
||||
modify it under the terms of the BSD License.
|
||||
|
||||
Physics Effects is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the BSD License for more details.
|
||||
|
||||
A copy of the BSD License is distributed with
|
||||
Physics Effects under the filename: physics_effects_license.txt
|
||||
*/
|
||||
|
||||
#include "../../../include/physics_effects/base_level/collision/pfx_shape.h"
|
||||
#include "../../base_level/collision/pfx_contact_box_box.h"
|
||||
#include "../../base_level/collision/pfx_contact_box_capsule.h"
|
||||
#include "../../base_level/collision/pfx_contact_box_sphere.h"
|
||||
#include "../../base_level/collision/pfx_contact_capsule_capsule.h"
|
||||
#include "../../base_level/collision/pfx_contact_capsule_sphere.h"
|
||||
#include "../../base_level/collision/pfx_contact_sphere_sphere.h"
|
||||
#include "../../base_level/collision/pfx_gjk_solver.h"
|
||||
#include "../../base_level/collision/pfx_contact_large_tri_mesh.h"
|
||||
#include "../../base_level/collision/pfx_gjk_support_func.h"
|
||||
#include "pfx_detect_collision_func.h"
|
||||
|
||||
|
||||
namespace sce {
|
||||
namespace PhysicsEffects {
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Collision Detection Function
|
||||
|
||||
void detectCollisionDummy(
|
||||
PfxContactCache &contacts,
|
||||
const PfxShape &shapeA,const PfxTransform3 &offsetTransformA,const PfxTransform3 &worldTransformA,int shapeIdA,
|
||||
const PfxShape &shapeB,const PfxTransform3 &offsetTransformB,const PfxTransform3 &worldTransformB,int shapeIdB,
|
||||
float contactThreshold)
|
||||
{
|
||||
(void)contacts;
|
||||
(void)shapeA,(void)offsetTransformA,(void)worldTransformA,(void)shapeIdA;
|
||||
(void)shapeB,(void)offsetTransformB,(void)worldTransformB,(void)shapeIdB;
|
||||
(void)contactThreshold;
|
||||
}
|
||||
|
||||
void detectCollisionBoxBox(
|
||||
PfxContactCache &contacts,
|
||||
const PfxShape &shapeA,const PfxTransform3 &offsetTransformA,const PfxTransform3 &worldTransformA,int shapeIdA,
|
||||
const PfxShape &shapeB,const PfxTransform3 &offsetTransformB,const PfxTransform3 &worldTransformB,int shapeIdB,
|
||||
float contactThreshold)
|
||||
{
|
||||
(void)shapeIdA,(void)shapeIdB;
|
||||
PfxBox boxA = shapeA.getBox();
|
||||
PfxBox boxB = shapeB.getBox();
|
||||
|
||||
PfxVector3 nml;
|
||||
PfxPoint3 pA,pB;
|
||||
|
||||
PfxFloat d = pfxContactBoxBox(nml,pA,pB,&boxA,worldTransformA,&boxB,worldTransformB);
|
||||
|
||||
if(d < contactThreshold) {
|
||||
contacts.addContactPoint(d,-nml,offsetTransformA*pA,offsetTransformB*pB,PfxSubData());
|
||||
}
|
||||
}
|
||||
|
||||
void detectCollisionBoxCapsule(
|
||||
PfxContactCache &contacts,
|
||||
const PfxShape &shapeA,const PfxTransform3 &offsetTransformA,const PfxTransform3 &worldTransformA,int shapeIdA,
|
||||
const PfxShape &shapeB,const PfxTransform3 &offsetTransformB,const PfxTransform3 &worldTransformB,int shapeIdB,
|
||||
float contactThreshold)
|
||||
{
|
||||
(void)shapeIdA,(void)shapeIdB;
|
||||
PfxBox boxA = shapeA.getBox();
|
||||
PfxCapsule capsuleB = shapeB.getCapsule();
|
||||
|
||||
PfxVector3 nml;
|
||||
PfxPoint3 pA,pB;
|
||||
|
||||
PfxFloat d = pfxContactBoxCapsule(nml,pA,pB,&boxA,worldTransformA,&capsuleB,worldTransformB);
|
||||
|
||||
if(d < contactThreshold) {
|
||||
contacts.addContactPoint(d,-nml,offsetTransformA*pA,offsetTransformB*pB,PfxSubData());
|
||||
}
|
||||
}
|
||||
|
||||
void detectCollisionBoxSphere(
|
||||
PfxContactCache &contacts,
|
||||
const PfxShape &shapeA,const PfxTransform3 &offsetTransformA,const PfxTransform3 &worldTransformA,int shapeIdA,
|
||||
const PfxShape &shapeB,const PfxTransform3 &offsetTransformB,const PfxTransform3 &worldTransformB,int shapeIdB,
|
||||
float contactThreshold)
|
||||
{
|
||||
(void)shapeIdA,(void)shapeIdB;
|
||||
PfxBox boxA = shapeA.getBox();
|
||||
PfxSphere sphereB = shapeB.getSphere();
|
||||
|
||||
PfxVector3 nml;
|
||||
PfxPoint3 pA,pB;
|
||||
|
||||
PfxFloat d = pfxContactBoxSphere(nml,pA,pB,&boxA,worldTransformA,&sphereB,worldTransformB);
|
||||
|
||||
if(d < contactThreshold) {
|
||||
contacts.addContactPoint(d,-nml,offsetTransformA*pA,offsetTransformB*pB,PfxSubData());
|
||||
}
|
||||
}
|
||||
|
||||
void detectCollisionCapsuleBox(
|
||||
PfxContactCache &contacts,
|
||||
const PfxShape &shapeA,const PfxTransform3 &offsetTransformA,const PfxTransform3 &worldTransformA,int shapeIdA,
|
||||
const PfxShape &shapeB,const PfxTransform3 &offsetTransformB,const PfxTransform3 &worldTransformB,int shapeIdB,
|
||||
float contactThreshold)
|
||||
{
|
||||
(void)shapeIdA,(void)shapeIdB;
|
||||
PfxCapsule capsuleA = shapeA.getCapsule();
|
||||
PfxBox boxB = shapeB.getBox();
|
||||
|
||||
PfxVector3 nml;
|
||||
PfxPoint3 pA,pB;
|
||||
|
||||
PfxFloat d = pfxContactBoxCapsule(nml,pB,pA,&boxB,worldTransformB,&capsuleA,worldTransformA);
|
||||
|
||||
if(d < contactThreshold) {
|
||||
contacts.addContactPoint(d,nml,offsetTransformA*pA,offsetTransformB*pB,PfxSubData());
|
||||
}
|
||||
}
|
||||
|
||||
void detectCollisionCapsuleCapsule(
|
||||
PfxContactCache &contacts,
|
||||
const PfxShape &shapeA,const PfxTransform3 &offsetTransformA,const PfxTransform3 &worldTransformA,int shapeIdA,
|
||||
const PfxShape &shapeB,const PfxTransform3 &offsetTransformB,const PfxTransform3 &worldTransformB,int shapeIdB,
|
||||
float contactThreshold)
|
||||
{
|
||||
(void)shapeIdA,(void)shapeIdB;
|
||||
PfxCapsule capsuleA = shapeA.getCapsule();
|
||||
PfxCapsule capsuleB = shapeB.getCapsule();
|
||||
|
||||
PfxVector3 nml;
|
||||
PfxPoint3 pA,pB;
|
||||
|
||||
PfxFloat d = pfxContactCapsuleCapsule(nml,pA,pB,&capsuleA,worldTransformA,&capsuleB,worldTransformB);
|
||||
|
||||
if(d < contactThreshold) {
|
||||
contacts.addContactPoint(d,-nml,offsetTransformA*pA,offsetTransformB*pB,PfxSubData());
|
||||
}
|
||||
}
|
||||
|
||||
void detectCollisionCapsuleSphere(
|
||||
PfxContactCache &contacts,
|
||||
const PfxShape &shapeA,const PfxTransform3 &offsetTransformA,const PfxTransform3 &worldTransformA,int shapeIdA,
|
||||
const PfxShape &shapeB,const PfxTransform3 &offsetTransformB,const PfxTransform3 &worldTransformB,int shapeIdB,
|
||||
float contactThreshold)
|
||||
{
|
||||
(void)shapeIdA,(void)shapeIdB;
|
||||
PfxCapsule capsuleA = shapeA.getCapsule();
|
||||
PfxSphere sphereB = shapeB.getSphere();
|
||||
|
||||
PfxVector3 nml;
|
||||
PfxPoint3 pA,pB;
|
||||
|
||||
PfxFloat d = pfxContactCapsuleSphere(nml,pA,pB,&capsuleA,worldTransformA,&sphereB,worldTransformB);
|
||||
|
||||
if(d < contactThreshold) {
|
||||
contacts.addContactPoint(d,-nml,offsetTransformA*pA,offsetTransformB*pB,PfxSubData());
|
||||
}
|
||||
}
|
||||
|
||||
void detectCollisionSphereBox(
|
||||
PfxContactCache &contacts,
|
||||
const PfxShape &shapeA,const PfxTransform3 &offsetTransformA,const PfxTransform3 &worldTransformA,int shapeIdA,
|
||||
const PfxShape &shapeB,const PfxTransform3 &offsetTransformB,const PfxTransform3 &worldTransformB,int shapeIdB,
|
||||
float contactThreshold)
|
||||
{
|
||||
(void)shapeIdA,(void)shapeIdB;
|
||||
PfxSphere sphereA = shapeA.getSphere();
|
||||
PfxBox boxB = shapeB.getBox();
|
||||
|
||||
PfxVector3 nml;
|
||||
PfxPoint3 pA,pB;
|
||||
|
||||
PfxFloat d = pfxContactBoxSphere(nml,pB,pA,&boxB,worldTransformB,&sphereA,worldTransformA);
|
||||
|
||||
if(d < contactThreshold) {
|
||||
contacts.addContactPoint(d,nml,offsetTransformA*pA,offsetTransformB*pB,PfxSubData());
|
||||
}
|
||||
}
|
||||
|
||||
void detectCollisionSphereCapsule(
|
||||
PfxContactCache &contacts,
|
||||
const PfxShape &shapeA,const PfxTransform3 &offsetTransformA,const PfxTransform3 &worldTransformA,int shapeIdA,
|
||||
const PfxShape &shapeB,const PfxTransform3 &offsetTransformB,const PfxTransform3 &worldTransformB,int shapeIdB,
|
||||
float contactThreshold)
|
||||
{
|
||||
(void)shapeIdA,(void)shapeIdB;
|
||||
PfxSphere sphereA = shapeA.getSphere();
|
||||
PfxCapsule capsuleB = shapeB.getCapsule();
|
||||
|
||||
PfxVector3 nml;
|
||||
PfxPoint3 pA,pB;
|
||||
|
||||
PfxFloat d = pfxContactCapsuleSphere(nml,pB,pA,&capsuleB,worldTransformB,&sphereA,worldTransformA);
|
||||
|
||||
if(d < contactThreshold) {
|
||||
contacts.addContactPoint(d,nml,offsetTransformA*pA,offsetTransformB*pB,PfxSubData());
|
||||
}
|
||||
}
|
||||
|
||||
void detectCollisionSphereSphere(
|
||||
PfxContactCache &contacts,
|
||||
const PfxShape &shapeA,const PfxTransform3 &offsetTransformA,const PfxTransform3 &worldTransformA,int shapeIdA,
|
||||
const PfxShape &shapeB,const PfxTransform3 &offsetTransformB,const PfxTransform3 &worldTransformB,int shapeIdB,
|
||||
float contactThreshold)
|
||||
{
|
||||
(void)shapeIdA,(void)shapeIdB;
|
||||
PfxSphere sphereA = shapeA.getSphere();
|
||||
PfxSphere sphereB = shapeB.getSphere();
|
||||
|
||||
PfxVector3 nml;
|
||||
PfxPoint3 pA,pB;
|
||||
|
||||
PfxFloat d = pfxContactSphereSphere(nml,pA,pB,&sphereA,worldTransformA,&sphereB,worldTransformB);
|
||||
|
||||
if(d < contactThreshold) {
|
||||
contacts.addContactPoint(d,-nml,offsetTransformA*pA,offsetTransformB*pB,PfxSubData());
|
||||
}
|
||||
}
|
||||
|
||||
void detectCollisionGjk(
|
||||
PfxContactCache &contacts,
|
||||
const PfxShape &shapeA,const PfxTransform3 &offsetTransformA,const PfxTransform3 &worldTransformA,int shapeIdA,
|
||||
const PfxShape &shapeB,const PfxTransform3 &offsetTransformB,const PfxTransform3 &worldTransformB,int shapeIdB,
|
||||
float contactThreshold)
|
||||
{
|
||||
(void)shapeIdA,(void)shapeIdB;
|
||||
PfxFloat d = SCE_PFX_FLT_MAX;
|
||||
PfxVector3 nml;
|
||||
PfxPoint3 pA,pB;
|
||||
PfxGjkSolver gjk;
|
||||
|
||||
if(shapeA.getType() == kPfxShapeCylinder) {
|
||||
PfxCylinder cylinderA = shapeA.getCylinder();
|
||||
|
||||
if(shapeB.getType() == kPfxShapeSphere) {
|
||||
PfxSphere sphereB = shapeB.getSphere();
|
||||
gjk.setup((void*)&cylinderA,(void*)&sphereB,pfxGetSupportVertexCylinder,pfxGetSupportVertexSphere);
|
||||
d = gjk.collide(nml,pA,pB,worldTransformA,worldTransformB,SCE_PFX_FLT_MAX);
|
||||
}
|
||||
else if(shapeB.getType() == kPfxShapeBox) {
|
||||
PfxBox boxB = shapeB.getBox();
|
||||
gjk.setup((void*)&cylinderA,(void*)&boxB,pfxGetSupportVertexCylinder,pfxGetSupportVertexBox);
|
||||
d = gjk.collide(nml,pA,pB,worldTransformA,worldTransformB,SCE_PFX_FLT_MAX);
|
||||
}
|
||||
else if(shapeB.getType() == kPfxShapeCapsule) {
|
||||
PfxCapsule capsuleB = shapeB.getCapsule();
|
||||
gjk.setup((void*)&cylinderA,(void*)&capsuleB,pfxGetSupportVertexCylinder,pfxGetSupportVertexCapsule);
|
||||
d = gjk.collide(nml,pA,pB,worldTransformA,worldTransformB,SCE_PFX_FLT_MAX);
|
||||
}
|
||||
else if(shapeB.getType() == kPfxShapeCylinder) {
|
||||
PfxCylinder cylinderB = shapeB.getCylinder();
|
||||
gjk.setup((void*)&cylinderA,(void*)&cylinderB,pfxGetSupportVertexCylinder,pfxGetSupportVertexCylinder);
|
||||
d = gjk.collide(nml,pA,pB,worldTransformA,worldTransformB,SCE_PFX_FLT_MAX);
|
||||
}
|
||||
else if(shapeB.getType() == kPfxShapeConvexMesh) {
|
||||
const PfxConvexMesh *convexB = shapeB.getConvexMesh();
|
||||
|
||||
gjk.setup((void*)&cylinderA,(void*)convexB,pfxGetSupportVertexCylinder,pfxGetSupportVertexConvex);
|
||||
d = gjk.collide(nml,pA,pB,worldTransformA,worldTransformB,SCE_PFX_FLT_MAX);
|
||||
|
||||
}
|
||||
}
|
||||
else if(shapeB.getType() == kPfxShapeCylinder) {
|
||||
PfxCylinder cylinderB = shapeB.getCylinder();
|
||||
|
||||
if(shapeA.getType() == kPfxShapeSphere) {
|
||||
PfxSphere sphereA = shapeA.getSphere();
|
||||
gjk.setup((void*)&sphereA,(void*)&cylinderB,pfxGetSupportVertexSphere,pfxGetSupportVertexCylinder);
|
||||
d = gjk.collide(nml,pA,pB,worldTransformA,worldTransformB,SCE_PFX_FLT_MAX);
|
||||
}
|
||||
else if(shapeA.getType() == kPfxShapeBox) {
|
||||
PfxBox boxA = shapeA.getBox();
|
||||
gjk.setup((void*)&boxA,(void*)&cylinderB,pfxGetSupportVertexBox,pfxGetSupportVertexCylinder);
|
||||
d = gjk.collide(nml,pA,pB,worldTransformA,worldTransformB,SCE_PFX_FLT_MAX);
|
||||
}
|
||||
else if(shapeA.getType() == kPfxShapeCapsule) {
|
||||
PfxCapsule capsuleA = shapeA.getCapsule();
|
||||
gjk.setup((void*)&capsuleA,(void*)&cylinderB,pfxGetSupportVertexCapsule,pfxGetSupportVertexCylinder);
|
||||
d = gjk.collide(nml,pA,pB,worldTransformA,worldTransformB,SCE_PFX_FLT_MAX);
|
||||
}
|
||||
else if(shapeA.getType() == kPfxShapeConvexMesh) {
|
||||
const PfxConvexMesh *convexA = shapeA.getConvexMesh();
|
||||
|
||||
gjk.setup((void*)convexA,(void*)&cylinderB,pfxGetSupportVertexConvex,pfxGetSupportVertexCylinder);
|
||||
d = gjk.collide(nml,pA,pB,worldTransformA,worldTransformB,SCE_PFX_FLT_MAX);
|
||||
|
||||
}
|
||||
}
|
||||
else if(shapeA.getType() == kPfxShapeConvexMesh) {
|
||||
const PfxConvexMesh *convexA = shapeA.getConvexMesh();
|
||||
|
||||
if(shapeB.getType() == kPfxShapeSphere) {
|
||||
PfxSphere sphereB = shapeB.getSphere();
|
||||
gjk.setup((void*)convexA,(void*)&sphereB,pfxGetSupportVertexConvex,pfxGetSupportVertexSphere);
|
||||
d = gjk.collide(nml,pA,pB,worldTransformA,worldTransformB,SCE_PFX_FLT_MAX);
|
||||
}
|
||||
else if(shapeB.getType() == kPfxShapeBox) {
|
||||
PfxBox boxB = shapeB.getBox();
|
||||
gjk.setup((void*)convexA,(void*)&boxB,pfxGetSupportVertexConvex,pfxGetSupportVertexBox);
|
||||
d = gjk.collide(nml,pA,pB,worldTransformA,worldTransformB,SCE_PFX_FLT_MAX);
|
||||
}
|
||||
else if(shapeB.getType() == kPfxShapeCapsule) {
|
||||
PfxCapsule capsuleB = shapeB.getCapsule();
|
||||
gjk.setup((void*)convexA,(void*)&capsuleB,pfxGetSupportVertexConvex,pfxGetSupportVertexCapsule);
|
||||
d = gjk.collide(nml,pA,pB,worldTransformA,worldTransformB,SCE_PFX_FLT_MAX);
|
||||
}
|
||||
else if(shapeB.getType() == kPfxShapeCylinder) {
|
||||
PfxCylinder cylinderB = shapeB.getCylinder();
|
||||
gjk.setup((void*)convexA,(void*)&cylinderB,pfxGetSupportVertexConvex,pfxGetSupportVertexCylinder);
|
||||
d = gjk.collide(nml,pA,pB,worldTransformA,worldTransformB,SCE_PFX_FLT_MAX);
|
||||
}
|
||||
else if(shapeB.getType() == kPfxShapeConvexMesh) {
|
||||
const PfxConvexMesh *convexB = shapeB.getConvexMesh();
|
||||
|
||||
gjk.setup((void*)convexA,(void*)convexB,pfxGetSupportVertexConvex,pfxGetSupportVertexConvex);
|
||||
d = gjk.collide(nml,pA,pB,worldTransformA,worldTransformB,SCE_PFX_FLT_MAX);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if(shapeB.getType() == kPfxShapeConvexMesh) {
|
||||
const PfxConvexMesh *convexB = shapeB.getConvexMesh();
|
||||
|
||||
if(shapeA.getType() == kPfxShapeSphere) {
|
||||
PfxSphere sphereA = shapeA.getSphere();
|
||||
gjk.setup((void*)&sphereA,(void*)convexB,pfxGetSupportVertexSphere,pfxGetSupportVertexConvex);
|
||||
d = gjk.collide(nml,pA,pB,worldTransformA,worldTransformB,SCE_PFX_FLT_MAX);
|
||||
}
|
||||
else if(shapeA.getType() == kPfxShapeBox) {
|
||||
PfxBox boxA = shapeA.getBox();
|
||||
gjk.setup((void*)&boxA,(void*)convexB,pfxGetSupportVertexBox,pfxGetSupportVertexConvex);
|
||||
d = gjk.collide(nml,pA,pB,worldTransformA,worldTransformB,SCE_PFX_FLT_MAX);
|
||||
}
|
||||
else if(shapeA.getType() == kPfxShapeCapsule) {
|
||||
PfxCapsule capsuleA = shapeA.getCapsule();
|
||||
gjk.setup((void*)&capsuleA,(void*)convexB,pfxGetSupportVertexCapsule,pfxGetSupportVertexConvex);
|
||||
d = gjk.collide(nml,pA,pB,worldTransformA,worldTransformB,SCE_PFX_FLT_MAX);
|
||||
}
|
||||
else if(shapeA.getType() == kPfxShapeConvexMesh) {
|
||||
const PfxConvexMesh *convexA = shapeA.getConvexMesh();
|
||||
|
||||
gjk.setup((void*)convexA,(void*)convexB,pfxGetSupportVertexConvex,pfxGetSupportVertexConvex);
|
||||
d = gjk.collide(nml,pA,pB,worldTransformA,worldTransformB,SCE_PFX_FLT_MAX);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(d < contactThreshold) {
|
||||
contacts.addContactPoint(d,nml,offsetTransformA*pA,offsetTransformB*pB,PfxSubData());
|
||||
}
|
||||
}
|
||||
|
||||
void detectCollisionLargeTriMesh(
|
||||
PfxContactCache &contacts,
|
||||
const PfxShape &shapeA,const PfxTransform3 &offsetTransformA,const PfxTransform3 &worldTransformA,int shapeIdA,
|
||||
const PfxShape &shapeB,const PfxTransform3 &offsetTransformB,const PfxTransform3 &worldTransformB,int shapeIdB,
|
||||
float contactThreshold)
|
||||
{
|
||||
(void)shapeIdA,(void)shapeIdB;
|
||||
if(shapeA.getType() == kPfxShapeLargeTriMesh) {
|
||||
const PfxLargeTriMesh *lmeshA = shapeA.getLargeTriMesh();
|
||||
|
||||
PfxContactCache localContacts;
|
||||
pfxContactLargeTriMesh(localContacts,
|
||||
lmeshA,worldTransformA,
|
||||
shapeB,worldTransformB,
|
||||
contactThreshold);
|
||||
|
||||
|
||||
for(int i=0;i<localContacts.getNumContacts();i++) {
|
||||
contacts.addContactPoint(
|
||||
localContacts.getDistance(i),
|
||||
localContacts.getNormal(i),
|
||||
offsetTransformA * localContacts.getLocalPointA(i),
|
||||
offsetTransformB * localContacts.getLocalPointB(i),
|
||||
localContacts.getSubData(i));
|
||||
}
|
||||
}
|
||||
else if(shapeB.getType() == kPfxShapeLargeTriMesh) {
|
||||
const PfxLargeTriMesh *lmeshB = shapeB.getLargeTriMesh();
|
||||
|
||||
PfxContactCache localContacts;
|
||||
pfxContactLargeTriMesh(localContacts,
|
||||
lmeshB,worldTransformB,
|
||||
shapeA,worldTransformA,
|
||||
contactThreshold);
|
||||
|
||||
|
||||
for(int i=0;i<localContacts.getNumContacts();i++) {
|
||||
contacts.addContactPoint(
|
||||
localContacts.getDistance(i),
|
||||
-localContacts.getNormal(i),
|
||||
offsetTransformA * localContacts.getLocalPointB(i),
|
||||
offsetTransformB * localContacts.getLocalPointA(i),
|
||||
localContacts.getSubData(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Collision Detection Function Table
|
||||
|
||||
pfx_detect_collision_func funcTbl_detectCollision[kPfxShapeCount][kPfxShapeCount] = {
|
||||
{detectCollisionSphereSphere ,detectCollisionSphereBox ,detectCollisionSphereCapsule ,detectCollisionGjk ,detectCollisionGjk ,detectCollisionLargeTriMesh, detectCollisionDummy,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy, detectCollisionDummy},
|
||||
{detectCollisionBoxSphere ,detectCollisionBoxBox ,detectCollisionBoxCapsule ,detectCollisionGjk ,detectCollisionGjk ,detectCollisionLargeTriMesh, detectCollisionDummy,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy, detectCollisionDummy},
|
||||
{detectCollisionCapsuleSphere ,detectCollisionCapsuleBox ,detectCollisionCapsuleCapsule ,detectCollisionGjk ,detectCollisionGjk ,detectCollisionLargeTriMesh, detectCollisionDummy,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy, detectCollisionDummy},
|
||||
{detectCollisionGjk ,detectCollisionGjk ,detectCollisionGjk ,detectCollisionGjk ,detectCollisionGjk ,detectCollisionLargeTriMesh, detectCollisionDummy,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy, detectCollisionDummy},
|
||||
{detectCollisionGjk ,detectCollisionGjk ,detectCollisionGjk ,detectCollisionGjk ,detectCollisionGjk ,detectCollisionLargeTriMesh, detectCollisionDummy,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy, detectCollisionDummy},
|
||||
{detectCollisionLargeTriMesh ,detectCollisionLargeTriMesh,detectCollisionLargeTriMesh ,detectCollisionLargeTriMesh,detectCollisionLargeTriMesh ,detectCollisionDummy, detectCollisionDummy,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy, detectCollisionDummy},
|
||||
{detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy, detectCollisionDummy,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy, detectCollisionDummy},
|
||||
{detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy, detectCollisionDummy,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy, detectCollisionDummy},
|
||||
{detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy, detectCollisionDummy,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy, detectCollisionDummy},
|
||||
{detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy, detectCollisionDummy,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy, detectCollisionDummy},
|
||||
{detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy, detectCollisionDummy,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy, detectCollisionDummy},
|
||||
{detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy, detectCollisionDummy,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy ,detectCollisionDummy, detectCollisionDummy},
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Collision Detection Function Table Interface
|
||||
|
||||
pfx_detect_collision_func pfxGetDetectCollisionFunc(PfxUInt8 shapeTypeA,PfxUInt8 shapeTypeB)
|
||||
{
|
||||
SCE_PFX_ASSERT(shapeTypeA<kPfxShapeCount);
|
||||
SCE_PFX_ASSERT(shapeTypeB<kPfxShapeCount);
|
||||
return funcTbl_detectCollision[shapeTypeA][shapeTypeB];
|
||||
}
|
||||
|
||||
int pfxSetDetectCollisionFunc(PfxUInt8 shapeTypeA,PfxUInt8 shapeTypeB,pfx_detect_collision_func func)
|
||||
{
|
||||
if(shapeTypeA >= kPfxShapeCount || shapeTypeB >= kPfxShapeCount) {
|
||||
return SCE_PFX_ERR_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
funcTbl_detectCollision[shapeTypeA][shapeTypeB] = func;
|
||||
|
||||
return SCE_PFX_OK;
|
||||
}
|
||||
|
||||
} //namespace PhysicsEffects
|
||||
} //namespace sce
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc.
|
||||
All rights reserved.
|
||||
|
||||
Physics Effects is open software; you can redistribute it and/or
|
||||
modify it under the terms of the BSD License.
|
||||
|
||||
Physics Effects is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the BSD License for more details.
|
||||
|
||||
A copy of the BSD License is distributed with
|
||||
Physics Effects under the filename: physics_effects_license.txt
|
||||
*/
|
||||
|
||||
#ifndef _SCE_PFX_DETECT_COLLISION_FUNC_H
|
||||
#define _SCE_PFX_DETECT_COLLISION_FUNC_H
|
||||
|
||||
#include "../../base_level/collision/pfx_contact_cache.h"
|
||||
|
||||
namespace sce {
|
||||
namespace PhysicsEffects {
|
||||
|
||||
typedef void (*pfx_detect_collision_func)(
|
||||
PfxContactCache &contacts,
|
||||
const PfxShape & shapeA,const PfxTransform3 &offsetTransformA,const PfxTransform3 &worldTransformA,int shapeIdA,
|
||||
const PfxShape & shapeB,const PfxTransform3 &offsetTransformB,const PfxTransform3 &worldTransformB,int shapeIdB,
|
||||
float contactThreshold);
|
||||
|
||||
pfx_detect_collision_func pfxGetDetectCollisionFunc(PfxUInt8 shapeTypeA,PfxUInt8 shapeTypeB);
|
||||
|
||||
int pfxSetDetectCollisionFunc(PfxUInt8 shapeTypeA,PfxUInt8 shapeTypeB,pfx_detect_collision_func func);
|
||||
|
||||
} //namespace PhysicsEffects
|
||||
} //namespace sce
|
||||
#endif // _SCE_PFX_DETECT_COLLISION_FUNC_H
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc.
|
||||
All rights reserved.
|
||||
|
||||
Physics Effects is open software; you can redistribute it and/or
|
||||
modify it under the terms of the BSD License.
|
||||
|
||||
Physics Effects is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the BSD License for more details.
|
||||
|
||||
A copy of the BSD License is distributed with
|
||||
Physics Effects under the filename: physics_effects_license.txt
|
||||
*/
|
||||
|
||||
#include "../../../include/physics_effects/base_level/collision/pfx_shape.h"
|
||||
#include "../../base_level/collision/pfx_intersect_ray_box.h"
|
||||
#include "../../base_level/collision/pfx_intersect_ray_sphere.h"
|
||||
#include "../../base_level/collision/pfx_intersect_ray_capsule.h"
|
||||
#include "../../base_level/collision/pfx_intersect_ray_cylinder.h"
|
||||
#include "../../base_level/collision/pfx_intersect_ray_convex.h"
|
||||
#include "../../base_level/collision/pfx_intersect_ray_large_tri_mesh.h"
|
||||
#include "pfx_intersect_ray_func.h"
|
||||
|
||||
|
||||
namespace sce {
|
||||
namespace PhysicsEffects {
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Ray Intersection Function Table
|
||||
|
||||
PfxBool intersectRayFuncDummy(
|
||||
const PfxRayInput &ray,PfxRayOutput &out,
|
||||
const PfxShape &shape,const PfxTransform3 &transform)
|
||||
{
|
||||
(void)ray,(void)out,(void)shape,(void)transform;
|
||||
return false;
|
||||
}
|
||||
|
||||
PfxBool intersectRayFuncBox(
|
||||
const PfxRayInput &ray,PfxRayOutput &out,
|
||||
const PfxShape &shape,const PfxTransform3 &transform)
|
||||
{
|
||||
return pfxIntersectRayBox(ray,out,shape.getBox(),transform);
|
||||
}
|
||||
|
||||
PfxBool intersectRayFuncSphere(
|
||||
const PfxRayInput &ray,PfxRayOutput &out,
|
||||
const PfxShape &shape,const PfxTransform3 &transform)
|
||||
{
|
||||
return pfxIntersectRaySphere(ray,out,shape.getSphere(),transform);
|
||||
}
|
||||
|
||||
PfxBool intersectRayFuncCapsule(
|
||||
const PfxRayInput &ray,PfxRayOutput &out,
|
||||
const PfxShape &shape,const PfxTransform3 &transform)
|
||||
{
|
||||
return pfxIntersectRayCapsule(ray,out,shape.getCapsule(),transform);
|
||||
}
|
||||
|
||||
PfxBool intersectRayFuncCylinder(
|
||||
const PfxRayInput &ray,PfxRayOutput &out,
|
||||
const PfxShape &shape,const PfxTransform3 &transform)
|
||||
{
|
||||
return pfxIntersectRayCylinder(ray,out,shape.getCylinder(),transform);
|
||||
}
|
||||
|
||||
PfxBool intersectRayFuncConvex(
|
||||
const PfxRayInput &ray,PfxRayOutput &out,
|
||||
const PfxShape &shape,const PfxTransform3 &transform)
|
||||
{
|
||||
const PfxConvexMesh *convex = shape.getConvexMesh();
|
||||
|
||||
PfxBool ret = pfxIntersectRayConvex(ray,out,(const void*)convex,transform);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
PfxBool intersectRayFuncLargeTriMesh(
|
||||
const PfxRayInput &ray,PfxRayOutput &out,
|
||||
const PfxShape &shape,const PfxTransform3 &transform)
|
||||
{
|
||||
const PfxLargeTriMesh *lmesh = shape.getLargeTriMesh();
|
||||
|
||||
PfxBool ret = pfxIntersectRayLargeTriMesh(ray,out,(const void*)lmesh,transform);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
PfxIntersectRayFunc funcTbl_intersectRay[kPfxShapeCount] = {
|
||||
intersectRayFuncSphere,
|
||||
intersectRayFuncBox,
|
||||
intersectRayFuncCapsule,
|
||||
intersectRayFuncCylinder,
|
||||
intersectRayFuncConvex,
|
||||
intersectRayFuncLargeTriMesh,
|
||||
intersectRayFuncDummy,
|
||||
intersectRayFuncDummy,
|
||||
intersectRayFuncDummy,
|
||||
intersectRayFuncDummy,
|
||||
intersectRayFuncDummy,
|
||||
intersectRayFuncDummy,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Ray Intersection Function Table Interface
|
||||
|
||||
PfxIntersectRayFunc pfxGetIntersectRayFunc(PfxUInt8 shapeType)
|
||||
{
|
||||
return funcTbl_intersectRay[shapeType];
|
||||
}
|
||||
|
||||
PfxInt32 pfxSetIntersectRayFunc(PfxUInt8 shapeType,PfxIntersectRayFunc func)
|
||||
{
|
||||
if(shapeType >= kPfxShapeCount) {
|
||||
return SCE_PFX_ERR_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
funcTbl_intersectRay[shapeType] = func;
|
||||
|
||||
return SCE_PFX_OK;
|
||||
}
|
||||
|
||||
} //namespace PhysicsEffects
|
||||
} //namespace sce
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc.
|
||||
All rights reserved.
|
||||
|
||||
Physics Effects is open software; you can redistribute it and/or
|
||||
modify it under the terms of the BSD License.
|
||||
|
||||
Physics Effects is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the BSD License for more details.
|
||||
|
||||
A copy of the BSD License is distributed with
|
||||
Physics Effects under the filename: physics_effects_license.txt
|
||||
*/
|
||||
|
||||
#ifndef _SCE_PFX_INTERSECT_RAY_FUNC_H
|
||||
#define _SCE_PFX_INTERSECT_RAY_FUNC_H
|
||||
|
||||
#include "../../../include/physics_effects/base_level/collision/pfx_ray.h"
|
||||
|
||||
namespace sce {
|
||||
namespace PhysicsEffects {
|
||||
|
||||
typedef PfxBool (*PfxIntersectRayFunc)(
|
||||
const PfxRayInput &ray,PfxRayOutput &out,
|
||||
const PfxShape &shape,const PfxTransform3 &transform);
|
||||
|
||||
PfxIntersectRayFunc pfxGetIntersectRayFunc(PfxUInt8 shapeType);
|
||||
|
||||
PfxInt32 pfxSetIntersectRayFunc(PfxUInt8 shapeType,PfxIntersectRayFunc func);
|
||||
|
||||
} //namespace PhysicsEffects
|
||||
} //namespace sce
|
||||
|
||||
#endif /* _SCE_PFX_INTERSECT_RAY_FUNC_H */
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc.
|
||||
All rights reserved.
|
||||
|
||||
Physics Effects is open software; you can redistribute it and/or
|
||||
modify it under the terms of the BSD License.
|
||||
|
||||
Physics Effects is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the BSD License for more details.
|
||||
|
||||
A copy of the BSD License is distributed with
|
||||
Physics Effects under the filename: physics_effects_license.txt
|
||||
*/
|
||||
|
||||
#include "../../../include/physics_effects/base_level/rigidbody/pfx_rigid_state.h"
|
||||
#include "../../../include/physics_effects/low_level/collision/pfx_island_generation.h"
|
||||
|
||||
namespace sce {
|
||||
namespace PhysicsEffects {
|
||||
|
||||
struct PfxIslandNode {
|
||||
PfxUInt32 rootId;
|
||||
PfxUInt32 rank;
|
||||
PfxUInt32 islandId;
|
||||
PfxUInt32 isRoot;
|
||||
};
|
||||
|
||||
struct PfxIslandUnit
|
||||
{
|
||||
PfxUInt32 id;
|
||||
PfxIslandUnit *next;
|
||||
};
|
||||
|
||||
struct PfxIsland
|
||||
{
|
||||
PfxUInt32 numNodes;
|
||||
PfxUInt32 numIslands;
|
||||
PfxIslandNode *nodes;
|
||||
PfxIslandUnit *islandsUnits;
|
||||
PfxIslandUnit **islandsHeads;
|
||||
};
|
||||
|
||||
PfxUInt32 pfxIslandNodeFind(PfxUInt32 i,PfxIsland *island)
|
||||
{
|
||||
if( i != island->nodes[i].rootId ) {
|
||||
island->nodes[i].rootId = pfxIslandNodeFind(island->nodes[i].rootId,island);
|
||||
}
|
||||
return island->nodes[i].rootId;
|
||||
}
|
||||
|
||||
void pfxIslandNodeLink(PfxUInt32 iA,PfxUInt32 iB,PfxIsland *island)
|
||||
{
|
||||
if(island->nodes[iA].rank > island->nodes[iB].rank) {
|
||||
island->nodes[iB].rootId = iA;
|
||||
}
|
||||
else if(island->nodes[iA].rank == island->nodes[iB].rank) {
|
||||
island->nodes[iA].rootId = iB;
|
||||
island->nodes[iB].rank++;
|
||||
}
|
||||
else {
|
||||
island->nodes[iA].rootId = iB;
|
||||
}
|
||||
}
|
||||
|
||||
void pfxIslandNodeUnion(PfxUInt32 iA,PfxUInt32 iB,PfxIsland *island)
|
||||
{
|
||||
SCE_PFX_ALWAYS_ASSERT(iA<island->numNodes);
|
||||
SCE_PFX_ALWAYS_ASSERT(iB<island->numNodes);
|
||||
|
||||
pfxIslandNodeLink(pfxIslandNodeFind(iA,island),pfxIslandNodeFind(iB,island),island);
|
||||
}
|
||||
|
||||
PfxUInt32 pfxGetIslandBytesOfGenerateIsland(PfxUInt32 numObjects)
|
||||
{
|
||||
return 16 +
|
||||
SCE_PFX_ALLOC_BYTES_ALIGN16(sizeof(PfxIsland)) +
|
||||
SCE_PFX_ALLOC_BYTES_ALIGN16(sizeof(PfxIslandNode)*numObjects) +
|
||||
SCE_PFX_ALLOC_BYTES_ALIGN16(sizeof(PfxIslandUnit*)*numObjects) +
|
||||
SCE_PFX_ALLOC_BYTES_ALIGN16(sizeof(PfxIslandUnit)*numObjects);
|
||||
}
|
||||
|
||||
SCE_PFX_FORCE_INLINE int pfxCheckParamOfGenerateIsland(const PfxGenerateIslandParam ¶m)
|
||||
{
|
||||
if(!param.islandBuff || !param.pairs) return SCE_PFX_ERR_INVALID_VALUE;
|
||||
if(!SCE_PFX_PTR_IS_ALIGNED16(param.pairs)) return SCE_PFX_ERR_INVALID_ALIGN;
|
||||
if(SCE_PFX_AVAILABLE_BYTES_ALIGN16(param.islandBuff,param.islandBytes) < pfxGetIslandBytesOfGenerateIsland(param.numObjects) ) return SCE_PFX_ERR_OUT_OF_BUFFER;
|
||||
return SCE_PFX_OK;
|
||||
}
|
||||
|
||||
PfxInt32 pfxGenerateIsland(PfxGenerateIslandParam ¶m,PfxGenerateIslandResult &result)
|
||||
{
|
||||
int ret = pfxCheckParamOfGenerateIsland(param);
|
||||
if(ret != SCE_PFX_OK) return ret;
|
||||
|
||||
PfxConstraintPair *pairs = param.pairs;
|
||||
PfxUInt32 numPairs = param.numPairs;
|
||||
PfxUInt32 numUnits = param.numObjects;
|
||||
|
||||
memset(param.islandBuff,0,param.islandBytes);
|
||||
|
||||
PfxHeapManager pool((unsigned char*)param.islandBuff,param.islandBytes);
|
||||
|
||||
PfxIsland *island = (PfxIsland*)pool.allocate(sizeof(PfxIsland));
|
||||
island->numIslands = 0;
|
||||
island->numNodes = numUnits;
|
||||
island->nodes = (PfxIslandNode*)pool.allocate(sizeof(PfxIslandNode)*numUnits);
|
||||
island->islandsHeads = (PfxIslandUnit**)pool.allocate(sizeof(PfxIslandUnit*)*numUnits);
|
||||
island->islandsUnits = (PfxIslandUnit*)pool.allocate(sizeof(PfxIslandUnit)*numUnits);
|
||||
|
||||
result.island = island;
|
||||
|
||||
// 初期化
|
||||
for(PfxUInt32 i=0;i<island->numNodes;i++) {
|
||||
island->nodes[i].rootId = i;
|
||||
island->nodes[i].rank = 0;
|
||||
}
|
||||
|
||||
return pfxAppendPairs(island,pairs,numPairs);
|
||||
}
|
||||
|
||||
PfxUInt32 pfxGetNumIslands(const PfxIsland *islands)
|
||||
{
|
||||
SCE_PFX_ALWAYS_ASSERT(islands);
|
||||
return islands->numIslands;
|
||||
}
|
||||
|
||||
PfxIslandUnit *pfxGetFirstUnitInIsland(const PfxIsland *islands,PfxUInt32 islandId)
|
||||
{
|
||||
SCE_PFX_ALWAYS_ASSERT(islands);
|
||||
SCE_PFX_ALWAYS_ASSERT(islandId < islands->numIslands);
|
||||
return islands->islandsHeads[islandId];
|
||||
}
|
||||
|
||||
PfxIslandUnit *pfxGetNextUnitInIsland(const PfxIslandUnit *islandUnit)
|
||||
{
|
||||
SCE_PFX_ALWAYS_ASSERT(islandUnit);
|
||||
return islandUnit->next;
|
||||
}
|
||||
|
||||
PfxUInt32 pfxGetUnitId(const PfxIslandUnit *islandUnit)
|
||||
{
|
||||
SCE_PFX_ALWAYS_ASSERT(islandUnit);
|
||||
return islandUnit->id;
|
||||
}
|
||||
|
||||
PfxUInt32 pfxGetIslandId(const PfxIsland *islands,PfxUInt32 unitId)
|
||||
{
|
||||
SCE_PFX_ALWAYS_ASSERT(islands&&unitId<islands->numNodes);
|
||||
return islands->nodes[unitId].islandId;
|
||||
}
|
||||
|
||||
PfxInt32 pfxAppendPairs(PfxIsland *island,PfxConstraintPair *pairs,PfxUInt32 numPairs)
|
||||
{
|
||||
if(numPairs == 0) {
|
||||
return SCE_PFX_OK;
|
||||
}
|
||||
|
||||
if(!island || !pairs) return SCE_PFX_ERR_INVALID_VALUE;
|
||||
if(!SCE_PFX_PTR_IS_ALIGNED16(island) || !SCE_PFX_PTR_IS_ALIGNED16(pairs)) return SCE_PFX_ERR_INVALID_ALIGN;
|
||||
|
||||
// 統合
|
||||
for(PfxUInt32 i=0;i<numPairs;i++) {
|
||||
PfxConstraintPair &pair = pairs[i];
|
||||
if(pfxGetActive(pair)) {
|
||||
PfxUInt32 iA = pfxGetObjectIdA(pair);
|
||||
PfxUInt32 iB = pfxGetObjectIdB(pair);
|
||||
|
||||
SCE_PFX_ALWAYS_ASSERT(iA<island->numNodes);
|
||||
SCE_PFX_ALWAYS_ASSERT(iB<island->numNodes);
|
||||
|
||||
if( (SCE_PFX_MOTION_MASK_DYNAMIC(pfxGetMotionMaskA(pair)&SCE_PFX_MOTION_MASK_TYPE)) &&
|
||||
(SCE_PFX_MOTION_MASK_DYNAMIC(pfxGetMotionMaskB(pair)&SCE_PFX_MOTION_MASK_TYPE)) ) {
|
||||
pfxIslandNodeUnion(iA,iB,island);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// アイランド生成のための初期化
|
||||
for(PfxUInt32 i=0;i<island->numNodes;i++) {
|
||||
island->nodes[i].islandId = 0;
|
||||
island->nodes[i].isRoot = 0;
|
||||
island->islandsHeads[i] = NULL;
|
||||
}
|
||||
|
||||
// 親へ直結
|
||||
PfxUInt32 id = 0;
|
||||
for(PfxUInt32 i=0;i<island->numNodes;i++) {
|
||||
PfxUInt32 rootId = pfxIslandNodeFind(i,island);
|
||||
if( island->nodes[rootId].isRoot == 0 ) {
|
||||
island->nodes[rootId].islandId = id++;
|
||||
island->nodes[rootId].isRoot = 1;
|
||||
}
|
||||
island->nodes[i].islandId = island->nodes[rootId].islandId;
|
||||
}
|
||||
|
||||
// アイランド作成
|
||||
PfxUInt32 n = 0;
|
||||
for(PfxUInt32 i=0;i<island->numNodes;i++) {
|
||||
PfxUInt32 islandId = island->nodes[i].islandId;
|
||||
PfxIslandUnit *newUnit = &island->islandsUnits[n++];
|
||||
newUnit->id = i;
|
||||
|
||||
if(!island->islandsHeads[islandId]) {
|
||||
island->islandsHeads[islandId] = newUnit;
|
||||
continue;
|
||||
}
|
||||
|
||||
PfxIslandUnit *unit=island->islandsHeads[islandId];
|
||||
island->islandsHeads[islandId] = newUnit;
|
||||
newUnit->next = unit;
|
||||
}
|
||||
|
||||
island->numIslands = id;
|
||||
|
||||
return SCE_PFX_OK;
|
||||
}
|
||||
|
||||
void pfxResetIsland(PfxIsland *island)
|
||||
{
|
||||
SCE_PFX_ALWAYS_ASSERT(island);
|
||||
island->numIslands = 0;
|
||||
for(PfxUInt32 i=0;i<island->numNodes;i++) {
|
||||
island->nodes[i].rootId = i;
|
||||
island->nodes[i].rank = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace PhysicsEffects
|
||||
} //namespace sce
|
||||
228
Extras/PhysicsEffects/src/low_level/collision/pfx_ray_cast.cpp
Normal file
228
Extras/PhysicsEffects/src/low_level/collision/pfx_ray_cast.cpp
Normal file
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc.
|
||||
All rights reserved.
|
||||
|
||||
Physics Effects is open software; you can redistribute it and/or
|
||||
modify it under the terms of the BSD License.
|
||||
|
||||
Physics Effects is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the BSD License for more details.
|
||||
|
||||
A copy of the BSD License is distributed with
|
||||
Physics Effects under the filename: physics_effects_license.txt
|
||||
*/
|
||||
|
||||
#include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h"
|
||||
#include "../../../include/physics_effects/low_level/collision/pfx_ray_cast.h"
|
||||
#include "../../../include/physics_effects/base_level/collision/pfx_shape_iterator.h"
|
||||
#include "pfx_intersect_ray_func.h"
|
||||
#include "../../base_level/collision/pfx_intersect_common.h"
|
||||
|
||||
|
||||
namespace sce {
|
||||
namespace PhysicsEffects {
|
||||
|
||||
|
||||
void pfxRayTraverseForward(
|
||||
const PfxRayInput &ray,PfxRayOutput &out,const PfxAabb16 &rayAABB,
|
||||
PfxBroadphaseProxy *proxies,int numProxies,
|
||||
PfxRigidState *offsetRigidStates,
|
||||
PfxCollidable *offsetCollidables,
|
||||
int axis,const PfxVector3 ¢er,const PfxVector3 &half)
|
||||
{
|
||||
#ifdef SCE_PFX_USE_GEOMETRY
|
||||
PfxGeomSegment segment((PfxPoint3)ray.m_startPosition,ray.m_direction);
|
||||
#endif
|
||||
|
||||
for(int i=0;i<numProxies;i++) {
|
||||
PfxBroadphaseProxy &proxy = proxies[i];
|
||||
|
||||
// 終了条件のチェック
|
||||
if(pfxGetXYZMax(rayAABB,axis) < pfxGetXYZMin(proxy,axis)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PfxVector3 boundOnRay = ray.m_startPosition + out.m_variable * ray.m_direction;
|
||||
PfxVector3 AABBmin = pfxConvertCoordLocalToWorld(PfxVecInt3((PfxInt32)pfxGetXMin(proxy),(PfxInt32)pfxGetYMin(proxy),(PfxInt32)pfxGetZMin(proxy)),center,half);
|
||||
PfxVector3 AABBmax = pfxConvertCoordLocalToWorld(PfxVecInt3((PfxInt32)pfxGetXMax(proxy),(PfxInt32)pfxGetYMax(proxy),(PfxInt32)pfxGetZMax(proxy)),center,half);
|
||||
|
||||
if(boundOnRay[axis] < AABBmin[axis]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// スキップ
|
||||
if(pfxGetXYZMax(proxy,axis) < pfxGetXYZMin(rayAABB,axis)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PfxUInt16 rigidbodyId = pfxGetObjectId(proxy);
|
||||
PfxUInt32 contactFilterSelf = pfxGetSelf(proxy);
|
||||
PfxUInt32 contactFilterTarget = pfxGetTarget(proxy);
|
||||
|
||||
#ifdef SCE_PFX_USE_GEOMETRY
|
||||
PfxFloatInVec t_(1.0f);
|
||||
PfxGeomAabb aabb((PfxPoint3)AABBmin,(PfxPoint3)AABBmax);
|
||||
if( (ray.m_contactFilterSelf&contactFilterTarget) && (ray.m_contactFilterTarget&contactFilterSelf) && pfxTestAabb(rayAABB,proxy) &&
|
||||
intersectionPoint(segment,aabb,&t_) && t_ < out.m_variable ) {
|
||||
#else
|
||||
float t_=1.0f;
|
||||
if( (ray.m_contactFilterSelf&contactFilterTarget) && (ray.m_contactFilterTarget&contactFilterSelf) && pfxTestAabb(rayAABB,proxy) &&
|
||||
pfxIntersectRayAABBFast(ray.m_startPosition,ray.m_direction,(AABBmax+AABBmin)*0.5f,(AABBmax-AABBmin)*0.5f,t_) && t_ < out.m_variable ) {
|
||||
#endif
|
||||
|
||||
PfxRigidState &state = offsetRigidStates[rigidbodyId];
|
||||
PfxCollidable &coll = offsetCollidables[rigidbodyId];
|
||||
PfxTransform3 transform(state.getOrientation(), state.getPosition());
|
||||
|
||||
PfxRayOutput tout = out;
|
||||
|
||||
PfxShapeIterator itrShape(coll);
|
||||
for(PfxUInt32 j=0;j<coll.getNumShapes();j++,++itrShape) {
|
||||
const PfxShape &shape = *itrShape;
|
||||
PfxTransform3 shapeTr = transform * shape.getOffsetTransform();
|
||||
|
||||
if(pfxGetIntersectRayFunc(shape.getType())(ray,tout,shape,shapeTr) && tout.m_variable < out.m_variable) {
|
||||
out = tout;
|
||||
out.m_shapeId = j;
|
||||
out.m_objectId = rigidbodyId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pfxRayTraverseBackward(
|
||||
const PfxRayInput &ray,PfxRayOutput &out,const PfxAabb16 &rayAABB,
|
||||
PfxBroadphaseProxy *proxies,int numProxies,
|
||||
PfxRigidState *offsetRigidStates,
|
||||
PfxCollidable *offsetCollidables,
|
||||
int axis,const PfxVector3 ¢er,const PfxVector3 &half)
|
||||
{
|
||||
#ifdef SCE_PFX_USE_GEOMETRY
|
||||
PfxGeomSegment segment((PfxPoint3)ray.m_startPosition,ray.m_direction);
|
||||
#endif
|
||||
|
||||
for(int i=numProxies-1;i>=0;i--) {
|
||||
PfxBroadphaseProxy &proxy = proxies[i];
|
||||
|
||||
// 終了条件のチェック
|
||||
if(pfxGetXYZMax(proxy,axis) < pfxGetXYZMin(rayAABB,axis)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PfxVector3 boundOnRay = ray.m_startPosition + out.m_variable * ray.m_direction;
|
||||
PfxVector3 AABBmin = pfxConvertCoordLocalToWorld(PfxVecInt3((PfxInt32)pfxGetXMin(proxy),(PfxInt32)pfxGetYMin(proxy),(PfxInt32)pfxGetZMin(proxy)),center,half);
|
||||
PfxVector3 AABBmax = pfxConvertCoordLocalToWorld(PfxVecInt3((PfxInt32)pfxGetXMax(proxy),(PfxInt32)pfxGetYMax(proxy),(PfxInt32)pfxGetZMax(proxy)),center,half);
|
||||
|
||||
if(AABBmax[axis] < boundOnRay[axis]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// スキップ
|
||||
if(pfxGetXYZMax(rayAABB,axis) < pfxGetXYZMin(proxy,axis)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PfxUInt16 rigidbodyId = pfxGetObjectId(proxy);
|
||||
PfxUInt32 contactFilterSelf = pfxGetSelf(proxy);
|
||||
PfxUInt32 contactFilterTarget = pfxGetTarget(proxy);
|
||||
|
||||
#ifdef SCE_PFX_USE_GEOMETRY
|
||||
PfxFloatInVec t_(1.0f);
|
||||
PfxGeomAabb aabb((PfxPoint3)AABBmin,(PfxPoint3)AABBmax);
|
||||
if( (ray.m_contactFilterSelf&contactFilterTarget) && (ray.m_contactFilterTarget&contactFilterSelf) && pfxTestAabb(rayAABB,proxy) &&
|
||||
intersectionPoint(segment,aabb,&t_) && t_ < out.m_variable ) {
|
||||
#else
|
||||
float t_=1.0f;
|
||||
if( (ray.m_contactFilterSelf&contactFilterTarget) && (ray.m_contactFilterTarget&contactFilterSelf) && pfxTestAabb(rayAABB,proxy) &&
|
||||
pfxIntersectRayAABBFast(ray.m_startPosition,ray.m_direction,(AABBmax+AABBmin)*0.5f,(AABBmax-AABBmin)*0.5f,t_) && t_ < out.m_variable ) {
|
||||
#endif
|
||||
|
||||
PfxRigidState &state = offsetRigidStates[rigidbodyId];
|
||||
PfxCollidable &coll = offsetCollidables[rigidbodyId];
|
||||
PfxTransform3 transform(state.getOrientation(), state.getPosition());
|
||||
|
||||
PfxRayOutput tout = out;
|
||||
|
||||
PfxShapeIterator itrShape(coll);
|
||||
for(PfxUInt32 j=0;j<coll.getNumShapes();j++,++itrShape) {
|
||||
const PfxShape &shape = *itrShape;
|
||||
PfxTransform3 shapeTr = transform * shape.getOffsetTransform();
|
||||
|
||||
if(pfxGetIntersectRayFunc(shape.getType())(ray,tout,shape,shapeTr) && tout.m_variable < out.m_variable) {
|
||||
out = tout;
|
||||
out.m_shapeId = j;
|
||||
out.m_objectId = rigidbodyId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void pfxCastSingleRay(const PfxRayInput &ray,PfxRayOutput &out,const PfxRayCastParam ¶m)
|
||||
{
|
||||
SCE_PFX_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesX));
|
||||
SCE_PFX_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesY));
|
||||
SCE_PFX_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesZ));
|
||||
SCE_PFX_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesXb));
|
||||
SCE_PFX_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesYb));
|
||||
SCE_PFX_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.proxiesZb));
|
||||
SCE_PFX_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.offsetRigidStates));
|
||||
SCE_PFX_ASSERT(SCE_PFX_PTR_IS_ALIGNED16(param.offsetCollidables));
|
||||
|
||||
PfxBroadphaseProxy *proxies[] = {
|
||||
param.proxiesX,
|
||||
param.proxiesY,
|
||||
param.proxiesZ,
|
||||
param.proxiesXb,
|
||||
param.proxiesYb,
|
||||
param.proxiesZb,
|
||||
};
|
||||
|
||||
out.m_variable = 1.0f;
|
||||
out.m_contactFlag = false;
|
||||
|
||||
// 探索軸
|
||||
PfxVector3 chkAxisVec = absPerElem(ray.m_direction);
|
||||
int axis = 0;
|
||||
if(chkAxisVec[1] < chkAxisVec[0]) axis = 1;
|
||||
if(chkAxisVec[2] < chkAxisVec[axis]) axis = 2;
|
||||
|
||||
// レイのAABB作成
|
||||
PfxVector3 p1 = ray.m_startPosition;
|
||||
PfxVector3 p2 = ray.m_startPosition + ray.m_direction;
|
||||
PfxVecInt3 rayMin,rayMax;
|
||||
pfxConvertCoordWorldToLocal(param.rangeCenter,param.rangeExtent,minPerElem(p1,p2),maxPerElem(p1,p2),rayMin,rayMax);
|
||||
|
||||
PfxAabb16 rayAABB;
|
||||
pfxSetXMin(rayAABB,rayMin.getX());
|
||||
pfxSetXMax(rayAABB,rayMax.getX());
|
||||
pfxSetYMin(rayAABB,rayMin.getY());
|
||||
pfxSetYMax(rayAABB,rayMax.getY());
|
||||
pfxSetZMin(rayAABB,rayMin.getZ());
|
||||
pfxSetZMax(rayAABB,rayMax.getZ());
|
||||
|
||||
// AABB探索開始
|
||||
int sign = ray.m_direction[axis] < 0.0f ? -1 : 1; // 探索方向
|
||||
|
||||
if(sign > 0) {
|
||||
pfxRayTraverseForward(
|
||||
ray,out,rayAABB,
|
||||
proxies[axis],param.numProxies,
|
||||
param.offsetRigidStates,param.offsetCollidables,
|
||||
axis,param.rangeCenter,param.rangeExtent);
|
||||
}
|
||||
else {
|
||||
pfxRayTraverseBackward(
|
||||
ray,out,rayAABB,
|
||||
proxies[axis+3],param.numProxies,
|
||||
param.offsetRigidStates,param.offsetCollidables,
|
||||
axis,param.rangeCenter,param.rangeExtent);
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace PhysicsEffects
|
||||
} //namespace sce
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
Applied Research Associates Inc. (c)2011
|
||||
|
||||
Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc.
|
||||
All rights reserved.
|
||||
|
||||
Physics Effects is open software; you can redistribute it and/or
|
||||
modify it under the terms of the BSD License.
|
||||
|
||||
Physics Effects is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the BSD License for more details.
|
||||
|
||||
A copy of the BSD License is distributed with
|
||||
Physics Effects under the filename: physics_effects_license.txt
|
||||
*/
|
||||
|
||||
#include "../../../include/physics_effects/base_level/base/pfx_perf_counter.h"
|
||||
#include "../../../include/physics_effects/base_level/sort/pfx_sort.h"
|
||||
#include "../../../include/physics_effects/low_level/collision/pfx_refresh_contacts.h"
|
||||
|
||||
namespace sce {
|
||||
namespace PhysicsEffects {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// This function is implemented in pfx_refresh_contacts_single.cpp
|
||||
extern int pfxCheckParamOfRefreshContacts(PfxRefreshContactsParam ¶m);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// MULTIPLE THREADS
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// pfxRefreshContactsTaskEntry
|
||||
//
|
||||
/// The thread PfxTaskEntry function used to perform refresh contacts in
|
||||
/// parallel
|
||||
//----------------------------------------------------------------------------
|
||||
void pfxRefreshContactsTaskEntry(PfxTaskArg *arg)
|
||||
{
|
||||
PfxRefreshContactsParam ¶m = *((PfxRefreshContactsParam*)arg->io);
|
||||
|
||||
PfxUInt32 iFirstContactPair = arg->data[0];
|
||||
PfxUInt32 iEndContactPair = arg->data[1];
|
||||
|
||||
PfxConstraintPair *contactPairs = param.contactPairs;
|
||||
PfxContactManifold *offsetContactManifolds = param.offsetContactManifolds;
|
||||
PfxRigidState *offsetRigidStates = param.offsetRigidStates;
|
||||
PfxUInt32 numRigidBodies = param.numRigidBodies;
|
||||
|
||||
for(PfxUInt32 i = iFirstContactPair; i < iEndContactPair; i++)
|
||||
{
|
||||
PfxBroadphasePair &pair = contactPairs[i];
|
||||
|
||||
PfxUInt32 iContact = pfxGetContactId(pair);
|
||||
PfxUInt32 iA = pfxGetObjectIdA(pair);
|
||||
PfxUInt32 iB = pfxGetObjectIdB(pair);
|
||||
|
||||
PfxContactManifold &contact = offsetContactManifolds[iContact];
|
||||
|
||||
SCE_PFX_ALWAYS_ASSERT(iA==contact.getRigidBodyIdA());
|
||||
SCE_PFX_ALWAYS_ASSERT(iB==contact.getRigidBodyIdB());
|
||||
|
||||
PfxRigidState &instA = offsetRigidStates[iA];
|
||||
PfxRigidState &instB = offsetRigidStates[iB];
|
||||
|
||||
contact.refresh(
|
||||
instA.getPosition(),instA.getOrientation(),
|
||||
instB.getPosition(),instB.getOrientation() );
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// pfxRefreshContacts
|
||||
//
|
||||
/// Perform refresh contacts in parallel using a task manager.
|
||||
///
|
||||
/// @param param Information about contact pairs
|
||||
/// @param taskManager Pointer to the thread task manager to use
|
||||
///
|
||||
/// @return SCE_PFX_OK if successful, otherwise, returns an error code.
|
||||
//----------------------------------------------------------------------------
|
||||
PfxInt32 pfxRefreshContacts(PfxRefreshContactsParam ¶m, PfxTaskManager *taskManager)
|
||||
{
|
||||
PfxInt32 ret = pfxCheckParamOfRefreshContacts(param);
|
||||
if(ret != SCE_PFX_OK) return ret;
|
||||
|
||||
SCE_PFX_PUSH_MARKER("pfxRefreshContacts");
|
||||
|
||||
PfxUInt32 maxBatchSize = param.numContactPairs / (PfxUInt32)(taskManager->getNumTasks());
|
||||
PfxUInt32 iEnd = maxBatchSize, iStart = 0;
|
||||
int task = 0;
|
||||
taskManager->setTaskEntry((void*)pfxRefreshContactsTaskEntry);
|
||||
|
||||
for (task = 0; task < taskManager->getNumTasks() - 1; task++, iStart += maxBatchSize, iEnd += maxBatchSize)
|
||||
{
|
||||
taskManager->startTask(task, static_cast<void*>(¶m), iStart, iEnd, 0, 0);
|
||||
}
|
||||
|
||||
// send final task
|
||||
iEnd = param.numContactPairs;
|
||||
taskManager->startTask(taskManager->getNumTasks() - 1, static_cast<void*>(¶m), iStart, iEnd, 0, 0);
|
||||
|
||||
// wait for tasks to complete
|
||||
PfxUInt32 data1, data2, data3, data4;
|
||||
for (PfxUInt32 i = 0; i < taskManager->getNumTasks(); i++)
|
||||
taskManager->waitTask(task, data1, data2, data3, data4);
|
||||
|
||||
SCE_PFX_POP_MARKER();
|
||||
|
||||
return SCE_PFX_OK;
|
||||
}
|
||||
|
||||
} //namespace PhysicsEffects
|
||||
} //namespace sce
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc.
|
||||
All rights reserved.
|
||||
|
||||
Physics Effects is open software; you can redistribute it and/or
|
||||
modify it under the terms of the BSD License.
|
||||
|
||||
Physics Effects is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the BSD License for more details.
|
||||
|
||||
A copy of the BSD License is distributed with
|
||||
Physics Effects under the filename: physics_effects_license.txt
|
||||
*/
|
||||
|
||||
#include "../../../include/physics_effects/base_level/base/pfx_perf_counter.h"
|
||||
#include "../../../include/physics_effects/base_level/sort/pfx_sort.h"
|
||||
#include "../../../include/physics_effects/low_level/collision/pfx_refresh_contacts.h"
|
||||
|
||||
namespace sce {
|
||||
namespace PhysicsEffects {
|
||||
|
||||
int pfxCheckParamOfRefreshContacts(PfxRefreshContactsParam ¶m)
|
||||
{
|
||||
if(!param.contactPairs || !param.offsetContactManifolds || !param.offsetRigidStates ) return SCE_PFX_ERR_INVALID_VALUE;
|
||||
if(!SCE_PFX_PTR_IS_ALIGNED16(param.contactPairs) || !SCE_PFX_PTR_IS_ALIGNED16(param.offsetContactManifolds) ||
|
||||
!SCE_PFX_PTR_IS_ALIGNED16(param.offsetRigidStates)) return SCE_PFX_ERR_INVALID_ALIGN;
|
||||
return SCE_PFX_OK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// SINGLE THREAD
|
||||
|
||||
PfxInt32 pfxRefreshContacts(PfxRefreshContactsParam ¶m)
|
||||
{
|
||||
PfxInt32 ret = pfxCheckParamOfRefreshContacts(param);
|
||||
if(ret != SCE_PFX_OK) return ret;
|
||||
|
||||
SCE_PFX_PUSH_MARKER("pfxRefreshContacts");
|
||||
|
||||
PfxConstraintPair *contactPairs = param.contactPairs;
|
||||
PfxUInt32 numContactPairs = param.numContactPairs;
|
||||
PfxContactManifold *offsetContactManifolds = param.offsetContactManifolds;
|
||||
PfxRigidState *offsetRigidStates = param.offsetRigidStates;
|
||||
PfxUInt32 numRigidBodies = param.numRigidBodies;
|
||||
|
||||
for(PfxUInt32 i=0;i<numContactPairs;i++) {
|
||||
PfxBroadphasePair &pair = contactPairs[i];
|
||||
|
||||
PfxUInt32 iContact = pfxGetContactId(pair);
|
||||
PfxUInt32 iA = pfxGetObjectIdA(pair);
|
||||
PfxUInt32 iB = pfxGetObjectIdB(pair);
|
||||
|
||||
PfxContactManifold &contact = offsetContactManifolds[iContact];
|
||||
|
||||
SCE_PFX_ALWAYS_ASSERT(iA==contact.getRigidBodyIdA());
|
||||
SCE_PFX_ALWAYS_ASSERT(iB==contact.getRigidBodyIdB());
|
||||
|
||||
PfxRigidState &instA = offsetRigidStates[iA];
|
||||
PfxRigidState &instB = offsetRigidStates[iB];
|
||||
|
||||
contact.refresh(
|
||||
instA.getPosition(),instA.getOrientation(),
|
||||
instB.getPosition(),instB.getOrientation() );
|
||||
}
|
||||
|
||||
SCE_PFX_POP_MARKER();
|
||||
|
||||
(void) numRigidBodies;
|
||||
|
||||
return SCE_PFX_OK;
|
||||
}
|
||||
|
||||
} //namespace PhysicsEffects
|
||||
} //namespace sce
|
||||
Reference in New Issue
Block a user