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);
			    }
			}
		}
	}
}
Exemple #7
0
// 增加一辆车
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;
}
Exemple #8
0
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();
}