diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /APEX_1.4/module/destructible/src/DestructibleActorJointImpl.cpp | |
| download | physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip | |
Initial commit:
PhysX 3.4.0 Update @ 21294896
APEX 1.4.0 Update @ 21275617
[CL 21300167]
Diffstat (limited to 'APEX_1.4/module/destructible/src/DestructibleActorJointImpl.cpp')
| -rw-r--r-- | APEX_1.4/module/destructible/src/DestructibleActorJointImpl.cpp | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/APEX_1.4/module/destructible/src/DestructibleActorJointImpl.cpp b/APEX_1.4/module/destructible/src/DestructibleActorJointImpl.cpp new file mode 100644 index 00000000..958d3111 --- /dev/null +++ b/APEX_1.4/module/destructible/src/DestructibleActorJointImpl.cpp @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA CORPORATION and its licensors retain all intellectual property + * and proprietary rights in and to this software, related documentation + * and any modifications thereto. Any use, reproduction, disclosure or + * distribution of this software and related documentation without an express + * license agreement from NVIDIA CORPORATION is strictly prohibited. + */ + + +#include "ApexDefs.h" + +#include "Apex.h" +#include "ModuleDestructibleImpl.h" +#include "DestructibleActorJointImpl.h" +#include "DestructibleScene.h" +#include "DestructibleActorJoint.h" +#include "DestructibleActorProxy.h" + +#include <PxScene.h> +#include <PxJoint.h> +#include <PxD6Joint.h> +#include <PxDistanceJoint.h> +#include <PxFixedJoint.h> +#include <PxPrismaticJoint.h> +#include <PxRevoluteJoint.h> +#include <PxSphericalJoint.h> + +namespace nvidia +{ +namespace destructible +{ +using namespace physx; + +DestructibleActorJointImpl::DestructibleActorJointImpl(const DestructibleActorJointDesc& desc, DestructibleScene& dscene) : + joint(NULL) +{ + if (desc.destructible[0] == NULL && desc.destructible[1] == NULL) + { + APEX_DEBUG_WARNING("Both destructible actors in DestructibleActorJoint are NULL."); + return; + } + + PxRigidActor* actor[2] = {desc.actor[0], desc.actor[1]}; + PxVec3 localAxis[2] = {desc.localAxis[0], desc.localAxis[1]}; + PxVec3 localAnchor[2] = {desc.localAnchor[0], desc.localAnchor[1]}; + PxVec3 localNormal[2] = {desc.localNormal[0], desc.localNormal[1]}; + + PxTransform localFrame[2]; + + for (int i = 0; i < 2; ++i) + { + if (desc.destructible[i] == NULL) + { + structure[i] = NULL; + attachmentChunkIndex[i] = ModuleDestructibleConst::INVALID_CHUNK_INDEX; + + if(NULL == actor[i]) + { + // World constrained + PxMat33 rot(desc.globalAxis[i],desc.globalNormal[i],desc.globalAxis[i].cross(desc.globalNormal[i])); + + localFrame[i].p = desc.globalAnchor[i]; + localFrame[i].q = PxQuat(rot); + localFrame[i].q.normalize(); + } + else + { + // Constrained to physics object + PxMat33 rot(localAxis[i], localNormal[i], localAxis[i].cross(localNormal[i])); + + localFrame[i].p = localAnchor[i]; + localFrame[i].q = PxQuat(rot); + localFrame[i].q.normalize(); + } + continue; + } + + PxRigidDynamic* attachActor = NULL; + DestructibleActorImpl& destructible = ((DestructibleActorProxy*)desc.destructible[i])->impl; + structure[i] = destructible.getStructure(); + + attachmentChunkIndex[i] = desc.attachmentChunkIndex[i]; + + if (attachmentChunkIndex[i] >= 0 && attachmentChunkIndex[i] < (int32_t)destructible.getDestructibleAsset()->getChunkCount()) + { + DestructibleStructure::Chunk& chunk = structure[i]->chunks[destructible.getFirstChunkIndex() + attachmentChunkIndex[i]]; + attachActor = structure[i]->dscene->chunkIntact(chunk); + } + + SCOPED_PHYSX_LOCK_READ(dscene.getModulePhysXScene()); + + if (attachActor == NULL) + { + float minDistance = PX_MAX_F32; + for (uint32_t j = 0; j < destructible.getDestructibleAsset()->getChunkCount(); ++j) + { + DestructibleAssetParametersNS::Chunk_Type& source = destructible.getDestructibleAsset()->mParams->chunks.buf[j]; + const bool hasChildren = source.numChildren != 0; + if (!hasChildren) // Only attaching to lowest-level chunks, initially + { + DestructibleStructure::Chunk& chunk = structure[i]->chunks[destructible.getFirstChunkIndex() + j]; + PxRigidDynamic* actor = structure[i]->dscene->chunkIntact(chunk); + if (actor) + { + const float distance = (actor->getGlobalPose().transform(chunk.localSphereCenter) - desc.globalAnchor[i]).magnitude(); + if (distance < minDistance) + { + attachActor = actor; + attachmentChunkIndex[i] = (int32_t)(destructible.getFirstChunkIndex() + j); + minDistance = distance; + } + } + } + } + } + + if (attachActor == NULL) + { + APEX_DEBUG_WARNING("No physx actor could be found in destructible actor %p to attach the joint.", desc.destructible[i]); + return; + } + + actor[i] = (PxRigidActor*)attachActor; + + if (attachActor->getScene() != NULL && dscene.getModulePhysXScene() != attachActor->getScene()) + { + APEX_DEBUG_WARNING("Trying to joint actors from a scene different from the joint scene."); + return; + } + + localAnchor[i] = attachActor->getGlobalPose().transformInv(desc.globalAnchor[i]); + localAxis[i] = attachActor->getGlobalPose().rotateInv(desc.globalAxis[i]); + localNormal[i] = attachActor->getGlobalPose().rotateInv(desc.globalNormal[i]); + + PxMat33 rot(localAxis[i], localNormal[i], localAxis[i].cross(localNormal[i])); + + localFrame[i].p = localAnchor[i]; + localFrame[i].q = PxQuat(rot); + localFrame[i].q.normalize(); + } + + dscene.getModulePhysXScene()->lockRead(); + switch (desc.type) + { + case PxJointConcreteType::eD6: + joint = PxD6JointCreate(dscene.getModulePhysXScene()->getPhysics(), actor[0], localFrame[0], actor[1], localFrame[1]); + break; + case PxJointConcreteType::eDISTANCE: + joint = PxDistanceJointCreate(dscene.getModulePhysXScene()->getPhysics(), actor[0], localFrame[0], actor[1], localFrame[1]); + break; + case PxJointConcreteType::eFIXED: + joint = PxFixedJointCreate(dscene.getModulePhysXScene()->getPhysics(), actor[0], localFrame[0], actor[1], localFrame[1]); + break; + case PxJointConcreteType::ePRISMATIC: + joint = PxPrismaticJointCreate(dscene.getModulePhysXScene()->getPhysics(), actor[0], localFrame[0], actor[1], localFrame[1]); + break; + case PxJointConcreteType::eREVOLUTE: + joint = PxRevoluteJointCreate(dscene.getModulePhysXScene()->getPhysics(), actor[0], localFrame[0], actor[1], localFrame[1]); + break; + case PxJointConcreteType::eSPHERICAL: + joint = PxSphericalJointCreate(dscene.getModulePhysXScene()->getPhysics(), actor[0], localFrame[0], actor[1], localFrame[1]); + break; + default: + PX_ALWAYS_ASSERT(); + break; + } + dscene.getModulePhysXScene()->unlockRead(); + + PX_ASSERT(joint != NULL); +} + +DestructibleActorJointImpl::~DestructibleActorJointImpl() +{ + if (joint) + { + joint->release(); + } +} + +bool DestructibleActorJointImpl::updateJoint() +{ + if (!joint) + { + return false; + } + + PxRigidActor* actors[2]; + joint->getActors(actors[0], actors[1]); + + bool needsReattachment = false; + for (uint32_t i = 0; i < 2; ++i) + { + if (structure[i] == NULL) + { + continue; + } + if (attachmentChunkIndex[i] < 0 || attachmentChunkIndex[i] >= (int32_t)structure[i]->chunks.size()) + { + return false; + } + DestructibleStructure::Chunk& chunk = structure[i]->chunks[(uint32_t)attachmentChunkIndex[i]]; + PxRigidDynamic* actor = structure[i]->dscene->chunkIntact(chunk); + if (actor == NULL) + { + return false; + } + if ((PxRigidDynamic*)actors[i] != actor) + { + needsReattachment = true; + actors[i] = (PxRigidDynamic*)actor; + } + + } + + if (!needsReattachment) + { + return true; + } + +#define JOINT_SET_ACTORS_WORKAROUND 1 +#if JOINT_SET_ACTORS_WORKAROUND + PxScene* pxScenes[2] = { NULL, NULL }; + for (uint32_t i = 0; i < 2; ++i) + { + if (actors[i] != NULL) + { + pxScenes[i] = actors[i]->getScene(); + if (actors[i]->getScene() != NULL) + { + pxScenes[i]->lockWrite(); + pxScenes[i]->removeActor(*actors[i], false); + pxScenes[i]->unlockWrite(); + } + } + } +#endif + joint->setActors(actors[0], actors[1]); +#if JOINT_SET_ACTORS_WORKAROUND + for (uint32_t i = 0; i < 2; ++i) + { + if (actors[i] != NULL && pxScenes[i] != NULL) + { + pxScenes[i]->lockWrite(); + pxScenes[i]->addActor(*actors[i]); + pxScenes[i]->unlockWrite(); + } + } +#endif + return joint != NULL; +} + +} +} // end namespace nvidia + + |