void Entity::decode(const std::string& fileName) { // tinyxml2::XMLDocument doc; if (tinyxml2::XML_SUCCESS != doc.LoadFile(fileName.c_str())) { return; } tinyxml2::XMLElement* r = doc.RootElement(); tinyxml2::XMLElement* tex= r->FirstChildElement("subEntity"); std::string parentPath = Buddha::FileSystem::getInstancePtr()->standardFilePath(fileName); parentPath = Buddha::FileSystem::getInstancePtr()->getParent(parentPath); parentPath = Buddha::FileSystem::getInstancePtr()->getParent(parentPath); parentPath += "/"; while (tex) { std::string subEntityFileName = tex->Attribute("file"); SubEntity* sub = new SubEntity; sub->decode(parentPath + subEntityFileName); mSubEntities.push_back(sub); tex = tex->NextSiblingElement("subEntity"); } }
void OgreSample13App::setupInstancedMaterialToEntity(Ogre::Entity *ent) { for (Ogre::uint i=0;i<ent->getNumSubEntities();++i) { SubEntity * se = ent->getSubEntity(i); String materialName = se->getMaterialName(); se->setMaterialName(buildInstancedMaterial(materialName)); } }
//----------------------------------------------------------------------------- void VisibleBspLeavesSearch::addBspEntityToRenderQueue() { for(size_t i = 0; i != mNumMaterials; ++i) { SubEntity* subEntity = mEntity->getSubEntity(i); if(subEntity->isVisible() && mIndexDatas[i] && mIndexDatas[i]->indexCount != 0) { mRenderQueue->addRenderable(subEntity); } } }
//----------------------------------------------------------------------- void MeshInformer::getEntityStatistics(const Entity* entity, size_t& numVertices, size_t& numIndices) { size_t numSubEntities = entity->getNumSubEntities(); bool added_shared_vertex = false; for (size_t i = 0; i < numSubEntities; ++i) { SubEntity* subEntity = entity->getSubEntity(i); if (!subEntity->isVisible()) { // Skip non-visible sub-entity continue; } SubMesh* subMesh = subEntity->getSubMesh(); if (subMesh->operationType == RenderOperation::OT_TRIANGLE_LIST || subMesh->operationType == RenderOperation::OT_TRIANGLE_STRIP || subMesh->operationType == RenderOperation::OT_TRIANGLE_FAN) { if (subMesh->useSharedVertices) { if (!added_shared_vertex) { added_shared_vertex = true; numVertices += subMesh->parent->sharedVertexData->vertexCount; } } else { numVertices += subMesh->vertexData->vertexCount; } assert(subMesh->indexData->indexCount >= 3); switch (subMesh->operationType) { case RenderOperation::OT_TRIANGLE_LIST: assert(subMesh->indexData->indexCount % 3 == 0); numIndices += subMesh->indexData->indexCount; break; case RenderOperation::OT_TRIANGLE_STRIP: case RenderOperation::OT_TRIANGLE_FAN: numIndices += (subMesh->indexData->indexCount - 2) * 3; break; } } } }
//--------------------------------------------------------------------- void Animation::apply(Entity* entity, Real timePos, Real weight, bool software, bool hardware) { _applyBaseKeyFrame(); // Calculate time index for fast keyframe search TimeIndex timeIndex = _getTimeIndex(timePos); VertexTrackList::iterator i; for (i = mVertexTrackList.begin(); i != mVertexTrackList.end(); ++i) { unsigned short handle = i->first; VertexAnimationTrack* track = i->second; VertexData* swVertexData; VertexData* hwVertexData; if (handle == 0) { // shared vertex data swVertexData = entity->_getSoftwareVertexAnimVertexData(); hwVertexData = entity->_getHardwareVertexAnimVertexData(); entity->_markBuffersUsedForAnimation(); } else { // sub entity vertex data (-1) SubEntity* s = entity->getSubEntity(handle - 1); // Skip this track if subentity is not visible if (!s->isVisible()) continue; swVertexData = s->_getSoftwareVertexAnimVertexData(); hwVertexData = s->_getHardwareVertexAnimVertexData(); s->_markBuffersUsedForAnimation(); } // Apply to both hardware and software, if requested if (software) { track->setTargetMode(VertexAnimationTrack::TM_SOFTWARE); track->applyToVertexData(swVertexData, timeIndex, weight, &(entity->getMesh()->getPoseList())); } if (hardware) { track->setTargetMode(VertexAnimationTrack::TM_HARDWARE); track->applyToVertexData(hwVertexData, timeIndex, weight, &(entity->getMesh()->getPoseList())); } } }
void MeshObject::setHighlighted( bool highlight ) { String nameExtension = "_HighLight"; Entity* ent = getEntity(); int numEnts = ent->getNumSubEntities(); for( int i = 0; i < numEnts; i++ ) { SubEntity* subent = ent->getSubEntity(i); if( subent == NULL ) continue; // TODO - optimieren, nur wenn der Typ verändert wird //if(StringUtil::endsWith(subent->getMaterialName(),nameExtension) // == highlight ) // continue; MaterialPtr oldMaterial = subent->getMaterial(); // Highlight setzen if( highlight ) { MaterialPtr material = MaterialManager::getSingleton().getByName( oldMaterial->getName()+nameExtension ); if( material.isNull() ) { material = oldMaterial->clone( oldMaterial->getName()+nameExtension ); material->setAmbient(1.0, 1.0, 1.0); material->setDiffuse(1.0, 1.0, 1.0, 1.0); material->setSelfIllumination(0.4, 0.4, 0.4); } subent->setMaterialName(material->getName()); } // Highlight entfernen else { String matName = oldMaterial->getName(); matName = matName.erase(matName.length() - nameExtension.length(), nameExtension.length() ); subent->setMaterialName( matName ); } } }
int MultiPlayChapter::OnMouseMove(int x, int y) { if( m_pkThirdCube->IsWait() ) return 0; if( g_nMouseState & 1 ) { //Ray mouseRay = m_pkCamera->getCameraToViewportRay((float)x/m_pkWindow->getWidth(), (float)y/m_pkWindow->getHeight()); Ray mouseRay = m_pkCamera->getCameraToViewportRay((float)(x-(m_pkWindow->getWidth()*0.25f))/m_pkViewport->getActualWidth(), (float)y/m_pkViewport->getActualHeight()); Entity *target; float dis; int subIndex = -1; Vector3 result; if( m_pkCollisionTools->raycastFromPoint(mouseRay.getOrigin(), mouseRay.getDirection(), result, target, dis, subIndex) ) { if( m_currentEntity == target ) return 0; if( m_currentEntity ) { m_pkMIManager->SetTransparency(m_currentEntity, 0.4f, m_nCurrentSubIndex); m_currentEntity = 0; } SubEntity *subEntity = target->getSubEntity(subIndex); if( subEntity->getMaterialName().substr(0,10) == "07-Default" ) return 0; for(int i=0; i<4; ++i) { if( target == m_pkMaterialChange[i] && subIndex == m_nMaterialChangeIndex[i] ) { m_currentEntity = target; m_nCurrentSubIndex = subIndex; m_nCurrentMOC = result; } } if( m_currentEntity == 0 ) return 0; m_pkMIManager->ChangeOriginalMaterial(m_currentEntity, subIndex); } } return 0; }
//----------------------------------------------------------------------- void Entity::buildSubEntityList(Mesh* mesh, SubEntityList* sublist) { // Create SubEntities int i, numSubMeshes; SubMesh* subMesh; SubEntity* subEnt; numSubMeshes = mesh->getNumSubMeshes(); for (i = 0; i < numSubMeshes; ++i) { subMesh = mesh->getSubMesh(i); subEnt = new SubEntity(); subEnt->mParentEntity = this; subEnt->mSubMesh = subMesh; if (subMesh->isMatInitialised()) subEnt->setMaterialName(subMesh->getMaterialName()); sublist->push_back(subEnt); } }
//----------------------------------------------------------------------- void HardwareSkinningFactory::prepareEntityForSkinning(const Entity* pEntity, SkinningType skinningType, bool correctAntidpodalityHandling, bool shearScale) { if (pEntity != NULL) { size_t lodLevels = pEntity->getNumManualLodLevels() + 1; for(size_t indexLod = 0 ; indexLod < lodLevels ; ++indexLod) { const Entity* pCurEntity = pEntity; if (indexLod > 0) pCurEntity = pEntity->getManualLodLevel(indexLod - 1); ushort boneCount = 0,weightCount = 0; bool isValid = extractSkeletonData(pCurEntity,boneCount,weightCount); unsigned int numSubEntities = pCurEntity->getNumSubEntities(); for(unsigned int indexSub = 0 ; indexSub < numSubEntities ; ++indexSub) { SubEntity* pSubEntity = pCurEntity->getSubEntity(indexSub); const MaterialPtr& pMat = pSubEntity->getMaterial(); imprintSkeletonData(pMat, isValid, boneCount, weightCount, skinningType, correctAntidpodalityHandling, shearScale); } } } }
//--------------------------------------------------------------------- void Animation::apply(Entity* entity, Real timePos, Real weight, bool software, bool hardware) { // Calculate time index for fast keyframe search TimeIndex timeIndex = _getTimeIndex(timePos); VertexTrackList::iterator i; for (i = mVertexTrackList.begin(); i != mVertexTrackList.end(); ++i) { unsigned short handle = i->first; VertexAnimationTrack* track = i->second; VertexData* swVertexData; VertexData* hwVertexData; VertexData* origVertexData; bool firstAnim = false; if (handle == 0) { // shared vertex data firstAnim = !entity->_getBuffersMarkedForAnimation(); swVertexData = entity->_getSoftwareVertexAnimVertexData(); hwVertexData = entity->_getHardwareVertexAnimVertexData(); origVertexData = entity->getMesh()->sharedVertexData; entity->_markBuffersUsedForAnimation(); } else { // sub entity vertex data (-1) SubEntity* s = entity->getSubEntity(handle - 1); // Skip this track if subentity is not visible if (!s->isVisible()) continue; firstAnim = !s->_getBuffersMarkedForAnimation(); swVertexData = s->_getSoftwareVertexAnimVertexData(); hwVertexData = s->_getHardwareVertexAnimVertexData(); origVertexData = s->getSubMesh()->vertexData; s->_markBuffersUsedForAnimation(); } // Apply to both hardware and software, if requested if (software) { if (firstAnim && track->getAnimationType() == VAT_POSE) { // First time through for a piece of pose animated vertex data // We need to copy the original position values to the temp accumulator const VertexElement* origelem = origVertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); const VertexElement* destelem = swVertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); HardwareVertexBufferSharedPtr origBuffer = origVertexData->vertexBufferBinding->getBuffer(origelem->getSource()); HardwareVertexBufferSharedPtr destBuffer = swVertexData->vertexBufferBinding->getBuffer(destelem->getSource()); destBuffer->copyData(*origBuffer.get(), 0, 0, destBuffer->getSizeInBytes(), true); } track->setTargetMode(VertexAnimationTrack::TM_SOFTWARE); track->applyToVertexData(swVertexData, timeIndex, weight, &(entity->getMesh()->getPoseList())); } if (hardware) { track->setTargetMode(VertexAnimationTrack::TM_HARDWARE); track->applyToVertexData(hwVertexData, timeIndex, weight, &(entity->getMesh()->getPoseList())); } } }
//----------------------------------------------------------------------- void MeshInformer::getEntityTriangles(const Entity* entity, std::vector<Vector3>& vertices, std::vector<size_t>& indices, std::vector<size_t>* indexOffsets) { size_t numVertices = 0, numIndices = 0; getEntityStatistics(entity, numVertices, numIndices); size_t vertex_offset = vertices.size(); size_t index_offset = indices.size(); vertices.resize(vertex_offset + numVertices); indices.resize(index_offset + numIndices); // Software blended vertex data available only if animation enabled, and software animation are // used by internally engine, or user requested software animation. bool useBlended = entity->_isAnimated() && (!entity->isHardwareAnimationEnabled() || entity->getSoftwareAnimationRequests() > 0); // Use skinned vertex data only if blended data available and skeleton animation enabled. bool useSkinned = useBlended && entity->_isSkeletonAnimated(); Vector3* pVertices = &vertices[0]; size_t* pIndices = &indices[0]; size_t shared_vertex_offset = vertex_offset; bool added_shared_vertex = false; size_t numSubEntities = entity->getNumSubEntities(); for (size_t i = 0; i < numSubEntities; ++i) { SubEntity* subEntity = entity->getSubEntity(i); if (!subEntity->isVisible()) { // Skip non-visible sub-entity continue; } SubMesh* subMesh = subEntity->getSubMesh(); if (indexOffsets) { indexOffsets->push_back(index_offset); } if (subMesh->operationType == RenderOperation::OT_TRIANGLE_LIST || subMesh->operationType == RenderOperation::OT_TRIANGLE_STRIP || subMesh->operationType == RenderOperation::OT_TRIANGLE_FAN) { size_t current_vertex_offset; if (subMesh->useSharedVertices) { if (!added_shared_vertex) { size_t vertexCount = getVertices(pVertices + vertex_offset, useSkinned ? entity->_getSkelAnimVertexData() : useBlended && subMesh->parent->getSharedVertexDataAnimationType() != VAT_NONE ? entity->_getSoftwareVertexAnimVertexData() : subMesh->parent->sharedVertexData); shared_vertex_offset = vertex_offset; vertex_offset += vertexCount; added_shared_vertex = true; } current_vertex_offset = shared_vertex_offset; } else { size_t vertexCount = getVertices(pVertices + vertex_offset, useSkinned ? subEntity->_getSkelAnimVertexData() : useBlended && subMesh->getVertexAnimationType() != VAT_NONE ? subEntity->_getSoftwareVertexAnimVertexData() : subMesh->vertexData); current_vertex_offset = vertex_offset; vertex_offset += vertexCount; } size_t index_count = getTriangles(pIndices + index_offset, subMesh->indexData, current_vertex_offset, subMesh->operationType); index_offset += index_count; } } }
// Just override the mandatory create scene method void createScene(void) { // Check capabilities const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities(); if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !(caps->hasCapability(RSC_FRAGMENT_PROGRAM))) { OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support vertex and fragment programs, so cannot " "run this demo. Sorry!", "CelShading::createScene"); } // Create a point light Light* l = mSceneMgr->createLight("MainLight"); // Accept default settings: point light, white diffuse, just set position // Add light to the scene node rotNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); rotNode->createChildSceneNode(Vector3(20,40,50))->attachObject(l); Entity *ent = mSceneMgr->createEntity("head", "ogrehead.mesh"); mCamera->setPosition(20, 0, 100); mCamera->lookAt(0,0,0); // Set common material, but define custom parameters to change colours // See Example-Advanced.material for how these are finally bound to GPU parameters SubEntity* sub; // eyes sub = ent->getSubEntity(0); sub->setMaterialName("Examples/CelShading"); sub->setCustomParameter(CUSTOM_SHININESS, Vector4(35.0f, 0.0f, 0.0f, 0.0f)); sub->setCustomParameter(CUSTOM_DIFFUSE, Vector4(1.0f, 0.3f, 0.3f, 1.0f)); sub->setCustomParameter(CUSTOM_SPECULAR, Vector4(1.0f, 0.6f, 0.6f, 1.0f)); // skin sub = ent->getSubEntity(1); sub->setMaterialName("Examples/CelShading"); sub->setCustomParameter(CUSTOM_SHININESS, Vector4(10.0f, 0.0f, 0.0f, 0.0f)); sub->setCustomParameter(CUSTOM_DIFFUSE, Vector4(0.0f, 0.5f, 0.0f, 1.0f)); sub->setCustomParameter(CUSTOM_SPECULAR, Vector4(0.3f, 0.5f, 0.3f, 1.0f)); // earring sub = ent->getSubEntity(2); sub->setMaterialName("Examples/CelShading"); sub->setCustomParameter(CUSTOM_SHININESS, Vector4(25.0f, 0.0f, 0.0f, 0.0f)); sub->setCustomParameter(CUSTOM_DIFFUSE, Vector4(1.0f, 1.0f, 0.0f, 1.0f)); sub->setCustomParameter(CUSTOM_SPECULAR, Vector4(1.0f, 1.0f, 0.7f, 1.0f)); // teeth sub = ent->getSubEntity(3); sub->setMaterialName("Examples/CelShading"); sub->setCustomParameter(CUSTOM_SHININESS, Vector4(20.0f, 0.0f, 0.0f, 0.0f)); sub->setCustomParameter(CUSTOM_DIFFUSE, Vector4(1.0f, 1.0f, 0.7f, 1.0f)); sub->setCustomParameter(CUSTOM_SPECULAR, Vector4(1.0f, 1.0f, 1.0f, 1.0f)); // Add entity to the root scene node mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); mWindow->getViewport(0)->setBackgroundColour(ColourValue::White); }
int MultiPlayChapter::OnMouseClick(int x, int y, unsigned short nButton, unsigned short nModifier) { if( m_pkThirdCube->IsWait() ) return 0; switch( nButton ) { case 0: { ShowCursor(true); if( m_pkThirdCube->IsShuffle() ) break; Ray mouseRay = m_pkCamera->getCameraToViewportRay((float)(x-(m_pkWindow->getWidth()*0.25f))/m_pkViewport->getActualWidth(), (float)y/m_pkViewport->getActualHeight()); Entity *target; float dis; int subIndex = 0; Vector3 result; if( m_pkCollisionTools->raycastFromPoint(mouseRay.getOrigin(), mouseRay.getDirection(), result, target, dis, subIndex) ) { SubEntity *subEntity = target->getSubEntity(subIndex); if( subEntity->getMaterialName() == "07-Default" ) break; String tmp = target->getParentNode()->getName(); int dumiIndex = Ogre::StringConverter::parseInt(tmp.substr(5,2)); m_pkThirdCube->InputFirstSelect(dumiIndex-1, result); Vector3 dumi(m_pkThirdCube->GetDumiPos(dumiIndex-1)); int axis=0; float x, y, z; x = result.x<0?result.x*-1: result.x; y = result.y<0?result.y*-1: result.y; z = result.z<0?result.z*-1: result.z; for(int i=0; i<27; ++i) { Entity *entity = m_pkThirdCube->GetBoxEntity(i); m_pkMIManager->AddData(new MIManagerData(entity, new EntityMaterialInstance(entity))); } Vector3 Ray1[2] = { Vector3(dumi), Vector3(dumi) }; Vector3 Ray2[2] = { Vector3(dumi), Vector3(dumi) }; Vector3 dir(Vector3::ZERO); if( x > 15.4f ) axis = 1; else if( y > 15.4f ) axis = 2; else if( z > 15.4f ) axis = 3; switch( axis ) { case 1: { dir.x = result.x<0?1.0f:-1.0f; Ray1[0].x = dumi.x<0?dumi.x-10.0f: dumi.x+10.0f; Ray1[1].x = Ray1[0].x; Ray2[0].x = Ray1[0].x; Ray2[1].x = Ray1[0].x; if( dumi.y == 0 ) { Ray1[0].y = dumi.y+10.5f; Ray1[1].y = dumi.y-10.5f; } else if( dumi.y > 0 ) { Ray1[0].y = dumi.y-10.5f; Ray1[1].y = dumi.y-21.0f; } else if( dumi.y < 0 ) { Ray1[0].y = dumi.y+10.5f; Ray1[1].y = dumi.y+21.0f; } if( dumi.z == 0 ) { Ray2[0].z = dumi.z+10.5f; Ray2[1].z = dumi.z-10.5f; } else if( dumi.z > 0 ) { Ray2[0].z = dumi.z-10.5f; Ray2[1].z = dumi.z-21.0f; } else if( dumi.z < 0 ) { Ray2[0].z = dumi.z+10.5f; Ray2[1].z = dumi.z+21.0f; } } break; case 2: { dir.y = result.y<0?1.0f:-1.0f; Ray1[0].y = dumi.y<0?dumi.y-10.0f: dumi.y+10.0f; Ray1[1].y = Ray1[0].y; Ray2[0].y = Ray1[0].y; Ray2[1].y = Ray1[0].y; if( dumi.x == 0 ) { Ray1[0].x = dumi.x+10.5f; Ray1[1].x = dumi.x-10.5f; } else if( dumi.x > 0 ) { Ray1[0].x = dumi.x-10.5f; Ray1[1].x = dumi.x-21.0f; } else if( dumi.x < 0 ) { Ray1[0].x = dumi.x+10.5f; Ray1[1].x = dumi.x+21.0f; } if( dumi.z == 0 ) { Ray2[0].z = dumi.z+10.5f; Ray2[1].z = dumi.z-10.5f; } else if( dumi.z > 0 ) { Ray2[0].z = dumi.z-10.5f; Ray2[1].z = dumi.z-21.0f; } else if( dumi.z < 0 ) { Ray2[0].z = dumi.z+10.5f; Ray2[1].z = dumi.z+21.0f; } } break; case 3: { dir.z = result.z<0?1.0f:-1.0f; Ray1[0].z = dumi.z<0?dumi.z-10.0f: dumi.z+10.0f; Ray1[1].z = Ray1[0].z; Ray2[0].z = Ray1[0].z; Ray2[1].z = Ray1[0].z; if( dumi.x == 0 ) { Ray1[0].x = dumi.x+10.5f; Ray1[1].x = dumi.x-10.5f; } else if( dumi.x > 0 ) { Ray1[0].x = dumi.x-10.5f; Ray1[1].x = dumi.x-21.0f; } else if( dumi.x < 0 ) { Ray1[0].x = dumi.x+10.5f; Ray1[1].x = dumi.x+21.0f; } if( dumi.y == 0 ) { Ray2[0].y = dumi.y+10.5f; Ray2[1].y = dumi.y-10.5f; } else if( dumi.y > 0 ) { Ray2[0].y = dumi.y-10.5f; Ray2[1].y = dumi.y-21.0f; } else if( dumi.y < 0 ) { Ray2[0].y = dumi.y+10.5f; Ray2[1].y = dumi.y+21.0f; } } break; } m_pkCollisionTools->raycastFromPoint(Ray1[0], dir, result, target, dis, subIndex); m_pkMaterialChange[0] = target; m_nMaterialChangeIndex[0] = subIndex; m_pkMIManager->SetTransparency(target, 0.4f, subIndex); m_pkCollisionTools->raycastFromPoint(Ray1[1], dir, result, target, dis, subIndex); m_pkMaterialChange[1] = target; m_nMaterialChangeIndex[1] = subIndex; m_pkMIManager->SetTransparency(target, 0.4f, subIndex); m_pkCollisionTools->raycastFromPoint(Ray2[0], dir, result, target, dis, subIndex); m_pkMaterialChange[2] = target; m_nMaterialChangeIndex[2] = subIndex; m_pkMIManager->SetTransparency(target, 0.4f, subIndex); m_pkCollisionTools->raycastFromPoint(Ray2[1], dir, result, target, dis, subIndex); m_pkMaterialChange[3] = target; m_nMaterialChangeIndex[3] = subIndex; m_pkMIManager->SetTransparency(target, 0.4f, subIndex); g_nMouseState |= 1; } else { m_pkThirdCube->InputFirstSelect(-1, result); } break; } case 1: { m_pkThirdCube->OnRMouseClick(x, y, nModifier); break; } case 2: { break; } } return 0; }
void TerrainObjectManager::loadObject(const Ogre::String &name, const Ogre::Vector3 &pos, const Ogre::Vector3 &rot, Ogre::SceneNode *bakeNode, const Ogre::String &instancename, const Ogre::String &type, bool enable_collisions /* = true */, int scripthandler /* = -1 */, bool uniquifyMaterial /* = false */) { ScopeLog log("object_"+name); if (type == "grid") { // some fast grid object hacks :) for (int x=0; x < 500; x += 50) { for (int z=0; z < 500; z += 50) { const String notype = ""; loadObject(name, pos + Vector3(x, 0.0f, z), rot, bakeNode, name, notype, enable_collisions, scripthandler, uniquifyMaterial); } } return; } // nice idea, but too many random hits //if (abs(rot.x+1) < 0.001) rot.x = Math::RangeRandom(0, 360); //if (abs(rot.y+1) < 0.001) rot.y = Math::RangeRandom(0, 360); //if (abs(rot.z+1) < 0.001) rot.z = Math::RangeRandom(0, 360); if (name.empty()) return; //FILE *fd; //char oname[1024] = {}; char mesh[1024] = {}; char line[1024] = {}; char collmesh[1024] = {}; Vector3 l(Vector3::ZERO); Vector3 h(Vector3::ZERO); Vector3 dr(Vector3::ZERO); Vector3 fc(Vector3::ZERO); Vector3 sc(Vector3::ZERO); Vector3 sr(Vector3::ZERO); bool forcecam=false; bool ismovable=false; int event_filter = EVENT_ALL; Quaternion rotation = Quaternion(Degree(rot.x), Vector3::UNIT_X) * Quaternion(Degree(rot.y), Vector3::UNIT_Y) * Quaternion(Degree(rot.z), Vector3::UNIT_Z); // try to load with UID first! String odefgroup = ""; String odefname = name + ".odef"; bool odefFound = false; bool exists = ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(odefname); if (exists) { odefgroup = ResourceGroupManager::getSingleton().findGroupContainingResource(odefname); odefFound = true; } if (!RoR::Application::GetCacheSystem()->checkResourceLoaded(odefname, odefgroup)) if (!odefFound) { LOG("Error while loading Terrain: could not find required .odef file: " + odefname + ". Ignoring entry."); return; } DataStreamPtr ds=ResourceGroupManager::getSingleton().openResource(odefname, odefgroup); ds->readLine(mesh, 1023); if (String(mesh) == "LOD") { // LOD line is obsolete ds->readLine(mesh, 1023); } //scale ds->readLine(line, 1023); sscanf(line, "%f, %f, %f",&sc.x, &sc.y, &sc.z); String entityName = "object" + TOSTRING(objcounter) + "(" + name + ")"; objcounter++; SceneNode *tenode = gEnv->sceneManager->getRootSceneNode()->createChildSceneNode(); bool background_loading = BSETTING("Background Loading", false); MeshObject *mo = NULL; if (String(mesh) != "none") { mo = new MeshObject(mesh, entityName, tenode, NULL, background_loading); } //mo->setQueryFlags(OBJECTS_MASK); //tenode->attachObject(te); tenode->setScale(sc); tenode->setPosition(pos); tenode->rotate(rotation); tenode->pitch(Degree(-90)); tenode->setVisible(true); // register in map loadedObject_t *obj = &loadedObjects[instancename]; obj->instanceName = instancename; obj->loadType = 0; obj->enabled = true; obj->sceneNode = tenode; obj->collTris.clear(); if (mo && uniquifyMaterial && !instancename.empty()) { for (unsigned int i = 0; i < mo->getEntity()->getNumSubEntities(); i++) { SubEntity *se = mo->getEntity()->getSubEntity(i); String matname = se->getMaterialName(); String newmatname = matname + "/" + instancename; //LOG("subentity " + TOSTRING(i) + ": "+ matname + " -> " + newmatname); se->getMaterial()->clone(newmatname); se->setMaterialName(newmatname); } } //String meshGroup = ResourceGroupManager::getSingleton().findGroupContainingResource(mesh); //MeshPtr mainMesh = mo->getMesh(); //collision box(es) bool virt=false; bool rotating=false; bool classic_ref=true; // everything is of concrete by default ground_model_t *gm = gEnv->collisions->getGroundModelByString("concrete"); char eventname[256] = {}; while (!ds->eof()) { size_t ll=ds->readLine(line, 1023); // little workaround to trim it String lineStr = String(line); Ogre::StringUtil::trim(lineStr); const char* ptline = lineStr.c_str(); if (ll==0 || line[0]=='/' || line[0]==';') continue; if (!strcmp("end",ptline)) break; if (!strcmp("movable", ptline)) {ismovable=true;continue;}; if (!strcmp("localizer-h", ptline)) { localizers[free_localizer].position=Vector3(pos.x,pos.y,pos.z); localizers[free_localizer].rotation=rotation; localizers[free_localizer].type=Autopilot::LOCALIZER_HORIZONTAL; free_localizer++; continue; } if (!strcmp("localizer-v", ptline)) { localizers[free_localizer].position=Vector3(pos.x,pos.y,pos.z); localizers[free_localizer].rotation=rotation; localizers[free_localizer].type=Autopilot::LOCALIZER_VERTICAL; free_localizer++; continue; } if (!strcmp("localizer-ndb", ptline)) { localizers[free_localizer].position=Vector3(pos.x,pos.y,pos.z); localizers[free_localizer].rotation=rotation; localizers[free_localizer].type=Autopilot::LOCALIZER_NDB; free_localizer++; continue; } if (!strcmp("localizer-vor", ptline)) { localizers[free_localizer].position=Vector3(pos.x,pos.y,pos.z); localizers[free_localizer].rotation=rotation; localizers[free_localizer].type=Autopilot::LOCALIZER_VOR; free_localizer++; continue; } if (!strcmp("standard", ptline)) {classic_ref=false;tenode->pitch(Degree(90));continue;}; if (!strncmp("sound", ptline, 5)) { #ifdef USE_OPENAL if (!SoundScriptManager::getSingleton().isDisabled()) { char tmp[255]=""; sscanf(ptline, "sound %s", tmp); SoundScriptInstance *sound = SoundScriptManager::getSingleton().createInstance(tmp, MAX_TRUCKS+1, tenode); sound->setPosition(tenode->getPosition(), Vector3::ZERO); sound->start(); } #endif //USE_OPENAL continue; } if (!strcmp("beginbox", ptline) || !strcmp("beginmesh", ptline)) { dr = Vector3::ZERO; rotating=false; virt=false; forcecam=false; event_filter=EVENT_NONE; eventname[0]=0; collmesh[0]=0; gm = gEnv->collisions->getGroundModelByString("concrete"); continue; }; if (!strncmp("boxcoords", ptline, 9)) { sscanf(ptline, "boxcoords %f, %f, %f, %f, %f, %f",&l.x,&h.x,&l.y,&h.y,&l.z, &h.z); continue; } if (!strncmp("mesh", ptline, 4)) { sscanf(ptline, "mesh %s",collmesh); continue; } if (!strncmp("rotate", ptline, 6)) { sscanf(ptline, "rotate %f, %f, %f",&sr.x, &sr.y, &sr.z); rotating=true; continue; } if (!strncmp("forcecamera", ptline, 11)) { sscanf(ptline, "forcecamera %f, %f, %f",&fc.x, &fc.y, &fc.z); forcecam=true; continue; } if (!strncmp("direction", ptline, 9)) { sscanf(ptline, "direction %f, %f, %f",&dr.x, &dr.y, &dr.z); continue; } if (!strncmp("frictionconfig", ptline, 14) && strlen(ptline) > 15) { // load a custom friction config gEnv->collisions->loadGroundModelsConfigFile(String(ptline + 15)); continue; } if ((!strncmp("stdfriction", ptline, 11) || !strncmp("usefriction", ptline, 11)) && strlen(ptline) > 12) { String modelName = String(ptline + 12); gm = gEnv->collisions->getGroundModelByString(modelName); continue; } if (!strcmp("virtual", ptline)) {virt=true;continue;}; if (!strncmp("event", ptline, 5)) { char ts[256]; ts[0]=0; sscanf(ptline, "event %s %s",eventname, ts); if (!strncmp(ts, "avatar", 6)) event_filter=EVENT_AVATAR; else if (!strncmp(ts, "truck", 5)) event_filter=EVENT_TRUCK; else if (!strncmp(ts, "airplane", 8)) event_filter=EVENT_AIRPLANE; else if (!strncmp(ts, "boat", 8)) event_filter=EVENT_BOAT; else if (!strncmp(ts, "delete", 8)) event_filter=EVENT_DELETE; //if (!strncmp(ts, "shoptruck", 9)) // terrainManager->terrainHasTruckShop=true; // fallback if (strlen(ts) == 0) event_filter=EVENT_ALL; continue; } if (!strcmp("endbox", ptline)) { if (enable_collisions) { const String eventnameStr = eventname; int boxnum = gEnv->collisions->addCollisionBox(tenode, rotating, virt, pos, rot, l, h, sr, eventnameStr, instancename, forcecam, fc, sc, dr, event_filter, scripthandler); obj->collBoxes.push_back((boxnum)); } continue; } if (!strcmp("endmesh", ptline)) { gEnv->collisions->addCollisionMesh(collmesh, Vector3(pos.x,pos.y,pos.z), tenode->getOrientation(), sc, gm, &(obj->collTris)); continue; } if (!strncmp("particleSystem", ptline, 14) && tenode) { float x=0, y=0, z=0, scale=0; char pname[255]="", sname[255]=""; int res = sscanf(ptline, "particleSystem %f, %f, %f, %f, %s %s", &scale, &x, &y, &z, pname, sname); if (res != 6) continue; // hacky: prevent duplicates String paname = String(pname); while(gEnv->sceneManager->hasParticleSystem(paname)) paname += "_"; // create particle system ParticleSystem* pParticleSys = gEnv->sceneManager->createParticleSystem(paname, String(sname)); pParticleSys->setCastShadows(false); pParticleSys->setVisibilityFlags(DEPTHMAP_DISABLED); // disable particles in depthmap // Some affectors may need its instance name (e.g. for script feedback purposes) #ifdef USE_ANGELSCRIPT unsigned short affCount = pParticleSys->getNumAffectors(); ParticleAffector* pAff; for (unsigned short i = 0; i<affCount; ++i) { pAff = pParticleSys->getAffector(i); if (pAff->getType()=="ExtinguishableFire") { ((ExtinguishableFireAffector*)pAff)->setInstanceName(obj->instanceName); } } #endif // USE_ANGELSCRIPT SceneNode *sn = tenode->createChildSceneNode(); sn->attachObject(pParticleSys); sn->pitch(Degree(90)); continue; } if (!strncmp("setMeshMaterial", ptline, 15)) { char mat[256]=""; sscanf(ptline, "setMeshMaterial %s", mat); if (mo->getEntity() && strnlen(mat,250)>0) { mo->getEntity()->setMaterialName(String(mat)); // load it //MaterialManager::getSingleton().load(String(mat), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); } continue; } if (!strncmp("generateMaterialShaders", ptline, 23)) { char mat[256]=""; sscanf(ptline, "generateMaterialShaders %s", mat); if (BSETTING("Use RTShader System", false)) { Ogre::RTShader::ShaderGenerator::getSingleton().createShaderBasedTechnique(String(mat), Ogre::MaterialManager::DEFAULT_SCHEME_NAME, Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); Ogre::RTShader::ShaderGenerator::getSingleton().invalidateMaterial(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, String(mat)); } continue; } if (!strncmp("playanimation", ptline, 13) && mo) { char animname[256]=""; float speedfactorMin = 0, speedfactorMax = 0; sscanf(ptline, "playanimation %f, %f, %s", &speedfactorMin, &speedfactorMax, animname); if (tenode && mo->getEntity() && strnlen(animname,250)>0) { AnimationStateSet *s = mo->getEntity()->getAllAnimationStates(); if (!s->hasAnimationState(String(animname))) { LOG("ODEF: animation '" + String(animname) + "' for mesh: '" + String(mesh) + "' in odef file '" + name + ".odef' not found!"); continue; } animated_object_t ao; ao.node = tenode; ao.ent = mo->getEntity(); ao.speedfactor = speedfactorMin; if (speedfactorMin != speedfactorMax) ao.speedfactor = Math::RangeRandom(speedfactorMin, speedfactorMax); ao.anim = 0; try { ao.anim = mo->getEntity()->getAnimationState(String(animname)); } catch (...) { ao.anim = 0; } if (!ao.anim) { LOG("ODEF: animation '" + String(animname) + "' for mesh: '" + String(mesh) + "' in odef file '" + name + ".odef' not found!"); continue; } ao.anim->setEnabled(true); animatedObjects.push_back(ao); } continue; } if (!strncmp("drawTextOnMeshTexture", ptline, 21) && mo) { if (!mo->getEntity()) continue; String matName = mo->getEntity()->getSubEntity(0)->getMaterialName(); MaterialPtr m = MaterialManager::getSingleton().getByName(matName); if (m.getPointer() == 0) { LOG("ODEF: problem with drawTextOnMeshTexture command: mesh material not found: "+odefname+" : "+String(ptline)); continue; } String texName = m->getTechnique(0)->getPass(0)->getTextureUnitState(0)->getTextureName(); Texture* background = (Texture *)TextureManager::getSingleton().getByName(texName).getPointer(); if (!background) { LOG("ODEF: problem with drawTextOnMeshTexture command: mesh texture not found: "+odefname+" : "+String(ptline)); continue; } static int textureNumber = 0; textureNumber++; char tmpTextName[256]="", tmpMatName[256]=""; sprintf(tmpTextName, "TextOnTexture_%d_Texture", textureNumber); sprintf(tmpMatName, "TextOnTexture_%d_Material", textureNumber); // Make sure the texture is not WRITE_ONLY, we need to read the buffer to do the blending with the font (get the alpha for example) TexturePtr texture = TextureManager::getSingleton().createManual(tmpTextName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, (Ogre::uint)background->getWidth(), (Ogre::uint)background->getHeight(), MIP_UNLIMITED , PF_X8R8G8B8, Ogre::TU_STATIC|Ogre::TU_AUTOMIPMAP, new ResourceBuffer()); if (texture.getPointer() == 0) { LOG("ODEF: problem with drawTextOnMeshTexture command: could not create texture: "+odefname+" : "+String(ptline)); continue; } float x=0, y=0, w=0, h=0; float a=0, r=0, g=0, b=0; char fontname[256]=""; char text[256]=""; char option='l'; int res = sscanf(ptline, "drawTextOnMeshTexture %f, %f, %f, %f, %f, %f, %f, %f, %c, %s %s", &x, &y, &w, &h, &r, &g, &b, &a, &option, fontname, text); if (res < 11) { LOG("ODEF: problem with drawTextOnMeshTexture command: "+odefname+" : "+String(ptline)); continue; } // check if we got a template argument if (!strncmp(text, "{{argument1}}", 13)) strncpy(text, instancename.c_str(), 250); // replace '_' with ' ' char *text_pointer = text; while (*text_pointer!=0) {if (*text_pointer=='_') *text_pointer=' ';text_pointer++;}; Font* font = (Font *)FontManager::getSingleton().getByName(String(fontname)).getPointer(); if (!font) { LOG("ODEF: problem with drawTextOnMeshTexture command: font not found: "+odefname+" : "+String(ptline)); continue; } //Draw the background to the new texture texture->getBuffer()->blit(background->getBuffer()); x = background->getWidth() * x; y = background->getHeight() * y; w = background->getWidth() * w; h = background->getHeight() * h; Image::Box box = Image::Box((size_t)x, (size_t)y, (size_t)(x+w), (size_t)(y+h)); WriteToTexture(String(text), texture, box, font, ColourValue(r, g, b, a), option); // we can save it to disc for debug purposes: //SaveImage(texture, "test.png"); m->clone(tmpMatName); MaterialPtr mNew = MaterialManager::getSingleton().getByName(tmpMatName); mNew->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(tmpTextName); mo->getEntity()->setMaterialName(String(tmpMatName)); continue; } LOG("ODEF: unknown command in "+odefname+" : "+String(ptline)); } //add icons if type is set #ifdef USE_MYGUI String typestr = ""; if (!type.empty() && gEnv->surveyMap) { typestr = type; // hack for raceways if (name == "chp-checkpoint") typestr = "checkpoint"; if (name == "chp-start") typestr = "racestart"; if (name == "road", 4) typestr = "road"; if (typestr != "" && typestr != "road" && typestr != "sign") { SurveyMapEntity *e = gEnv->surveyMap->createMapEntity(typestr); if (e) { e->setVisibility(true); e->setPosition(pos); e->setRotation(Radian(rot.y)); if (!name.empty()) e->setDescription(instancename); } } } #endif //USE_MYGUI }