NxWheelShape* AddWheelToActor(NxActor* actor, NxWheelDesc* wheelDesc) { NxWheelShapeDesc wheelShapeDesc; // Create a shared car wheel material to be used by all wheels if (!wsm) { NxMaterialDesc m; m.flags |= NX_MF_DISABLE_FRICTION; wsm = gScene->createMaterial(m); } wheelShapeDesc.materialIndex = wsm->getMaterialIndex(); wheelShapeDesc.localPose.t = wheelDesc->position; NxQuat q; q.fromAngleAxis(90, NxVec3(0,1,0)); wheelShapeDesc.localPose.M.fromQuat(q); NxReal heightModifier = (wheelDesc->wheelSuspension + wheelDesc->wheelRadius) / wheelDesc->wheelSuspension; wheelShapeDesc.suspension.spring = wheelDesc->springRestitution*heightModifier; wheelShapeDesc.suspension.damper = wheelDesc->springDamping*heightModifier; wheelShapeDesc.suspension.targetValue = wheelDesc->springBias*heightModifier; wheelShapeDesc.radius = wheelDesc->wheelRadius; wheelShapeDesc.suspensionTravel = wheelDesc->wheelSuspension; wheelShapeDesc.inverseWheelMass = 0.1; //not given!? TODO // wheelShapeDesc.lateralTireForceFunction.stiffnessFactor *= wheelDesc->frictionToSide; // wheelShapeDesc.longitudalTireForceFunction.stiffnessFactor *= wheelDesc->frictionToFront; NxWheelShape* wheelShape = NULL; wheelShape = static_cast<NxWheelShape *>(actor->createShape(wheelShapeDesc)); return wheelShape; }
NxFluidEmitter* CreateFluidEmitter(const NxReal dimX, const NxReal dimY) { fluid = CreateFluid(); assert(fluid); NxQuat q; q.fromAngleAxis(90,NxVec3(1,0,0)); NxMat34 mat; mat.M.fromQuat(q); mat.t = NxVec3(0,4.5,0); // Create emitter NxFluidEmitterDesc emitterDesc; emitterDesc.setToDefault(); emitterDesc.frameShape = NULL; emitterDesc.dimensionX = dimX; emitterDesc.dimensionY = dimY; emitterDesc.relPose = mat; emitterDesc.rate = 100; emitterDesc.randomAngle = 0.0f; emitterDesc.randomPos = NxVec3(0.0f,0.0f,0.0f); emitterDesc.fluidVelocityMagnitude = 2.5f; emitterDesc.repulsionCoefficient = 0.02f; emitterDesc.maxParticles = 0; emitterDesc.particleLifetime = 0.0f; emitterDesc.type = NX_FE_CONSTANT_PRESSURE; emitterDesc.shape = NX_FE_ELLIPSE; return fluid->createEmitter(emitterDesc); }
void PhysXShape::setLocalOrintation(const math::quaternion&v) { NxMat33 nm; NxQuat q; q.setWXYZ(v.w,v.x,v.y,v.z); nm.fromQuat(q); m_nxShape->setLocalOrientation(nm); }
void SetupAttachmentScene() { sprintf(gTitleString, "Attachment Demo"); // Create objects in scene groundPlane = CreateGroundPlane(); NxActor* box1 = CreateBox(NxVec3(-7,12.25,0), NxVec3(2.5,1,1), 0); NxActor* box2 = CreateBox(NxVec3(0,12.25,0), NxVec3(2.5,1,1), 0); NxActor* box3 = CreateBox(NxVec3(7,12.25,0), NxVec3(2.5,1,1), 0); NxActor* attachedBox = CreateBox(NxVec3(-7.2,4.5,1.6), NxVec3(1.25,1,1), 1); NxActor* attachedSphere = CreateSphere(NxVec3(-0.25,4.0,2.0), 1.3, 1); NxActor* attachedCapsule = CreateCapsule(NxVec3(9.0,5.5,2.0),2.0, 1, 1); NxReal damping = 0.3; attachedBox->setAngularDamping(damping); attachedBox->setLinearDamping(damping); attachedSphere->setAngularDamping(damping); attachedSphere->setLinearDamping(damping); attachedCapsule->setAngularDamping(damping); attachedCapsule->setLinearDamping(damping); NxQuat q; q.fromAngleAxis(90,NxVec3(0,0,1)); attachedCapsule->setGlobalOrientationQuat(q); // Cloth NxClothDesc clothDesc; clothDesc.globalPose.M.rotX(1.3); clothDesc.thickness = 0.3; clothDesc.attachmentResponseCoefficient = 1; clothDesc.flags |= NX_CLF_BENDING; clothDesc.flags |= NX_CLF_BENDING_ORTHO; clothDesc.flags |= NX_CLF_DAMPING | NX_CLF_VISUALIZATION; if (gHardwareCloth) clothDesc.flags |= NX_CLF_HARDWARE; // Cloth attaching to sphere clothDesc.globalPose.t = NxVec3(0.75,5,2); MyCloth* regularCloth1 = new MyCloth(gScene, clothDesc, 2, 8, 0.4); regularCloth1->getNxCloth()->attachToCollidingShapes(NX_CLOTH_ATTACHMENT_TWOWAY); gCloths.push_back(regularCloth1); // Cloth attaching to box clothDesc.globalPose.t = NxVec3(-6.2,5,2); MyCloth* regularCloth2 = new MyCloth(gScene, clothDesc, 2, 8, 0.4); regularCloth2->getNxCloth()->attachToCollidingShapes(NX_CLOTH_ATTACHMENT_TWOWAY); gCloths.push_back(regularCloth2); // Cloth attaching to capsule clothDesc.globalPose.t = NxVec3(8.0,5,2); clothDesc.attachmentTearFactor = 2.0; MyCloth* regularCloth3 = new MyCloth(gScene, clothDesc, 2, 8, 0.4); regularCloth3->getNxCloth()->attachToShape(box3->getShapes()[0], NX_CLOTH_ATTACHMENT_TEARABLE); regularCloth3->getNxCloth()->attachToShape(attachedCapsule->getShapes()[0], NX_CLOTH_ATTACHMENT_TWOWAY); gCloths.push_back(regularCloth3); }
NxQuat getFrom(VxQuaternion source) { NxQuat result; result.setx(-source.x); result.sety(-source.y); result.setz(-source.z); result.setw(source.w); return result; }
/*********************************************************** get direction vector ***********************************************************/ LbaVec3 LbaQuaternion::GetDirection(const LbaVec3 &vec) { NxVec3 dir(vec.x, vec.y, vec.z); NxQuat current; current.setXYZW(X, Y, Z, W); current.rotate(dir); return LbaVec3(dir.x, dir.y, dir.z); }
/*********************************************************** add rotation to quaternion ***********************************************************/ void LbaQuaternion::AddRotation(float angle, LbaVec3 vec) { NxQuat q(angle, NxVec3(vec.x, vec.y, vec.z)); NxQuat current; current.setXYZW(X, Y, Z, W); current = q * current; X = current.x; Y = current.y; Z = current.z; W = current.w; }
void NxQuat::rotate(Point & v) const { NxQuat myInverse; myInverse.x = -x; myInverse.y = -y; myInverse.z = -z; myInverse.w = w; NxQuat left; left.multiply(*this,v); v.x = left.w*myInverse.x + myInverse.w*left.x + left.y*myInverse.z - myInverse.y*left.z; v.y = left.w*myInverse.y + myInverse.w*left.y + left.z*myInverse.x - myInverse.z*left.x; v.z = left.w*myInverse.z + myInverse.w*left.z + left.x*myInverse.y - myInverse.x*left.y; }
void Vehicle::resetCarPos() { NxVec3 vec3(mOriginalPos.x, mOriginalPos.y, mOriginalPos.z); NxQuat quat; quat.setWXYZ(mOriginalQuat.w, mOriginalQuat.x, mOriginalQuat.y, mOriginalQuat.z); mActor->setGlobalPose(NxMat34(quat, vec3)); vec3.zero(); mActor->setLinearVelocity(vec3); mActor->setAngularVelocity(vec3); }
void rotate(btVector3 & v) const { NxQuat myInverse; myInverse.x = -x; myInverse.y = -y; myInverse.z = -z; myInverse.w = w; NxQuat left; left.multiply(*this,v); float vx = left.w*myInverse.x + myInverse.w*left.x + left.y*myInverse.z - myInverse.y*left.z; float vy = left.w*myInverse.y + myInverse.w*left.y + left.z*myInverse.x - myInverse.z*left.x; float vz = left.w*myInverse.z + myInverse.w*left.z + left.x*myInverse.y - myInverse.x*left.y; v.setValue(vx, vy, vz); }
void NxVehicle::_computeLocalVelocity() { _computeMostTouchedActor(); NxVec3 relativeVelocity; if (_mostTouchedActor == NULL || !_mostTouchedActor->isDynamic()) { relativeVelocity = _bodyActor->getLinearVelocity(); } else { relativeVelocity = _bodyActor->getLinearVelocity() - _mostTouchedActor->getLinearVelocity(); } NxQuat rotation = _bodyActor->getGlobalOrientationQuat(); NxQuat global2Local; _localVelocity = relativeVelocity; rotation.inverseRotate(_localVelocity); //printf("Velocity: %2.3f %2.3f %2.3f\n", _localVelocity.x, _localVelocity.y, _localVelocity.z); }
VxQuaternion getFrom(NxQuat source) { VxQuaternion result; source.getXYZW(result.v); result.x = -result.x; result.z = -result.z; result.y = -result.y; return result; }
void NxVehicle::standUp() { NxVec3 pos = getActor()->getGlobalPosition() + NxVec3(0,2,0); NxQuat rot = getActor()->getGlobalOrientationQuat(); NxVec3 front(1,0,0); rot.rotate(front); front.y = 0; front.normalize(); NxReal dotproduct = front.x; NxReal angle = NxMath::sign(-front.z) * NxMath::acos(dotproduct); rot.fromAngleAxis(NxMath::radToDeg(angle), NxVec3(0,1,0)); getActor()->setGlobalPosition(pos); getActor()->setGlobalOrientationQuat(rot); getActor()->setLinearVelocity(NxVec3(0,0,0)); getActor()->setAngularVelocity(NxVec3(0,0,0)); }
void pVehicle::_computeLocalVelocity() { _computeMostTouchedActor(); NxVec3 relativeVelocity; if (_mostTouchedActor == NULL || !_mostTouchedActor->isDynamic()) { relativeVelocity = getActor()->getLinearVelocity(); } else { relativeVelocity = getActor()->getLinearVelocity() - _mostTouchedActor->getLinearVelocity(); } NxQuat rotation = getActor()->getGlobalOrientationQuat(); NxQuat global2Local; _localVelocity = relativeVelocity; rotation.inverseRotate(_localVelocity); char master[512]; //sprintf(master,"Velocity: %2.3f %2.3f %2.3f\n", _localVelocity.x, _localVelocity.y, _localVelocity.z); //OutputDebugString(master); }
Vector3 StillDesign::PhysX::Math::QuatToEuler( NxQuat q ) { q.normalize(); float sqw = q.w * q.w; float sqx = q.x * q.x; float sqy = q.y * q.y; float sqz = q.z * q.z; float test = q.x*q.y + q.z*q.w; Vector3 rotation = Vector3( 0, 0, 0 ); // Singularity at north pole if( test >= 0.499999999999999999f ) { rotation.Y = 2.0f * atan2( q.x, q.w ); rotation.Z = (float)System::Math::PI; rotation.X = 0.0f; return rotation; } if( test <= -0.499999999999999999f ) { rotation.Y = -2.0f * atan2( q.x, q.w ); rotation.Z = -((float)System::Math::PI / 2.0f); rotation.X = 0.0f; return rotation; } rotation.Y = atan2(2*q.y*q.w-2*q.x*q.z , sqx - sqy - sqz + sqw); rotation.Z = asin(2*test); rotation.X = atan2(2*q.x*q.w-2*q.y*q.z , -sqx + sqy - sqz + sqw); return rotation; }
void Vehicle::loadScene(const std::string &fileName) { //车的父节点 mBaseCarNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(fileName + "BaseCarNode"); //DotSceneLoader* dsl = new DotSceneLoader();//rel //dsl->parseDotScene(fileName + ".scene", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, mSceneMgr, mBaseCarNode); mVehicleRenderable = new VehicleRenderable(mSceneMgr, mBaseCarNode); mVehicleRenderable->load(fileName + ".vrf"); //车身节点 mBodyNode = static_cast<Ogre::SceneNode*>(mBaseCarNode->getChild(fileName + "Body")); //轮子节点 mWheels[TOP_LEFT].mSceneNode = static_cast<Ogre::SceneNode*>(mBaseCarNode->getChild(fileName + "LTWheel")); mWheels[TOP_LEFT].mName = fileName + "LTWheel"; mWheels[TOP_RIGHT].mSceneNode = static_cast<Ogre::SceneNode*>(mBaseCarNode->getChild(fileName + "RTWheel")); mWheels[TOP_RIGHT].mName = fileName + "RTWheel"; mWheels[Bottom_LEFT].mSceneNode = static_cast<Ogre::SceneNode*>(mBaseCarNode->getChild(fileName + "LBWheel")); mWheels[Bottom_LEFT].mName = fileName + "LBWheel"; mWheels[Bottom_RIGHT].mSceneNode = static_cast<Ogre::SceneNode*> (mBaseCarNode->getChild(fileName + "RBWheel")); mWheels[Bottom_RIGHT].mName = fileName + "RBWheel"; //设置整体参数 NxBodyDesc bodyDes; //bodyDes.wakeUpCounter = 1E8; bodyDes.mass = 12000;//mVehicleInfo.gMass; //bodyDes.massLocalPose.t = NxVec3(mVehicleInfo.gMassLocalPose.x, mVehicleInfo.gMassLocalPose.y, mVehicleInfo.gMassLocalPose.z); bodyDes.angularDamping = 0.03f; bodyDes.linearDamping = 0.08f; //写入车身的shapeDesc mBoundingBox = mBodyNode->getAttachedObject(0)->getBoundingBox(); NxBoxShapeDesc boxDes; NxVec3 dimen (mBoundingBox.getHalfSize().x, mBoundingBox.getHalfSize().y, mBoundingBox.getHalfSize().z); NxVec3 localPos (mBodyNode->getPosition().x, mBodyNode->getPosition().y, mBodyNode->getPosition().z); ////车身到轮子的距离 //NxReal d1 = NxMath::abs(mBodyNode->getPosition().y - mWheels[0].mSceneNode->getPosition().y); ////包围盒半径之和 //NxReal d2 = mBoundingBox.getHalfSize().y + mWheels[0].mSceneNode->getAttachedObject(0)->getBoundingBox().getHalfSize().y; ////判断轮子是否与车身的包围盒重叠 //if(d1 < d2) //{ // //设置为最大适合高度 // dimen.y = (mBoundingBox.getSize().y - (d2 - d1)) / 2.0f; //} boxDes.dimensions.set(dimen); boxDes.localPose.t = localPos; NxActorDesc actorDesc; actorDesc.body = &bodyDes; actorDesc.globalPose.t = NxVec3(mOriginalPos.x, mOriginalPos.y, mOriginalPos.z); NxQuat quat; quat.setWXYZ(mOriginalQuat.w, mOriginalQuat.x, mOriginalQuat.y, mOriginalQuat.z); actorDesc.globalPose.M.fromQuat(quat); actorDesc.shapes.pushBack(&boxDes); mActor = mNxScene->createActor(actorDesc); mActor->setCMassOffsetLocalPosition(NxVec3(0, -mBoundingBox.getSize().y, 0)); mBodyShape = static_cast<NxBoxShape*>(mActor->getShapes()[0]); //写入轮子的shapeDesc createWheelShapeDesc(&mWheels[TOP_LEFT], true); createWheelShapeDesc(&mWheels[TOP_RIGHT], true); createWheelShapeDesc(&mWheels[Bottom_LEFT], false); createWheelShapeDesc(&mWheels[Bottom_RIGHT], false); //mWheels[TOP_LEFT].mWheelDesc.localPose.t = NxVec3(mBoundingBox.getHalfSize().x, 2, 0); //mWheels[TOP_RIGHT].mWheelDesc.localPose.t = NxVec3(-mBoundingBox.getHalfSize().x, 2, 0); //mWheels[Bottom_LEFT].mWheelDesc.localPose.t = NxVec3(mBoundingBox.getHalfSize().x, -mBoundingBox.getHalfSize().y, 0); //mWheels[Bottom_RIGHT].mWheelDesc.localPose.t = NxVec3(-mBoundingBox.getHalfSize().x, -mBoundingBox.getHalfSize().y, 0); //创建轮子 mWheels[TOP_LEFT].mWheel = static_cast<NxWheelShape*>(mActor->createShape(mWheels[TOP_LEFT].mWheelDesc)); mWheels[TOP_RIGHT].mWheel = static_cast<NxWheelShape*>(mActor->createShape(mWheels[TOP_RIGHT].mWheelDesc)); mWheels[Bottom_LEFT].mWheel = static_cast<NxWheelShape*>(mActor->createShape(mWheels[Bottom_LEFT].mWheelDesc)); mWheels[Bottom_RIGHT].mWheel = static_cast<NxWheelShape*>(mActor->createShape(mWheels[Bottom_RIGHT].mWheelDesc)); NxMaterial* mat = mNxScene->getMaterialFromIndex(0); mat->setFrictionCombineMode(NX_CM_MULTIPLY); mat->setStaticFriction(300.2f); mat->setDynamicFriction(100.5f); }
/*********************************************************** get object rotation on all axis ***********************************************************/ float PhysXActorsHandler::GetRotationSingleAngle() { NxQuat quat = _Actor->getGlobalOrientationQuat(); return quat.getAngle(); }
HeightmapActor::HeightmapActor(NxPhysicsSDK &sdk_, NxScene &scene, const unsigned short *buffer, int samplesX, int samplesY, const VC3 &size) : sdk(sdk_), heightField(0) { NxHeightFieldDesc heightDesc; heightDesc.nbColumns = samplesX; heightDesc.nbRows = samplesY; heightDesc.verticalExtent = -1000; heightDesc.convexEdgeThreshold = 0; heightDesc.samples = new NxU32[samplesX * samplesY]; heightDesc.sampleStride = sizeof(NxU32); NxU8 *currentByte = (NxU8 *) heightDesc.samples; for(int row = 0; row < samplesY; ++row) for(int column = 0; column < samplesX; ++column) { NxHeightFieldSample *currentSample = (NxHeightFieldSample *) currentByte; //int sample = buffer[row * samplesX + column]; //int sample = buffer[column * samplesY + row]; int sample = buffer[(samplesY - row - 1) * samplesX + column]; //int sample = buffer[column * samplesX + row]; sample -= 32768; currentSample->height = sample; currentSample->materialIndex0 = 0; currentSample->materialIndex1 = 0; currentSample->tessFlag = 0; currentByte += heightDesc.sampleStride; } heightField = sdk.createHeightField(heightDesc); delete[] (NxU32 *) heightDesc.samples; if(heightField) { float scaleX = size.x / samplesX; float scaleY = 1.f / 65536.f * size.y; float scaleZ = size.z / samplesY; NxHeightFieldShapeDesc shapeDesc; shapeDesc.heightField = heightField; shapeDesc.heightScale = scaleY; shapeDesc.rowScale = scaleZ; shapeDesc.columnScale = scaleX; shapeDesc.materialIndexHighBits = 0; shapeDesc.holeMaterial = 2; NxVec3 pos; pos.x = -size.x * 0.5f; pos.y = size.y * 0.5f; pos.z = (size.z * 0.5f) - scaleZ; NxQuat quat; quat.zero(); quat.fromAngleAxis(90, NxVec3(0, 1, 0)); NxActorDesc actorDesc; actorDesc.shapes.pushBack(&shapeDesc); actorDesc.globalPose.t = pos; actorDesc.globalPose.M = quat; actor = scene.createActor(actorDesc); } this->scene = &scene; init(); }
// Reconfigure joint, a.k.a., roll joint void ReconfigureD6Joint() { NxActor* a0 = capsule1; NxActor* a1 = capsule2; NxD6JointDesc d6Desc; // Reset actor #1 NxMat33 orient; orient.id(); a1->raiseBodyFlag(NX_BF_KINEMATIC); a1->setGlobalOrientation(orient); a1->setGlobalPosition(NxVec3(0,3,0)); a1->clearBodyFlag(NX_BF_KINEMATIC); d6Desc.actor[0] = a0; d6Desc.actor[1] = a1; // Reset Anchor and Axis NxVec3 globalAnchor = NxVec3(0,5,0); NxVec3 globalAxis = NxVec3(0,1,0); d6Desc.setGlobalAnchor(globalAnchor); d6Desc.setGlobalAxis(globalAxis); switch (gJointType) { case 0: // Translation Limited Joint { d6Desc.twistMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc.swing1Motion = NX_D6JOINT_MOTION_LOCKED; d6Desc.swing2Motion = NX_D6JOINT_MOTION_LOCKED; d6Desc.xMotion = NX_D6JOINT_MOTION_LIMITED; d6Desc.yMotion = NX_D6JOINT_MOTION_LIMITED; d6Desc.zMotion = NX_D6JOINT_MOTION_LIMITED; d6Desc.linearLimit.value = 0.8; d6Desc.linearLimit.restitution = 0; d6Desc.linearLimit.spring = 0; d6Desc.linearLimit.damping = 0; } break; case 1: // Translation Soft Limited Joint { d6Desc.twistMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc.swing1Motion = NX_D6JOINT_MOTION_LOCKED; d6Desc.swing2Motion = NX_D6JOINT_MOTION_LOCKED; d6Desc.xMotion = NX_D6JOINT_MOTION_LIMITED; d6Desc.yMotion = NX_D6JOINT_MOTION_LIMITED; d6Desc.zMotion = NX_D6JOINT_MOTION_LIMITED; d6Desc.linearLimit.value = 0.8; d6Desc.linearLimit.restitution = 0; d6Desc.linearLimit.spring = 100; d6Desc.linearLimit.damping = 0.1; } break; case 2: // Rotation Limited Joint { d6Desc.twistMotion = NX_D6JOINT_MOTION_LIMITED; d6Desc.swing1Motion = NX_D6JOINT_MOTION_LIMITED; d6Desc.swing2Motion = NX_D6JOINT_MOTION_LIMITED; d6Desc.xMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc.yMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc.zMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc.swing1Limit.value = 0.3*NxPi; d6Desc.swing1Limit.restitution = 0; d6Desc.swing1Limit.spring = 0; d6Desc.swing1Limit.damping = 0; d6Desc.swing2Limit.value = 0.3*NxPi; d6Desc.swing2Limit.restitution = 0; d6Desc.swing2Limit.spring = 0; d6Desc.swing2Limit.damping = 0; d6Desc.twistLimit.low.value = -0.05*NxPi; d6Desc.twistLimit.low.restitution = 0; d6Desc.twistLimit.low.spring = 0; d6Desc.twistLimit.low.damping = 0; d6Desc.twistLimit.high.value = 0.05*NxPi; d6Desc.twistLimit.high.restitution = 0; d6Desc.twistLimit.high.spring = 0; d6Desc.twistLimit.high.damping = 0; } break; case 3: // Rotation Soft Limited Joint { d6Desc.twistMotion = NX_D6JOINT_MOTION_LIMITED; d6Desc.swing1Motion = NX_D6JOINT_MOTION_LIMITED; d6Desc.swing2Motion = NX_D6JOINT_MOTION_LIMITED; d6Desc.xMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc.yMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc.zMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc.swing1Limit.value = 0.3*NxPi; d6Desc.swing1Limit.restitution = 0; d6Desc.swing1Limit.spring = 300; d6Desc.swing1Limit.damping = 10; d6Desc.swing2Limit.value = 0.3*NxPi; d6Desc.swing2Limit.restitution = 0; d6Desc.swing2Limit.spring = 300; d6Desc.swing2Limit.damping = 10; d6Desc.twistLimit.low.value = -0.05*NxPi; d6Desc.twistLimit.low.restitution = 0; d6Desc.twistLimit.low.spring = 300; d6Desc.twistLimit.low.damping = 10; d6Desc.twistLimit.high.value = 0.05*NxPi; d6Desc.twistLimit.high.restitution = 0; } break; case 4: // Translation Motored Joint { d6Desc.twistMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc.swing1Motion = NX_D6JOINT_MOTION_LOCKED; d6Desc.swing2Motion = NX_D6JOINT_MOTION_LOCKED; d6Desc.xMotion = NX_D6JOINT_MOTION_LIMITED; d6Desc.yMotion = NX_D6JOINT_MOTION_LIMITED; d6Desc.zMotion = NX_D6JOINT_MOTION_LIMITED; d6Desc.linearLimit.value = 1; d6Desc.linearLimit.restitution = 0; d6Desc.linearLimit.spring = 0; d6Desc.linearLimit.damping = 0; d6Desc.zDrive.driveType = NX_D6JOINT_DRIVE_POSITION; d6Desc.zDrive.spring = 100; d6Desc.zDrive.damping = 0; d6Desc.drivePosition.set(0,5,1); // d6Desc.zDrive.driveType = NX_D6JOINT_DRIVE_VELOCITY; // d6Desc.zDrive.forceLimit = FLT_MAX; // d6Desc.driveLinearVelocity.set(0,0,5); } break; case 5: // Rotation Motored Joint { d6Desc.twistMotion = NX_D6JOINT_MOTION_LIMITED; d6Desc.swing1Motion = NX_D6JOINT_MOTION_LIMITED; d6Desc.swing2Motion = NX_D6JOINT_MOTION_LIMITED; d6Desc.xMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc.yMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc.zMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc.swing1Limit.value = 0.3*NxPi; d6Desc.swing1Limit.restitution = 0; d6Desc.swing1Limit.spring = 0; d6Desc.swing1Limit.damping = 0; d6Desc.swing2Limit.value = 0.3*NxPi; d6Desc.swing2Limit.restitution = 0; d6Desc.swing2Limit.spring = 0; d6Desc.swing2Limit.damping = 0; d6Desc.twistLimit.low.value = -0.05*NxPi; d6Desc.twistLimit.low.restitution = 0; d6Desc.twistLimit.low.spring = 0; d6Desc.twistLimit.low.damping = 0; d6Desc.twistLimit.high.value = 0.05*NxPi; d6Desc.twistLimit.high.restitution = 0; d6Desc.twistLimit.high.spring = 0; d6Desc.twistLimit.high.damping = 0; // Slerp Drive - Orientation Target d6Desc.flags = NX_D6JOINT_SLERP_DRIVE; d6Desc.slerpDrive.driveType = NX_D6JOINT_DRIVE_POSITION; d6Desc.slerpDrive.spring = 200; d6Desc.slerpDrive.damping = 0; NxQuat q; q.fromAngleAxis(90,NxVec3(0,1,0)); d6Desc.driveOrientation = q; } break; }; d6Desc.projectionMode = NX_JPM_NONE; // Set joint motion display values gJointMotion[3] = d6Desc.twistMotion; gJointMotion[4] = d6Desc.swing1Motion; gJointMotion[5] = d6Desc.swing2Motion; gJointMotion[0] = d6Desc.xMotion; gJointMotion[1] = d6Desc.yMotion; gJointMotion[2] = d6Desc.zMotion; char ds[512]; // Set joint type in HUD sprintf(ds, "JOINT TYPE: %s", gJointTypeString[gJointType]); hud.SetDisplayString(2, ds, 0.015f, 0.92f); // Set rotation motions in HUD sprintf(ds, " Axis: %s", gJointMotionString[gJointMotion[3]]); hud.SetDisplayString(4, ds, 0.015f, 0.82f); sprintf(ds, " Normal: %s", gJointMotionString[gJointMotion[4]]); hud.SetDisplayString(5, ds, 0.015f, 0.77f); sprintf(ds, " Binormal: %s", gJointMotionString[gJointMotion[5]]); hud.SetDisplayString(6, ds, 0.015f, 0.72f); // Set translation motions in HUD sprintf(ds, " Axis: %s", gJointMotionString[gJointMotion[0]]); hud.SetDisplayString(8, ds, 0.015f, 0.62f); sprintf(ds, " Normal: %s", gJointMotionString[gJointMotion[1]]); hud.SetDisplayString(9, ds, 0.015f, 0.57f); sprintf(ds, " Binormal: %s", gJointMotionString[gJointMotion[2]]); hud.SetDisplayString(10, ds, 0.015f, 0.52f); d6Joint->loadFromDesc(d6Desc); }
void UpdateJointMotorTarget() { if (gJointType == 4) // Linear Motor { NxD6JointDesc d6Desc; d6Joint->saveToDesc(d6Desc); if (d6Desc.zDrive.driveType == NX_D6JOINT_DRIVE_POSITION) // Position Target { NxVec3 jointPos = d6Joint->getGlobalAnchor(); if ((jointPos.x > 0.4) || (jointPos.x < -0.4)) { if (jointPos.x > 0.4) d6Desc.drivePosition = NxVec3(0,5,-1); else if (jointPos.x < -0.4) d6Desc.drivePosition = NxVec3(0,5,1); d6Joint->loadFromDesc(d6Desc); } } else if (d6Desc.zDrive.driveType == NX_D6JOINT_DRIVE_VELOCITY) // Velocity Target { NxVec3 jointPos = d6Joint->getGlobalAnchor(); if ((jointPos.x > 0.4) || (jointPos.x < -0.4)) { if (jointPos.x > 0.4) d6Desc.driveLinearVelocity = NxVec3(0,0,-5); else if (jointPos.x < -0.4) d6Desc.driveLinearVelocity = NxVec3(0,0,5); d6Joint->loadFromDesc(d6Desc); } } } else if (gJointType == 5) // Rotational Motor { NxD6JointDesc d6Desc; d6Joint->saveToDesc(d6Desc); NxVec3 localAnchor[2], localAxis[2], localNormal[2], localBinormal[2]; localAnchor[0] = d6Desc.localAnchor[0]; localAnchor[1] = d6Desc.localAnchor[1]; localAxis[0] = d6Desc.localAxis[0]; localNormal[0] = d6Desc.localNormal[0]; localBinormal[0] = localNormal[0].cross(localAxis[0]); localAxis[1] = d6Desc.localAxis[1]; localNormal[1] = d6Desc.localNormal[1]; localBinormal[1] = localNormal[1].cross(localAxis[1]); NxMat34 pose1 = capsule1->getGlobalPose(); NxVec3 axis1; pose1.M.getRow(1,axis1); NxMat34 pose2 = capsule2->getGlobalPose(); NxVec3 axis2; pose2.M.getRow(1,axis2); if (d6Desc.flags == NX_D6JOINT_SLERP_DRIVE) // Slerp Angular Drive { if (d6Desc.slerpDrive.driveType == NX_D6JOINT_DRIVE_POSITION) // Orientation Target { if ((axis2.x > 0.5) || (axis2.x < -0.5)) { if (axis2.x > 0.5) { NxQuat q; q.fromAngleAxis(-90, NxVec3(0,1,0)); d6Desc.driveOrientation = q; } else if (axis2.x < -0.5) { NxQuat q; q.fromAngleAxis(90, NxVec3(0,1,0)); d6Desc.driveOrientation = q; } d6Joint->loadFromDesc(d6Desc); } } else if (d6Desc.slerpDrive.driveType == NX_D6JOINT_DRIVE_VELOCITY) // Angular Velocity Target { if ((axis2.x > 0.5) || (axis2.x < -0.5)) { if (axis2.x > 0.5) { d6Desc.driveAngularVelocity = NxVec3(0,5,0); } else if (axis2.x < -0.5) { d6Desc.driveAngularVelocity = NxVec3(0,-5,0); } d6Joint->loadFromDesc(d6Desc); } } } else // Swing-twist Angular Drive { if (d6Desc.swingDrive.driveType == NX_D6JOINT_DRIVE_POSITION) // Orientation Target { if ((axis2.x > 0.5) || (axis2.x < -0.5)) { if (axis2.x > 0.5) { NxQuat q; q.fromAngleAxis(-90, NxVec3(0,1,0)); d6Desc.driveOrientation = q; } else if (axis2.x < -0.5) { NxQuat q; q.fromAngleAxis(90, NxVec3(0,1,0)); d6Desc.driveOrientation = q; } d6Joint->loadFromDesc(d6Desc); } } else if (d6Desc.swingDrive.driveType == NX_D6JOINT_DRIVE_VELOCITY) // Angular Velocity Target { if ((axis2.x > 0.5) || (axis2.x < -0.5)) { if (axis2.x > 0.5) { d6Desc.driveAngularVelocity = NxVec3(0,5,0); } else if (axis2.x < -0.5) { d6Desc.driveAngularVelocity = NxVec3(0,-5,0); } d6Joint->loadFromDesc(d6Desc); } } } } }
// 增加一辆车 NxVehicle* NxAllVehicle::addVehicle(const NxVec3& pos, VehicleInfo vinfo, std::string name, NxScene* nxScene, NxPhysicsSDK* nxPhysics) { NxVehicleDesc vehicleDesc; NxBoxShapeDesc boxShapes[2]; NxConvexShapeDesc carShape[2]; NxArray<NxVec3> points; NxArray<NxVec3> points2; NxReal halfWidth = vinfo.width / 2;//1.1529f; NxReal halfLength = vinfo.length / 2;//2.5278f; NxReal halfHeight = vinfo.height / 2; //0.6027; points.pushBack().set(halfLength,-halfHeight * 0.1f, 0); points.pushBack().set(halfLength * 0.7f, 0, 0); points.pushBack().set(0.2f * halfLength, halfHeight * 0.2f, 0); points.pushBack().set(-halfLength, halfHeight * 0.2f, 0); points.pushBack().set(0.1*halfLength, halfHeight * 0.2f, halfWidth * 0.9f); points.pushBack().set(0.1*halfLength, halfHeight * 0.2f,-halfWidth * 0.9f); points.pushBack().set(-0.8*halfLength, halfHeight * 0.2f, halfWidth * 0.9f); points.pushBack().set(-0.8*halfLength, halfHeight * 0.2f,-halfWidth * 0.9f); points.pushBack().set(halfLength * 0.9f,-halfHeight * 0.25f, halfWidth * 0.8f); points.pushBack().set(halfLength * 0.9f,-halfHeight * 0.25f,-halfWidth * 0.8f); points.pushBack().set(0,-halfHeight * 0.2f, halfWidth); points.pushBack().set(0,-halfHeight * 0.2f,-halfWidth); points.pushBack().set(-halfLength * 0.9f,-halfHeight * 0.2f, halfWidth * 0.9f); points.pushBack().set(-halfLength * 0.9f,-halfHeight * 0.2f,-halfWidth * 0.9f); points.pushBack().set(halfLength * 0.8f, -halfHeight, halfWidth * 0.79f); points.pushBack().set(halfLength * 0.8f, -halfHeight,-halfWidth * 0.79f); points.pushBack().set(-halfLength * 0.8f, -halfHeight, halfWidth * 0.79f); points.pushBack().set(-halfLength * 0.8f, -halfHeight,-halfWidth * 0.79f); for(NxU32 i = 2; i < 8; i++) { points2.pushBack(points[i]); } points2.pushBack().set(-0.5*halfLength, halfHeight*0.8f, halfWidth*0.7f); points2.pushBack().set(-0.5*halfLength, halfHeight*0.8f,-halfWidth*0.7f); points2.pushBack().set(-0.7*halfLength, halfHeight*0.7f, halfWidth*0.7f); points2.pushBack().set(-0.7*halfLength, halfHeight*0.7f,-halfWidth*0.7f); static NxConvexMeshDesc convexMesh; convexMesh.numVertices = points.size(); convexMesh.points = &(points[0].x); convexMesh.pointStrideBytes = sizeof(NxVec3); convexMesh.flags |= NX_CF_COMPUTE_CONVEX|NX_CF_USE_LEGACY_COOKER; MemoryWriteBuffer buf; bool status = NxCookConvexMesh(convexMesh, buf); if(status) { carShape[0].meshData = nxPhysics->createConvexMesh(MemoryReadBuffer(buf.data)); vehicleDesc.carShapes.pushBack(&carShape[0]); } static NxConvexMeshDesc convexMesh2; convexMesh2.numVertices = points2.size(); convexMesh2.points = (&points2[0].x); convexMesh2.pointStrideBytes = sizeof(NxVec3); convexMesh2.flags = NX_CF_COMPUTE_CONVEX|NX_CF_USE_LEGACY_COOKER; MemoryWriteBuffer buf2; status = NxCookConvexMesh(convexMesh2, buf2); if(status) { carShape[1].meshData = nxPhysics->createConvexMesh(MemoryReadBuffer(buf2.data)); vehicleDesc.carShapes.pushBack(&carShape[1]); } vehicleDesc.position = pos; vehicleDesc.mass = vinfo.mass;//1200;//monsterTruck ? 12000 : vehicleDesc.digitalSteeringDelta = vinfo.steerablity;//0.04f; vehicleDesc.steeringMaxAngle = vinfo.maxSteeringAngle; //30.f; vehicleDesc.motorForce = vinfo.maxAcceleraion * vinfo.mass;//3500.f;//monsterTruck?180.f: NxVehicleMotorDesc motorDesc; NxVehicleGearDesc gearDesc; NxReal wheelRadius = 0.4f; vehicleDesc.maxVelocity = vinfo.maxVelocity; //80.f;//(monsterTruck)?40.f:80.f; motorDesc.setToCorvette(); vehicleDesc.motorDesc = &motorDesc; gearDesc.setToCorvette(); vehicleDesc.gearDesc = &gearDesc; vehicleDesc.differentialRatio = 3.42f; wheelRadius = 0.3622f; vehicleDesc.centerOfMass.set(0,-0.7f,0); NxWheelDesc wheelDesc[4]; for(NxU32 i=0;i<4;i++) { wheelDesc[i].wheelApproximation = 10; //wheelDesc[i].wheelFlags |= NX_WF_BUILD_LOWER_HALF; wheelDesc[i].wheelRadius = wheelRadius;//(monsterTruck)?wheelRadius*3.f:wheelRadius; wheelDesc[i].wheelWidth = 0.1923f;//(monsterTruck)?0.3f:0.1923f; wheelDesc[i].wheelSuspension = 0.2f;//(monsterTruck)?0.6f:0.2f; wheelDesc[i].springRestitution = 7000;//monsterTruck?(crovette?5000:4000):7000; wheelDesc[i].springDamping = 800; wheelDesc[i].springBias = 0.0f; // 设为1.0后居然会出错!!!!!!!! //wheelDesc[i].maxHandBraking = 1.f; //monsterTruck?0.5f:1.f; wheelDesc[i].inverseWheelMass = 4.0f / vinfo.maxAcceleraion; // 换算成动力 wheelDesc[i].frictionToFront = 1.f; wheelDesc[i].frictionToSide = 2.f; vehicleDesc.carWheels.pushBack(&wheelDesc[i]); } NxReal heightPos = -0.3622f; //(monsterTruck)?1.f: wheelDesc[0].position.set( 1.02f, heightPos, 1.26); wheelDesc[1].position.set( 1.12f, heightPos,-1.54); wheelDesc[2].position.set(-1.02f, heightPos, 1.26); wheelDesc[3].position.set(-1.12f, heightPos,-1.54); NxU32 flags = NX_WF_BUILD_LOWER_HALF; wheelDesc[0].wheelFlags |= ((vinfo.driven==FrontDriven)?NX_WF_ACCELERATED:0) | NX_WF_STEERABLE_INPUT | flags; wheelDesc[1].wheelFlags |= ((vinfo.driven==FrontDriven)?NX_WF_ACCELERATED:0) | NX_WF_STEERABLE_INPUT | flags; wheelDesc[2].wheelFlags |= ((vinfo.driven==BackDriven)?NX_WF_ACCELERATED:0) | NX_WF_AFFECTED_BY_HANDBRAKE | flags; wheelDesc[3].wheelFlags |= ((vinfo.driven==BackDriven)?NX_WF_ACCELERATED:0) | NX_WF_AFFECTED_BY_HANDBRAKE | flags; vehicleDesc.steeringSteerPoint.set(1.8, 0, 0); vehicleDesc.steeringTurnPoint.set(-1.5, 0, 0); NxVehicle* vehicle = NxVehicle::createVehicle(nxScene, &vehicleDesc, name); NxQuat q; // 少转过90度,可能会有问题 q.fromAngleAxis(90.0f, NxVec3(0.0f, 1.0f, 0.0f)); vehicle->getActor()->setGlobalOrientationQuat(q); vehicle->mVInfo = vinfo; vehicle->setOilAmount(vinfo.oilAmount); // 加到队列中 mAllVehicle.pushBack(vehicle); mIsLive.pushBack(0); // miUserVehicle = mAllVehicle.size() - 1; return vehicle; }
/*********************************************************** get object rotation on a single angle ***********************************************************/ float LbaQuaternion::GetRotationSingleAngle() { NxQuat current; current.setXYZW(X, Y, Z, W); return current.getAngle(); }
void pWheel2::_tick(float dt) { NxWheelShape *wShape = getWheelShape(); if (!wShape) return; NxVec3 _localVelocity; bool _breaking=false; ////////////////////////////////////////////////////////////////////////// // // // NxWheelContactData wcd; NxShape* contactShape = wShape->getContact(wcd); if (contactShape) { NxVec3 relativeVelocity; if ( !contactShape->getActor().isDynamic()) { relativeVelocity = getActor()->getLinearVelocity(); } else { relativeVelocity = getActor()->getLinearVelocity() - contactShape->getActor().getLinearVelocity(); } NxQuat rotation = getActor()->getGlobalOrientationQuat(); _localVelocity = relativeVelocity; rotation.inverseRotate(_localVelocity); _breaking = false; //NxMath::abs(_localVelocity.z) < ( 0.1 ); // wShape->setAxleSpeed() } float rollAngle = getWheelRollAngle(); rollAngle+=wShape->getAxleSpeed() * (dt* 0.01f); //rollAngle+=wShape->getAxleSpeed() * (1.0f/60.0f /*dt* 0.01f*/); while (rollAngle > NxTwoPi) //normally just 1x rollAngle-= NxTwoPi; while (rollAngle< -NxTwoPi) //normally just 1x rollAngle+= NxTwoPi; setWheelRollAngle(rollAngle); NxMat34& wheelPose = wShape->getGlobalPose(); NxReal stravel = wShape->getSuspensionTravel(); NxReal radius = wShape->getRadius(); //have ground contact? if( contactShape && wcd.contactPosition <= (stravel + radius) ) { wheelPose.t = NxVec3( wheelPose.t.x, wcd.contactPoint.y + getRadius(), wheelPose.t.z ); } else { wheelPose.t = NxVec3( wheelPose.t.x, wheelPose.t.y - getSuspensionTravel(), wheelPose.t.z ); } float rAngle = getWheelRollAngle(); float steer = wShape->getSteerAngle(); NxVec3 p0; NxVec3 dir; /* getWorldSegmentFast(seg); seg.computeDirection(dir); dir.normalize(); */ NxReal r = wShape->getRadius(); NxReal st = wShape->getSuspensionTravel(); NxReal steerAngle = wShape->getSteerAngle(); p0 = wheelPose.t; //cast from shape origin wheelPose.M.getColumn(1, dir); dir = -dir; //cast along -Y. NxReal castLength = r + st; //cast ray this long NxMat33 rot, axisRot, rollRot; rot.rotY( wShape->getSteerAngle() ); axisRot.rotY(0); rollRot.rotX(rAngle); wheelPose.M = rot * wheelPose.M * axisRot * rollRot; setWheelPose(wheelPose); }
void ParticlePhysics::update() { if(!data->physics) return; data->actorBaseList.clear(); data->fluidBaseList.clear(); // Update physics actors { for(PhysicsActorList::iterator it = data->physicsActorList.begin(); it != data->physicsActorList.end(); ++it) { PhysicsActor *actor = *it; if(!actor->actor) continue; /* if(actor->actor) { VC3 velocity; actor->actor->getVelocity(velocity); float len = velocity.GetLength(); if(len > 1) { velocity /= len; actor->actor->setVelocity(velocity); } } */ #ifndef PHYSX_GRAVITY if(actor->force.GetSquareLength() > 0.01f) { if(!actor->forceUpdate && ++actor->sleepCounter % 10 == 0) { VC3 currentPos; actor->getPosition(currentPos); VC3 currentAngular; actor->actor->getAngularVelocity(currentAngular); if( currentPos.GetSquareRangeTo(actor->lastPosition1) < 0.00001f || currentAngular.GetSquareRangeTo(actor->lastAngular1) < 0.00001f || currentPos.GetSquareRangeTo(actor->lastPosition2) < 0.00001f || currentAngular.GetSquareRangeTo(actor->lastAngular2) < 0.00001f) { if(!actor->actor->isSleeping()) actor->actor->putToSleep(); } actor->lastPosition2 = actor->lastPosition1; actor->lastAngular2 = actor->lastAngular1; actor->lastPosition1 = currentPos; actor->lastAngular1 = currentAngular; } if(actor->forceUpdate || !actor->actor->isSleeping()) actor->actor->addVelocityChange(actor->force); actor->force = VC3(); } #else if(actor->forceUpdate) { VC3 base; actor->actor->getVelocity(base); VC3 newForce = base; newForce += actor->force; float len = newForce.GetSquareLength(); if(len > MAX_VELOCITY * MAX_VELOCITY) { len = sqrtf(len); newForce /= len; newForce *= MAX_VELOCITY; } newForce -= base; actor->actor->addVelocityChange(newForce); { QUAT rot; rotateToward(VC3(0, 1.f, 0), actor->force.GetNormalized(), rot); VC3 test(rot.x, rot.y, rot.z); test.x += ((float)(rand() - RAND_MAX/2) / (float)RAND_MAX/2); test.z += ((float)(rand() - RAND_MAX/2) / (float)RAND_MAX/2); if(test.GetSquareLength() > 0.001f) test.Normalize(); test *= 2.f; actor->actor->setAngularVelocity(test * 2.f); } actor->force = VC3(); } #endif actor->forceUpdate = false; } physics::resetFluidParticleCount(); for(FluidActorList::iterator it = data->fluidActorList.begin(); it != data->fluidActorList.end(); ++it) { PhysicsFluid *fluid = *it; if(!fluid->fluid) continue; if(fluid->addAmount) { fluid->fluid->addParticles(&fluid->buffer[0], fluid->addAmount); fluid->buffer.clear(); fluid->addAmount = 0; } fluid->fluid->setAcceleration(fluid->acceleration); fluid->fluid->update(); //fluid->renderFlag = false; } } /* // Meshes { for(MeshList::iterator it = data->meshList.begin(); it != data->meshList.end(); ++it) { MeshData &convex = *it; boost::shared_ptr<PhysicsMesh> mesh = convex.mesh.lock(); if(!mesh) continue; filesystem::FB_FILE *fp = filesystem::fb_fopen(convex.filename.c_str(), "rb"); if(!fp) { physics::Cooker cooker; cooker.cookApproxConvex(convex.filename.c_str(), convex.object); } else filesystem::fb_fclose(fp); mesh->mesh = data->physics->createConvexMesh(convex.filename.c_str()); } data->meshList.clear(); } */ // Actors { /* if(actorList.size() + physicsActorList.size() > MAX_ACTOR_AMOUNT) { boost::shared_ptr<PhysicsActor> nullActor; return nullActor; } */ bool sort = false; int createAmount = data->actorList.size(); if(createAmount > data->maxParticleSpawnAmount) { createAmount = data->maxParticleSpawnAmount; sort = true; } if(createAmount + data->createdActors > data->maxParticleAmount) { sort = true; createAmount = data->maxParticleAmount - data->createdActors; } if(sort) std::sort(data->actorList.begin(), data->actorList.end(), ActorListSorter()); // For collision test #ifdef PHYSX_SPAWN_TEST std::vector<BoxStruct> previousBoxes; #endif int index = 0; for(ActorList::iterator it = data->actorList.begin(); it != data->actorList.end(); ++it) { ActorData &convex = *it; if(convex.createDelayCounter++ >= MAX_WAIT_FOR_CREATE) continue; boost::shared_ptr<PhysicsActor> actor = convex.actor.lock(); if(!actor) continue; boost::shared_ptr<PhysicsMesh> mesh = convex.mesh.lock(); if(!mesh) continue; /* //VC3 boxCenter = mesh->localPosition + actor->position; VC3 boxCenter = mesh->localPosition; actor->rotation.RotateVector(boxCenter); boxCenter += actor->position; // Test to previous tick physics if(data->physics->checkOverlapOBB(boxCenter, mesh->size, actor->rotation, physics::PhysicsLib::CollisionStatic)) { convex.actor.reset(); convex.mesh.reset(); continue; } */ #ifdef PHYSX_SPAWN_TEST BoxStruct currentBox; currentBox.center.set(boxCenter.x, boxCenter.y, boxCenter.z); currentBox.extents.set(mesh->size.x, mesh->size.y, mesh->size.z); QUAT r = actor->rotation.GetInverse(); NxQuat quat; quat.setXYZW(r.x, r.y, r.z, r.w); currentBox.rotation.fromQuat(quat); // Test to previous tick physics if(data->physics->checkOverlapOBB(boxCenter, mesh->size, actor->rotation)) continue; bool hit = false; for(unsigned int i = 0; i < previousBoxes.size(); ++i) { const BoxStruct &b = previousBoxes[i]; if(NxBoxBoxIntersect(currentBox.extents, currentBox.center, currentBox.rotation, b.extents, b.center, b.rotation, true)) { hit = true; break; } } if(hit) continue; #endif // Don't create too many particles if(index++ >= createAmount) break; /* boost::shared_ptr<physics::ConvexActor> convexActor = data->physics->createConvexActor(mesh->mesh, actor->position); if(convexActor) { convexActor->setRotation(actor->rotation); convexActor->setVelocity(convex.velocity); convexActor->setAngularVelocity(convex.angularVelocity); convexActor->setMass(convex.mass); convexActor->setCollisionGroup(2); //convexActor->enableFeature(physics::ActorBase::DISABLE_GRAVITY, true); actor->actor = convexActor; } */ boost::shared_ptr<physics::BoxActor> boxActor = data->physics->createBoxActor(mesh->size, actor->position, mesh->localPosition); if(boxActor) { ++data->createdActors; boxActor->setRotation(actor->rotation); boxActor->setVelocity(convex.velocity); boxActor->setAngularVelocity(convex.angularVelocity); boxActor->setMass(convex.mass); boxActor->setCollisionGroup(convex.collisionGroup); #ifndef PHYSX_GRAVITY boxActor->enableFeature(physics::ActorBase::DISABLE_GRAVITY, true); #endif boxActor->setIntData(convex.soundGroup); actor->actor = boxActor; #ifdef PHYSX_SPAWN_TEST previousBoxes.push_back(currentBox); #endif } } int size = data->actorList.size(); for(int i = index; i < size; ++i) { data->actorList[i].createDelayCounter++; } if(index < size) { for(int i = 0; i < size - index; ++i) data->actorList[i] = data->actorList[i + index]; data->actorList.resize(size - index); } else data->actorList.clear(); } // Fluids { for(FluidList::iterator it = data->fluidList.begin(); it != data->fluidList.end(); ++it) { FluidData &fluidData = *it; boost::shared_ptr<PhysicsFluid> fluid = fluidData.fluid.lock(); if(!fluid) continue; boost::shared_ptr<physics::Fluid> fluidActor = data->physics->createFluid(physics::PhysicsLib::FluidType(fluidData.type), fluidData.maxParticles, fluidData.fluidStaticRestitution, fluidData.fluidStaticAdhesion, fluidData.fluidDynamicRestitution, fluidData.fluidDynamicAdhesion, fluidData.fluidDamping, fluidData.fluidStiffness, fluidData.fluidViscosity, fluidData.fluidKernelRadiusMultiplier, fluidData.fluidRestParticlesPerMeter, fluidData.fluidRestDensity, fluidData.fluidMotionLimit, fluidData.fluidPacketSizeMultiplier, fluidData.collisionGroup); fluid->fluid = fluidActor; fluid->lib = data; } data->fluidList.clear(); } }
void TriPod::attach(IAgriDevice *device) { if(m_attachedTrailer) return; if(m_attachedDevice) return; m_attachedDevice = device; Vec3 transformedDeviceConnectorTop; Vec3 transformedDeviceConnectorBottom; Vec3 transformedTriPodPos; Vec3 diff = m_triPodDimms->posTopPodDeviceConnector - m_triPodDimms->posTopPodTractorConnector; Vec3 transDiff; D3DXVec3TransformCoord(&transDiff, &diff, &m_matTop); if(m_frontPod) { D3DXVec3TransformCoord(&transformedDeviceConnectorTop, &m_triPodDimms->posTopPodTractorConnector, &m_matTop); D3DXVec3TransformCoord(&transformedDeviceConnectorBottom, &m_triPodDimms->posBottomPodTractorConnector, &m_matBottom); } else { D3DXVec3TransformCoord(&transformedDeviceConnectorTop, &m_triPodDimms->posTopPodDeviceConnector, &m_matTop); D3DXVec3TransformCoord(&transformedDeviceConnectorBottom, &m_triPodDimms->posBottomPodDeviceConnector, &m_matBottom); } NxMat34 pose = m_vehicle->getVehicleController()->getActor()->getGlobalPose(); if(m_frontPod) { Mat mat; D3DXMatrixRotationY(&mat, D3DX_PI); NxMat33 mat33; NxQuat quat; pose.M.toQuat(quat); quat.normalize(); NxReal angle; NxVec3 axis; quat.getAngleAxis(angle, axis); axis.x *= -1; axis.z *= -1; //quat.w *= -1; quat.fromAngleAxis(angle, axis); pose.M.fromQuat(quat); pose = NxMat34(NxMat33(NxVec3(mat._11, mat._12, mat._13), NxVec3(mat._21, mat._22, mat._23), NxVec3(mat._31, mat._32, mat._33)), NxVec3(0, 0, 0)) * pose; } NxVec3 trans = NxVec3(m_vehicle->getVehicleController()->getForwardVec() * -10); pose.t.x = pose.t.x + trans.x; pose.t.y = pose.t.y + trans.y; pose.t.z = pose.t.z + trans.z; m_attachedDevice->getActor()->setGlobalPose(pose); m_attachedDevice->update(); transformedTriPodPos = transformedDeviceConnectorTop - m_triPodDimms->posTopPod; Vec3 move = transformedTriPodPos - m_attachedDevice->getTriPodPos(); m_attachedDevice->getActor()->setGlobalPosition(m_attachedDevice->getActor()->getGlobalPosition() + NxVec3(move)); m_attachedDevice->update(); //NxRevoluteJointDesc revDescTop; //revDescTop.actor[0] = m_actorTop; //revDescTop.actor[1] = m_attachedDevice->getActor(); //revDescTop.localNormal[0] = NxVec3(0, 1, 0); //revDescTop.localNormal[1] = NxVec3(0, 1, 0); //revDescTop.setGlobalAxis(NxVec3(0, 0, 1)); //The direction of the axis the bodies revolve around. //revDescTop.setGlobalAnchor(NxVec3(m_attachedDevice->getTriPodPos() + m_triPodDimms->posTopPod)); //Reference point that the axis passes through. //m_jointTopPodDevice = (NxRevoluteJoint*)core.dynamics->getScene()->createJoint(revDescTop); Vec3 leftPos = Vec3(0, 0, m_triPodDimms->width/2); Mat temp; m_actorTop->getGlobalPose().getColumnMajor44((NxF32*)&temp); temp._41 = 0; temp._42 = 0; temp._43 = 0; D3DXVec3TransformCoord(&leftPos, &leftPos, &temp); //NxRevoluteJointDesc revDescBottomLeft; //revDescBottomLeft.actor[0] = m_actorBottom; //revDescBottomLeft.actor[1] = m_attachedDevice->getActor(); //revDescBottomLeft.localNormal[0] = NxVec3(0, 1, 0); //revDescBottomLeft.localNormal[1] = NxVec3(0, 1, 0); //revDescBottomLeft.setGlobalAxis(NxVec3(0, 0, 1)); //The direction of the axis the bodies revolve around. //revDescBottomLeft.setGlobalAnchor(NxVec3(m_attachedDevice->getTriPodPos() + m_triPodDimms->posBottomPod + leftPos)); //Reference point that the axis passes through. //m_jointBottomLeftPodDevice = (NxRevoluteJoint*)core.dynamics->getScene()->createJoint(revDescBottomLeft); //NxRevoluteJointDesc revDescBottomRight; //revDescBottomRight.actor[0] = m_actorBottom; //revDescBottomRight.actor[1] = m_attachedDevice->getActor(); //revDescBottomRight.localNormal[0] = NxVec3(0, 1, 0); //revDescBottomRight.localNormal[1] = NxVec3(0, 1, 0); //revDescBottomRight.setGlobalAxis(NxVec3(0, 0, 1)); //The direction of the axis the bodies revolve around. //revDescBottomRight.setGlobalAnchor(NxVec3(m_attachedDevice->getTriPodPos() + m_triPodDimms->posBottomPod - leftPos)); //Reference point that the axis passes through. //m_jointBottomRightPodDevice = (NxRevoluteJoint*)core.dynamics->getScene()->createJoint(revDescBottomRight); //if(m_f NxD6JointDesc d6Desc; d6Desc.actor[0] = m_actorTop; d6Desc.actor[1] = m_attachedDevice->getActor(); d6Desc.localNormal[0] = NxVec3(0, 1, 0); d6Desc.localNormal[1] = NxVec3(0, 1, 0); d6Desc.setGlobalAxis(NxVec3(1, 0, 0)); //The direction of the axis the bodies revolve around. d6Desc.setGlobalAnchor(NxVec3(m_attachedDevice->getTriPodPos() + m_triPodDimms->posTopPod)); d6Desc.twistMotion = NX_D6JOINT_MOTION_FREE; d6Desc.swing1Motion = NX_D6JOINT_MOTION_FREE; d6Desc.swing2Motion = NX_D6JOINT_MOTION_FREE; d6Desc.xMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc.yMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc.zMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc.projectionMode = NX_JPM_NONE; d6Desc.projectionMode = NX_JPM_POINT_MINDIST; d6Desc.projectionDistance = 0.01f; m_jointTopPodDevice = (NxD6Joint*)core.dynamics->getScene()->createJoint(d6Desc); NxD6JointDesc d6Desc1; d6Desc1.actor[0] = m_actorBottom; d6Desc1.actor[1] = m_attachedDevice->getActor(); d6Desc1.localNormal[0] = NxVec3(0, 1, 0); d6Desc1.localNormal[1] = NxVec3(0, 1, 0); d6Desc1.setGlobalAxis(NxVec3(1, 0, 0)); //The direction of the axis the bodies revolve around. d6Desc1.setGlobalAnchor(NxVec3((m_attachedDevice->getTriPodPos() + m_triPodDimms->posBottomPod) + leftPos)); d6Desc1.twistMotion = NX_D6JOINT_MOTION_FREE; d6Desc1.swing1Motion = NX_D6JOINT_MOTION_FREE; d6Desc1.swing2Motion = NX_D6JOINT_MOTION_FREE; d6Desc1.xMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc1.yMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc1.zMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc1.projectionMode = NX_JPM_NONE; d6Desc1.projectionMode = NX_JPM_POINT_MINDIST; d6Desc1.projectionDistance = 0.01f; m_jointBottomLeftPodDevice = (NxD6Joint*)core.dynamics->getScene()->createJoint(d6Desc1); NxD6JointDesc d6Desc2; d6Desc2.actor[0] = m_actorBottom; d6Desc2.actor[1] = m_attachedDevice->getActor(); d6Desc2.localNormal[0] = NxVec3(0, 1, 0); d6Desc2.localNormal[1] = NxVec3(0, 1, 0); d6Desc2.setGlobalAxis(NxVec3(1, 0, 0)); //The direction of the axis the bodies revolve around. d6Desc2.setGlobalAnchor(NxVec3((m_attachedDevice->getTriPodPos() + m_triPodDimms->posBottomPod) - leftPos)); d6Desc2.twistMotion = NX_D6JOINT_MOTION_FREE; d6Desc2.swing1Motion = NX_D6JOINT_MOTION_FREE; d6Desc2.swing2Motion = NX_D6JOINT_MOTION_FREE; d6Desc2.xMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc2.yMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc2.zMotion = NX_D6JOINT_MOTION_LOCKED; d6Desc2.projectionMode = NX_JPM_NONE; d6Desc2.projectionMode = NX_JPM_POINT_MINDIST; d6Desc2.projectionDistance = 0.01f; m_jointBottomRightPodDevice = (NxD6Joint*)core.dynamics->getScene()->createJoint(d6Desc2); return; }