void Replicator::update(float value) { //logFile << getFrequentcyRange() << " :\t " << value << "\n"; Ogre::Vector3 currentScale = getScale(); this->setThreshold(0.7*this->getThreshold() + 0.4*value); float result = value / this->getThreshold(); int numOfChildrenToGenerate = result > 1.0 ? (result - value) * 2 : 0; //logFile << value / this->getThreashold() << "\t" << (result - value) * 10 << "\t" << numOfChildrenToGenerate << "\n"; for ( int i = 0; i < numOfChildrenToGenerate; i++ ) { createChildren(numOfChildrenToGenerate); } for(std::vector<Ogre::Entity*>::size_type i = 0; i < children.size(); ) { Ogre::SceneNode* childNode = children[i]->getParentSceneNode(); Ogre::Real res = childNode->getScale().length(); if ( res < 0.1 ) { children[i]->setVisible(false); childNode->setVisible(false); childNode->detachObject(children[i]->getName()); _sceneManager->destroyEntity(children[i]->getName()); // entity is now destroyed, don't try to use the pointer anymore! // optionally destroy node _sceneManager->destroySceneNode(childNode->getName()); children.erase( children.begin() + i ); } else { Ogre::Vector3 currScale = childNode->getScale(); childNode->setScale(Ogre::Vector3(currScale.x - currScale.x/3, currScale.y - currScale.y/3, currScale.z - currScale.z/3)); i++; } } }
void PhysicsSystem::addActor (const Ptr& ptr) { std::string mesh = MWWorld::Class::get(ptr).getModel(ptr); Ogre::SceneNode* node = ptr.getRefData().getBaseNode(); //TODO:optimize this. Searching the std::map isn't very efficient i think. mEngine->addCharacter(node->getName(), mesh, node->getPosition(), node->getScale().x, node->getOrientation()); }
void PhysicsSystem::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string model){ Ogre::SceneNode* node = ptr.getRefData().getBaseNode(); // unused //Ogre::Vector3 objPos = node->getPosition(); addObject (node->getName(), model, node->getOrientation(), node->getScale().x, node->getPosition()); }
void BubbleController::Update(float dt){ if (m_apply_impulse){ Ogre::Vector3 impulse = (m_impulse_direction * m_velocity) * dt; m_messenger->Notify(MSG_RIGIDBODY_APPLY_IMPULSE, &impulse, "body"); m_apply_impulse = false; if (m_owner->GetType() == GAME_OBJECT_PINK_BUBBLE){ m_distance -= impulse.squaredLength(); } } if (m_owner->GetType() == GAME_OBJECT_PINK_BUBBLE){ float percent = m_max_distance * 0.5f; if (m_distance < percent){ Ogre::SceneNode* node = NULL; m_messenger->Notify(MSG_NODE_GET_NODE, &node); if (node){ float scale_inc = (m_scale_increment * (percent / m_distance)) * dt; if (m_scale_state == 0) { // increase size Ogre::Vector3 scale = node->getScale() + scale_inc; node->setScale(scale); if (node->getScale().y > m_max_scale){ node->setScale(Ogre::Vector3(m_max_scale)); m_scale_state = 1; } } else if (m_scale_state == 1){ // decrease size Ogre::Vector3 scale = node->getScale() - scale_inc; node->setScale(scale); if (node->getScale().y < m_original_scale){ node->setScale(Ogre::Vector3(m_original_scale)); m_scale_state = 0; } } } } if (m_distance <= 0.0f){ SoundData2D pop_sound = m_owner->GetGameObjectManager()->GetSoundManager()->Create2DData("Bubble_Burst", false, false, false, false, 1.0, 1.0); m_owner->GetGameObjectManager()->GetGameObject("Player")->GetComponentMessenger()->Notify(MSG_SFX2D_PLAY, &pop_sound); m_owner->RemoveGameObject(m_owner); } } }
int Create_Static_Object::create(Ogre::SceneManager *mainSceneMgr) { if (meshName.empty() ) { std::cout << "Whoops, what do you think you're doing? You didn't give a mesh name!" << std::endl; return 0; } if (meshFile.empty() ) { std::cout << "Well what did you expect? There's no mesh file to load!" << std::endl; return 0; } Ogre::SceneNode *nodeStaticObject = mainSceneMgr->getRootSceneNode()->createChildSceneNode(meshName, location, rotation); Ogre::Entity *entityStaticObject = mainSceneMgr->createEntity(meshName, meshFile); if (!materialName.empty() ){ entityStaticObject->setMaterialName(materialName); } entityStaticObject->setCastShadows(shadow); nodeStaticObject->attachObject(entityStaticObject); nodeStaticObject->showBoundingBox(showBBox); nodeStaticObject->scale(scale); //Create the ground shape. BtOgre::StaticMeshToShapeConverter ogreBulletShapeConverter(entityStaticObject); if (bulletCollision == "sphere"){ shapeStaticObject = ogreBulletShapeConverter.createSphere(); } else if (bulletCollision == "box"){ shapeStaticObject = ogreBulletShapeConverter.createBox(); offsetLocation = entityStaticObject->getBoundingBox().getHalfSize(); location.y = location.y - offsetLocation.y; } else if (bulletCollision == "trimesh"){ shapeStaticObject = ogreBulletShapeConverter.createTrimesh(); } else if (bulletCollision == "cylinder"){ shapeStaticObject = ogreBulletShapeConverter.createCylinder(); } else if (bulletCollision == "convex"){ shapeStaticObject = ogreBulletShapeConverter.createConvex(); }else{ return 0; } shapeStaticObject->setLocalScaling(BtOgre::Convert::toBullet(nodeStaticObject->getScale() ) ); //Create MotionState (no need for BtOgre here, you can use it if you want to though). stateStaticObject = new btDefaultMotionState(btTransform( BtOgre::Convert::toBullet(rotation), BtOgre::Convert::toBullet(location) ) ); //Create the Body. bodyStaticObject = new btRigidBody(0, stateStaticObject, shapeStaticObject, btVector3(0,0,0)); Globals::phyWorld->addRigidBody(bodyStaticObject); return 1; }
void PhysicsSystem::scaleObject (const Ptr& ptr) { Ogre::SceneNode* node = ptr.getRefData().getBaseNode(); std::string handle = node->getName(); if(handleToMesh.find(handle) != handleToMesh.end()) { removeObject(handle); addObject(ptr); } if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) act->setScale(node->getScale().x); }
void BubbleController::Notify(int type, void* msg){ switch (type){ case MSG_BUBBLE_CONTROLLER_APPLY_IMPULSE: m_apply_impulse = true; m_impulse_direction = *static_cast<Ogre::Vector3*>(msg); break; case MSG_BUBBLE_CONTROLLER_TIMER_RUN: //m_run_timer = *static_cast<bool*>(msg); break; case MSG_BUBBLE_CONTROLLER_ACTIVATE: { if (m_owner->GetType() == GAME_OBJECT_BLUE_BUBBLE){ if (m_ready){ btRigidBody* body = NULL; m_messenger->Notify(MSG_RIGIDBODY_GET_BODY, &body, "body"); if (body){ body->setLinearFactor(btVector3(1,1,1)); m_messenger->Unregister(MSG_BUBBLE_CONTROLLER_ACTIVATE, this); } } } } break; case MSG_BUBBLE_CONTROLLER_READY: { m_ready = true; Ogre::SceneNode* node = NULL; m_messenger->Notify(MSG_NODE_GET_NODE, &node); if (node){ m_original_scale = node->getScale().y; m_max_scale = m_original_scale * 1.2f; } } break; case MSG_BUBBLE_CONTROLLER_PROPERTIES_SET: { BubblePropertiesDef& def = *static_cast<BubblePropertiesDef*>(msg); m_bubble_body->setFriction(def.friction); m_bubble_body->setRollingFriction(def.rolling_friction); m_bubble_body->setRestitution(def.restitution); m_bubble_body->setDamping(def.damping, btScalar(0.0f)); m_bubble_body->setGravity(btVector3(0.0f, -def.gravity, 0.0f)); m_velocity = def.velocity; m_max_velocity = def.max_velocity; } break; default: break; } }
float3x4 EC_Mesh::LocalToParent() const { if (!entity_) { LogError(QString("EC_Mesh::LocalToParent failed! No entity exists in mesh \"%1\" (entity: \"%2\")!").arg(meshRef.Get().ref).arg(ParentEntity() ? ParentEntity()->Name() : "(EC_Mesh with no parent entity)")); return float3x4::identity; } Ogre::SceneNode *node = entity_->getParentSceneNode(); if (!node) { LogError(QString("EC_Mesh::LocalToParent failed! Ogre::Entity is not attached to a Ogre::SceneNode! Mesh \"%1\" (entity: \"%2\")!").arg(meshRef.Get().ref).arg(ParentEntity() ? ParentEntity()->Name() : "(EC_Mesh with no parent entity)")); return float3x4::identity; } return float3x4::FromTRS(node->getPosition(), node->getOrientation(), node->getScale()); }
float3x4 EC_Mesh::LocalToParent() const { if (!entity_) { LogError("EC_Mesh::LocalToParent failed! No entity exists in this mesh!"); return float3x4::identity; } Ogre::SceneNode *node = entity_->getParentSceneNode(); if (!node) { LogError("EC_Mesh::LocalToParent failed! Ogre::Entity is not attached to a Ogre::SceneNode!"); return float3x4::identity; } return float3x4::FromTRS(node->getPosition(), node->getOrientation(), node->getScale()); }
void PhysicsSystem::rotateObject (const Ptr& ptr) { Ogre::SceneNode* node = ptr.getRefData().getBaseNode(); std::string handle = node->getName(); Ogre::Quaternion rotation = node->getOrientation(); if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) { //Needs to be changed act->setRotation(rotation); } if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle)) { if(dynamic_cast<btBoxShape*>(body->getCollisionShape()) == NULL) body->getWorldTransform().setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); else mEngine->boxAdjustExternal(handleToMesh[handle], body, node->getScale().x, node->getPosition(), rotation); } }
void PhysicsSystem::moveObject (const Ptr& ptr) { Ogre::SceneNode* node = ptr.getRefData().getBaseNode(); std::string handle = node->getName(); Ogre::Vector3 position = node->getPosition(); if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle)) { // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow // start positions others than 0, 0, 0 if(dynamic_cast<btBoxShape*>(body->getCollisionShape()) == NULL){ btTransform tr = body->getWorldTransform(); tr.setOrigin(btVector3(position.x,position.y,position.z)); body->setWorldTransform(tr); } else{ //For objects that contain a box shape. //Do any such objects exist? Perhaps animated objects? mEngine->boxAdjustExternal(handleToMesh[handle], body, node->getScale().x, position, node->getOrientation()); } } if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) { // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow // start positions others than 0, 0, 0 if (handle == "player") { playerphysics->ps.origin = position; } else { act->setPosition(position); } } }
void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) { Ogre::SceneNode* insert = ptr.getRefData().getBaseNode(); assert(insert); Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL; NifOgre::EntityList entities = NifOgre::NIFLoader::createEntities(insert, NULL, mesh); for(size_t i = 0;i < entities.mEntities.size();i++) { const Ogre::AxisAlignedBox &tmp = entities.mEntities[i]->getBoundingBox(); bounds.merge(Ogre::AxisAlignedBox(insert->_getDerivedPosition() + tmp.getMinimum(), insert->_getDerivedPosition() + tmp.getMaximum()) ); } Ogre::Vector3 extents = bounds.getSize(); extents *= insert->getScale(); float size = std::max(std::max(extents.x, extents.y), extents.z); bool small = (size < Settings::Manager::getInt("small object size", "Viewing distance")) && Settings::Manager::getBool("limit small object distance", "Viewing distance"); // do not fade out doors. that will cause holes and look stupid if (ptr.getTypeName().find("Door") != std::string::npos) small = false; if (mBounds.find(ptr.getCell()) == mBounds.end()) mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL; mBounds[ptr.getCell()].merge(bounds); bool transparent = false; for(size_t i = 0;i < entities.mEntities.size();i++) { Ogre::Entity *ent = entities.mEntities[i]; for (unsigned int i=0; i<ent->getNumSubEntities(); ++i) { Ogre::MaterialPtr mat = ent->getSubEntity(i)->getMaterial(); Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); while (techIt.hasMoreElements()) { Ogre::Technique* tech = techIt.getNext(); Ogre::Technique::PassIterator passIt = tech->getPassIterator(); while (passIt.hasMoreElements()) { Ogre::Pass* pass = passIt.getNext(); if (pass->getDepthWriteEnabled() == false) transparent = true; } } } } if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects") || transparent) { for(size_t i = 0;i < entities.mEntities.size();i++) { Ogre::Entity *ent = entities.mEntities[i]; ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc); ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); } } else { Ogre::StaticGeometry* sg = 0; if (small) { if( mStaticGeometrySmall.find(ptr.getCell()) == mStaticGeometrySmall.end()) { uniqueID = uniqueID +1; sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); mStaticGeometrySmall[ptr.getCell()] = sg; sg->setRenderingDistance(Settings::Manager::getInt("small object distance", "Viewing distance")); } else sg = mStaticGeometrySmall[ptr.getCell()]; } else { if( mStaticGeometry.find(ptr.getCell()) == mStaticGeometry.end()) { uniqueID = uniqueID +1; sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); mStaticGeometry[ptr.getCell()] = sg; } else sg = mStaticGeometry[ptr.getCell()]; } // This specifies the size of a single batch region. // If it is set too high: // - there will be problems choosing the correct lights // - the culling will be more inefficient // If it is set too low: // - there will be too many batches. sg->setRegionDimensions(Ogre::Vector3(2500,2500,2500)); sg->setVisibilityFlags(small ? RV_StaticsSmall : RV_Statics); sg->setCastShadows(true); sg->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); for(size_t i = 0;i < entities.mEntities.size();i++) { Ogre::Entity *ent = entities.mEntities[i]; insert->detachObject(ent); sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale()); mRenderer.getScene()->destroyEntity(ent); } } }
void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh, bool light) { Ogre::SceneNode* insert = ptr.getRefData().getBaseNode(); assert(insert); Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL; NifOgre::ObjectList objects = NifOgre::Loader::createObjects(insert, mesh); for(size_t i = 0;i < objects.mEntities.size();i++) bounds.merge(objects.mEntities[i]->getWorldBoundingBox(true)); Ogre::Vector3 extents = bounds.getSize(); extents *= insert->getScale(); float size = std::max(std::max(extents.x, extents.y), extents.z); bool small = (size < Settings::Manager::getInt("small object size", "Viewing distance")) && Settings::Manager::getBool("limit small object distance", "Viewing distance"); // do not fade out doors. that will cause holes and look stupid if (ptr.getTypeName().find("Door") != std::string::npos) small = false; if (mBounds.find(ptr.getCell()) == mBounds.end()) mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL; mBounds[ptr.getCell()].merge(bounds); bool anyTransparency = false; for(size_t i = 0;!anyTransparency && i < objects.mEntities.size();i++) { Ogre::Entity *ent = objects.mEntities[i]; for(unsigned int i=0;!anyTransparency && i < ent->getNumSubEntities(); ++i) { anyTransparency = ent->getSubEntity(i)->getMaterial()->isTransparent(); } } if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects") || anyTransparency || objects.mParticles.size() > 0) { for(size_t i = 0;i < objects.mEntities.size();i++) { Ogre::Entity *ent = objects.mEntities[i]; for(unsigned int i=0; i < ent->getNumSubEntities(); ++i) { Ogre::SubEntity* subEnt = ent->getSubEntity(i); subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main); } ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc); } for(size_t i = 0;i < objects.mParticles.size();i++) { Ogre::ParticleSystem *part = objects.mParticles[i]; // TODO: Check the particle system's material for actual transparency part->setRenderQueueGroup(RQG_Alpha); part->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); part->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc); } } else { Ogre::StaticGeometry* sg = 0; if (small) { if( mStaticGeometrySmall.find(ptr.getCell()) == mStaticGeometrySmall.end()) { uniqueID = uniqueID +1; sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); mStaticGeometrySmall[ptr.getCell()] = sg; sg->setRenderingDistance(Settings::Manager::getInt("small object distance", "Viewing distance")); } else sg = mStaticGeometrySmall[ptr.getCell()]; } else { if( mStaticGeometry.find(ptr.getCell()) == mStaticGeometry.end()) { uniqueID = uniqueID +1; sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); mStaticGeometry[ptr.getCell()] = sg; } else sg = mStaticGeometry[ptr.getCell()]; } // This specifies the size of a single batch region. // If it is set too high: // - there will be problems choosing the correct lights // - the culling will be more inefficient // If it is set too low: // - there will be too many batches. sg->setRegionDimensions(Ogre::Vector3(2500,2500,2500)); sg->setVisibilityFlags(small ? RV_StaticsSmall : RV_Statics); sg->setCastShadows(true); sg->setRenderQueueGroup(RQG_Main); std::vector<Ogre::Entity*>::reverse_iterator iter = objects.mEntities.rbegin(); while(iter != objects.mEntities.rend()) { Ogre::Node *node = (*iter)->getParentNode(); sg->addEntity(*iter, node->_getDerivedPosition(), node->_getDerivedOrientation(), node->_getDerivedScale()); (*iter)->detachFromParent(); mRenderer.getScene()->destroyEntity(*iter); iter++; } } if (light) { insertLight(ptr, objects.mSkelBase, bounds.getCenter() - insert->_getDerivedPosition()); } }
void PhysicsSystem::addObject (const Ptr& ptr) { std::string mesh = MWWorld::Class::get(ptr).getModel(ptr); Ogre::SceneNode* node = ptr.getRefData().getBaseNode(); handleToMesh[node->getName()] = mesh; OEngine::Physic::RigidBody* body = mEngine->createAndAdjustRigidBody(mesh, node->getName(), node->getScale().x, node->getPosition(), node->getOrientation()); mEngine->addRigidBody(body); }