ParaEngine::AxisAlignedBox AxisAlignedBox::intersection(const AxisAlignedBox& b2) const { if (this->isNull() || b2.isNull()) { return AxisAlignedBox(); } else if (this->isInfinite()) { return b2; } else if (b2.isInfinite()) { return *this; } Vector3 intMin = mMinimum; Vector3 intMax = mMaximum; intMin.makeCeil(b2.getMinimum()); intMax.makeFloor(b2.getMaximum()); // Check intersection isn't null if (intMin.x < intMax.x && intMin.y < intMax.y && intMin.z < intMax.z) { return AxisAlignedBox(intMin, intMax); } return AxisAlignedBox(); }
void PlanetFilter::initRenderOp() { mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP; mRenderOp.useIndexes = FALSE; mRenderOp.vertexData = new VertexData(); setBoundingBox(AxisAlignedBox(Vector3(-getBoundingRadius()), Vector3(getBoundingRadius()))); }
//------------------------------------------------------------------------- void TerrainSceneManager::setWorldGeometry(DataStreamPtr& stream, const String& typeName ) { // Clear out any existing world resources (if not default) if (ResourceGroupManager::getSingleton().getWorldResourceGroupName() != ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME) { ResourceGroupManager::getSingleton().clearResourceGroup( ResourceGroupManager::getSingleton().getWorldResourceGroupName()); } destroyLevelIndexes(); mTerrainPages.clear(); // Load the configuration loadConfig(stream); initLevelIndexes(); // Resize the octree, allow for 1 page for now float max_x = mOptions.scale.x * mOptions.pageSize; float max_y = mOptions.scale.y; float max_z = mOptions.scale.z * mOptions.pageSize; resize( AxisAlignedBox( 0, 0, 0, max_x, max_y, max_z ) ); setupTerrainMaterial(); setupTerrainPages(); }
void OgreConsole::init(Ogre::Root *root){ if(!root->getSceneManagerIterator().hasMoreElements()) OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "No scene manager found!", "init" ); this->root=root; scene=root->getSceneManagerIterator().getNext(); root->addFrameListener(this); height=1; // Create background rectangle covering the whole screen rect = new Rectangle2D(true); rect->setCorners(-1, 1, 1, 1-height); rect->setMaterial("console/background"); rect->setRenderQueueGroup(RENDER_QUEUE_OVERLAY); rect->setBoundingBox(AxisAlignedBox(-100000.0*Vector3::UNIT_SCALE, 100000.0*Vector3::UNIT_SCALE)); noder = scene->getRootSceneNode()->createChildSceneNode("#Console"); noder->attachObject(rect); textbox=OverlayManager::getSingleton().createOverlayElement("TextArea","ConsoleText"); textbox->setCaption("hello"); textbox->setMetricsMode(GMM_RELATIVE); textbox->setPosition(0,0); textbox->setParameter("font_name","Console"); textbox->setParameter("colour_top","1 1 1"); textbox->setParameter("colour_bottom","1 1 1"); textbox->setParameter("char_height","0.03"); overlay=OverlayManager::getSingleton().create("Console"); overlay->add2D((OverlayContainer*)textbox); overlay->show(); LogManager::getSingleton().getDefaultLog()->addListener(this); initialized=true; }
void CGLWin::dupe_currentobj() { if (m_pGLUIWin==NULL || m_pGLUIWin->m_SceneGraph.GetActiveSceneNode()==NULL){ return; } CSceneNode *pnode = m_pGLUIWin->m_SceneGraph.GetActiveSceneNode(); CPolyObj *pobj = pnode->m_pObject; Vector3d lowleft, upright; pobj->ComputeBoundingBox(lowleft, upright); const Vector3d objsize = upright - lowleft; const double *matrix = pnode->m_pFrame->matrix(); Vector3d step = objsize; const int N = 9; CPolyObj * newobj = NULL; const int nv = pobj->m_nVertexCount; const Vector3d *pvert = pobj->m_pVertex; const int ntri = pobj->m_nPolygonCount; if (pobj->m_nPlyVertexCount == 3){ const Vector3i *ptri = (const Vector3i*)pobj->m_pPolygon; CTriangleObj * ptriobj = dynamic_cast<CTriangleObj*>(pobj); if (ptriobj != NULL){ Vector3d *p2 = new Vector3d[N*nv]; Vector3d *p3 = p2; for (int j=0; j<N; j++, step+=objsize, p3+=nv){ for (int i=0; i<nv; i++){ TransformVertex3dToVertex3d(pvert[i], matrix, &p3[i].x); p3[i].x += step.x; } } Vector3i *ptri2, *ptri3; ptri2 = ptri3 = new Vector3i[ntri*N]; Vector3i offset(0, 0, 0); for (int j=0; j<N; j++, ptri3+=ntri, offset+=Vector3i(nv)){ for (int i=0; i<ntri; i++) ptri3[i] = ptri[i] + offset; } newobj = new CTriangleObj(p2, nv*N, ptri2, ntri*N, false); } } else if (pobj->m_nPlyVertexCount == 4){ /* CQuadObj * ptriobj = dynamic_cast<CQuadObj*>(pobj); if (ptriobj!=NULL){ newobj = new CQuadObj(*ptriobj); } */ } if (newobj != NULL){ newobj->ComputeBoundingBox(lowleft, upright); newobj->SetBoundingBox(AxisAlignedBox(lowleft, upright)); CSceneNode *p = AddOneObjectToSceneGraph(newobj, m_pGLUIWin->m_SceneGraph); p->m_DrawParms.m_bUseDispList = true; p->m_DrawParms.m_bUseVbo = true; p->m_DrawParms.m_bEnableSmoothing = true; } }
AmbientLight::AmbientLight() { setRenderQueueGroup(RENDER_QUEUE_2); mRenderOp.vertexData = new VertexData(); mRenderOp.indexData = 0; GeomUtils::createQuad(mRenderOp.vertexData); mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP; mRenderOp.useIndexes = false; // Set bounding setBoundingBox(AxisAlignedBox(-10000,-10000,-10000,10000,10000,10000)); mRadius = 15000; mMatPtr = MaterialManager::getSingleton().getByName("DeferredShading/AmbientLight"); assert(mMatPtr.isNull()==false); mMatPtr->load(); //This shader needs to be aware if its running under OpenGL or DirectX. //Real depthFactor = (Root::getSingleton().getRenderSystem()->getName() == // "OpenGL Rendering Subsystem") ? 2.0 : 1.0; //mMatPtr->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant( // "depthFactor", depthFactor); }
void GeomUtils::createSphere( const String& strName , float radius , int nRings, int nSegments , bool bNormals , bool bTexCoords) { MeshPtr pSphere = MeshManager::getSingleton().createManual(strName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); SubMesh *pSphereVertex = pSphere->createSubMesh(); pSphere->sharedVertexData = new VertexData(); createSphere(pSphere->sharedVertexData, pSphereVertex->indexData , radius , nRings, nSegments , bNormals // need normals , bTexCoords // need texture co-ordinates ); // Generate face list pSphereVertex->useSharedVertices = true; // the original code was missing this line: pSphere->_setBounds( AxisAlignedBox( Vector3(-radius, -radius, -radius), Vector3(radius, radius, radius) ), false ); pSphere->_setBoundingSphereRadius(radius); // this line makes clear the mesh is loaded (avoids memory leaks) pSphere->load(); }
void EffectBillboardChain::updateBoundingBox() { if (mChainElementList.size() < 2) return; Ogre::Real width = mChainElementList[0].width; Vector3 widthVector = Vector3(width, width, width); const Vector3& position = mChainElementList[0].position; Vector3 minimum = position - widthVector; Vector3 maximum = position + widthVector; for (unsigned int i = 1; i < mChainElementList.size(); i++) { // Update the bounds of the bounding box Ogre::Real width = mChainElementList[i].width; Vector3 widthVector = Vector3(width, width, width); const Vector3& position = mChainElementList[i].position; minimum.makeFloor(position - widthVector); maximum.makeCeil(position + widthVector); } // Set the current bounding box setBoundingBox(AxisAlignedBox(minimum, maximum)); // Set the current radius mRadius = Math::Sqrt(std::max(minimum.squaredLength(), maximum.squaredLength())); }
void Utility::drawIMG(Ogre::SceneManager *mSceneMgr, Ogre::String imgName, Ogre::String imgFileName, Ogre::Real x1, Ogre::Real y1, Ogre::Real x2, Ogre::Real y2) { MaterialPtr material = MaterialManager::getSingleton().create(imgName, "General"); material->getTechnique(0)->getPass(0)->createTextureUnitState(imgFileName); material->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); material->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); material->getTechnique(0)->getPass(0)->setLightingEnabled(false); Rectangle2D* rect = new Rectangle2D(true); //Corners vẽ 2D có dạng như sau /* +________1________+ | : | | 0.5 | | : | -1...-0.5..0..0.5...1 | : | | -0.5 | | : | +_______-1________+ */ rect->setCorners(x1, y1, x2, y2); rect->setMaterial(imgName); rect->setRenderQueueGroup(RENDER_QUEUE_BACKGROUND); rect->setBoundingBox(AxisAlignedBox(-100000.0*Vector3::UNIT_SCALE, 100000.0*Vector3::UNIT_SCALE)); SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode(imgName); node->attachObject(rect); }
void CGLWin::dupe_currentobjN() { if (m_pGLUIWin==NULL || m_pGLUIWin->m_SceneGraph.GetActiveSceneNode()==NULL){ return; } CSceneNode *pnode = m_pGLUIWin->m_SceneGraph.GetActiveSceneNode(); CPolyObj *pobj = pnode->m_pObject; Vector3d lowleft, upright; pobj->ComputeBoundingBox(lowleft, upright); const Vector3d objsize = upright - lowleft; const double *matrix = pnode->m_pFrame->matrix(); Vector3d step = objsize; QString text = "1"; /* bool ok; text = QInputDialog::getText("Input object number", "Please input number of objects to copy, must be [1..100]", QLineEdit::Normal, text, &ok ); //if ( !ok ) return; int N = text.toInt(); */ int N = 9; //this->statusBar()->message(QString("Input is: ") + text, 3000); //if (N<1 || N>100) return; const int nv = pobj->m_nVertexCount; const Vector3d *pvert = pobj->m_pVertex; const int ntri = pobj->m_nPolygonCount; CPolyObj * newobj = NULL; for (int k=0; k<N; k++, step+=objsize){ if (pobj->m_nPlyVertexCount == 3){ const Vector3i *ptri = (const Vector3i*)pobj->m_pPolygon; CTriangleObj * ptriobj = dynamic_cast<CTriangleObj*>(pobj); if (ptriobj != NULL){ Vector3d *p2 = new Vector3d[nv]; for (int i=0; i<nv; i++){ TransformVertex3dToVertex3d(pvert[i], matrix, &p2[i].x); p2[i].x += step.x; } Vector3i *ptri2 = new Vector3i[ntri]; for (int i=0; i<ntri; i++) ptri2[i] = ptri[i]; newobj = new CTriangleObj(p2, nv, ptri2, ntri, false); } } else if (pobj->m_nPlyVertexCount == 4){ } if (newobj != NULL){ newobj->ComputeBoundingBox(lowleft, upright); newobj->SetBoundingBox(AxisAlignedBox(lowleft, upright)); CSceneNode *p = AddOneObjectToSceneGraph(newobj, m_pGLUIWin->m_SceneGraph); p->m_DrawParms.m_bUseDispList = true; p->m_DrawParms.m_bUseVbo = true; p->m_DrawParms.m_bEnableSmoothing = true; } } }
//----------------------------------------------------------------------- void BillboardParticleRenderer::_updateRenderQueue(RenderQueue* queue, list<Particle*>::type& currentParticles, bool cullIndividually) { mBillboardSet->setCullIndividually(cullIndividually); // Update billboard set geometry Vector3 bboxMin = Math::POS_INFINITY * Vector3::UNIT_SCALE; Vector3 bboxMax = Math::NEG_INFINITY * Vector3::UNIT_SCALE; Real radius = 0.0f; mBillboardSet->beginBillboards(currentParticles.size()); Billboard bb; Matrix4 invWorld; if (mBillboardSet->getBillboardsInWorldSpace() && mBillboardSet->getParentSceneNode()) invWorld = mBillboardSet->getParentSceneNode()->_getFullTransform().inverse(); for (list<Particle*>::type::iterator i = currentParticles.begin(); i != currentParticles.end(); ++i) { Particle* p = *i; bb.mPosition = p->position; Vector3 pos = p->position; if (mBillboardSet->getBillboardsInWorldSpace() && mBillboardSet->getParentSceneNode()) pos = invWorld * pos; bboxMin.makeFloor( pos ); bboxMax.makeCeil( pos ); radius = std::max( radius, p->position.length() ); if (mBillboardSet->getBillboardType() == BBT_ORIENTED_SELF || mBillboardSet->getBillboardType() == BBT_PERPENDICULAR_SELF) { // Normalise direction vector bb.mDirection = p->direction; bb.mDirection.normalise(); } bb.mColour = p->colour; bb.mRotation = p->rotation; // Assign and compare at the same time if ((bb.mOwnDimensions = p->mOwnDimensions) == true) { bb.mWidth = p->mWidth; bb.mHeight = p->mHeight; } mBillboardSet->injectBillboard(bb); } // Only set bounds if there are any active particles if(currentParticles.size()) mBillboardSet->setBounds( AxisAlignedBox( bboxMin, bboxMax ), radius ); mBillboardSet->endBillboards(); // Update the queue mBillboardSet->_updateRenderQueue(queue); }
//--------------------------------------------------------------------- void PrefabFactory::createPlane(Mesh* mesh) { SubMesh* sub = mesh->createSubMesh(); float vertices[32] = { -100, -100, 0, // pos 0,0,1, // normal 0,1, // texcoord 100, -100, 0, 0,0,1, 1,1, 100, 100, 0, 0,0,1, 1,0, -100, 100, 0 , 0,0,1, 0,0 }; mesh->sharedVertexData = OGRE_NEW VertexData(); mesh->sharedVertexData->vertexCount = 4; VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration; VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding; size_t offset = 0; decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); offset += VertexElement::getTypeSize(VET_FLOAT2); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, 4, HardwareBuffer::HBU_STATIC_WRITE_ONLY); bind->setBinding(0, vbuf); vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); sub->useSharedVertices = true; HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, 6, HardwareBuffer::HBU_STATIC_WRITE_ONLY); unsigned short faces[6] = {0,1,2, 0,2,3 }; sub->indexData->indexBuffer = ibuf; sub->indexData->indexCount = 6; sub->indexData->indexStart =0; ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); mesh->_setBounds(AxisAlignedBox(-100,-100,0,100,100,0), true); mesh->_setBoundingSphereRadius(Math::Sqrt(100*100+100*100)); }
AxisAlignedBox TerrainInfo::getExtents() const { if (mWidth == 0) OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "You must set a heightmap first.", "TerrainInfo::setExtents"); Vector3 maximum = mScale; maximum.x *= mWidth; maximum.z *= mHeight; maximum += mOffset; return AxisAlignedBox(mOffset, maximum); }
AxisAlignedBox AxisAlignedBox::Intersection(const AxisAlignedBox& other) const { if (!Valid() || !other.Valid()) { return AxisAlignedBox(); } double x0; double x1; double y0; double y1; double z0; double z1; if (!Isect1d(min_.x(), max_.x(), other.min_.x(), other.max_.x(), &x0, &x1)) { return AxisAlignedBox(); } if (!Isect1d(min_.y(), max_.y(), other.min_.y(), other.max_.y(), &y0, &y1)) { return AxisAlignedBox(); } if (!Isect1d(min_.z(), max_.z(), other.min_.z(), other.max_.z(), &z0, &z1)) { return AxisAlignedBox(); } return AxisAlignedBox(QVector3D(x0, y0, z0), QVector3D(x1, y1, z1)); }
int CPointObj::SplitIntoSubObj(const int objidbuff[], const int bufflen, CObject3D* obj[]) { Vector3d lowleft, upright; for (int i=0; i<bufflen; i++){ CPointObj *p = new CPointObj; assert(p!=NULL); _copyToObject(*p, objidbuff[i]); p->ComputeBoundingBox(lowleft, upright); p->SetBoundingBox(AxisAlignedBox(lowleft, upright)); obj[i] = p; } return bufflen; }
const AxisAlignedBox& GroupNode::WorldBoundingBox() { if (bounding_box_dirty_) { bounding_box_ = AxisAlignedBox(); for (SceneNode* child : children_) { const AxisAlignedBox& child_box = child->WorldBoundingBox(); if (child_box.Valid()) { bounding_box_.IncludeBox(child_box); } } bounding_box_dirty_ = false; } return bounding_box_; }
void Physics::computeBoundingShapes(const float& elapsedTime) { for (std::set<Entity*>::iterator it = movingEntity.begin(); it != movingEntity.end(); it++) { RigidBody* rigidbody = (*it)->getComponent<RigidBody>(); glm::vec3 delta = rigidbody->predictPosition - (*it)->getPosition(); AxisAlignedBox firstBox = (*it)->getShape().toAxisAlignedBox(); AxisAlignedBox finalBox = AxisAlignedBox(firstBox); finalBox.transform(delta, glm::vec3(1.f), rigidbody->deltaRotation); glm::vec3 queryMin = glm::min(firstBox.min, finalBox.min); glm::vec3 queryMax = glm::min(firstBox.max, finalBox.max); AxisAlignedBox queryBox(queryMin, queryMax); } }
DebugRectangle2D::DebugRectangle2D() : SimpleRenderable () { #ifdef PLSM2_EIHORT mUseIdentityProjection = true; mUseIdentityView = true; #endif mRenderOp.indexData = new IndexData(); mRenderOp.vertexData = new VertexData(); mRenderOp.operationType = RenderOperation::OT_LINE_LIST; mRenderOp.indexData->indexCount = 8; mRenderOp.vertexData->vertexCount = 4; mRenderOp.vertexData->vertexStart = 0; mRenderOp.useIndexes = true; VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); const size_t offset = VertexElement::getTypeSize(VET_FLOAT3); decl->addElement (POSITION_BINDING, offset, VET_COLOUR, VES_DIFFUSE); mRenderOp.indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( HardwareIndexBuffer::IT_16BIT, mRenderOp.indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(POSITION_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Bind buffer bind->setBinding(POSITION_BINDING, vbuf); SimpleRenderable::setBoundingBox(AxisAlignedBox(-1000 * Vector3::UNIT_SCALE, 1000 * Vector3::UNIT_SCALE)); SimpleRenderable::setRenderQueueGroup (RENDER_QUEUE_OVERLAY); // set basic white material SimpleRenderable::setMaterial("BaseWhiteNoLighting"); }
OctreeTriggerPlayer::OctreeTriggerPlayer(const String &name , OctreeTriggerWorld *world) : m_name(name) , m_world(world) , m_sceneMgr(0) , m_node(0) , m_radius(1) , m_query(0) , m_aabb(-0.5 , -0.5 , -0.5 , 0.5 , 0.5 , 0.5) , MovableObject(name) { m_sceneMgr = world->getSceneManager(); m_node = m_sceneMgr->getRootSceneNode()->createChildSceneNode(name); m_node->attachObject(this); // 玩家不参加碰撞计算 setQueryFlags(0); MovableObject::setUserAny(Any(static_cast<ITriggerEntity*>(this))); // 创建一个缺省的包围盒查询器 m_query = m_sceneMgr->createAABBQuery(AxisAlignedBox()); }
ParticleSystem::ParticleSystem(): m_time(0), m_maxParticles(PARTICLE_SIZE), m_finalized(false) { m_visible = true; m_alignedBox = AxisAlignedBox(AxisAlignedBox::EXTENT_INFINITE); m_posVec.resize(4*m_maxParticles); m_velocityVec.resize(4*m_maxParticles); m_texCoordVec.resize(4*m_maxParticles); m_indexVec.resize(6 * m_maxParticles); for(int i=0; i<m_maxParticles; ++i) { Vector3f velocity = _GetRandomVector(); m_posVec[4*i+0] = Vector3f(-1, -1, -1000);/*100(m/s) * 10(s)*/ m_posVec[4*i+1] = Vector3f(1, -1, -1000); m_posVec[4*i+2] = Vector3f(1, 1, -1000); m_posVec[4*i+3] = Vector3f(-1, 1, -1000); m_texCoordVec[4*i+0] = Vector2f(0, 0); m_texCoordVec[4*i +1] = Vector2f(1, 0); m_texCoordVec[4*i +2] = Vector2f(1, 1); m_texCoordVec[4*i +3] = Vector2f(0, 1); for(int j=0; j<4; ++j) { m_velocityVec[4*i+j] = velocity; } m_indexVec[6*i +0] = 4*i +0; m_indexVec[6*i +1] = 4*i +1; m_indexVec[6*i +2] = 4*i +2; m_indexVec[6*i +3] = 4*i +0; m_indexVec[6*i +4] = 4*i +2; m_indexVec[6*i +5] = 4*i +3; } }
void GeomUtils::createCone(const Ogre::String& strName , float radius , float height, int nVerticesInBase) { MeshPtr pCone = MeshManager::getSingleton().createManual(strName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); SubMesh *pConeVertex = pCone->createSubMesh(); pCone->sharedVertexData = new VertexData(); createCone(pCone->sharedVertexData, pConeVertex->indexData , radius , height , nVerticesInBase); // Generate face list pConeVertex->useSharedVertices = true; // the original code was missing this line: pCone->_setBounds( AxisAlignedBox( Vector3(-radius, 0, -radius), Vector3(radius, height, radius) ), false ); pCone->_setBoundingSphereRadius(Math::Sqrt(height*height + radius*radius)); // this line makes clear the mesh is loaded (avoids memory leaks) pCone->load(); }
void CMeshSlantBrickDialog::onApply(void) { //Delete old object m_pGLPreviewWin->releaseObject(); //Create a new brick object const int nx = this->m_nx; const int ny = this->m_ny; const int nz = this->m_nz; Vector3d* pVertex; Vector4i* pQuad; Vector8i* pHex; int nVertexCount, nPolygonCount, nHexCount; //doMeshBrick(lowleft, upright, nx, ny, nz, pVertex, pQuad, pHex, nVertexCount, nPolygonCount, nHexCount); meshSlantBrickVertices(m_vVertex, nx+1, ny+1, nz+1, pVertex, nVertexCount); getBrickElements(nx, ny, nz, pHex, nHexCount); getBrickBounday(nx, ny, nz, pQuad, nPolygonCount); CHexObj *p = new CHexObj(pVertex, nVertexCount, pHex, nHexCount, pQuad, nPolygonCount); if (p==NULL) return; Vector3d lowleft(+1e30f); Vector3d upright(-1e30f); for (int i=0; i<8; i++){ const Vector3d vvv(m_vVertex[i].x, m_vVertex[i].y, m_vVertex[i].z); Minimize(lowleft, vvv); Maximize(upright, vvv); } p->SetBoundingBox(AxisAlignedBox(lowleft, upright)); char namebuff[256]; sprintf(namebuff, "Brick%d", 0); p->SetObjectName(namebuff); //Set the new object for the preview window m_pGLPreviewWin->setObject(p); m_pGLPreviewWin->updateGL(); }
MeshPtr MergeMesh::bake() { log( "Baking: New Mesh started" ); MeshPtr mp = MeshManager::getSingleton(). createManual( "mergedMesh", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME ); mp->setSkeletonName( m_BaseSkeleton->getName() ); AxisAlignedBox totalBounds = AxisAlignedBox(); for( std::vector< Ogre::MeshPtr >::iterator it = m_Meshes.begin(); it != m_Meshes.end(); ++it ) { log( "Baking: adding submeshes for " + (*it)->getName() ); // insert all submeshes for( Ogre::ushort sid = 0; sid < (*it)->getNumSubMeshes(); ++sid ) { SubMesh* sub = (*it)->getSubMesh( sid ); const String name = findSubmeshName( (*it), sid ); // create submesh with correct name SubMesh* newsub; if( name.length() == 0 ) newsub = mp->createSubMesh( ); else /// @todo check if a submesh with this name has been created before newsub = mp->createSubMesh( name ); newsub->useSharedVertices = sub->useSharedVertices; // add index newsub->indexData = sub->indexData->clone(); // add geometry if( !newsub->useSharedVertices ) { newsub->vertexData = sub->vertexData->clone(); // build bone assignments SubMesh::BoneAssignmentIterator bit = sub->getBoneAssignmentIterator(); while (bit.hasMoreElements()) { VertexBoneAssignment vba = bit.getNext(); newsub->addBoneAssignment(vba); } } newsub->setMaterialName( sub->getMaterialName() ); log("Baking: adding submesh '" + name + "' with material " + sub->getMaterialName()); } // sharedvertices if ((*it)->sharedVertexData) { /// @todo merge with existing sharedVertexData if (!mp->sharedVertexData) { mp->sharedVertexData = (*it)->sharedVertexData->clone(); } Mesh::BoneAssignmentIterator bit = (*it)->getBoneAssignmentIterator(); while (bit.hasMoreElements()) { VertexBoneAssignment vba = bit.getNext(); mp->addBoneAssignment(vba); } } log("Baking: adding bounds for " + (*it)->getName()); // add bounds totalBounds.merge((*it)->getBounds()); } mp->_setBounds( totalBounds ); /// @todo merge submeshes with same material /// @todo add parameters mp->buildEdgeList(); log( "Baking: Finished" ); return mp; }
//--------------------------------------------------------------------- void PrefabFactory::createSphere(Mesh* mesh) { // sphere creation code taken from the DeferredShading sample, originally from the wiki SubMesh *pSphereVertex = mesh->createSubMesh(); const int NUM_SEGMENTS = 16; const int NUM_RINGS = 16; const Real SPHERE_RADIUS = 50.0; mesh->sharedVertexData = OGRE_NEW VertexData(); VertexData* vertexData = mesh->sharedVertexData; // define the vertex format VertexDeclaration* vertexDecl = vertexData->vertexDeclaration; size_t currOffset = 0; // positions vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION); currOffset += VertexElement::getTypeSize(VET_FLOAT3); // normals vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL); currOffset += VertexElement::getTypeSize(VET_FLOAT3); // two dimensional texture coordinates vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); // allocate the vertex buffer vertexData->vertexCount = (NUM_RINGS + 1) * (NUM_SEGMENTS+1); HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); VertexBufferBinding* binding = vertexData->vertexBufferBinding; binding->setBinding(0, vBuf); float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD)); // allocate index buffer pSphereVertex->indexData->indexCount = 6 * NUM_RINGS * (NUM_SEGMENTS + 1); pSphereVertex->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, pSphereVertex->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); HardwareIndexBufferSharedPtr iBuf = pSphereVertex->indexData->indexBuffer; unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(HardwareBuffer::HBL_DISCARD)); float fDeltaRingAngle = (Math::PI / NUM_RINGS); float fDeltaSegAngle = (2 * Math::PI / NUM_SEGMENTS); unsigned short wVerticeIndex = 0 ; // Generate the group of rings for the sphere for( int ring = 0; ring <= NUM_RINGS; ring++ ) { float r0 = SPHERE_RADIUS * sinf (ring * fDeltaRingAngle); float y0 = SPHERE_RADIUS * cosf (ring * fDeltaRingAngle); // Generate the group of segments for the current ring for(int seg = 0; seg <= NUM_SEGMENTS; seg++) { float x0 = r0 * sinf(seg * fDeltaSegAngle); float z0 = r0 * cosf(seg * fDeltaSegAngle); // Add one vertex to the strip which makes up the sphere *pVertex++ = x0; *pVertex++ = y0; *pVertex++ = z0; Vector3 vNormal = Vector3(x0, y0, z0).normalisedCopy(); *pVertex++ = vNormal.x; *pVertex++ = vNormal.y; *pVertex++ = vNormal.z; *pVertex++ = (float) seg / (float) NUM_SEGMENTS; *pVertex++ = (float) ring / (float) NUM_RINGS; if (ring != NUM_RINGS) { // each vertex (except the last) has six indicies pointing to it *pIndices++ = wVerticeIndex + NUM_SEGMENTS + 1; *pIndices++ = wVerticeIndex; *pIndices++ = wVerticeIndex + NUM_SEGMENTS; *pIndices++ = wVerticeIndex + NUM_SEGMENTS + 1; *pIndices++ = wVerticeIndex + 1; *pIndices++ = wVerticeIndex; wVerticeIndex ++; } }; // end for seg } // end for ring // Unlock vBuf->unlock(); iBuf->unlock(); // Generate face list pSphereVertex->useSharedVertices = true; // the original code was missing this line: mesh->_setBounds( AxisAlignedBox( Vector3(-SPHERE_RADIUS, -SPHERE_RADIUS, -SPHERE_RADIUS), Vector3(SPHERE_RADIUS, SPHERE_RADIUS, SPHERE_RADIUS) ), false ); mesh->_setBoundingSphereRadius(SPHERE_RADIUS); }
//--------------------------------------------------------------------- void PrefabFactory::createCube(Mesh* mesh) { SubMesh* sub = mesh->createSubMesh(); const int NUM_VERTICES = 4 * 6; // 4 vertices per side * 6 sides const int NUM_ENTRIES_PER_VERTEX = 8; const int NUM_VERTEX_ENTRIES = NUM_VERTICES * NUM_ENTRIES_PER_VERTEX; const int NUM_INDICES = 3 * 2 * 6; // 3 indices per face * 2 faces per side * 6 sides const Real CUBE_SIZE = 100.0f; const Real CUBE_HALF_SIZE = CUBE_SIZE / 2.0f; // Create 4 vertices per side instead of 6 that are shared for the whole cube. // The reason for this is with only 6 vertices the normals will look bad // since each vertex can "point" in a different direction depending on the face it is included in. float vertices[NUM_VERTEX_ENTRIES] = { // front side -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, // pos 0,0,1, // normal 0,1, // texcoord CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,0,1, 1,1, CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,0,1, 1,0, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE , 0,0,1, 0,0, // back side CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,0,-1, 0,1, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,0,-1, 1,1, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,0,-1, 1,0, CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,0,-1, 0,0, // left side -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -1,0,0, 0,1, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -1,0,0, 1,1, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, -1,0,0, 1,0, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -1,0,0, 0,0, // right side CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, 1,0,0, 0,1, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 1,0,0, 1,1, CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 1,0,0, 1,0, CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, 1,0,0, 0,0, // up side -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,1,0, 0,1, CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,1,0, 1,1, CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,1,0, 1,0, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,1,0, 0,0, // down side -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,-1,0, 0,1, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, 0,-1,0, 1,1, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,-1,0, 1,0, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, 0,-1,0, 0,0 }; mesh->sharedVertexData = OGRE_NEW VertexData(); mesh->sharedVertexData->vertexCount = NUM_VERTICES; VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration; VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding; size_t offset = 0; decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); offset += VertexElement::getTypeSize(VET_FLOAT2); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, NUM_VERTICES, HardwareBuffer::HBU_STATIC_WRITE_ONLY); bind->setBinding(0, vbuf); vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); sub->useSharedVertices = true; HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, NUM_INDICES, HardwareBuffer::HBU_STATIC_WRITE_ONLY); unsigned short faces[NUM_INDICES] = { // front 0,1,2, 0,2,3, // back 4,5,6, 4,6,7, // left 8,9,10, 8,10,11, // right 12,13,14, 12,14,15, // up 16,17,18, 16,18,19, // down 20,21,22, 20,22,23 }; sub->indexData->indexBuffer = ibuf; sub->indexData->indexCount = NUM_INDICES; sub->indexData->indexStart = 0; ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); mesh->_setBounds(AxisAlignedBox(-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE), true); mesh->_setBoundingSphereRadius(CUBE_HALF_SIZE); }
//----------------------------------------------------------------------- void MeshManager::loadManualCurvedIllusionPlane(Mesh* pMesh, MeshBuildParams& params) { if (params.ySegmentsToKeep == -1) params.ySegmentsToKeep = params.ysegments; if ((params.xsegments + 1) * (params.ySegmentsToKeep + 1) > 65536) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Plane tessellation is too high, must generate max 65536 vertices", __FUNCTION__); SubMesh *pSub = pMesh->createSubMesh(); // Set up vertex data // Use a single shared buffer pMesh->sharedVertexData = OGRE_NEW VertexData(); VertexData* vertexData = pMesh->sharedVertexData; // Set up Vertex Declaration VertexDeclaration* vertexDecl = vertexData->vertexDeclaration; size_t currOffset = 0; // We always need positions vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION); currOffset += VertexElement::getTypeSize(VET_FLOAT3); // Optional normals if(params.normals) { vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL); currOffset += VertexElement::getTypeSize(VET_FLOAT3); } for (unsigned short i = 0; i < params.numTexCoordSets; ++i) { // Assumes 2D texture coords vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, i); currOffset += VertexElement::getTypeSize(VET_FLOAT2); } vertexData->vertexCount = (params.xsegments + 1) * (params.ySegmentsToKeep + 1); // Allocate vertex buffer HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton(). createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, params.vertexBufferUsage, params.vertexShadowBuffer); // Set up the binding (one source only) VertexBufferBinding* binding = vertexData->vertexBufferBinding; binding->setBinding(0, vbuf); // Work out the transform required // Default orientation of plane is normal along +z, distance 0 Matrix4 xlate, xform, rot; Matrix3 rot3; xlate = rot = Matrix4::IDENTITY; // Determine axes Vector3 zAxis, yAxis, xAxis; zAxis = params.plane.normal; zAxis.normalise(); yAxis = params.upVector; yAxis.normalise(); xAxis = yAxis.crossProduct(zAxis); if (xAxis.length() == 0) { //upVector must be wrong OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "The upVector you supplied is parallel to the plane normal, so is not valid.", "MeshManager::createPlane"); } rot3.FromAxes(xAxis, yAxis, zAxis); rot = rot3; // Set up standard transform from origin xlate.setTrans(params.plane.normal * -params.plane.d); // concatenate xform = xlate * rot; // Generate vertex data // Imagine a large sphere with the camera located near the top // The lower the curvature, the larger the sphere // Use the angle from viewer to the points on the plane // Credit to Aftershock for the general approach Real camPos; // Camera position relative to sphere center // Derive sphere radius Vector3 vertPos; // position relative to camera Real sphDist; // Distance from camera to sphere along box vertex vector // Vector3 camToSph; // camera position to sphere Real sphereRadius;// Sphere radius // Actual values irrelevant, it's the relation between sphere radius and camera position that's important const Real SPHERE_RAD = 100.0; const Real CAM_DIST = 5.0; sphereRadius = SPHERE_RAD - params.curvature; camPos = sphereRadius - CAM_DIST; // Lock the whole buffer float* pFloat = static_cast<float*>( vbuf->lock(HardwareBuffer::HBL_DISCARD) ); Real xSpace = params.width / params.xsegments; Real ySpace = params.height / params.ysegments; Real halfWidth = params.width / 2; Real halfHeight = params.height / 2; Vector3 vec, norm; Vector3 min = Vector3::ZERO, max = Vector3::UNIT_SCALE; Real maxSquaredLength = 0; bool firstTime = true; for (int y = params.ysegments - params.ySegmentsToKeep; y < params.ysegments + 1; ++y) { for (int x = 0; x < params.xsegments + 1; ++x) { // Work out centered on origin vec.x = (x * xSpace) - halfWidth; vec.y = (y * ySpace) - halfHeight; vec.z = 0.0f; // Transform by orientation and distance vec = xform.transformAffine(vec); // Assign to geometry *pFloat++ = vec.x; *pFloat++ = vec.y; *pFloat++ = vec.z; // Build bounds as we go if (firstTime) { min = vec; max = vec; maxSquaredLength = vec.squaredLength(); firstTime = false; } else { min.makeFloor(vec); max.makeCeil(vec); maxSquaredLength = std::max(maxSquaredLength, vec.squaredLength()); } if (params.normals) { // Default normal is along unit Z norm = Vector3::UNIT_Z; // Rotate norm = params.orientation * norm; *pFloat++ = norm.x; *pFloat++ = norm.y; *pFloat++ = norm.z; } // Generate texture coords // Normalise position // modify by orientation to return +y up vec = params.orientation.Inverse() * vec; vec.normalise(); // Find distance to sphere sphDist = Math::Sqrt(camPos*camPos * (vec.y*vec.y-1.0f) + sphereRadius*sphereRadius) - camPos*vec.y; vec.x *= sphDist; vec.z *= sphDist; // Use x and y on sphere as texture coordinates, tiled Real s = vec.x * (0.01f * params.xTile); Real t = 1.0f - (vec.z * (0.01f * params.yTile)); for (unsigned short i = 0; i < params.numTexCoordSets; ++i) { *pFloat++ = s; *pFloat++ = t; } } // x } // y // Unlock vbuf->unlock(); // Generate face list pSub->useSharedVertices = true; tesselate2DMesh(pSub, params.xsegments + 1, params.ySegmentsToKeep + 1, false, params.indexBufferUsage, params.indexShadowBuffer); pMesh->_setBounds(AxisAlignedBox(min, max), true); pMesh->_setBoundingSphereRadius(Math::Sqrt(maxSquaredLength)); }
FlexAirfoil::FlexAirfoil(SceneManager *manager, char* name, node_t *nds, int pnfld, int pnfrd, int pnflu, int pnfru, int pnbld, int pnbrd, int pnblu, int pnbru, char* texband, Vector2 texlf, Vector2 texrf, Vector2 texlb, Vector2 texrb, char mtype, float controlratio, float mind, float maxd, char* afname, float lift_coef, AeroEngine** tps, bool break_able) { // innan=0; liftcoef=lift_coef; breakable=break_able; broken=false; debug[0]=0; free_wash=0; smanager=manager; aeroengines=tps; nodes=nds; useInducedDrag=false; nfld=pnfld; nodes[nfld].iIsSkin=true; nfrd=pnfrd; nodes[nfrd].iIsSkin=true; nflu=pnflu; nodes[nflu].iIsSkin=true; nfru=pnfru; nodes[nfru].iIsSkin=true; nbld=pnbld; nodes[nbld].iIsSkin=true; nbrd=pnbrd; nodes[nbrd].iIsSkin=true; nblu=pnblu; nodes[nblu].iIsSkin=true; nbru=pnbru; nodes[nbru].iIsSkin=true; mindef=mind; maxdef=maxd; airfoil=new Airfoil(afname); //airfoil->getcl(-180.0, 0, 0); //airfoil->dumpcl(); int i; for (i=0; i<90; i++) airfoilpos[i]=refairfoilpos[i]; type=mtype; hascontrol=(mtype!='n' && mtype!='S'&& mtype!='T' && mtype!='U'&& mtype!='V'); isstabilator=(mtype=='S' || mtype=='T' || mtype=='U' || mtype=='V'); stabilleft=(mtype=='T' || mtype=='V'); deflection=0.0; chordratio=controlratio; if (hascontrol) { //setup control surface airfoilpos[56]=controlratio; airfoilpos[56+3]=controlratio; airfoilpos[56+6]=controlratio; airfoilpos[56+9]=controlratio; airfoilpos[55]=-controlratio+1.5; airfoilpos[55+3]=-controlratio+1.5; airfoilpos[55+6]=controlratio-0.5; airfoilpos[55+9]=controlratio-0.5; for (i=0; i<12; i++) airfoilpos[54+12+i]=airfoilpos[54+i]; } /// Create the mesh via the MeshManager msh = MeshManager::getSingleton().createManual(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, new ResourceBuffer()); /// Create submeshes subface = msh->createSubMesh(); subband = msh->createSubMesh(); subcup=msh->createSubMesh(); subcdn=msh->createSubMesh(); //materials subface->setMaterialName(texband); subband->setMaterialName(texband); subcup->setMaterialName(texband); subcdn->setMaterialName(texband); /// Define the vertices nVertices = 24*2+4+2; vbufCount = (2*3+2)*nVertices; vertices=(float*)malloc(vbufCount*sizeof(float)); //shadow shadownorvertices=(float*)malloc(nVertices*(3+2)*sizeof(float)); shadowposvertices=(float*)malloc(nVertices*3*2*sizeof(float)); //textures coordinates covertices[0].texcoord=texlf; covertices[1].texcoord=texrf; covertices[2].texcoord=texlf+(texlb-texlf)*0.03; covertices[3].texcoord=texrf+(texrb-texrf)*0.03; covertices[4].texcoord=texlf+(texlb-texlf)*0.03; covertices[5].texcoord=texrf+(texrb-texrf)*0.03; covertices[6].texcoord=texlf+(texlb-texlf)*0.10; covertices[7].texcoord=texrf+(texrb-texrf)*0.10; covertices[8].texcoord=texlf+(texlb-texlf)*0.10; covertices[9].texcoord=texrf+(texrb-texrf)*0.10; covertices[10].texcoord=texlf+(texlb-texlf)*0.25; covertices[11].texcoord=texrf+(texrb-texrf)*0.25; covertices[12].texcoord=texlf+(texlb-texlf)*0.25; covertices[13].texcoord=texrf+(texrb-texrf)*0.25; covertices[14].texcoord=texlf+(texlb-texlf)*0.45; covertices[15].texcoord=texrf+(texrb-texrf)*0.45; covertices[16].texcoord=texlf+(texlb-texlf)*0.45; covertices[17].texcoord=texrf+(texrb-texrf)*0.45; covertices[18].texcoord=texlf+(texlb-texlf)*airfoilpos[56]; covertices[19].texcoord=texrf+(texrb-texrf)*airfoilpos[56]; covertices[20].texcoord=texlf+(texlb-texlf)*airfoilpos[56]; covertices[21].texcoord=texrf+(texrb-texrf)*airfoilpos[56]; covertices[22].texcoord=covertices[18].texcoord; covertices[23].texcoord=covertices[19].texcoord; covertices[24].texcoord=covertices[20].texcoord; covertices[25].texcoord=covertices[21].texcoord; covertices[26].texcoord=texlb; covertices[27].texcoord=texrb; covertices[28].texcoord=texlb; covertices[29].texcoord=texrb; for (i=0; i<24; i++) covertices[i+30].texcoord=covertices[i].texcoord; /// Define triangles /// The values in this table refer to vertices in the above table bandibufCount = 3*20; faceibufCount = 3*20; cupibufCount=3*2; cdnibufCount=3*2; facefaces=(unsigned short*)malloc(faceibufCount*sizeof(unsigned short)); bandfaces=(unsigned short*)malloc(bandibufCount*sizeof(unsigned short)); cupfaces=(unsigned short*)malloc(cupibufCount*sizeof(unsigned short)); cdnfaces=(unsigned short*)malloc(cdnibufCount*sizeof(unsigned short)); //attack bandfaces[0]=0; bandfaces[1]=2; bandfaces[2]=1; bandfaces[3]=2; bandfaces[4]=3; bandfaces[5]=1; bandfaces[6]=0; bandfaces[7]=1; bandfaces[8]=4; bandfaces[9]=4; bandfaces[10]=1; bandfaces[11]=5; for (i=0; i<5; i++) { //band int v=i*4+2; if (i!=4) { bandfaces[i*12+12]=v; bandfaces[i*12+13]=v+4; bandfaces[i*12+14]=v+1; bandfaces[i*12+15]=v+4; bandfaces[i*12+16]=v+5; bandfaces[i*12+17]=v+1; bandfaces[i*12+18]=v+2; bandfaces[i*12+19]=v+3; bandfaces[i*12+20]=v+6; bandfaces[i*12+21]=v+6; bandfaces[i*12+22]=v+3; bandfaces[i*12+23]=v+7; } /* if (i==4) { bandfaces[i*12+20]=v+4; bandfaces[i*12+21]=v+4; bandfaces[i*12+23]=v+5; } */ //sides facefaces[i*12]=30+0; facefaces[i*12+1]=30+v+4; facefaces[i*12+2]=30+v; facefaces[i*12+3]=30+0; facefaces[i*12+4]=30+v+2; facefaces[i*12+5]=30+v+6; facefaces[i*12+6]=30+1; facefaces[i*12+7]=30+v+1; facefaces[i*12+8]=30+v+5; facefaces[i*12+9]=30+1; facefaces[i*12+10]=30+v+7; facefaces[i*12+11]=30+v+3; if (i==4) { // facefaces[i*12+5]=20+v+4; // facefaces[i*12+10]=20+v+5; facefaces[i*12]=30+0; facefaces[i*12+1]=30+v+2; facefaces[i*12+2]=30+v; facefaces[i*12+3]=30+v+4; facefaces[i*12+4]=30+v; facefaces[i*12+5]=30+v+2; facefaces[i*12+6]=30+1; facefaces[i*12+7]=30+v+1; facefaces[i*12+8]=30+v+3; facefaces[i*12+9]=30+v+5; facefaces[i*12+10]=30+v+3; facefaces[i*12+11]=30+v+1; } } cupfaces[0]=22; cupfaces[1]=26; cupfaces[2]=23; cupfaces[3]=26; cupfaces[4]=27; cupfaces[5]=23; cdnfaces[0]=24; cdnfaces[1]=25; cdnfaces[2]=29; cdnfaces[3]=24; cdnfaces[4]=29; cdnfaces[5]=28; float tsref=2.0*(nodes[nfrd].RelPosition-nodes[nfld].RelPosition).crossProduct(nodes[nbld].RelPosition-nodes[nfld].RelPosition).length(); sref=2.0*(nodes[nfrd].RelPosition-nodes[nfld].RelPosition).crossProduct(nodes[nbrd].RelPosition-nodes[nfrd].RelPosition).length(); if (tsref>sref) sref=tsref; sref=sref*sref; lratio=(nodes[nfld].RelPosition-nodes[nflu].RelPosition).length()/(nodes[nfld].RelPosition-nodes[nbld].RelPosition).length(); rratio=(nodes[nfrd].RelPosition-nodes[nfru].RelPosition).length()/(nodes[nfrd].RelPosition-nodes[nbrd].RelPosition).length(); thickness=(nodes[nfld].RelPosition-nodes[nflu].RelPosition).length(); //update coords updateVertices(); /// Create vertex data structure for 8 vertices shared between submeshes msh->sharedVertexData = new VertexData(); msh->sharedVertexData->vertexCount = nVertices; /// Create declaration (memory format) of vertex data decl = msh->sharedVertexData->vertexDeclaration; size_t offset = 0; decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); // decl->addElement(0, offset, VET_FLOAT3, VES_DIFFUSE); // offset += VertexElement::getTypeSize(VET_FLOAT3); decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); offset += VertexElement::getTypeSize(VET_FLOAT2); /// Allocate vertex buffer of the requested number of vertices (vertexCount) /// and bytes per vertex (offset) vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); /// Upload the vertex data to the card vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding; bind->setBinding(0, vbuf); //for the face /// Allocate index buffer of the requested number of vertices (ibufCount) HardwareIndexBufferSharedPtr faceibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, faceibufCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the index data to the card faceibuf->writeData(0, faceibuf->getSizeInBytes(), facefaces, true); /// Set parameters of the submesh subface->useSharedVertices = true; subface->indexData->indexBuffer = faceibuf; subface->indexData->indexCount = faceibufCount; subface->indexData->indexStart = 0; //for the band /// Allocate index buffer of the requested number of vertices (ibufCount) HardwareIndexBufferSharedPtr bandibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, bandibufCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the index data to the card bandibuf->writeData(0, bandibuf->getSizeInBytes(), bandfaces, true); /// Set parameters of the submesh subband->useSharedVertices = true; subband->indexData->indexBuffer = bandibuf; subband->indexData->indexCount = bandibufCount; subband->indexData->indexStart = 0; //for the aileron up /// Allocate index buffer of the requested number of vertices (ibufCount) HardwareIndexBufferSharedPtr cupibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, cupibufCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the index data to the card cupibuf->writeData(0, cupibuf->getSizeInBytes(), cupfaces, true); /// Set parameters of the submesh subcup->useSharedVertices = true; subcup->indexData->indexBuffer = cupibuf; subcup->indexData->indexCount = cupibufCount; subcup->indexData->indexStart = 0; //for the aileron down /// Allocate index buffer of the requested number of vertices (ibufCount) HardwareIndexBufferSharedPtr cdnibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, cdnibufCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the index data to the card cdnibuf->writeData(0, cdnibuf->getSizeInBytes(), cdnfaces, true); /// Set parameters of the submesh subcdn->useSharedVertices = true; subcdn->indexData->indexBuffer = cdnibuf; subcdn->indexData->indexCount = cdnibufCount; subcdn->indexData->indexStart = 0; /// Set bounding information (for culling) msh->_setBounds(AxisAlignedBox(-20,-20,-20,20,20,20), true); //msh->_setBoundingSphereRadius(20.0); /// Notify Mesh object that it has been loaded //MeshManager::getSingleton().setPrepareAllMeshesForShadowVolumes(false); msh->buildEdgeList(); //msh->prepareForShadowVolume(); msh->load(); //MeshManager::getSingleton().setPrepareAllMeshesForShadowVolumes() }
void PlanetMovable::initObject() { setListener(this); mMap = new PlanetMap(&mDescriptor); mCube = new PlanetCube(this, mMap); mBoundingBox = AxisAlignedBox(Vector3(-mCube->getScale()), Vector3(mCube->getScale())); }
MeshPtr MeshMergeTool::merge(const Ogre::String& name, const Ogre::String& resourceGroupName) { print("Baking: New Mesh started", V_HIGH); MeshPtr mp = MeshManager::getSingleton().createManual(name, resourceGroupName); if (!mBaseSkeleton.isNull()) { mp->setSkeletonName(mBaseSkeleton->getName()); } AxisAlignedBox totalBounds = AxisAlignedBox(); for (std::vector<Ogre::MeshPtr>::iterator it = mMeshes.begin(); it != mMeshes.end(); ++it) { print("Baking: adding submeshes for " + (*it)->getName(), V_HIGH); // insert all submeshes for (Ogre::ushort sid = 0; sid < (*it)->getNumSubMeshes(); ++sid) { SubMesh* sub = (*it)->getSubMesh(sid); const String name = findSubmeshName((*it), sid); // create submesh with correct name SubMesh* newsub; if (name.length() == 0) { newsub = mp->createSubMesh(); } else { /// @todo check if a submesh with this name has been created before newsub = mp->createSubMesh(name); } newsub->useSharedVertices = sub->useSharedVertices; // add index newsub->indexData = sub->indexData->clone(); // add geometry if (!newsub->useSharedVertices) { newsub->vertexData = sub->vertexData->clone(); if (!mBaseSkeleton.isNull()) { // build bone assignments SubMesh::BoneAssignmentIterator bit = sub->getBoneAssignmentIterator(); while (bit.hasMoreElements()) { VertexBoneAssignment vba = bit.getNext(); newsub->addBoneAssignment(vba); } } } newsub->setMaterialName(sub->getMaterialName()); // Add vertex animations for this submesh Animation *anim = 0; for (unsigned short i = 0; i < (*it)->getNumAnimations(); ++i) { anim = (*it)->getAnimation(i); // get or create the animation for the new mesh Animation *newanim; if (mp->hasAnimation(anim->getName())) { newanim = mp->getAnimation(anim->getName()); } else { newanim = mp->createAnimation(anim->getName(), anim->getLength()); } print("Baking: adding vertex animation " + anim->getName() + " for " + (*it)->getName(), V_HIGH); Animation::VertexTrackIterator vti=anim->getVertexTrackIterator(); while (vti.hasMoreElements()) { VertexAnimationTrack *vt = vti.getNext(); // handle=0 targets the main mesh, handle i (where i>0) targets submesh i-1. // In this case there are only submeshes so index 0 will not be used. unsigned short handle = mp->getNumSubMeshes(); VertexAnimationTrack* newvt = newanim->createVertexTrack( handle, vt->getAssociatedVertexData()->clone(), vt->getAnimationType()); for (int keyFrameIndex = 0; keyFrameIndex < vt->getNumKeyFrames(); ++keyFrameIndex) { switch (vt->getAnimationType()) { case VAT_MORPH: { // copy the keyframe vertex buffer VertexMorphKeyFrame *kf = vt->getVertexMorphKeyFrame(keyFrameIndex); VertexMorphKeyFrame *newkf = newvt->createVertexMorphKeyFrame(kf->getTime()); // This creates a ref to the buffer in the original model // so don't delete it until the export is completed. newkf->setVertexBuffer(kf->getVertexBuffer()); break; } case VAT_POSE: { /// @todo implement pose amination merge break; } case VAT_NONE: default: { break; } } } } } print("Baking: adding submesh '" + name + "' with material " + sub->getMaterialName(), V_HIGH); } // sharedvertices if ((*it)->sharedVertexData) { /// @todo merge with existing sharedVertexData if (!mp->sharedVertexData) { mp->sharedVertexData = (*it)->sharedVertexData->clone(); } if (!mBaseSkeleton.isNull()) { Mesh::BoneAssignmentIterator bit = (*it)->getBoneAssignmentIterator(); while (bit.hasMoreElements()) { VertexBoneAssignment vba = bit.getNext(); mp->addBoneAssignment(vba); } } } print("Baking: adding bounds for " + (*it)->getName(), V_HIGH); // add bounds totalBounds.merge((*it)->getBounds()); } mp->_setBounds(totalBounds); /// @todo merge submeshes with same material /// @todo add parameters mp->buildEdgeList(); print("Baking: Finished", V_HIGH); reset(); return mp; }
AxisAlignedBox Player::GetBoundingBox() { return AxisAlignedBox(); }