Exemple #1
0
bool PhysicsEngine::PerformSphereSphereCollisionTest(const Ogre::FrameEvent &fe, PhysicsEntity *sphere1, PhysicsEntity *sphere2)
{
	float overlapMagnitude = (sphere1->GetRadius() + sphere2->GetRadius()) - sphere1->getPosition().distance(sphere2->getPosition());
	if (overlapMagnitude >= 0.0f)
	{
		Ogre::Vector3 d = sphere2->getPosition() - sphere1->getPosition();
		Ogre::Vector3 relativeVelocity = d * (d.dotProduct(sphere1->GetVelocity() - sphere2->GetVelocity()) / d.squaredLength());
		
		Ogre::Vector3 impulse1 = (((sphere2->GetRestitution() + 1.0f) * relativeVelocity) /
			((1 / sphere1->GetMass()) + (1 / sphere2->GetMass())));
		Ogre::Vector3 impulse2 = -(((sphere1->GetRestitution() + 1.0f) * relativeVelocity) /
			((1 / sphere1->GetMass()) + (1 / sphere2->GetMass())));
		
		//Ogre::Vector3 currentImpulse1 = d * (d.dotProduct(sphere1->GetAppliedForce()) / d.squaredLength());
		//Ogre::Vector3 currentImpulse2 = -d * (d.dotProduct(sphere2->GetAppliedForce()) / d.squaredLength());
		
		if (sphere1->GetBodyType() == ENTITY_BODY_SPHERE && sphere2->GetBodyType() == ENTITY_BODY_SPHERE)
		{
			sphere1->translate(-d.normalisedCopy() * (overlapMagnitude / 2.0f));
			sphere2->translate(d.normalisedCopy() * (overlapMagnitude / 2.0f));

			sphere2->ApplyForce(impulse1);// + currentImpulse1);
			sphere1->ApplyForce(impulse2);// + currentImpulse2);
		}

		sphere1->Collide(fe, sphere2);
		sphere2->Collide(fe, sphere1);

		return true;
	}

	return false;
}
Exemple #2
0
void CharacterController::UpdateAI(float dt)
{
	_CurrentPathAge += dt;
	//std::cerr << _CurrentPathIndex << " / " << _CurrentPath.size() << "\n";
	if (_CurrentPathIndex + 2 <= _CurrentPath.size())
	{
		Ogre::Vector3 const & a = _CurrentPath[_CurrentPathIndex];
		Ogre::Vector3 const & b = _CurrentPath[_CurrentPathIndex+1];
		Ogre::Vector3 const & m = GetPosition();
		Ogre::Vector3 const ab = b - a;
		Ogre::Vector3 const am = m - a;
		Ogre::Vector3 const mb = b - m;
		Ogre::Vector3 const mb_unit = mb.normalisedCopy();
		
		float remaining = mb.length();
		for(size_t i = _CurrentPathIndex + 1; i + 2 <= _CurrentPath.size(); ++i)
		{
			remaining += _CurrentPath[i].distance(_CurrentPath[i+1]);
		}
		//std::cerr << "Remaining distance: " << remaining << " m\n";
		
		float lambda = am.dotProduct(ab) / ab.squaredLength();
		
		//const float tau = 0.1;
		
		SetVelocity(_CurrentVelocity * mb_unit);
		
		if (lambda > 1) _CurrentPathIndex++;
		/*if (_CurrentPathIndex + 1 == _CurrentPath.size())
			SetVelocity(Ogre::Vector3(0.));*/
	}
}
void AnimalThirdPersonControler::orient(int i_xRel, int i_yRel, double i_timeSinceLastFrame)
{
	if (!(m_pAnimal != nullptr && m_pCamera != nullptr))
		return;

	Ogre::Vector3 camPos = m_pCamera->getPosition();
	
	Ogre::Radian angleX(i_xRel * -m_camAngularSpeed);
	Ogre::Radian angleY(i_yRel * -m_camAngularSpeed);

	Ogre::Vector3 avatarToCamera = m_pCamera->getPosition() - m_pAnimal->m_pNode->getPosition();

	// restore lenght
	if (avatarToCamera.length() != m_camDistance)
		avatarToCamera = avatarToCamera.normalisedCopy() * m_camDistance;
	
	// Do not go to the poles
	Ogre::Radian latitude = m_pAnimal->m_pNode->getOrientation().zAxis().angleBetween(avatarToCamera);
	if (latitude < Ogre::Radian(Ogre::Math::DegreesToRadians(10.f)) && angleY < Ogre::Radian(0.f))
		angleY = Ogre::Radian(0.f);
	else if (latitude > Ogre::Radian(Ogre::Math::DegreesToRadians(170.f)) && angleY > Ogre::Radian(0.f))
		angleY = Ogre::Radian(0.f);

	Ogre::Quaternion orient = Ogre::Quaternion(angleY, m_pCamera->getOrientation().xAxis()) * Ogre::Quaternion(angleX, m_pCamera->getOrientation().yAxis());
	Ogre::Vector3 newAvatarToCamera = orient * avatarToCamera;

	// Move camera closer if collides with terrain
	m_collideCamWithTerrain(newAvatarToCamera);
}
//------------------------------------------------------------------------------------------------
RayDebugShape::RayDebugShape(const Ogre::Vector3& start,
                             const Ogre::Vector3& direction,
                             const Ogre::Real length) {
  const Ogre::Vector3 end(start + (direction.normalisedCopy() * length));
  addLine(start, end);

  draw();
}
//------------------------------------------------------------------------------------------------
void RayDebugShape::setDefinition(const Ogre::Vector3& start,
                                  const Ogre::Vector3& direction,
                                  const Ogre::Real length) {
  clear();

  const Ogre::Vector3 end(start + (direction.normalisedCopy() * length));
  addLine(start, end);

  draw();
}
Exemple #6
0
//-----------------------------------------------------------------------------------------
bool CLightEditor::_setDirection(OgitorsPropertyBase* property, const Ogre::Vector3& value)
{
    if(value == Ogre::Vector3::ZERO)
        mDirection->init(mDirection->getOld());

    if(mHandle)
    {
        mHandle->setDirection(value.normalisedCopy());
        _calculateOrientation();
    }
    return true;
}
Exemple #7
0
 void SkyDome::setSunDirection (const Ogre::Vector3& sunDir) {
     float elevation = sunDir.dotProduct (Ogre::Vector3::UNIT_Y);
     elevation = elevation * 0.5 + 0.5;
     Ogre::Pass* pass = mMaterial->getBestTechnique()->getPass(0);
     if (mShadersEnabled) {
         mParams.sunDirection.set(mParams.vpParams, sunDir.normalisedCopy());
         mParams.offset.set(mParams.fpParams, elevation);
     } else {
         Ogre::TextureUnitState* gradientsTus = pass->getTextureUnitState(0);
         gradientsTus->setTextureUScroll (elevation);
     }
 }
void LuaScriptUtilities::SetLineStartEnd(
    Ogre::SceneNode* line,
    const Ogre::Vector3& start,
    const Ogre::Vector3& end)
{
    Ogre::Vector3 lineVector = end - start;

    Ogre::Quaternion lineRotation =
        Ogre::Vector3::UNIT_Z.getRotationTo(lineVector.normalisedCopy());

    line->setOrientation(lineRotation *
                         Ogre::Quaternion(Ogre::Degree(90), Ogre::Vector3::UNIT_X));
    line->setPosition(start);
    line->setScale(0.01f, lineVector.length(), 0.01f);
}
Exemple #9
0
void Fighter::fire()
{
	if(lastShot.getMilliseconds() > 100)
		lastShot.reset();
	else
		return;

	AudioManager::getInstance().play("shot1");
	

	Ogre::Vector3 shotPos = mNode->getPosition();
	Ogre::Vector3 direction = mNode->getOrientation()*Ogre::Vector3::UNIT_Z;
	Shot* shotPtr = new Shot(mSceneManagerPtr,shotPos,direction.normalisedCopy());	
	mShots.push_back(shotPtr);
}
 QColor SparseOccupancyGridArrayDisplay::axisColor(const Ogre::Quaternion& q,
                                                   const Ogre::Vector3& p)
 {
   Ogre::Vector3 zaxis = q.zAxis();
   Ogre::Vector3 reference = p.normalisedCopy();
   double dot = zaxis.dotProduct(reference);
   if (dot < -1) {
     dot = -1.0;
   }
   else if (dot > 1) {
     dot = 1.0;
   }
   double scale = (dot + 1) / 2.0;
   return gridColor(scale);
 }
void AnimalThirdPersonControler::m_collideCamWithTerrain(const Ogre::Vector3& i_avatarToCamera)
{
	// Move camera closer if collides with terrain
	Ogre::Vector3 colPos, newCamPos;
	if (rayToTerrain(m_pAnimal->m_pNode->getPosition(), i_avatarToCamera, *m_pTerrainGroup, colPos) &&
		((m_pAnimal->m_pNode->getPosition() - colPos).length() < m_camDistance + m_camHeightOffset))
	{
		newCamPos = colPos - i_avatarToCamera.normalisedCopy() * m_camHeightOffset;
	}
	else
	{
		newCamPos = m_pAnimal->m_pNode->getPosition() + i_avatarToCamera;
	}

	m_pCamera->setPosition(newCamPos);
	m_pCamera->lookAt(m_pAnimal->m_pNode->getPosition() + m_pAnimal->m_cameraLookAtOffset);
}
	const float Ellipsoid::_getLength(const int &x, const int &y, const int &z) const
	{
		//  x^2   y^2   z^2
		//  /   + /   + /    = 1  (Ellipsoid ecuation)
		//  a^2   b^2   c^2
		// 
		//  maxradatdir = lambda (Xo, Yo, Zo) = lambda; where Xo, Yo and Zo are the components of the normaliced direction vector
		//
		//  => lambda^2 = 1 / ( EllipsoidEcuation...)
		//
		//  => lambda = sqrt (...) => maxradatdir = lambda

		Ogre::Vector3 Direction = Ogre::Vector3(x-mX, y-mY, z-mZ),
					  DirectionNormalized = Direction.normalisedCopy();

		Ogre::Real a = Ogre::Math::Pow(DirectionNormalized.x, 2) / mA2 + 
				       Ogre::Math::Pow(DirectionNormalized.y, 2) / mB2 +
				       Ogre::Math::Pow(DirectionNormalized.z, 2) / mC2,

		           lambda = 1.0f / Ogre::Math::Sqrt(a);

		return Ogre::Math::Clamp<Ogre::Real>(Direction.length() / lambda, 0, 1);
	}
void AnimalThirdPersonControler::move(int i_frontDir, int i_sideDir, bool i_run, double i_timeSinceLastFrame)
{
	if (!(m_pAnimal != nullptr && m_pCamera != nullptr))
		return;

	if (!(i_frontDir == 0 && i_sideDir == 0))
	{
		Ogre::Vector3 oldAniPos = m_pAnimal->m_pNode->getPosition();
		m_pAnimal->moveOnTerrain(i_frontDir, i_sideDir, i_run, i_timeSinceLastFrame, *m_pTerrainGroup);
		Ogre::Vector3 newAniPos = m_pAnimal->m_pNode->getPosition();

		// Update cammera
		Ogre::Vector3 newCamPos = m_pCamera->getPosition() + newAniPos - oldAniPos;
		Ogre::Vector3 newAvatarToCamera = newCamPos - m_pAnimal->m_pNode->getPosition();
		if (newAvatarToCamera.length() != m_camDistance)
			newAvatarToCamera = newAvatarToCamera.normalisedCopy() * m_camDistance;
		// Collide with terrain
		m_collideCamWithTerrain(newAvatarToCamera);

	}

	if (!m_lookAround)
		alignAnimalToCamera(i_timeSinceLastFrame);
}
int DecalManager::addTerrainSplineDecal(Ogre::SimpleSpline *spline, float width, Ogre::Vector2 numSeg, Ogre::Vector2 uvSeg, Ogre::String materialname, float ground_offset, Ogre::String export_fn, bool debug)
{
#if 0
	Ogre::ManualObject *mo = gEnv->ogreSceneManager->createManualObject();
	String oname = mo->getName();
	SceneNode *mo_node = terrain_decals_snode->createChildSceneNode();

	mo->begin(materialname, Ogre::RenderOperation::OT_TRIANGLE_LIST);
	AxisAlignedBox *aab=new AxisAlignedBox();

	int offset = 0;

	// how width is the road?
	float delta_width = width / numSeg.x;

	float steps_len = 1.0f / numSeg.x;

	for (int l = 0; l<=numSeg.x; l++)
	{
		// get current position on that spline
		Vector3 pos_cur  = spline->interpolate(steps_len * (float)l);
		Vector3 pos_next = spline->interpolate(steps_len * (float)(l + 1));
        Ogre::Vector3 direction = (pos_next - pos_cur);
		if (l == numSeg.x)
		{
			// last segment uses previous position
			pos_next = spline->interpolate(steps_len * (float)(l - 1));
			direction = (pos_cur - pos_next);
		}


		for (int w = 0; w<=numSeg.y; w++)
		{
			// build vector for the width
			Vector3 wn = direction.normalisedCopy().crossProduct(Vector3::UNIT_Y);
			
			// calculate the offset, spline in the middle
			Vector3 offset = (-0.5 * wn * width) + (w/numSeg.y) * wn * width;

			// push everything together
			Ogre::Vector3 pos = pos_cur + offset;
			// get ground height there
			pos.y = hfinder->getHeightAt(pos.x, pos.z) + ground_offset;

			// add the position to the mesh
			mo->position(pos);
			aab->merge(pos);
			mo->textureCoord(l/(Ogre::Real)numSeg.x*uvSeg.x, w/(Ogre::Real)numSeg.y*uvSeg.y);
			mo->normal(Vector3::UNIT_Y);
		}
	}

	bool reverse = false;
	for (int n1 = 0; n1<numSeg.x; n1++)
	{
		for (int n2 = 0; n2<numSeg.y; n2++)
		{
			if (reverse)
			{
				mo->index(offset+0);
				mo->index(offset+(numSeg.y+1));
				mo->index(offset+1);
				mo->index(offset+1);
				mo->index(offset+(numSeg.y+1));
				mo->index(offset+(numSeg.y+1)+1);
			}
			else
			{
				mo->index(offset+0);
				mo->index(offset+1);
				mo->index(offset+(numSeg.y+1));
				mo->index(offset+1);
				mo->index(offset+(numSeg.y+1)+1);
				mo->index(offset+(numSeg.y+1));
			}
			offset++;
		}
		offset++;
	}
	offset+=numSeg.y+1;

	mo->end();
	mo->setBoundingBox(*aab);
	// some optimizations
	mo->setCastShadows(false);
	mo->setDynamic(false);
	delete(aab);

	MeshPtr mesh = mo->convertToMesh(oname+"_mesh");

	// build edgelist
	mesh->buildEdgeList();

	// remove the manualobject again, since we dont need it anymore
	gEnv->ogreSceneManager->destroyManualObject(mo);

	unsigned short src, dest;
	if (!mesh->suggestTangentVectorBuildParams(VES_TANGENT, src, dest))
	{
		mesh->buildTangentVectors(VES_TANGENT, src, dest);
	}
	
	Entity *ent = gEnv->ogreSceneManager->createEntity(oname+"_ent", oname+"_mesh");
	mo_node->attachObject(ent);

	mo_node->setVisible(true);
	//mo_node->showBoundingBox(true);
	mo_node->setPosition(Vector3::ZERO); //(position.x, 0, position.z));


	if (!export_fn.empty())
	{
		MeshSerializer *ms = new MeshSerializer();
		ms->exportMesh(mesh.get(), export_fn);
		LOG("spline mesh exported as " + export_fn);
		delete(ms);
	}

	// TBD: RTSS
	//Ogre::RTShader::ShaderGenerator::getSingleton().createShaderBasedTechnique(materialname, Ogre::MaterialManager::DEFAULT_SCHEME_NAME, Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME);
	//Ogre::RTShader::ShaderGenerator::getSingleton().invalidateMaterial(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, materialname);
	RTSSgenerateShadersForMaterial(materialname, "");

#endif
	return 0;
}
Exemple #15
0
/***
Creates a chunk at (chunk_x,chunk_y,chunk_z) in chunk coordinates.
Allocations:
 - pos: position of chunk in real coordinates
 - sn: chunk's scenenode
 - mo: chunk's mesh (manualobject)
 - vertices: memoization of mesh's vertices
 - trimesh: holds triangle data for bullet
 - tms: collision shape using trimesh
 - ms: motion state
 - rb: chunk's rigidbody

***/
void ChunkManager::createChunk(int chunk_x, int chunk_y, int chunk_z) {
    if (hasChunkAtChunkCoords(chunk_x, chunk_y, chunk_z)) {
        // Don't do anything if we already have a chunk there.
        return;
    }
    mName = new Ogre::String("Chunk_"+Ogre::StringConverter::toString(chunk_x)+"_"+Ogre::StringConverter::toString(chunk_y)+"_"+Ogre::StringConverter::toString(chunk_z));
    Ogre::Vector3 pos = chunkToRealCoords(chunk_x,chunk_y,chunk_z);
    Ogre::SceneNode* sn = mGame->createSceneNode(pos);
    clock_t t;
    Game::log(TAG, "Creating chunk...");
    t = clock();
    Landscape* landscape = mGame->getLandscape();
    Ogre::ManualObject* mo = new Ogre::ManualObject("ChunkManualObject" + *mName);

    /*** The following code is to memoize the mesh creation process. I don't know if it will make things faster (most likely will), but
    I'll keep it here for now to test later in case the speed of this function is slow.***/

    Ogre::Vector3** vertices = new Ogre::Vector3* [(SIZES::CHUNK_SIZE+2)*(SIZES::CHUNK_SIZE+2)]; // + 2 to account for the edge vertices

    for (int i = 0; i < (SIZES::CHUNK_SIZE+2)*(SIZES::CHUNK_SIZE+2); i++) {
        vertices[i] = NULL;
    }

    // Create the meshes
    //mo->begin("Astral/Grass");
    mo->begin("Examples/GrassFloor");
    for (int x = 0; x < SIZES::CHUNK_SIZE; x++) {
        for (int z = 0; z < SIZES::CHUNK_SIZE; z++) {
            // vx, vy, vz define the next vertex we want to add to the manualobject.
            int vx = x + pos.x;
            int vz = z + pos.z;
            Ogre::Vector3 v = *getVector(vx,vz,landscape,vertices);
            // add the vertex
            mo->position(v);

            // now we need to find the faces this vertex touches
            Ogre::Vector3 ll = *getVector(vx-1,vz-1,landscape,vertices);
            Ogre::Vector3 lm = *getVector(vx,vz-1,landscape,vertices);
            Ogre::Vector3 lr = *getVector(vx+1,vz-1,landscape,vertices);
            Ogre::Vector3 ml = *getVector(vx-1,vz,landscape,vertices);
            Ogre::Vector3 mr = *getVector(vx+1,vz,landscape,vertices);
            Ogre::Vector3 ul = *getVector(vx-1,vz+1,landscape,vertices);
            Ogre::Vector3 um = *getVector(vx,vz+1,landscape,vertices);
            Ogre::Vector3 ur = *getVector(vx+1,vz+1,landscape,vertices);


            Ogre::Vector3 normal = Ogre::Vector3(0,0,0);

            normal += (v - ll).crossProduct(lm - ll).normalisedCopy();
            normal += (ml - ll).crossProduct(v - ll).normalisedCopy();
            normal += (um - ml).crossProduct(v - ml).normalisedCopy();
            normal += (ul - ml).crossProduct(um - ml).normalisedCopy();
            normal += (um - v).crossProduct(ur - v).normalisedCopy();
            normal += (ur - v).crossProduct(mr - v).normalisedCopy();
            normal += (v - lm).crossProduct(mr - lm).normalisedCopy();
            normal += (mr - lm).crossProduct(lr - lm).normalisedCopy();

            mo->normal(normal.normalisedCopy());

            mo->textureCoord((float)x/(float)SIZES::CHUNK_TEXTURE_TILE,(float)z/(float)SIZES::CHUNK_TEXTURE_TILE);

        }
    }
    Game::log(TAG, "Vertices created");

    btTriangleMesh* trimesh = new btTriangleMesh();
    for (int x = 0; x < SIZES::CHUNK_SIZE - 1; x++) {
        for (int z = 0; z < SIZES::CHUNK_SIZE - 1; z++) {
            mo->triangle((x * SIZES::CHUNK_SIZE) + z + 1,
                         ((x + 1) * SIZES::CHUNK_SIZE) + z,
                         (x * SIZES::CHUNK_SIZE) + z);

            mo->triangle((x * SIZES::CHUNK_SIZE) + z + 1,
                         ((x + 1) * SIZES::CHUNK_SIZE) + z + 1,
                         ((x + 1) * SIZES::CHUNK_SIZE) + z);

            Ogre::Vector3* a = vertices[(x+1)*(SIZES::CHUNK_SIZE+2)+z+2];
            Ogre::Vector3* b = vertices[(x+2)*(SIZES::CHUNK_SIZE+2)+z+1];
            Ogre::Vector3* c = vertices[(x+1)*(SIZES::CHUNK_SIZE+2)+z+1];
            Ogre::Vector3* d = vertices[(x+2)*(SIZES::CHUNK_SIZE+2)+z+2];
            trimesh->addTriangle(btVector3(a->x,a->y,a->z),
                                 btVector3(b->x,b->y,b->z),
                                 btVector3(c->x,c->y,c->z));
            trimesh->addTriangle(btVector3(a->x,a->y,a->z),
                                 btVector3(d->x,d->y,d->z),
                                 btVector3(b->x,b->y,b->z));
        }
    }
    mo->end();
    sn->attachObject(mo);
    Game::log(TAG, "mo attached");

    btBvhTriangleMeshShape* tms = new btBvhTriangleMeshShape(trimesh,
                                                             true); //useQuantizedAabbCompression
//    btShapeHull* hull = new btShapeHull(tms);
//    btScalar margin = tms->getMargin();
//    hull->buildHull(margin);
//    btConvexHullShape* chs = new btConvexHullShape((btScalar*)hull->getVertexPointer(), hull->numVertices());
    // I give it this motionstate and not an Ogre one because chunks shouldn't move anyways
    btDefaultMotionState* ms = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(pos.x,pos.y,pos.z)));
    btRigidBody::btRigidBodyConstructionInfo info(0,ms,tms);
    btRigidBody* rb = new btRigidBody(info);
    Game::log(TAG, "rb created");

    mGame->addRigidBody(rb);
    Game::log(TAG, "rb added");

    // Clean up
    for (int i = 0; i < (SIZES::CHUNK_SIZE+2)*(SIZES::CHUNK_SIZE+2); i++) {
        delete vertices[i];
    }
    delete [] vertices;

    // Time stats
    t = clock() - t;
    Game::log(TAG, "Done creating chunk mesh.");
    Game::log(TAG, "Mesh created in "+Ogre::StringConverter::toString((long)t)+" ticks.");
    mChunks[chunk_x][chunk_y][chunk_z] = new Chunk(sn, mo, trimesh, tms, ms, rb);
}
Exemple #16
0
bool RoomsManager::UpdateObject(Room::ObjectType* object)
{    
    bool updated=false, inrooms=false;
    Room *room;

    //std::vector<Room*>::iterator iPos=Rooms.begin(), iEnd=Rooms.end();
	inrooms=false;
    //for (size_t i=0;i<Rooms.Size;++i)
    Ogre::AxisAlignedBox box = object->GetRoomable()->GetBoundingBox(), *RoomBox;
    
	//assert()

	for (RoomsPool::ListNode *pos = Rooms.GetBegin(); pos!=NULL; pos=pos->Next)
    {
        room = pos->Value;        
        RoomBox = room->GetBox();
        if (RoomBox->intersects(box))
        {
            updated = room->UpdateObject(object);
            if (updated)
		    {           
			    inrooms=true;			
		    }
        }
    }

	if (!inrooms)
	{
		/*char log[100];
		sprintf(log,"Rooms 1: empty room set for object %d\n",object->GetScriptable()->GetID());
		Debugging::Log("Warnings.log",log);*/		
				
		IRoomable *rmbl = object->GetRoomable();
		IPhysical *phys = object->GetPhysical();
		if (rmbl)
		{
			rmbl->RemoveFromRooms();
			rmbl->GetRooms()->Clear();			
			switch (rmbl->GetRoomOnly())
			{
				case IRoomable::ROM_RESTORE:
					{						
						for (RoomsPool::ListNode *pos = Rooms.GetBegin(); pos!=NULL; pos=pos->Next)
						{
							Ogre::AxisAlignedBox *box = pos->Value->GetBox();
							Ogre::Vector3 center = box->getCenter();
							Ogre::Vector3 position = object->GetPosition();
							Ogre::Vector3 dist = position - center;

							int sqradius = AAUtilities::f2i(box->getHalfSize().squaredLength())+3*phys->GetRadius();
														
							int sqdist = AAUtilities::f2i(dist.squaredLength());
							if (sqradius>sqdist)
							{
								//GetPhysical()->SetForwardDirection(GetOrientation()*Vector3::UNIT_Z);
								//object->GetPhysical();
								//object->RestoreBackupPosition();								
								//Ogre::Vector3 newdir=phys->GetLastVelocity();
								//phys->Stop();
								phys->SetReplacingDirection(-dist.normalisedCopy()*10);
								break;
							}
						}
						AddOuterObject(object);
						//object->RestoreBackupPosition();
						break;
					}					
				case IRoomable::ROM_DESTROY:
					{
						CommonDeclarations::DeleteObjectRequest(object);
						break;
					}					
				case IRoomable::ROM_SCRIPT:
					{
						IScriptable *scr = object->GetScriptable();
						if (scr && scr->GetID()>0)
							ScriptManager::GetInstance()->Call("OnOutOfRooms", "i", false, object->GetScriptable()->GetID());
						break;
					}
				case IRoomable::ROM_NONE:
					{
						AddOuterObject(object);
						break;
					}

			};
		}
		
	}
    
    return inrooms;
}
Exemple #17
0
void SkyManager::LoadCaelumScript(std::string script, int fogStart, int fogEnd)
{
    // load the caelum config
    try
    {
        Caelum::CaelumPlugin::getSingleton().loadCaelumSystemFromScript(m_caelum_system, script);

        // overwrite some settings
#ifdef CAELUM_VERSION_SEC
        // important: overwrite fog settings if not using infinite farclip
        if (fogStart != -1 && fogEnd != -1 && fogStart < fogEnd)
        {
            // setting farclip (hacky)
            gEnv->mainCamera->setFarClipDistance(fogEnd / 0.8);
            // custom boundaries
            m_caelum_system->setManageSceneFog(Ogre::FOG_LINEAR);
            m_caelum_system->setManageSceneFogStart(fogStart);
            m_caelum_system->setManageSceneFogEnd(fogEnd);
        }
        else if (gEnv->mainCamera->getFarClipDistance() > 0)
        {
            if (fogStart != -1 && fogEnd != -1)
            {
                LOG("CaelumFogStart must be smaller then CaelumFogEnd. Ignoring boundaries.");
            }
            else if (fogStart != -1 || fogEnd != -1)
            {
                LOG("You always need to define both boundaries (CaelumFogStart AND CaelumFogEnd). Ignoring boundaries.");
            }
            // non infinite farclip
            float farclip = gEnv->mainCamera->getFarClipDistance();
            m_caelum_system->setManageSceneFog(Ogre::FOG_LINEAR);
            m_caelum_system->setManageSceneFogStart(farclip * 0.7);
            m_caelum_system->setManageSceneFogEnd(farclip * 0.9);
        }
        else
        {
            // no fog in infinite farclip
            m_caelum_system->setManageSceneFog(Ogre::FOG_NONE);
        }
#else
#error please use a recent Caelum version, see http://www.rigsofrods.org/wiki/pages/Compiling_3rd_party_libraries#Caelum
#endif // CAELUM_VERSION
        // now optimize the moon a bit
        if (m_caelum_system->getMoon())
        {
            m_caelum_system->getMoon()->setAutoDisable(true);
            //m_caelum_system->getMoon()->setAutoDisableThreshold(1);
            m_caelum_system->getMoon()->setForceDisable(true);
            m_caelum_system->getMoon()->getMainLight()->setCastShadows(false);
        }

        m_caelum_system->setEnsureSingleShadowSource(true);
        m_caelum_system->setEnsureSingleLightSource(true);

        // enforcing update, so shadows are set correctly before creating the terrain
        m_caelum_system->updateSubcomponents(0.1);
    }
    catch (Ogre::Exception& e)
    {
        RoR::LogFormat("[RoR] Exception while loading sky script: %s", e.getFullDescription().c_str());
    }
    Ogre::Vector3 lightsrc = m_caelum_system->getSun()->getMainLight()->getDirection();
    m_caelum_system->getSun()->getMainLight()->setDirection(lightsrc.normalisedCopy());
}
Exemple #18
0
 void SceneNodeWrapper::setOrientationVector(const Ogre::Vector3& value)
 {
   mOrientationVector = value.normalisedCopy();
 }
void CSpaghettiRigidBody::HandleCollision( 
		CSpaghettiWorld *world,							/*!< The world we are moving in */ 
		CSpaghettiRigidBody *otherRigidBody,			/*!< The other rigid body to compare against */ 
		const float deltaTime,							/*!< Delta time */
		std::vector<CCollision> &worldCollisionList		
	)
{
	std::vector<CCollision> collisions;
	if (!m_bounds->Intersects(otherRigidBody->GetBounds(), collisions))
		return;

	// no collisions stored, but there was a bound overlap
	if (collisions.empty())
		return;

	static const float restitution = 0.9f; 
	float sumOfMass = 0.0f;
	Ogre::Vector3 relativeVeclocity = Ogre::Vector3::ZERO;

	const float inverseMassBodyOne = 1.0f / GetMass();
	const float inverseMassBodyTwo = 1.0f / otherRigidBody->GetMass();

	if (otherRigidBody->IsStatic())
	{
		sumOfMass = inverseMassBodyOne;
		relativeVeclocity = GetVelocity();
	}
	else
	{
		sumOfMass = inverseMassBodyOne + inverseMassBodyTwo;
		relativeVeclocity = GetVelocity() - otherRigidBody->GetVelocity();
	}

	unsigned int noofCollision = collisions.size();
	for (unsigned int collisionIndex = 0; collisionIndex < noofCollision; ++collisionIndex)
	{
		worldCollisionList.push_back(collisions[collisionIndex]);

		Ogre::Vector3 collisionNormal = collisions[collisionIndex].collisionNormal;
		Ogre::Vector3 collisionPoint = collisions[collisionIndex].collisionPoint;

		float rvDn = relativeVeclocity.dotProduct(collisionNormal);
		Ogre::Vector3 impulseLinear = (collisionNormal * -(1 + restitution) * rvDn) / sumOfMass;

		SetVelocity(GetVelocity() + (impulseLinear * inverseMassBodyOne));
		SetPosition(GetPosition() + (-collisionNormal * collisions[collisionIndex].penetration));

		//angular
		Ogre::Vector3 collisionTangent = collisionNormal.crossProduct(relativeVeclocity.normalisedCopy());
		collisionTangent = collisionTangent.crossProduct(collisionNormal);

		static const float mu = -0.2f;
		Ogre::Vector3 frictionForce = ((collisionTangent * impulseLinear.length()) * mu) / deltaTime;
		AddTorqueAtPoint(frictionForce + (impulseLinear / deltaTime), collisionPoint);

		if (!otherRigidBody->IsStatic())
		{
			otherRigidBody->SetVelocity(otherRigidBody->GetVelocity() - (impulseLinear * inverseMassBodyTwo));
			otherRigidBody->SetPosition(otherRigidBody->GetPosition() + (collisionNormal * collisions[collisionIndex].penetration));

			otherRigidBody->AddTorqueAtPoint(-(frictionForce + (impulseLinear / deltaTime)), collisionPoint);
		}
	}

}
	void RenderBoxWrap::updateViewport()
	{
		// при нуле вылетает
		if ((mRenderBox->getWidth() <= 1) || (mRenderBox->getHeight() <= 1) ) return;

		if ((nullptr != mEntity) && (nullptr != mRttCam)) {
			// не ¤сно, нужно ли раст¤гивать камеру, установленную юзером
			mRttCam->setAspectRatio((float)mRenderBox->getWidth() / (float)mRenderBox->getHeight());

			//System::Console::WriteLine("Width {0}, Height {1}", getWidth(), getHeight());

			// вычисл¤ем рассто¤ние, чтобы был виден весь объект
			Ogre::AxisAlignedBox box;// = mNode->_getWorldAABB();//mEntity->getBoundingBox();

			VectorEntity::iterator iter = mVectorEntity.begin();

			while (iter != mVectorEntity.end())
			{
				box.merge((*iter)->getBoundingBox().getMinimum() + (*iter)->getParentSceneNode()->_getDerivedPosition());
				box.merge((*iter)->getBoundingBox().getMaximum() + (*iter)->getParentSceneNode()->_getDerivedPosition());
				iter++;
			}

			if (box.isNull()) return;

			//box.scale(Ogre::Vector3(1.41f,1.41f,1.41f));

			//System::Console::WriteLine("Minimum({0}), Maximum({1})",
			//	gcnew System::String(Ogre::StringConverter::toString(box.getMinimum()).c_str()),
			//	gcnew System::String(Ogre::StringConverter::toString(box.getMaximum()).c_str()));

			//box.getCenter();
			Ogre::Vector3 vec = box.getSize();

			// коррекци¤ под левосторонюю систему координат с осью Z направленную вверх
			#ifdef LEFT_HANDED_CS_UP_Z

				float width = sqrt(vec.x*vec.x + vec.y*vec.y); // самое длинное - диагональ (если крутить модель)
				float len2 = width; // mRttCam->getAspectRatio();
				float height = vec.z;
				float len1 = height;
				if (len1 < len2) len1 = len2;
				len1 /= 0.86; // [sqrt(3)/2] for 60 degrees field of view
				// центр объекта по вертикали + отъехать так, чтобы влезла ближн¤¤ грань BoundingBox'а + чуть вверх и еще назад дл¤ красоты
				Ogre::Vector3 result = box.getCenter() - Ogre::Vector3(vec.y/2 + len1, 0, 0) - Ogre::Vector3(len1*0.2, 0, -height*0.1);
				result.x *= mCurrentScale;
				mCamNode->setPosition(result);

				Ogre::Vector3 x = Ogre::Vector3(0, 0, box.getCenter().z + box.getCenter().z * (1-mCurrentScale)) - mCamNode->getPosition();
				Ogre::Vector3 y = Ogre::Vector3(Ogre::Vector3::UNIT_Z).crossProduct(x);
				Ogre::Vector3 z = x.crossProduct(y);
				mCamNode->setOrientation(Ogre::Quaternion(
					x.normalisedCopy(),
					y.normalisedCopy(),
					z.normalisedCopy()));

			#else

				float width = sqrt(vec.x*vec.x + vec.z*vec.z); // самое длинное - диагональ (если крутить модель)
				float len2 = width / mRttCam->getAspectRatio();
				float height = vec.y;
				float len1 = height;
				if (len1 < len2) len1 = len2;
				len1 /= 0.86; // [sqrt(3)/2] for 60 degrees field of view
				// центр объекта по вертикали + отъехать так, чтобы влезла ближн¤¤ грань BoundingBox'а + чуть вверх и еще назад дл¤ красоты
				Ogre::Vector3 result = box.getCenter() + Ogre::Vector3(0, 0, vec.z/2 + len1) + Ogre::Vector3(0, height*0.1, len1*0.2);
				result.z *= mCurrentScale;
				Ogre::Vector3 look = Ogre::Vector3(0, box.getCenter().y /*+ box.getCenter().y * (1-mCurrentScale)*/, 0);

				mCamNode->setPosition(result);
				mCamNode->lookAt(look, Ogre::Node::TS_WORLD);

			#endif
		}
	}
	void BaseGame::SetLightDirection(const Ogre::Vector3 &lightDir)
	{
		assert(m_light);
		m_light->setDirection(lightDir.normalisedCopy());
	}
TerrainPatchData::TerrainPatchData(TerrainQuadtree* tree) :
        tree(tree),
        tessellation(tree->getPlanetarySurface()->getTessellation()),
        vertices(tessellation + 3, std::vector<Ogre::Vector3>(tessellation + 3)),
        normals(tessellation + 3, std::vector<Ogre::Vector3>(tessellation + 3)),
        heights(tessellation + 3, std::vector<Ogre::Real>(tessellation + 3, 0.0)) {
    int patchSize = tree->getSize();
    Ogre::Real halfPatchSize = Ogre::Real(patchSize / 2);
    Ogre::Real delta = (Ogre::Real)patchSize * (1.0 / (Ogre::Real)tessellation);

    Ogre::SceneNode* patchSceneNode = tree->getSceneNode();
    Ogre::SceneNode* planetarySceneNode = tree->getPlanetarySurface()->getSceneNode();

    Ogre::Real planetaryRadius = (Ogre::Real)tree->getPlanetarySurface()->getRadius();

    for (int z = -1; z < tessellation + 2; ++z) {
        for (int x = -1; x < tessellation + 2; ++x) {
            Ogre::Vector3 position(-halfPatchSize + delta * x, 0.0, -halfPatchSize + delta * z);
            Ogre::Vector3 planetaryPosition = planetarySceneNode->convertWorldToLocalPosition(patchSceneNode->convertLocalToWorldPosition(position));
            planetaryPosition = mapToSphere(planetaryPosition, planetaryRadius);
            Ogre::Vector3 normal = planetaryPosition.normalisedCopy();
            Ogre::Real height = tree->getPlanetarySurface()->getNoiseFunction()->getValue(planetaryPosition);

            planetaryPosition = planetarySceneNode->convertLocalToWorldPosition(planetaryPosition);
            position = patchSceneNode->convertWorldToLocalPosition(planetaryPosition);

            normal = (tree->getRootSceneNode()->getOrientation().Inverse() * normal).normalisedCopy();

            vertices[z + 1][x + 1] = position;
            normals[z + 1][x + 1] = normal;
            heights[z + 1][x + 1] = height;
        }
    }

    for (int z = 0; z < tessellation + 1; ++z) {
        for (int x = 0; x < tessellation + 1; ++x) {
            processedPositions.push_back(getVertex(x, z));
            processedNormals.push_back(getVertexNormal(x, z));
            processedTextureCoords.push_back(getNormal(x, z));
        }
    }

    // Add triangles.
    for (int z = 0; z < tessellation; ++z) {
        int zOffset = z * (tessellation + 1);
        for (int x = 0; x < tessellation; ++x) {
            int indices[4] = {
                zOffset + x,
                zOffset + x + 1,
                zOffset + tessellation + 1 + x,
                zOffset + tessellation + 1 + x + 1
            };

            processedIndices.push_back(indices[0]);
            processedIndices.push_back(indices[2]);
            processedIndices.push_back(indices[1]);
            processedIndices.push_back(indices[2]);
            processedIndices.push_back(indices[3]);
            processedIndices.push_back(indices[1]);
        }
    }
}
Exemple #23
0
void PhysicsEngine::Update(const Ogre::FrameEvent &fe)
{
	std::vector<PhysicsEntity *> gravitationalEntities;
	std::vector<PhysicsEntity *> dynamicEntities;
	std::vector<PhysicsEntity *> collidableEntities;

	for (std::vector<PhysicsEntity *>::iterator it = physicsEntities.begin(); it != physicsEntities.end(); ++it)
	{
		if ((*it)->isAlive())
		{
			if ((*it)->IsGravitational())
			{
				gravitationalEntities.push_back(*it);
			}
			if ((*it)->IsDynamic())
			{
				dynamicEntities.push_back(*it);
			}
			if ((*it)->GetBodyType() != ENTITY_BODY_METAPHYSICAL)
			{
				collidableEntities.push_back(*it);
			}
		}
	}
	for (std::vector<PhysicsEntity *>::iterator it = dynamicEntities.begin(); it != dynamicEntities.end(); ++it)
	{
		for (std::vector<PhysicsEntity *>::iterator gr = gravitationalEntities.begin(); gr != gravitationalEntities.end(); ++gr)
		{
			if (*it != *gr)
			{
				Ogre::Vector3 distance = (*gr)->getPosition() - (*it)->getPosition();
				if (distance.squaredLength() != 0.0f)
				{
					Ogre::Vector3 force = distance.normalisedCopy() *
						gravitationalConstant * (((*it)->GetMass() * (*gr)->GetMass()) /
						((*gr)->IsAbsoluteGravitationalPull() ? ((*gr)->GetRadius() + (*it)->GetRadius()) : distance.squaredLength()));
					(*it)->ApplyForce(force);
					if ((*gr)->IsDynamic())
					{
						(*gr)->ApplyForce(force);
					}
				}
			}
		}
	}
	while (collidableEntities.size() > 0)
	{
		PhysicsEntity *i = collidableEntities.back();

		for (std::vector<PhysicsEntity *>::reverse_iterator it = collidableEntities.rbegin(); it != collidableEntities.rend(); ++it)
		{
			if (i != (*it) && i->isAlive() && (*it)->isAlive() && 
				//i->GetObjectID() != (*it)->GetObjectID() && i->GetParentID() != (*it)->GetParentID() &&
				i->GetObjectID() != (*it)->GetParentID() && i->GetParentID() != (*it)->GetObjectID())
			{
				if (i->GetBodyType() == ENTITY_BODY_SPHERE || i->GetBodyType() == ENTITY_BODY_METAPHYSICAL_SPHERE)
				{
					if ((*it)->GetBodyType() == ENTITY_BODY_SPHERE || (*it)->GetBodyType() == ENTITY_BODY_METAPHYSICAL_SPHERE)
					{
						PerformSphereSphereCollisionTest(fe, i, *it);
					}
					else if ((*it)->GetBodyType() == ENTITY_BODY_RAY || (*it)->GetBodyType() == ENTITY_BODY_METAPHYSICAL_RAY)
					{
						PerformRaySphereCollisionTest(fe, *it, i);
					}
				}
				else if (i->GetBodyType() == ENTITY_BODY_RAY || i->GetBodyType() == ENTITY_BODY_METAPHYSICAL_RAY)
				{
					if ((*it)->GetBodyType() == ENTITY_BODY_SPHERE || (*it)->GetBodyType() == ENTITY_BODY_METAPHYSICAL_SPHERE)
					{
						PerformRaySphereCollisionTest(fe, i, *it);
					}
				}
			}
		}
		collidableEntities.pop_back();
	}
}