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); }
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; }
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); }
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)); }
// 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; }
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; }
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(); }