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; }
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(); }
//----------------------------------------------------------------------------------------- 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; }
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); }
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; }
/*** 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); }
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; }
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()); }
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]); } } }
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(); } }