void Chart::indicator(const Ogre::Real chartX, const Ogre::Real chartY) { const std::string chartXString = Ogre::StringConverter::toString(chartX).substr(0, std::min(Ogre::StringConverter::toString(chartX).size(), (std::string::size_type)4)); const std::string chartYString = Ogre::StringConverter::toString(chartY).substr(0, std::min(Ogre::StringConverter::toString(chartY).size(), (std::string::size_type)3)); const Ogre::Vector3 x = chartToScreen( Ogre::Vector2(chartX, mMin.y) ); const Ogre::Vector3 y = chartToScreen( Ogre::Vector2(mMin.x, chartY) ); const Ogre::ColourValue magenta(1,0,1); // indicator Ogre::ManualObject *chartIndicator = mSceneMgr->createManualObject(); chartIndicator->setUseIdentityProjection(true); chartIndicator->setUseIdentityView(true); chartIndicator->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY); chartIndicator->setBoundingBox(Ogre::AxisAlignedBox::BOX_INFINITE); chartIndicator->begin("BaseWhiteNoLighting", Ogre::RenderOperation::OT_LINE_STRIP); chartIndicator->position( x ); chartIndicator->colour( magenta ); chartIndicator->position( chartToScreen( Ogre::Vector2(chartX, chartY) ) ); chartIndicator->colour( magenta ); chartIndicator->position( y ); chartIndicator->colour( magenta ); chartIndicator->end(); // text of values on the sides of the axes if(first) { TextRenderer::getSingleton().addTextBox("txt6" + rndIDString, chartXString, x.x - 0.01 * chartXString.size(), x.y - 0.035, 20, 20, magenta); TextRenderer::getSingleton().addTextBox("txt7" + rndIDString, chartYString, y.x - 0.035 - 0.01 * chartYString.size(), y.y - 0.0025, 20, 20, magenta); first = false; } else { TextRenderer::getSingleton().removeTextBox("txt6" + rndIDString); TextRenderer::getSingleton().removeTextBox("txt7" + rndIDString); TextRenderer::getSingleton().addTextBox("txt6" + rndIDString, chartXString, x.x - 0.01 * chartXString.size(), x.y - 0.035, 20, 20, magenta); TextRenderer::getSingleton().addTextBox("txt7" + rndIDString, chartYString, y.x - 0.035 - 0.01 * chartYString.size(), y.y - 0.0025, 20, 20, magenta); } if (mChartIndicator) { mChartSceneNode->detachObject(mChartIndicator); mSceneMgr->destroyManualObject(mChartIndicator); } mChartIndicator = chartIndicator; mChartSceneNode->attachObject(mChartIndicator); mChartSceneNode->needUpdate(); }
Ogre::SceneNode * Chart::attachTo(Ogre::SceneManager &sceneMgr) { mSceneMgr = &sceneMgr; if (mLineNames.size() < 3) { OGRE_EXCEPT(Ogre::Exception::ERR_INVALID_STATE, "I need exactly three line names. Yeah, it\'s hardcoded ;)", "Chart::attachTo()"); } Ogre::LogManager::getSingletonPtr()->logMessage("mpoints: " + Ogre::StringConverter::toString(mPoints.size())); Ogre::LogManager::getSingletonPtr()->logMessage("msize: " + Ogre::StringConverter::toString(mSize)); Ogre::LogManager::getSingletonPtr()->logMessage("mchartunitstep: " + Ogre::StringConverter::toString(mChartUnitStep)); Ogre::LogManager::getSingletonPtr()->logMessage("mmax: " + Ogre::StringConverter::toString(mMax)); Ogre::LogManager::getSingletonPtr()->logMessage("mmin: " + Ogre::StringConverter::toString(mMin)); // chart quad bg Ogre::ManualObject *chartQuad = sceneMgr.createManualObject(); chartQuad->setUseIdentityProjection(true); chartQuad->setUseIdentityView(true); chartQuad->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY); chartQuad->setBoundingBox(Ogre::AxisAlignedBox::BOX_INFINITE); chartQuad->begin("Chart/Background", Ogre::RenderOperation::OT_TRIANGLE_LIST); chartQuad->position(mOffset.x, mOffset.y, 0.5); chartQuad->position(mOffset.x + mSize.x, mOffset.y, 0.5); chartQuad->position(mOffset.x + mSize.x, mOffset.y + mSize.y, 0.5); chartQuad->position(mOffset.x, mOffset.y + mSize.y, 0.5); chartQuad->position(mOffset.x, mOffset.y, 0.5); chartQuad->position(mOffset.x + mSize.x, mOffset.y + mSize.y, 0.5); chartQuad->end(); // chart y axis Ogre::ManualObject *chartAxisY = sceneMgr.createManualObject(); chartAxisY->setUseIdentityProjection(true); chartAxisY->setUseIdentityView(true); chartAxisY->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY); chartAxisY->setBoundingBox(Ogre::AxisAlignedBox::BOX_INFINITE); chartAxisY->begin("BaseWhiteNoLighting", Ogre::RenderOperation::OT_LINE_LIST); chartAxisY->position(mOffset.x + mPadding.x, mOffset.y + mSize.y - 0.02, 0.0); chartAxisY->colour( 0.7, 0.7, 0.7 ); chartAxisY->position(mOffset.x + mPadding.x, mOffset.y + 0.02, 0.0); chartAxisY->colour( 0.7, 0.7, 0.7 ); chartAxisY->end(); // chart x axis Ogre::ManualObject *chartAxisX = sceneMgr.createManualObject(); chartAxisX->setUseIdentityProjection(true); chartAxisX->setUseIdentityView(true); chartAxisX->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY); chartAxisX->setBoundingBox(Ogre::AxisAlignedBox::BOX_INFINITE); chartAxisX->begin("BaseWhiteNoLighting", Ogre::RenderOperation::OT_LINE_LIST); chartAxisX->position(mOffset.x + 0.02, mOffset.y + mPadding.y, 0.0); chartAxisX->colour( 0.7, 0.7, 0.7 ); chartAxisX->position(mOffset.x + mSize.x - 0.02, mOffset.y + mPadding.y, 0.0); chartAxisX->colour( 0.7, 0.7, 0.7 ); chartAxisX->end(); // lines const Ogre::ColourValue colours[] = { Ogre::ColourValue(1.0, 0.2, 0.2), Ogre::ColourValue(0.0, 0.9, 0.0), Ogre::ColourValue(0.2, 0.2, 1.0) }; Ogre::ManualObject *lines = sceneMgr.createManualObject(); lines->setUseIdentityProjection(true); lines->setUseIdentityView(true); lines->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY); lines->setBoundingBox(Ogre::AxisAlignedBox::BOX_INFINITE); lines->begin("BaseWhiteNoLighting", Ogre::RenderOperation::OT_LINE_STRIP); for (std::vector<ChartPointsVector>::const_iterator it = mPoints.begin(); it != mPoints.end(); ++it) { for (ChartPointsVector::const_iterator jt = it->begin(); jt != it->end(); ++jt) { lines->position(chartToScreen(*jt)); lines->colour(colours[it - mPoints.begin()]); } } lines->end(); // caption text const Ogre::Real rndID = Ogre::Math::RangeRandom(0, 9999999999) + Ogre::Math::RangeRandom(0, 9999999999); TextRenderer::getSingleton().addTextBox("txt0" + Ogre::StringConverter::toString(rndID+ Ogre::Math::RangeRandom(0, 999999)), mCaption, mOffset.x + mSize.x * 0.40, mOffset.y + mSize.y, 100, 20, Ogre::ColourValue::Black); // text above the lines TextRenderer::getSingleton().addTextBox("txt1" + Ogre::StringConverter::toString(rndID+ Ogre::Math::RangeRandom(0, 999999)), mLineNames[0], mOffset.x + mPadding.x + 0.0025, mOffset.y + mSize.y - mPadding.y + 0.04, 100, 20, colours[0]); TextRenderer::getSingleton().addTextBox("txt2" + Ogre::StringConverter::toString(rndID+ Ogre::Math::RangeRandom(0, 999999)), mLineNames[1], mOffset.x + mPadding.x + 0.0025 + (mSize.x - mPadding.x * 2.0) * 0.35, mOffset.y + mSize.y - mPadding.y + 0.04, 100, 20, colours[1]); TextRenderer::getSingleton().addTextBox("txt3" + Ogre::StringConverter::toString(rndID+ Ogre::Math::RangeRandom(0, 999999)), mLineNames[2], mOffset.x + mPadding.x + 0.0025 + (mSize.x - mPadding.x * 2.0) * 0.75, mOffset.y + mSize.y - mPadding.y + 0.04, 100, 20, colours[2]); // text on y axis (1) TextRenderer::getSingleton().addTextBox("txt4" + Ogre::StringConverter::toString(rndID+ Ogre::Math::RangeRandom(0, 999999)), "1", mOffset.x + mPadding.x - 0.02, mOffset.y + mSize.y - mPadding.y, 20, 20, Ogre::ColourValue::Black); // text on x axis Ogre::Real rndID2 = Ogre::Math::RangeRandom(0, 9999999999) + Ogre::Math::RangeRandom(0, 9999999999); for (std::vector<ChartPointsVector>::const_iterator it = mPoints.begin(); it != mPoints.end(); ++it) { Ogre::Real rndID3 = Ogre::Math::RangeRandom(0, 9999999999) + Ogre::Math::RangeRandom(0, 9999999999); for (ChartPointsVector::const_iterator jt = it->begin(); jt != it->end(); ++jt) { const Ogre::Real rndID4 = Ogre::Math::RangeRandom(0, 9999999999) + Ogre::Math::RangeRandom(0, 9999999999); const Ogre::Vector3 chartVec = chartToScreen(*jt); const std::string xString = Ogre::StringConverter::toString(jt->x).substr(0, std::min(Ogre::StringConverter::toString(jt->x).size(), (std::string::size_type)3)); TextRenderer::getSingleton().addTextBox("txt100" + Ogre::StringConverter::toString(rndID2) + Ogre::StringConverter::toString(rndID3) + Ogre::StringConverter::toString(rndID4), xString, chartVec.x - 0.01 * xString.size(), mOffset.y + mPadding.y - 0.0025, 20, 20, Ogre::ColourValue::Black); } } mChartSceneNode = sceneMgr.getRootSceneNode()->createChildSceneNode(); mChartSceneNode->attachObject(chartQuad); mChartSceneNode->attachObject(chartAxisY); mChartSceneNode->attachObject(chartAxisX); mChartSceneNode->attachObject(lines); setVisible(false); return mChartSceneNode; }
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; }
int DecalManager::addTerrainDecal(Ogre::Vector3 position, Ogre::Vector2 size, Ogre::Vector2 numSeg, Ogre::Real rotation, Ogre::String materialname, Ogre::String normalname) { #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(); float uTile = 1, vTile = 1; Vector3 normal = Vector3(0,1,0); // UP int offset = 0; float ground_dist = 0.001f; Ogre::Vector3 vX = normal.perpendicular(); Ogre::Vector3 vY = normal.crossProduct(vX); Ogre::Vector3 delta1 = size.x / numSeg.x * vX; Ogre::Vector3 delta2 = size.y / numSeg.y * vY; // build one corner of the square Ogre::Vector3 orig = -0.5*size.x*vX - 0.5*size.y*vY; for (int i1 = 0; i1<=numSeg.x; i1++) for (int i2 = 0; i2<=numSeg.y; i2++) { Vector3 pos = orig+i1*delta1+i2*delta2 + position; pos.y = hfinder->getHeightAt(pos.x, pos.z) + ground_dist; mo->position(pos); aab->merge(pos); mo->textureCoord(i1/(Ogre::Real)numSeg.x*uTile, i2/(Ogre::Real)numSeg.y*vTile); mo->normal(normal); } bool reverse = false; if (delta1.crossProduct(delta2).dotProduct(normal)>0) reverse= true; 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)); // 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, normalname); #endif return 0; }
void AssetLoader::readModel(Ogre::SceneManager* sceneMgr, Ogre::SceneNode* scnNode, const aiScene* scene, aiNode* nd) { for (size_t n = 0; n < nd->mNumChildren; n++) { aiNode* cnd = nd->mChildren[n]; Ogre::SceneNode* cnode = createChildSceneNodeWithTransform(scnNode, cnd); for (size_t i = 0; i < cnd->mNumMeshes; i++) { aiMesh* m = scene->mMeshes[cnd->mMeshes[i]]; aiMaterial* mat = scene->mMaterials[m->mMaterialIndex]; std::string nodeName = getFullPathName(cnd); Ogre::MaterialPtr omat = createMaterial(Ogre::String(nodeName), m->mMaterialIndex, mat); aiVector3D* vec = m->mVertices; aiVector3D* norm = m->mNormals; aiVector3D* uv = m->mTextureCoords[0]; aiColor4D* vcol = NULL; if (m->HasVertexColors(0)) vcol = m->mColors[0]; // 頂点情報の読み込み Ogre::AxisAlignedBox aab; Ogre::ManualObject* mobj = new Ogre::ManualObject(nodeName+"_MObj"); mobj->begin(omat->getName()); //mobj->begin("Ogre/Skin"); for (size_t n = 0; n < m->mNumVertices; n ++) { Ogre::Vector3 position(vec->x, vec->y, vec->z); aab.merge(position); mobj->position(vec->x, vec->y, vec->z); vec++; mobj->normal(norm->x, norm->y, norm->z); norm++; if (uv) { mobj->textureCoord(uv->x, uv->y); uv++; } if (vcol) { mobj->colour(vcol->r, vcol->g, vcol->b, vcol->a); vcol++; } } // ポリゴンの構築 for (size_t n = 0; n < m->mNumFaces; n++) { aiFace* face = &m->mFaces[n]; for (size_t k = 0; k < face->mNumIndices; k++) { mobj->index(face->mIndices[k]); } } mobj->end(); mobj->setBoundingBox(aab); Ogre::String meshName(nodeName+"_Mesh"); mobj->convertToMesh(meshName); delete mobj; Ogre::String entityName(nodeName+"_Entity"); std::cout << "entity: " << entityName << std::endl; Ogre::Entity* ent = sceneMgr->createEntity(entityName, meshName); cnode->attachObject(ent); } readModel(sceneMgr, cnode, scene, cnd); } }