예제 #1
0
void OGPhysic::update(double time){     
    
    Vector3d terrainNorm;
    Vector3d vertex;
    Vector3d pos;
    bool collision = terrainCollision(vertex, terrainNorm);
    
    Vector3d fp = Vector3d(0,ball->getMass() * gravity,0); //forza peso
    
    if (!collision){
        Vector3d faa = 6 * M_PI * viscosity * ball->getMass() * (wind - ball->getSpeed()); //forza attrito aria
        Vector3d fr = fp + faa; //forza attiva sulla pallina
        Vector3d acc = fr / ball->getMass();
        ball->setSpeed(ball->getSpeed() + (acc * time));
        pos = ball->getPosition() + (ball->getSpeed() * time);
    }else{
        //attrito radente
        Vector3d normV = ball->getSpeed().getNormalized();
        Vector3d fat = normV * terrainNorm.dot(fp) * friction;
        
        //calcolo forza peso parallela
        Vector3d fpp = fp.length() * terrainNorm + Vector3d(0,-1,0);
        Vector3d acc = fat + fpp / ball->getMass();
        
        Vector3d speed = ball->getSpeed();
        pos = ball->getPosition();
        
        speed = Vector3d(speed.x + (acc.x * time), -speed.y * elasticity, speed.z + (acc.z * time));
        
        pos = Vector3d(pos.x + (speed.x * time), vertex.y + (speed.y * time) ,pos.z + (speed.z * time));
        
        ball->setSpeed(speed);
    }
    
    ball->setPosition(pos.x, pos.y, pos.z);
    //update pov
    pov->setPosition(pos.x, pos.y , pos.z);

}
예제 #2
0
void* OgreNewtonSceneBody::AddTerrain (Terrain* const terrain)
{
	OgreNewtonWorld* const world = (OgreNewtonWorld*) GetNewton();

	int width = terrain->getSize() - 1;
	int height = terrain->getSize() - 1;
	int size = width * height;
//	Real min = terrain->getMinHeight();
//	Real max = terrain->getMaxHeight();
	Real horizontalScale = (terrain->getWorldSize() / (terrain->getSize() - 1));

	dNewtonScopeBuffer<dFloat> elevations(size);
	dNewtonScopeBuffer<char> attributes(size);
	
	for (int i = 0; i < width; i++) {	
		int index = i * height;
		for (int k = 0; k < height; k++) {
			// for now make collsionID zero, until we can get material information from the terrain tile
			attributes[index] = 0;
			elevations[index] = terrain->getHeightAtPoint(i, k);
			index ++;
		}
	}

	// build the height field collision
	dNewtonCollisionHeightField terrainCollision (world, width, height, 5, 0, 1.0f, horizontalScale, &elevations[0], &attributes[0], 0);

	// set the offset matrix for this collision shape
	Vector3 posit (-(width / 2.0f) * horizontalScale, 0.0f, (height / 2.0f) * horizontalScale);
	Quaternion rot(Ogre::Degree(90.0f), Ogre::Vector3(0.0f, 1.0f, 0.0f));

	Matrix4 matrix;
	matrix.makeTransform (posit, Vector3(1.0f, 1.0f, 1.0f), rot);
	matrix = matrix.transpose();

	terrainCollision.SetMatrix (&matrix[0][0]);
	return AddCollision (&terrainCollision);
}