NxJoint* Rope::pinSegmentToPosition(int segIndex, NxVec3& pos) { if(segIndex < numSegs) { NxSphericalJointDesc sphericalDesc; // some damping on twist and swing springs helps smooth out the rope motion sphericalDesc.flags |= NX_SJF_SWING_SPRING_ENABLED; sphericalDesc.flags |= NX_SJF_TWIST_SPRING_ENABLED; sphericalDesc.swingSpring.spring = 0.0f; sphericalDesc.swingSpring.damper = 10.0f; sphericalDesc.twistSpring.spring = 1.0f; sphericalDesc.twistSpring.damper = 10.0f; // projection is critical to manage stretch; if it is too tight, energy dissipates quickly. sphericalDesc.projectionMode = NX_JPM_NONE; sphericalDesc.projectionDistance = baseProjectionDistance; sphericalDesc.actor[0] = ropeSegments[segIndex]; sphericalDesc.actor[1] = 0; sphericalDesc.setGlobalAnchor(ropeSegments[segIndex]->getGlobalPosition()); return scene->createJoint(sphericalDesc); } else return NULL; }
NxSphericalJoint* CreateBladeLink(NxActor* a0, NxActor* a1, const NxVec3& globalAnchor, const NxVec3& globalAxis, NxScene* gScene) { NxSphericalJointDesc sphericalDesc; sphericalDesc.actor[0] = a0; sphericalDesc.actor[1] = a1; sphericalDesc.setGlobalAnchor(globalAnchor); sphericalDesc.setGlobalAxis(globalAxis); sphericalDesc.flags |= NX_SJF_SWING_LIMIT_ENABLED; sphericalDesc.swingLimit.value = (NxReal)0.05*NxPi; sphericalDesc.swingLimit.restitution = 0.75; sphericalDesc.swingLimit.hardness = 0.5; sphericalDesc.flags |= NX_SJF_SWING_SPRING_ENABLED; sphericalDesc.swingSpring.spring = 0.75; sphericalDesc.swingSpring.damper = 1; sphericalDesc.flags |= NX_SJF_TWIST_LIMIT_ENABLED; sphericalDesc.twistLimit.low.value = -(NxReal)0.05*NxPi; sphericalDesc.twistLimit.low.restitution = 0.75; sphericalDesc.twistLimit.low.hardness = 0.5; sphericalDesc.twistLimit.high.value = (NxReal)0.05*NxPi; sphericalDesc.twistLimit.high.restitution = 0.75; sphericalDesc.twistLimit.high.hardness = 0.5; sphericalDesc.flags |= NX_SJF_TWIST_SPRING_ENABLED; sphericalDesc.twistSpring.spring = 0.75; sphericalDesc.twistSpring.damper = 1; return static_cast<NxSphericalJoint*>(gScene->createJoint(sphericalDesc)); }
NxSphericalJoint* CreateRopeSphericalJoint(NxActor* a0, NxActor* a1, const NxVec3& globalAnchor, const NxVec3& globalAxis, NxScene* gScene) { NxSphericalJointDesc sphericalDesc; sphericalDesc.actor[0] = a0; sphericalDesc.actor[1] = a1; sphericalDesc.setGlobalAnchor(globalAnchor); sphericalDesc.setGlobalAxis(globalAxis); sphericalDesc.flags |= NX_SJF_TWIST_LIMIT_ENABLED; sphericalDesc.twistLimit.low.value = -(NxReal)0.1*NxPi; sphericalDesc.twistLimit.high.value = (NxReal)0.1*NxPi; sphericalDesc.flags |= NX_SJF_TWIST_SPRING_ENABLED; NxSpringDesc ts; ts.spring = 500; ts.damper = 0.5; ts.targetValue = 0; sphericalDesc.twistSpring = ts; sphericalDesc.flags |= NX_SJF_SWING_LIMIT_ENABLED; sphericalDesc.swingLimit.value = (NxReal)0.3*NxPi; sphericalDesc.flags |= NX_SJF_SWING_SPRING_ENABLED; NxSpringDesc ss; ss.spring = 500; ss.damper = 0.5; ss.targetValue = 0; sphericalDesc.swingSpring = ss; return static_cast<NxSphericalJoint*>(gScene->createJoint(sphericalDesc)); }
SphericalJoint::SphericalJoint(RigidBody* first, RigidBody* second, const SphericalJointDescription& desc) : Joint(first, second), mSphericalJoint(0) { NxSphericalJointDesc description; mRigidBodies[0] = first; mRigidBodies[1] = second; description.actor[0] = mRigidBodies[0]->getNxActor(); if (mRigidBodies[1]) description.actor[1] = mRigidBodies[1]->getNxActor(); else description.actor[1] = 0; Functions::PrototypeFunctions::SphericalJointDescriptionToNxSphericalJointDescription(desc, description); if (description.isValid() == false) { SharedStringStream message(SharedStringStream::_LARGE); message << "An error occured whilst creating a SphericalJoint.\nThe reason(s) and cause(s) could be:\n\n"; message << Reason::whyAsStream(description).get(); NxOgre_ThrowError(message.get()); return; } mJoint = first->getScene()->getScene()->createJoint(description); mSphericalJoint = mJoint->isSphericalJoint(); }
NxSphericalJoint* CreateSphericalJoint(NxActor* a0, NxActor* a1, const NxVec3& globalAnchor, const NxVec3& globalAxis, NxScene* gScene) { NxSphericalJointDesc sphericalDesc; sphericalDesc.actor[0] = a0; sphericalDesc.actor[1] = a1; sphericalDesc.setGlobalAnchor(globalAnchor); sphericalDesc.setGlobalAxis(globalAxis); return static_cast<NxSphericalJoint*>(gScene->createJoint(sphericalDesc)); }
std::shared_ptr<SphericalJoint> PhysicsLib::createSphericalJoint(std::shared_ptr<ActorBase> &a, std::shared_ptr<ActorBase> &b, const VC3 &globalAnchor) { SphericalJoint *joint = 0; if(a && b && data->scene) { NxSphericalJointDesc jointDesc; jointDesc.setToDefault(); jointDesc.actor[0] = a->getActor(); jointDesc.actor[1] = b->getActor(); jointDesc.setGlobalAnchor(NxVec3(globalAnchor.x, globalAnchor.y, globalAnchor.z)); // Limits etc stuff? jointDesc.swingLimit.value = PI/20.f; /* jointDesc.swingLimit.value = PI/20.f; static int foofoo = 0; int value = foofoo++; if(value == 0) jointDesc.swingLimit.value /= 2.f; if(value == 1) jointDesc.swingLimit.value /= 2.f; if(value == 2) jointDesc.swingLimit.value /= 2.f; if(value == 3) jointDesc.swingLimit.value /= 2.f; */ jointDesc.swingLimit.restitution = 1.f; jointDesc.flags |= NX_SJF_SWING_LIMIT_ENABLED; jointDesc.twistLimit.low.value = -PI/8.f; jointDesc.twistLimit.high.value = PI/8.f; jointDesc.flags |= NX_SJF_TWIST_LIMIT_ENABLED; joint = new SphericalJoint(*data->scene, jointDesc, a, b); if(!joint->isValid()) { delete joint; joint = 0; } } return std::shared_ptr<SphericalJoint> (joint); }
NxSphericalJoint* World::CreateSphericalJoint(NxActor* a0, NxActor* a1, const NxVec3& globalAnchor, const NxVec3& globalAxis) { NxSphericalJointDesc sphericalDesc; sphericalDesc.actor[0] = a0; sphericalDesc.actor[1] = a1; sphericalDesc.setGlobalAnchor(globalAnchor); sphericalDesc.setGlobalAxis(globalAxis); sphericalDesc.flags |= NX_SJF_SWING_LIMIT_ENABLED; sphericalDesc.swingLimit.value = 0.3*NxPi; sphericalDesc.flags |= NX_SJF_TWIST_LIMIT_ENABLED; sphericalDesc.twistLimit.low.value = -0.05*NxPi; sphericalDesc.twistLimit.high.value = 0.05*NxPi; return (NxSphericalJoint*)gScene->createJoint(sphericalDesc); }
NxJoint* Rope::pinLastSegmentInPlace() { NxSphericalJointDesc sphericalDesc; // some damping on twist and swing springs helps smooth out the rope motion //sphericalDesc.flags |= NX_SJF_SWING_SPRING_ENABLED; //sphericalDesc.flags |= NX_SJF_TWIST_SPRING_ENABLED; sphericalDesc.swingSpring.spring = 0.0f; sphericalDesc.swingSpring.damper = 10.0f; sphericalDesc.twistSpring.spring = 1.0f; sphericalDesc.twistSpring.damper = 10.0f; // projection is critical to manage stretch; if it is too tight, energy dissipates quickly. sphericalDesc.projectionMode = NX_JPM_POINT_MINDIST; sphericalDesc.projectionDistance = baseProjectionDistance; sphericalDesc.actor[0] = ropeSegments[numSegs-1]; sphericalDesc.actor[1] = 0; sphericalDesc.setGlobalAnchor(ropeSegments[numSegs-1]->getGlobalPosition()); return scene->createJoint(sphericalDesc); }
NxSphericalJoint* CreateBodySphericalJoint(NxActor* a0, NxActor* a1, const NxVec3& globalAnchor, const NxVec3& globalAxis, NxScene* gScene) { NxSphericalJointDesc sphericalDesc; sphericalDesc.actor[0] = a0; sphericalDesc.actor[1] = a1; sphericalDesc.setGlobalAnchor(globalAnchor); sphericalDesc.setGlobalAxis(globalAxis); sphericalDesc.flags |= NX_SJF_TWIST_LIMIT_ENABLED; sphericalDesc.twistLimit.low.value = -(NxReal)0.025*NxPi; sphericalDesc.twistLimit.low.hardness = 0.5; sphericalDesc.twistLimit.low.restitution = 0.5; sphericalDesc.twistLimit.high.value = (NxReal)0.025*NxPi; sphericalDesc.twistLimit.high.hardness = 0.5; sphericalDesc.twistLimit.high.restitution = 0.5; sphericalDesc.flags |= NX_SJF_SWING_LIMIT_ENABLED; sphericalDesc.swingLimit.value = (NxReal)0.25*NxPi; sphericalDesc.swingLimit.hardness = 0.5; sphericalDesc.swingLimit.restitution = 0.5; sphericalDesc.flags |= NX_SJF_TWIST_SPRING_ENABLED; sphericalDesc.twistSpring.spring = 0.5; sphericalDesc.twistSpring.damper = 1; sphericalDesc.flags |= NX_SJF_SWING_SPRING_ENABLED; sphericalDesc.swingSpring.spring = 0.5; sphericalDesc.swingSpring.damper = 1; // sphericalDesc.flags |= NX_SJF_JOINT_SPRING_ENABLED; // sphericalDesc.jointSpring.spring = 0.5; // sphericalDesc.jointSpring.damper = 1; sphericalDesc.projectionDistance = (NxReal)0.15; sphericalDesc.projectionMode = NX_JPM_POINT_MINDIST; return static_cast<NxSphericalJoint*>(gScene->createJoint(sphericalDesc)); }
Rope::Rope(NxScene& nxScene,NxVec3& startPosition, int numSegments, float segLength, float segMass,float segCollisionRadius, float projectionRatio) :scene(&nxScene), numSegs(numSegments), segmentLength(segLength), baseMassOfRopeSegment(segMass), segmentCollisionRadius(segCollisionRadius), startingPos(startPosition), projectionDistanceRampRate(0.0005), baseProjectionDistance(segLength * projectionRatio), randomMassCoefficient(0.003), internalSpringDamping(50.0f), segmentLinearDamping(0.1f), segmentAngularDamping(0.1f), momentOfInertiaConstant(2.0f) { NxVec3 segmentPosDelta(segmentLength, 0.0f, 0.0); NxBodyDesc segmentBodyDesc; segmentBodyDesc.angularDamping = 0.1f; NxSphereShapeDesc SphereDesc; SphereDesc.radius = segCollisionRadius; NxActorDesc ActorDesc; ActorDesc.shapes.pushBack(&SphereDesc); ActorDesc.body = &segmentBodyDesc; ActorDesc.density = 1.0f; ropeSegments = new NxActor*[numSegments]; for(int i = 0; i < numSegments; i++) { ActorDesc.globalPose.t = startingPos + i * segmentPosDelta; ropeSegments[i] = scene->createActor(ActorDesc); int randMass = (rand() % 100); ropeSegments[i]->setMass(baseMassOfRopeSegment + randMass * randomMassCoefficient); ropeSegments[i]->setMassSpaceInertiaTensor(NxVec3(momentOfInertiaConstant, momentOfInertiaConstant, momentOfInertiaConstant)); ropeSegments[i]->setAngularDamping(segmentAngularDamping); ropeSegments[i]->setLinearDamping(segmentLinearDamping); ropeSegments[i]->wakeUp(1e10); NxSphericalJointDesc sphericalDesc; // some damping on twist and swing springs helps smooth out the rope motion sphericalDesc.flags |= NX_SJF_SWING_SPRING_ENABLED; sphericalDesc.flags |= NX_SJF_TWIST_SPRING_ENABLED; sphericalDesc.swingSpring.spring = 0.0f; sphericalDesc.swingSpring.damper = internalSpringDamping; sphericalDesc.twistSpring.spring = 1.0f; sphericalDesc.twistSpring.damper = internalSpringDamping; // projection is critical to manage stretch; if it is too tight, energy dissipates quickly. sphericalDesc.projectionMode = NX_JPM_POINT_MINDIST; sphericalDesc.projectionDistance = baseProjectionDistance + (i * projectionDistanceRampRate); if(i>0) { sphericalDesc.actor[0] = ropeSegments[i]; sphericalDesc.actor[1] = ropeSegments[i-1]; sphericalDesc.setGlobalAnchor(startingPos + (i-1) * segmentPosDelta); scene->createJoint(sphericalDesc); } } }
bool NxuPhysicsExport::Write(NxJoint *j,const char *userProperties,const char *id) { bool ret = false; NxSceneDesc *current = getCurrentScene(); CustomCopy cc(mCollection,current); NxJointDesc *joint = 0; switch ( j->getType() ) { case NX_JOINT_PRISMATIC: if ( 1 ) { ::NxPrismaticJointDesc d1; NxPrismaticJoint *sj = j->isPrismaticJoint(); sj->saveToDesc(d1); addActor( d1.actor[0] ); addActor( d1.actor[1] ); NxPrismaticJointDesc *desc = new NxPrismaticJointDesc; desc->copyFrom(d1,cc); joint = static_cast<NxJointDesc *>(desc); } break; case NX_JOINT_REVOLUTE: if ( 1 ) { ::NxRevoluteJointDesc d1; NxRevoluteJoint *sj = j->isRevoluteJoint(); sj->saveToDesc(d1); addActor( d1.actor[0] ); addActor( d1.actor[1] ); NxRevoluteJointDesc *desc = new NxRevoluteJointDesc; desc->copyFrom(d1,cc); joint = static_cast<NxJointDesc *>(desc); } break; case NX_JOINT_CYLINDRICAL: if ( 1 ) { ::NxCylindricalJointDesc d1; NxCylindricalJoint *sj = j->isCylindricalJoint(); sj->saveToDesc(d1); addActor( d1.actor[0] ); addActor( d1.actor[1] ); NxCylindricalJointDesc *desc = new NxCylindricalJointDesc; desc->copyFrom(d1,cc); joint = static_cast<NxJointDesc *>(desc); } break; case NX_JOINT_SPHERICAL: if ( 1 ) { ::NxSphericalJointDesc d1; NxSphericalJoint *sj = j->isSphericalJoint(); sj->saveToDesc(d1); addActor( d1.actor[0] ); addActor( d1.actor[1] ); NxSphericalJointDesc *desc = new NxSphericalJointDesc; desc->copyFrom(d1,cc); joint = static_cast<NxJointDesc *>(desc); } break; case NX_JOINT_POINT_ON_LINE: if ( 1 ) { ::NxPointOnLineJointDesc d1; NxPointOnLineJoint *sj = j->isPointOnLineJoint(); sj->saveToDesc(d1); addActor( d1.actor[0] ); addActor( d1.actor[1] ); NxPointOnLineJointDesc *desc = new NxPointOnLineJointDesc; desc->copyFrom(d1,cc); joint = static_cast<NxJointDesc *>(desc); } break; case NX_JOINT_POINT_IN_PLANE: if ( 1 ) { ::NxPointInPlaneJointDesc d1; NxPointInPlaneJoint *sj = j->isPointInPlaneJoint(); sj->saveToDesc(d1); addActor( d1.actor[0] ); addActor( d1.actor[1] ); NxPointInPlaneJointDesc *desc = new NxPointInPlaneJointDesc; desc->copyFrom(d1,cc); joint = static_cast<NxJointDesc *>(desc); } break; case NX_JOINT_DISTANCE: if ( 1 ) { ::NxDistanceJointDesc d1; NxDistanceJoint *sj = j->isDistanceJoint(); sj->saveToDesc(d1); addActor( d1.actor[0] ); addActor( d1.actor[1] ); NxDistanceJointDesc *desc = new NxDistanceJointDesc; desc->copyFrom(d1,cc); joint = static_cast<NxJointDesc *>(desc); } break; case NX_JOINT_PULLEY: if ( 1 ) { ::NxPulleyJointDesc d1; NxPulleyJoint *sj = j->isPulleyJoint(); sj->saveToDesc(d1); addActor( d1.actor[0] ); addActor( d1.actor[1] ); NxPulleyJointDesc *desc = new NxPulleyJointDesc; desc->copyFrom(d1,cc); joint = static_cast<NxJointDesc *>(desc); } break; case NX_JOINT_FIXED: if ( 1 ) { ::NxFixedJointDesc d1; NxFixedJoint *sj = j->isFixedJoint(); sj->saveToDesc(d1); addActor( d1.actor[0] ); addActor( d1.actor[1] ); NxFixedJointDesc *desc = new NxFixedJointDesc; desc->copyFrom(d1,cc); joint = static_cast<NxJointDesc *>(desc); } break; case NX_JOINT_D6: if ( 1 ) { ::NxD6JointDesc d1; NxD6Joint *sj = j->isD6Joint(); sj->saveToDesc(d1); addActor( d1.actor[0] ); addActor( d1.actor[1] ); NxD6JointDesc *desc = new NxD6JointDesc; desc->copyFrom(d1,cc); joint = static_cast<NxJointDesc *>(desc); } break; default: break; } //Add Limits // in addition, we also have to write out its limit planes! j->resetLimitPlaneIterator(); if (j->hasMoreLimitPlanes()) { // write limit point joint->mOnActor2 = j->getLimitPoint(joint->mPlaneLimitPoint); NxArray< NxPlaneInfoDesc *> plist; // write the plane normals while (j->hasMoreLimitPlanes()) { NxPlaneInfoDesc *pInfo = new NxPlaneInfoDesc(); #if NX_SDK_VERSION_NUMBER >= 272 j->getNextLimitPlane(pInfo->mPlaneNormal, pInfo->mPlaneD, &pInfo->restitution); #else j->getNextLimitPlane(pInfo->mPlaneNormal, pInfo->mPlaneD); #endif plist.push_back(pInfo); } if ( plist.size() ) { for (int i=plist.size()-1; i>=0; i--) { NxPlaneInfoDesc *p = plist[i]; joint->mPlaneInfo.pushBack(p); } } } if ( joint ) { if ( id ) { joint->mId = id; } else { char scratch[512]; sprintf(scratch,"Joint_%d", current->mJoints.size()); joint->mId = getGlobalString(scratch); joint->mUserProperties = getGlobalString(userProperties); } current->mJoints.push_back(joint); ret = true; } return ret; }