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);
}
Exemple #5
0
NxQuat getFrom(VxQuaternion source)
{
	NxQuat result;
	result.setx(-source.x);
	result.sety(-source.y);
	result.setz(-source.z);
	result.setw(source.w);
	return result;
}
Exemple #6
0
/***********************************************************
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);
}
Exemple #7
0
/***********************************************************
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;
		}
Exemple #9
0
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);
}
Exemple #12
0
 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));
}
Exemple #14
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);
}
Exemple #15
0
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;
}
Exemple #16
0
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);
			    }
			}
		}
	}
}
Exemple #21
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 #22
0
/***********************************************************
get object rotation on a single angle
***********************************************************/
float LbaQuaternion::GetRotationSingleAngle()
{
	NxQuat current;
	current.setXYZW(X, Y, Z, W);
	return current.getAngle();
}
Exemple #23
0
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();
	}
}
Exemple #25
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;
}