예제 #1
0
void Vehicle::InitPhysics()
{
	hkpRigidBody* rigidBody = HK_NULL;

	// Get HK Rigid Body from the entity
	{
		vHavokRigidBody *vRigidBody = (vHavokRigidBody *)m_chassis->Components().GetComponentOfType("vHavokRigidBody");

		// Check vHavokRigidBody creation
		VASSERT(vRigidBody != NULL);

		// Get rigid body
		rigidBody = vRigidBody->GetHkRigidBody();
		VASSERT(rigidBody != HK_NULL);
	}

	// Get World
	m_world = rigidBody->getWorld();
	m_world->markForWrite();

	// Create vehicle instance
	{
		// Setup rigid body
		rigidBody->setMotionType(hkpMotion::MOTION_BOX_INERTIA);

		// Specify control axis for our vehicle
		hkVector4      up( 0,  0,  1);
		hkVector4 forward( 1,  0,  0);
		hkVector4   right( 0, -1,  0);
		VehicleSetup setup(up, forward, right);

		m_instance = new hkpVehicleInstance(rigidBody);

		setup.buildVehicle(m_world, *m_instance);
		m_instance->m_wheelCollide->addToWorld(m_world);

		// Set collision filters
		m_instance->getChassis()->setCollisionFilterInfo(hkpGroupFilter::calcFilterInfo(CHASSIS_LAYER, 0));
		m_instance->m_wheelCollide->setCollisionFilterInfo(hkpGroupFilter::calcFilterInfo(WHEEL_LAYER, 0));

		m_world->addAction(m_instance);
	}

	// Add reorient action
	{
		hkVector4 rotationAxis(1.0f, 0.0f, 0.0f); 	 
		hkVector4 upAxis(0.0f, 0.0f, 1.0f);
		m_reorientAction = new hkpReorientAction(rigidBody, rotationAxis, upAxis);
	}

	m_world->unmarkForWrite();
}
예제 #2
0
bool BillBoard::calculateBillbaordTransform()
{
    //Get camera world position
    auto camera = Camera::getVisitingCamera();
    const Mat4& camWorldMat = camera->getNodeToWorldTransform();
    
    //TODO: use math lib to calculate math lib Make it easier to read and maintain
    if (memcmp(_camWorldMat.m, camWorldMat.m, sizeof(float) * 16) != 0 || memcmp(_mvTransform.m, _modelViewTransform.m, sizeof(float) * 16) != 0 || _modeDirty || true)
    {
        //Rotate based on anchor point
        Vec3 anchorPoint(_anchorPointInPoints.x , _anchorPointInPoints.y , 0.0f);
        Mat4 localToWorld = _modelViewTransform;
        localToWorld.translate(anchorPoint);
        
        //Decide billboard mode
        Vec3 camDir;
        switch (_mode)
        {
            case Mode::VIEW_POINT_ORIENTED:
                camDir.set(localToWorld.m[12] - camWorldMat.m[12], localToWorld.m[13] - camWorldMat.m[13], localToWorld.m[14] - camWorldMat.m[14]);
                break;
            case Mode::VIEW_PLANE_ORIENTED:
                camWorldMat.transformVector(Vec3(0.0f, 0.0f, -1.0f), &camDir);
                break;
            default:
                CCASSERT(false, "invalid billboard mode");
                break;
        }
        _modeDirty = false;
        
        if (camDir.length() < MATH_TOLERANCE)
        {
            camDir.set(camWorldMat.m[8], camWorldMat.m[9], camWorldMat.m[10]);
        }
        camDir.normalize();
        
        Quaternion rotationQuaternion;
        this->getNodeToWorldTransform().getRotation(&rotationQuaternion);
        
        Mat4 rotationMatrix;
        rotationMatrix.setIdentity();

        Vec3 upAxis(rotationMatrix.m[4],rotationMatrix.m[5],rotationMatrix.m[6]);
        Vec3 x, y;
        camWorldMat.transformVector(upAxis, &y);
        Vec3::cross(camDir, y, &x);
        x.normalize();
        Vec3::cross(x, camDir, &y);
        y.normalize();
        
        float xlen = sqrtf(localToWorld.m[0] * localToWorld.m[0] + localToWorld.m[1] * localToWorld.m[1] + localToWorld.m[2] * localToWorld.m[2]);
        float ylen = sqrtf(localToWorld.m[4] * localToWorld.m[4] + localToWorld.m[5] * localToWorld.m[5] + localToWorld.m[6] * localToWorld.m[6]);
        float zlen = sqrtf(localToWorld.m[8] * localToWorld.m[8] + localToWorld.m[9] * localToWorld.m[9] + localToWorld.m[10] * localToWorld.m[10]);
        
        Mat4 billboardTransform;
        
        billboardTransform.m[0] = x.x * xlen; billboardTransform.m[1] = x.y * xlen; billboardTransform.m[2] = x.z * xlen;
        billboardTransform.m[4] = y.x * ylen; billboardTransform.m[5] = y.y * ylen; billboardTransform.m[6] = y.z * ylen;
        billboardTransform.m[8] = -camDir.x * zlen; billboardTransform.m[9] = -camDir.y * zlen; billboardTransform.m[10] = -camDir.z * zlen;
        billboardTransform.m[12] = localToWorld.m[12]; billboardTransform.m[13] = localToWorld.m[13]; billboardTransform.m[14] = localToWorld.m[14];
        
        billboardTransform.translate(-anchorPoint);
        _mvTransform = _modelViewTransform = billboardTransform;
        
        _camWorldMat = camWorldMat;
        
        return true;
    }
    
    return false;
}
	void MakeKukaRobot(DemoEntityManager* const scene, DemoEntity* const model)
	{
		m_kinematicSolver = NewtonCreateInverseDynamics(scene->GetNewton());

		NewtonBody* const baseFrameBody = CreateBodyPart(model, armRobotConfig[0]);
		void* const baseFrameNode = NewtonInverseDynamicsAddRoot(m_kinematicSolver, baseFrameBody);
		NewtonBodySetMassMatrix(baseFrameBody, 0.0f, 0.0f, 0.0f, 0.0f);	

		dMatrix boneAligmentMatrix(
			dVector(0.0f, 1.0f, 0.0f, 0.0f),
			dVector(0.0f, 0.0f, 1.0f, 0.0f),
			dVector(1.0f, 0.0f, 0.0f, 0.0f),
			dVector(0.0f, 0.0f, 0.0f, 1.0f));

		int stackIndex = 0;
		DemoEntity* childEntities[32];
		void* parentBones[32];
		for (DemoEntity* child = model->GetChild(); child; child = child->GetSibling()) {
			parentBones[stackIndex] = baseFrameNode;
			childEntities[stackIndex] = child;
			stackIndex++;
		}

		dKukaEffector* effector = NULL;
		const int partCount = sizeof(armRobotConfig) / sizeof(armRobotConfig[0]);
		while (stackIndex) {
			stackIndex--;
			DemoEntity* const entity = childEntities[stackIndex];
			void* const parentJoint = parentBones[stackIndex];

			const char* const name = entity->GetName().GetStr();
			for (int i = 0; i < partCount; i++) {
				if (!strcmp(armRobotConfig[i].m_partName, name)) {

					if (strstr(name, "bone")) {
						// add a bone and all it children
						dMatrix matrix;
						NewtonBody* const limbBody = CreateBodyPart(entity, armRobotConfig[i]);
						NewtonBodyGetMatrix(limbBody, &matrix[0][0]);

						NewtonBody* const parentBody = NewtonInverseDynamicsGetBody(m_kinematicSolver, parentJoint);
						dCustomInverseDynamics* const rotatingColumnHinge = new dCustomInverseDynamics(boneAligmentMatrix * matrix, limbBody, parentBody);
						rotatingColumnHinge->SetJointTorque(armRobotConfig[i].m_mass * DEMO_GRAVITY * 50.0f);
						rotatingColumnHinge->SetTwistAngle(armRobotConfig[i].m_minLimit * dDegreeToRad, armRobotConfig[i].m_maxLimit * dDegreeToRad);
						void* const limbJoint = NewtonInverseDynamicsAddChildNode(m_kinematicSolver, parentJoint, rotatingColumnHinge->GetJoint());

						for (DemoEntity* child = entity->GetChild(); child; child = child->GetSibling()) {
							parentBones[stackIndex] = limbJoint;
							childEntities[stackIndex] = child;
							stackIndex++;
						}
					} else if (strstr(name, "effector")) {
						// add effector
						dMatrix gripperMatrix(entity->CalculateGlobalMatrix());
						effector = new dKukaEffector(m_kinematicSolver, parentJoint, baseFrameBody, gripperMatrix);
						effector->SetAsThreedof();
						effector->SetLinearSpeed(2.0f);
						effector->SetMaxLinearFriction(armRobotConfig[i].m_mass * DEMO_GRAVITY * 50.0f);
					}
					break;
				}
			}
		}

		// create the Animation tree for manipulation 
		DemoEntity* const effectoBone = model->Find("effector_arm");
		dMatrix baseFrameMatrix(model->GetCurrentMatrix());
		dMatrix effectorLocalMatrix(effectoBone->CalculateGlobalMatrix(model));

		dVector upAxis(baseFrameMatrix.UnrotateVector(dVector(0.0f, 1.0f, 0.0f, 1.0f)));
		dVector planeAxis(baseFrameMatrix.UnrotateVector(dVector(0.0f, 0.0f, 1.0f, 1.0f)));

		dEffectorTreeFixPose* const fixPose = new dEffectorTreeFixPose(baseFrameBody);
		m_inputModifier = new dEffectorTreeInputModifier(fixPose, upAxis, planeAxis);
		m_animTreeNode = new dEffectorTreeRoot(baseFrameBody, m_inputModifier);

		// set base pose
		dEffectorTreeInterface::dEffectorTransform frame;
		frame.m_effector = effector;
		frame.m_posit = effectorLocalMatrix.m_posit;
		frame.m_rotation = dQuaternion(effectorLocalMatrix);

		fixPose->GetPose().Append(frame);
		m_animTreeNode->GetPose().Append(frame);

		NewtonInverseDynamicsEndBuild(m_kinematicSolver);
	}
예제 #4
0
TruckDemo::TruckDemo(hkDemoEnvironment* env)
:	CarDemo(env, false, 4, 1)
{
	m_world->lock();
	{
		//
		// Create vehicle's chassis shape.
		//
		hkpConvexVerticesShape* chassisShape = HK_NULL;
		{
			hkReal xSize = 1.9f;
			hkReal xSizeFrontTop = 0.7f;
			hkReal xSizeFrontMid = 1.6f;
			hkReal ySize = 0.9f;
			hkReal ySizeMid = ySize - 0.7f;
			hkReal zSize = 1.0f;

			//hkReal xBumper = 1.9f;
			//hkReal yBumper = 0.35f;
			//hkReal zBumper = 1.0f;

			// 16 = 4 (size of "each float group", 3 for x,y,z, 1 for padding) * 4 (size of float).
			int stride = sizeof(float) * 4;
			
			{
				int numVertices = 10;

				float vertices[] = { 
					xSizeFrontTop, ySize, zSize, 0.0f,	// v0
					xSizeFrontTop, ySize, -zSize, 0.0f,	// v1
					xSize, -ySize, zSize, 0.0f,			// v2
					xSize, -ySize, -zSize, 0.0f,		// v3
					-xSize, ySize, zSize, 0.0f,			// v4
					-xSize, ySize, -zSize, 0.0f,		// v5
					-xSize, -ySize, zSize, 0.0f,		// v6
					-xSize, -ySize, -zSize, 0.0f,		// v7
					xSizeFrontMid, ySizeMid, zSize, 0.0f,	// v8
					xSizeFrontMid, ySizeMid, -zSize, 0.0f,	// v9
				};
				
				//
				// SHAPE CONSTRUCTION.
				//
				{
					hkStridedVertices stridedVerts;
					{
						stridedVerts.m_numVertices = numVertices;
						stridedVerts.m_striding = stride;
						stridedVerts.m_vertices = vertices;
					}
					chassisShape = new hkpConvexVerticesShape(stridedVerts);
				}
			}
		}

		createDisplayWheels(0.5f, 0.3f);

		for (int vehicleId = 0; vehicleId < m_numVehicles; vehicleId++)
		{
			//
			// Create the vehicle.
			//
			{
				//
				// Create the chassis body.
				//
				hkpRigidBody* chassisRigidBody;
				{
					hkpRigidBodyCinfo chassisInfo;

					chassisInfo.m_mass = 5000.0f;	
					chassisInfo.m_shape = chassisShape;
					chassisInfo.m_friction = 0.8f;
					chassisInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA;
					// Position chassis on the ground.
					chassisInfo.m_position.set(-10.0f, -4.5f, vehicleId * 5.0f);
					hkpInertiaTensorComputer::setShapeVolumeMassProperties(chassisInfo.m_shape,
																			chassisInfo.m_mass,
																			chassisInfo);

					chassisRigidBody = new hkpRigidBody(chassisInfo);
				}

				TruckSetup tsetup;
				m_vehicles[vehicleId].m_vehicle = createVehicle( tsetup, chassisRigidBody);
				m_vehicles[vehicleId].m_lastRPM = 0.0f;

				HK_SET_OBJECT_COLOR((hkUlong)chassisRigidBody->getCollidable(), 0x80ff8080);

				// This hkpAction flips the car upright if it turns over. 	 
				if (vehicleId == 0) 	 
				{ 	 
					hkVector4 rotationAxis(1.0f, 0.0f, 0.0f); 	 
					hkVector4 upAxis(0.0f, 1.0f, 0.0f); 	 
					hkReal strength = 8.0f; 	 
					m_reorientAction = new hkpReorientAction(chassisRigidBody, rotationAxis, upAxis, strength); 	 
				}

				chassisRigidBody->removeReference();
			}
		}
		chassisShape->removeReference();
	}

	//
	// Create the camera.
	//
	{
		VehicleApiUtils::createCamera( m_camera );
	}
	m_world->unlock();
}
예제 #5
0
VehicleManagerDemo::VehicleManagerDemo( hkDemoEnvironment* env, hkBool createWorld, int numWheels, int numVehicles )
:	hkDefaultPhysicsDemo( env )
{
	const MTVehicleRayCastDemoVariant& variant = g_MTVehicleRayCastDemoVariants[m_variantId];

	m_bootstrapIterations = 150;

	numVehicles = 50;
	m_numVehicles = numVehicles;
	m_numWheels = numWheels;

	m_vehicles.setSize( m_numVehicles );

	setUpWorld();

	if (!createWorld)
	{
		return;
	}

	m_world->lock();

	//
	// Create a vehicle manager and a vehicle setup object.
	//
	VehicleSetup* vehicleSetup;
	if ( variant.m_demoType == MTVehicleRayCastDemoVariant::SINGLETHREADED_RAY_CAST || variant.m_demoType == MTVehicleRayCastDemoVariant::MULTITHREADED_RAY_CAST )
	{
		m_vehicleManager = new hkpVehicleRayCastBatchingManager();
		vehicleSetup = new VehicleSetup();
	}
	else
	{
		m_vehicleManager = new hkpVehicleLinearCastBatchingManager();
		vehicleSetup = new LinearCastVehicleSetup();
	}

	//
	// Setup vehicle chassis and create vehicles
	//
	{
		//
		// Create vehicle's chassis shape.
		//
		hkpConvexVerticesShape* chassisShape = VehicleApiUtils::createCarChassisShape(); 

		createDisplayWheels();

		for ( int vehicleId = 0; vehicleId < m_vehicles.getSize(); vehicleId++ )
		{
			//
			// Create the vehicle.
			//
			{
				//
				// Create the chassis body.
				//
				hkpRigidBody* chassisRigidBody;
				{
					hkpRigidBodyCinfo chassisInfo;
					chassisInfo.m_mass = 750.0f;	
					chassisInfo.m_shape = chassisShape;
					chassisInfo.m_friction = 0.8f;
					chassisInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA;
					// Position chassis on the ground.

					// Inertia tensor will be set by VehicleSetupMultithreaded.
					chassisInfo.m_position.set(-40.0f, -4.5f, vehicleId * 5.0f);
					chassisInfo.m_inertiaTensor.setDiagonal(1.0f, 1.0f, 1.0f);
					
					chassisInfo.m_centerOfMass.set( -0.037f, 0.143f, 0.0f);
					chassisInfo.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo( CHASSIS_LAYER, 0 );

					chassisRigidBody = new hkpRigidBody( chassisInfo );
				}

				// Create vehicle
				{
					hkpVehicleInstance *const vehicle = new hkpVehicleInstance( chassisRigidBody );
					vehicleSetup->buildVehicle( m_world, *vehicle );
					vehicle->addToWorld( m_world );
					m_vehicleManager->addVehicle( vehicle );

					m_vehicles[vehicleId].m_vehicle = vehicle;
					m_vehicles[vehicleId].m_lastRPM = 0.0f;
					m_vehicles[vehicleId].m_vehicle->m_wheelCollide->setCollisionFilterInfo( hkpGroupFilter::calcFilterInfo( WHEEL_LAYER, 0 ) );
				}

				// This hkpAction flips the car upright if it turns over. 	 
				if (vehicleId == 0) 	 
				{ 	 
					hkVector4 rotationAxis(1.0f, 0.0f, 0.0f); 	 
					hkVector4 upAxis(0.0f, 1.0f, 0.0f); 	 
					m_reorientAction = new hkpReorientAction(chassisRigidBody, rotationAxis, upAxis); 	 
				}

				chassisRigidBody->removeReference();
			}
		}
		chassisShape->removeReference();
	} 
	vehicleSetup->removeReference();

	//
	// Create the camera.
	//
	{
		VehicleApiUtils::createCamera( m_camera );
		m_followCarView = true;
	}

	m_world->unlock();

	//
	// Setup for multithreading.
	//
	hkpCollisionQueryJobQueueUtils::registerWithJobQueue( m_jobQueue );
	
	// register the default addCdPoint() function; you are free to register your own implementation here though
	hkpFixedBufferCdPointCollector::registerDefaultAddCdPointFunction();

	// Special case for this demo variant: we do not allow the # of active SPUs to drop to zero as this can cause a deadlock.
	if ( variant.m_demoType == MTVehicleRayCastDemoVariant::MULTITHREADED_RAY_CAST || variant.m_demoType == MTVehicleRayCastDemoVariant::MULTITHREADED_LINEAR_CAST )
	{
		m_allowZeroActiveSpus = false;
	}
}