Airbrake::Airbrake(char* basename, int num, node_t *ndref, node_t *ndx, node_t *ndy, node_t *nda, Vector3 pos, float width, float length, float maxang, char* texname, float tx1, float ty1, float tx2, float ty2, float lift_coef) { snode=0; noderef=ndref; nodex=ndx; nodey=ndy; nodea=nda; offset=pos; maxangle=maxang; area=width*length*lift_coef; char meshname[256]; sprintf(meshname, "airbrakemesh-%s-%i", basename, num); /// Create the mesh via the MeshManager msh = MeshManager::getSingleton().createManual(meshname, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); union { float *vertices; CoVertice_t *covertices; }; /// Create submesh SubMesh* sub = msh->createSubMesh(); //materials sub->setMaterialName(texname); /// Define the vertices size_t nVertices = 4; size_t vbufCount = (2*3+2)*nVertices; vertices=(float*)malloc(vbufCount*sizeof(float)); //textures coordinates covertices[0].texcoord=Vector2(tx1, ty1); covertices[1].texcoord=Vector2(tx2, ty1); covertices[2].texcoord=Vector2(tx2, ty2); covertices[3].texcoord=Vector2(tx1, ty2); /// Define triangles /// The values in this table refer to vertices in the above table size_t ibufCount = 3*4; unsigned short *faces=(unsigned short*)malloc(ibufCount*sizeof(unsigned short)); faces[0]=0; faces[1]=1; faces[2]=2; faces[3]=0; faces[4]=2; faces[5]=3; faces[6]=0; faces[7]=2; faces[8]=1; faces[9]=0; faces[10]=3; faces[11]=2; //set coords covertices[0].vertex=Vector3(0,0,0); covertices[1].vertex=Vector3(width,0,0); covertices[2].vertex=Vector3(width,0,length); covertices[3].vertex=Vector3(0,0,length); covertices[0].normal=Vector3(0,1,0); covertices[1].normal=Vector3(0,1,0); covertices[2].normal=Vector3(0,1,0); covertices[3].normal=Vector3(0,1,0); /// Create vertex data structure for vertices shared between submeshes msh->sharedVertexData = new VertexData(); msh->sharedVertexData->vertexCount = nVertices; /// Create declaration (memory format) of vertex data VertexDeclaration* 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) HardwareVertexBufferSharedPtr 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); /// Allocate index buffer of the requested number of vertices (ibufCount) HardwareIndexBufferSharedPtr faceibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, ibufCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the index data to the card faceibuf->writeData(0, faceibuf->getSizeInBytes(), faces, true); /// Set parameters of the submesh sub->useSharedVertices = true; sub->indexData->indexBuffer = faceibuf; sub->indexData->indexCount = ibufCount; sub->indexData->indexStart = 0; /// Set bounding information (for culling) msh->_setBounds(AxisAlignedBox(-1,-1,0,1,1,0), true); //msh->_setBoundingSphereRadius(Math::Sqrt(1*1+1*1)); /// Notify Mesh object that it has been loaded msh->load(); // create the entity and scene node char entname[256]; sprintf(entname, "airbrakenode-%s-%i", basename, num); ec = gEnv->sceneManager->createEntity(entname, meshname); snode = gEnv->sceneManager->getRootSceneNode()->createChildSceneNode(); snode->attachObject(ec); updatePosition(0.0); free (vertices); free (faces); }
//--------------------------------------------------------------------- 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 Road2::createMesh() { AxisAlignedBox aab; union { float* vertices; CoVertice_t* covertices; }; /// Create the mesh via the MeshManager Ogre::String mesh_name = Ogre::String("RoadSystem-").append(Ogre::StringConverter::toString(mid)); msh = MeshManager::getSingleton().createManual(mesh_name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); mainsub = msh->createSubMesh(); mainsub->setMaterialName("road2"); /// Define the vertices size_t vbufCount = (2 * 3 + 2) * vertexcount; vertices = (float*)malloc(vbufCount * sizeof(float)); int i; //fill values for (i = 0; i < vertexcount; i++) { covertices[i].texcoord = tex[i]; covertices[i].vertex = vertex[i]; //normals are computed later covertices[i].normal = Vector3::ZERO; aab.merge(vertex[i]); } /// Define triangles size_t ibufCount = 3 * tricount; //compute normals for (i = 0; i < tricount && i * 3 + 2 < MAX_TRIS * 3; i++) { Vector3 v1, v2; v1 = covertices[tris[i * 3 + 1]].vertex - covertices[tris[i * 3]].vertex; v2 = covertices[tris[i * 3 + 2]].vertex - covertices[tris[i * 3]].vertex; v1 = v1.crossProduct(v2); v1.normalise(); covertices[tris[i * 3]].normal += v1; covertices[tris[i * 3 + 1]].normal += v1; covertices[tris[i * 3 + 2]].normal += v1; } //normalize for (i = 0; i < vertexcount; i++) { covertices[i].normal.normalise(); } /// Create vertex data structure for vertices shared between sub meshes msh->sharedVertexData = new VertexData(); msh->sharedVertexData->vertexCount = vertexcount; /// Create declaration (memory format) of vertex data VertexDeclaration* 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_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) HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// 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 ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, ibufCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the index data to the card ibuf->writeData(0, ibuf->getSizeInBytes(), tris, true); /// Set parameters of the submesh mainsub->useSharedVertices = true; mainsub->indexData->indexBuffer = ibuf; mainsub->indexData->indexCount = ibufCount; mainsub->indexData->indexStart = 0; msh->_setBounds(aab, true); /// Notify Mesh object that it has been loaded msh->load(); free(vertices); };
void VolumeRenderable::initialise() { // Create geometry size_t nvertices = mSlices*4; // n+1 planes size_t elemsize = 3*3; size_t dsize = elemsize*nvertices; size_t x; Ogre::IndexData *idata = new Ogre::IndexData(); Ogre::VertexData *vdata = new Ogre::VertexData(); // Create structures float *vertices = new float[dsize]; float coords[4][2] = { {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}, {1.0f, 1.0f} }; for(x=0; x<mSlices; x++) { for(size_t y=0; y<4; y++) { float xcoord = coords[y][0]-0.5f; float ycoord = coords[y][1]-0.5f; float zcoord = -((float)x/(float)(mSlices-1) - 0.5f); // 1.0f .. a/(a+1) // coordinate vertices[x*4*elemsize+y*elemsize+0] = xcoord*(mSize/2.0f); vertices[x*4*elemsize+y*elemsize+1] = ycoord*(mSize/2.0f); vertices[x*4*elemsize+y*elemsize+2] = zcoord*(mSize/2.0f); // normal vertices[x*4*elemsize+y*elemsize+3] = 0.0f; vertices[x*4*elemsize+y*elemsize+4] = 0.0f; vertices[x*4*elemsize+y*elemsize+5] = 1.0f; // tex vertices[x*4*elemsize+y*elemsize+6] = xcoord*sqrtf(3.0f); vertices[x*4*elemsize+y*elemsize+7] = ycoord*sqrtf(3.0f); vertices[x*4*elemsize+y*elemsize+8] = zcoord*sqrtf(3.0f); } } unsigned short *faces = new unsigned short[mSlices*6]; for(x=0; x<mSlices; x++) { faces[x*6+0] = x*4+0; faces[x*6+1] = x*4+1; faces[x*6+2] = x*4+2; faces[x*6+3] = x*4+1; faces[x*6+4] = x*4+2; faces[x*6+5] = x*4+3; } // Setup buffers vdata->vertexStart = 0; vdata->vertexCount = nvertices; VertexDeclaration* decl = vdata->vertexDeclaration; VertexBufferBinding* bind = vdata->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_FLOAT3, VES_TEXTURE_COORDINATES); offset += VertexElement::getTypeSize(VET_FLOAT3); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, nvertices, HardwareBuffer::HBU_STATIC_WRITE_ONLY); bind->setBinding(0, vbuf); vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, mSlices*6, HardwareBuffer::HBU_STATIC_WRITE_ONLY); idata->indexBuffer = ibuf; idata->indexCount = mSlices*6; idata->indexStart = 0; ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); // Delete temporary buffers delete [] vertices; delete [] faces; // Now make the render operation mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST; mRenderOp.indexData = idata; mRenderOp.vertexData = vdata; mRenderOp.useIndexes = true; // Create a brand new private material if (!ResourceGroupManager::getSingleton().resourceGroupExists("VolumeRenderable")) { ResourceGroupManager::getSingleton().createResourceGroup("VolumeRenderable"); } MaterialPtr material = MaterialManager::getSingleton().create(mTexture, "VolumeRenderable", false, 0); // Manual, loader // Remove pre-created technique from defaults material->removeAllTechniques(); // Create a techinique and a pass and a texture unit Technique * technique = material->createTechnique(); Pass * pass = technique->createPass(); TextureUnitState * textureUnit = pass->createTextureUnitState(); // Set pass parameters pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); pass->setDepthWriteEnabled(false); pass->setCullingMode(CULL_NONE); pass->setLightingEnabled(false); // Set texture unit parameters textureUnit->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); textureUnit->setTextureName(mTexture, TEX_TYPE_3D); textureUnit->setTextureFiltering(TFO_TRILINEAR); mUnit = textureUnit; mMaterial = material; }
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() }
Mesh* OgreSubsystem::createMesh(const MeshData& data,String name) { String nombre = name; if(name=="AUTO_NAME_ME") { nombre = "OryxSceneNodeAutoNamed"+StringUtils::toString(mAutoNameIndex); ++mAutoNameIndex; } using namespace Ogre; bool hasVertexColor = data.getDiffuse(); bool hasNormals = data.getNormals(); int numFaces = data.indices.size()/3; int numVertices = data.vertices.size()/3; HardwareVertexBufferSharedPtr posVertexBuffer; HardwareVertexBufferSharedPtr normVertexBuffer; std::vector<HardwareVertexBufferSharedPtr> texcoordsVertexBuffer; HardwareVertexBufferSharedPtr diffuseVertexBuffer; HardwareIndexBufferSharedPtr indexBuffer; Ogre::Mesh* m = Ogre::MeshManager::getSingletonPtr()->createManual( nombre,ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME).get(); Ogre::SubMesh* sm = m->createSubMesh(); sm->useSharedVertices = false; sm->vertexData = new VertexData(); sm->vertexData->vertexStart = 0; sm->vertexData->vertexCount = numVertices; Ogre::VertexDeclaration* vdecl = sm->vertexData->vertexDeclaration; Ogre::VertexBufferBinding* vbind = sm->vertexData->vertexBufferBinding; size_t bufferCount = 0; vdecl->addElement(bufferCount, 0, VET_FLOAT3, VES_POSITION); if(hasNormals) vdecl->addElement(++bufferCount, 0, VET_FLOAT3, VES_NORMAL); if(hasVertexColor) vdecl->addElement(++bufferCount, 0, VET_FLOAT4, VES_DIFFUSE); for(int i=0;i<data.texcoords.size();++i) vdecl->addElement(++bufferCount, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES,i); bufferCount = 0; // Positions posVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 3*sizeof(float),numVertices,Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); vbind->setBinding(bufferCount, posVertexBuffer); float* vertices = data.getVertices(); float* normals = data.getNormals(); float* diffuse = data.getDiffuse(); unsigned short* indices = data.getIndices(); posVertexBuffer->writeData(0,posVertexBuffer->getSizeInBytes(),vertices, true); // Normals if(hasNormals) { normVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 3*sizeof(float),numVertices,HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); vbind->setBinding(++bufferCount, normVertexBuffer); normVertexBuffer->writeData(0,normVertexBuffer->getSizeInBytes(),normals, true); } if(hasVertexColor) { diffuseVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 4*sizeof(float),numVertices,HardwareBuffer::HBU_STATIC_WRITE_ONLY); vbind->setBinding(++bufferCount, diffuseVertexBuffer); diffuseVertexBuffer->writeData(0,diffuseVertexBuffer->getSizeInBytes(), diffuse, true); } // Texcoords for(int i=0;i<data.texcoords.size();++i) { texcoordsVertexBuffer.push_back(HardwareBufferManager::getSingleton().createVertexBuffer( 2*sizeof(float),numVertices,HardwareBuffer::HBU_STATIC_WRITE_ONLY)); vbind->setBinding(++bufferCount, texcoordsVertexBuffer[i]); texcoordsVertexBuffer[i]->writeData(0,sizeof(float)*data.texcoords[i].size(),&data.texcoords[i][0], false); } if(!data.indices.empty()) { // Prepare buffer for indices indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( HardwareIndexBuffer::IT_16BIT,3*numFaces,HardwareBuffer::HBU_STATIC_WRITE_ONLY, true); //unsigned short *faceVertexIndices = (unsigned short*) //indexBuffer->lock(0, numFaces*3*2, HardwareBuffer::HBL_DISCARD); // Set index buffer for this submesh sm->indexData->indexBuffer = indexBuffer; sm->indexData->indexStart = 0; sm->indexData->indexCount = 3*numFaces; indexBuffer->writeData(0,indexBuffer->getSizeInBytes(),indices,true); } //vdecl->sort(); m->load(); m->touch(); m->_setBounds(AxisAlignedBox(data.bbox[0],data.bbox[1],data.bbox[2], data.bbox[3],data.bbox[4],data.bbox[5]), false); sm->setMaterialName("Terrain"); Ogre::Entity* ent = mSceneManager->createEntity(nombre,m->getName()); Ogre::SceneNode* node = mSceneManager->createSceneNode(nombre); node->attachObject(ent); ent->setCastShadows(false); Mesh* mm = new Mesh(nombre,node,ent); mSceneNodes.push_back(mm); return mm; }
FlexObj::FlexObj(node_t *nds, std::vector<CabTexcoord>& texcoords, int numtriangles, int* triangles, std::vector<CabSubmesh>& submesh_defs, char* texname, const char* name, char* backtexname, char* transtexname) { m_triangle_count = numtriangles; m_all_nodes=nds; // Create the mesh via the MeshManager m_mesh = MeshManager::getSingleton().createManual(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); // Create submeshes m_submeshes.reserve(submesh_defs.size()); for (size_t j=0; j<submesh_defs.size(); j++) { Ogre::SubMesh* submesh = m_mesh->createSubMesh(); switch (submesh_defs[j].backmesh_type) { case CabSubmesh::BACKMESH_OPAQUE: submesh->setMaterialName(backtexname); break; case CabSubmesh::BACKMESH_TRANSPARENT: submesh->setMaterialName(transtexname); break; default: submesh->setMaterialName(texname); } m_submeshes.push_back(submesh); }; // Define the m_vertices_raw (8 vertices, each consisting of 3 groups of 3 floats m_vertex_count = texcoords.size(); m_vertices_raw=(float*)malloc(((2*3+2)*m_vertex_count)*sizeof(float)); m_vertex_nodes=(int*)malloc(m_vertex_count*sizeof(int)); for (size_t i=0; i<m_vertex_count; i++) { m_vertex_nodes[i] = texcoords[i].node_id; //define node ids m_vertices[i].texcoord=Vector2(texcoords[i].texcoord_u, texcoords[i].texcoord_v); //textures coordinates } // Define triangles // The values in this table refer to vertices in the above table m_index_count = 3*numtriangles; m_indices=(unsigned short*)malloc(m_index_count*sizeof(unsigned short)); for (size_t i=0; i<m_index_count; i++) { m_indices[i]=ComputeVertexPos(i/3, triangles[i], submesh_defs); } m_s_ref=(float*)malloc(numtriangles*sizeof(float)); for (size_t i=0; i<(unsigned int)numtriangles;i++) { Ogre::Vector3 base_pos = m_all_nodes[m_vertex_nodes[m_indices[i*3]]].RelPosition; Ogre::Vector3 v1 = m_all_nodes[m_vertex_nodes[m_indices[i*3+1]]].RelPosition - base_pos; Ogre::Vector3 v2 = m_all_nodes[m_vertex_nodes[m_indices[i*3+2]]].RelPosition - base_pos; m_s_ref[i]=v1.crossProduct(v2).length()*2.0; } this->UpdateMesh(); // Initialize the dynamic mesh // Create vertex data structure for vertices shared between submeshes m_mesh->sharedVertexData = new VertexData(); m_mesh->sharedVertexData->vertexCount = m_vertex_count; // Create declaration (memory format) of vertex data m_vertex_format = m_mesh->sharedVertexData->vertexDeclaration; size_t offset = 0; m_vertex_format->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); m_vertex_format->addElement(0, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); m_vertex_format->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) m_hw_vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, m_mesh->sharedVertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); // Upload the vertex data to the card m_hw_vbuf->writeData(0, m_hw_vbuf->getSizeInBytes(), m_vertices_raw, true); // Set vertex buffer binding so buffer 0 is bound to our vertex buffer VertexBufferBinding* bind = m_mesh->sharedVertexData->vertexBufferBinding; bind->setBinding(0, m_hw_vbuf); // Set parameters of the submeshes for (size_t j=0; j<m_submeshes.size(); j++) { size_t index_count; if (j == 0) index_count = 3*submesh_defs[j].cabs_pos; else index_count = 3*(submesh_defs[j].cabs_pos-submesh_defs[j-1].cabs_pos); // 3 indices per triangle m_submeshes[j]->useSharedVertices = true; HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().createIndexBuffer( HardwareIndexBuffer::IT_16BIT, index_count, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Upload the index data to the card unsigned short* faces_ptr; if (j == 0) faces_ptr = &m_indices[0]; else faces_ptr = &m_indices[submesh_defs[j-1].cabs_pos * 3]; ibuf->writeData(0, ibuf->getSizeInBytes(), faces_ptr, true); m_submeshes[j]->indexData->indexBuffer = ibuf; m_submeshes[j]->indexData->indexCount = index_count; m_submeshes[j]->indexData->indexStart = 0; } // Set bounding information (for culling) m_mesh->_setBounds(AxisAlignedBox(-100,-100,-100,100,100,100), true); // Notify Mesh object that it has been loaded m_mesh->load(); }
FlexMeshWheel::FlexMeshWheel(SceneManager *manager, char* name, node_t *nds, int n1, int n2, int nstart, int nrays, char* meshname, char* texband, float rimradius, bool rimreverse, MaterialFunctionMapper *mfm, Skin *usedSkin, MaterialReplacer *mr) : mr(mr) { rim_radius=rimradius; revrim=rimreverse; smanager=manager; nbrays=nrays; nodes=nds; id0=n1; id1=n2; idstart=nstart; //the rim object char rimname[256]; sprintf(rimname, "rim-%s", name); rimEnt = manager->createEntity(rimname, meshname); MaterialFunctionMapper::replaceSimpleMeshMaterials(rimEnt, ColourValue(0, 0.5, 0.8)); if(mfm) mfm->replaceMeshMaterials(rimEnt); if(mr) mr->replaceMeshMaterials(rimEnt); if(usedSkin) usedSkin->replaceMeshMaterials(rimEnt); rnode=manager->getRootSceneNode()->createChildSceneNode(); rnode->attachObject(rimEnt); /// Create the mesh via the MeshManager msh = MeshManager::getSingleton().createManual(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,new ResourceBuffer()); /// Create submeshes sub = msh->createSubMesh(); //materials sub->setMaterialName(texband); /// Define the vertices nVertices = 6*(nrays+1); 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)); int i; //textures coordinates for (i=0; i<nrays+1; i++) { covertices[i*6 ].texcoord=Vector2((float)i/(float)nrays, 0.00); covertices[i*6+1 ].texcoord=Vector2((float)i/(float)nrays, 0.23); covertices[i*6+2 ].texcoord=Vector2((float)i/(float)nrays, 0.27); covertices[i*6+3 ].texcoord=Vector2((float)i/(float)nrays, 0.73); covertices[i*6+4 ].texcoord=Vector2((float)i/(float)nrays, 0.77); covertices[i*6+5 ].texcoord=Vector2((float)i/(float)nrays, 1.00); } /// Define triangles /// The values in this table refer to vertices in the above table ibufCount = 3*10*nrays; faces=(unsigned short*)malloc(ibufCount*sizeof(unsigned short)); for (i=0; i<nrays; i++) { faces[3*(i*10 )]=i*6; faces[3*(i*10 )+1]=i*6+1; faces[3*(i*10 )+2]=(i+1)*6; faces[3*(i*10+1)]=i*6+1; faces[3*(i*10+1)+1]=(i+1)*6+1; faces[3*(i*10+1)+2]=(i+1)*6; faces[3*(i*10+2)]=i*6+1; faces[3*(i*10+2)+1]=i*6+2; faces[3*(i*10+2)+2]=(i+1)*6+1; faces[3*(i*10+3)]=i*6+2; faces[3*(i*10+3)+1]=(i+1)*6+2; faces[3*(i*10+3)+2]=(i+1)*6+1; faces[3*(i*10+4)]=i*6+2; faces[3*(i*10+4)+1]=i*6+3; faces[3*(i*10+4)+2]=(i+1)*6+2; faces[3*(i*10+5)]=i*6+3; faces[3*(i*10+5)+1]=(i+1)*6+3; faces[3*(i*10+5)+2]=(i+1)*6+2; faces[3*(i*10+6)]=i*6+3; faces[3*(i*10+6)+1]=i*6+4; faces[3*(i*10+6)+2]=(i+1)*6+3; faces[3*(i*10+7)]=i*6+4; faces[3*(i*10+7)+1]=(i+1)*6+4; faces[3*(i*10+7)+2]=(i+1)*6+3; faces[3*(i*10+8)]=i*6+4; faces[3*(i*10+8)+1]=i*6+5; faces[3*(i*10+8)+2]=(i+1)*6+4; faces[3*(i*10+9)]=i*6+5; faces[3*(i*10+9)+1]=(i+1)*6+5; faces[3*(i*10+9)+2]=(i+1)*6+4; } normy=1.0; //update coords updateVertices(); //compute normy; normy=((covertices[0].vertex-covertices[1].vertex).crossProduct(covertices[1].vertex-covertices[6+1].vertex)).length(); //recompute for normals 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 ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, ibufCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the index data to the card ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); /// Set parameters of the submesh sub->useSharedVertices = true; sub->indexData->indexBuffer = ibuf; sub->indexData->indexCount = ibufCount; sub->indexData->indexStart = 0; /// Set bounding information (for culling) msh->_setBounds(AxisAlignedBox(-1,-1,0,1,1,0), true); //msh->_setBoundingSphereRadius(Math::Sqrt(1*1+1*1)); /// Notify Mesh object that it has been loaded msh->buildEdgeList(); //msh->buildTangentVectors(); /*unsigned short src, dest; if (!msh->suggestTangentVectorBuildParams(src, dest)) { msh->buildTangentVectors(src, dest); } */ msh->load(); //msh->touch(); // msh->load(); //msh->buildEdgeList(); }
void Tile::_generateSubMesh(MeshPtr& mesh) { // Create a submesh to the given mesh. SubMesh* tileMesh = mesh->createSubMesh(); // Define the vertices. size_t index = 0; size_t vertCount = this->mCorners.size() + 1; // corner count + center corner Real* vertices = new Real[vertCount*3*2]; // (number of verts)*(x, y, z)*(coord, normal) -or- vertCount*3*2 // Manually add center vertex. // -- Position (ord: x, y, z) vertices[index++] = this->mPosition.x; vertices[index++] = (Ogre::Real)(this->elevation); vertices[index++] = this->mPosition.y; // -- Normal (ord: x, y, z) Vector3 norm = Vector3::UNIT_Y; vertices[index++] = norm.x; vertices[index++] = norm.y; vertices[index++] = norm.z; // Add the rest of the vertices to data buffer. for(std::vector<Corner*>::iterator it = this->mCorners.begin(); it != this->mCorners.end(); ++it) { // Add to the next point to the array. // -- Position Vector3 vector = (*it)->vec3(); vertices[index++] = vector.x; vertices[index++] = vector.y; vertices[index++] = vector.z; // -- Normal Vector3 normal = Vector3::UNIT_Y; vertices[index++] = normal.x; vertices[index++] = normal.y; vertices[index++] = normal.z; } // Define vertices color. RenderSystem* rs = Root::getSingleton().getRenderSystem(); RGBA* colors = new RGBA[vertCount]; for(size_t i = 0; i < vertCount; ++i) rs->convertColourValue(ColourValue(0.0f + 0.175f*i, 0.2f, 1.0f - 0.175f*i), colors + i); // Define the triangles. size_t faceCount = vertCount - 1; // Face count = vertCount - cent size_t center = 0; size_t last = 1; //collin was here size_t curr = 2; unsigned short* faces = new unsigned short[faceCount*3]; index = 0; for(size_t i = 0; i < faceCount; ++i) { assert(last < vertCount && curr < vertCount); // Panic check faces[index++] = center; faces[index++] = curr; faces[index++] = last; last = curr++; if(curr >= vertCount) curr = 1; } // All information has been generated, move into mesh structures. // Note: Currently does not implement or used any sort of shared // vertices. This is intentional and should be changed at the // soonest conveienence. IE -- Never. ;P tileMesh->useSharedVertices = false; tileMesh->vertexData = new VertexData(); tileMesh->vertexData->vertexCount = vertCount; // Create memory footprint for vertex data. size_t offset = 0; VertexDeclaration* decl = tileMesh->vertexData->vertexDeclaration; // Position and normal buffer. // -- Position decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); // -- Normal decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); // Allocate a vertex buffer for a number of vertices and vertex size. HardwareVertexBufferSharedPtr vertBuff = HardwareBufferManager::getSingleton().createVertexBuffer( offset, // Size of a vertex, in bytes. tileMesh->vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Write our data to vertex buffer. vertBuff->writeData(0, vertBuff->getSizeInBytes(), vertices, true); // Set the buffer's bind location. VertexBufferBinding* vertBind = tileMesh->vertexData->vertexBufferBinding; vertBind->setBinding(0, vertBuff); // Color buffer for vertices offset = 0; decl->addElement(1, offset, VET_COLOUR, VES_DIFFUSE); offset += VertexElement::getTypeSize(VET_COLOUR); // Allocate a new buffer for colors. vertBuff = HardwareBufferManager::getSingleton().createVertexBuffer( offset, // Size of a vertex, in bytes. tileMesh->vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Write color data to buffer. vertBuff->writeData(0, vertBuff->getSizeInBytes(), colors, true); // Set the color buffer's bind location vertBind->setBinding(1, vertBuff); // Allocate a buffer for the index information HardwareIndexBufferSharedPtr indexBuff = HardwareBufferManager::getSingleton().createIndexBuffer( HardwareIndexBuffer::IT_16BIT, faceCount*3, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Write data to the buffer. indexBuff->writeData(0, indexBuff->getSizeInBytes(), faces, true); // Finalize submesh. tileMesh->indexData->indexBuffer = indexBuff; tileMesh->indexData->indexCount = faceCount*3; tileMesh->indexData->indexStart = 0; // Deallocate the vertex and face arrays. if(vertices) delete[] vertices; if(faces) delete[] faces; }
Ogre::MeshPtr LodOutsideMarker::createConvexHullMesh(const String& meshName, const String& resourceGroupName) { // Based on the wiki sample: http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Generating+A+Mesh // Resource with given name should not exist! assert(MeshManager::getSingleton().getByName(meshName).isNull()); generateHull(); // calculate mHull triangles. // Convex hull can't be empty! assert(!mHull.empty()); MeshPtr mesh = MeshManager::getSingleton().createManual(meshName, resourceGroupName, NULL); SubMesh* subMesh = mesh->createSubMesh(); vector<Real>::type vertexBuffer; vector<unsigned short>::type indexBuffer; // 3 position/triangle * 3 Real/position vertexBuffer.reserve(mHull.size() * 9); // 3 index / triangle indexBuffer.reserve(mHull.size() * 3); int id=0; // min & max position Vector3 minBounds(std::numeric_limits<Real>::max(), std::numeric_limits<Real>::max(), std::numeric_limits<Real>::max()); Vector3 maxBounds(std::numeric_limits<Real>::min(), std::numeric_limits<Real>::min(), std::numeric_limits<Real>::min()); for (size_t i = 0; i < mHull.size(); i++) { assert(!mHull[i].removed); for(size_t n = 0; n < 3; n++){ indexBuffer.push_back(id++); vertexBuffer.push_back(mHull[i].vertex[n]->position.x); vertexBuffer.push_back(mHull[i].vertex[n]->position.y); vertexBuffer.push_back(mHull[i].vertex[n]->position.z); minBounds.x = std::min<Real>(minBounds.x, mHull[i].vertex[n]->position.x); minBounds.y = std::min<Real>(minBounds.y, mHull[i].vertex[n]->position.y); minBounds.z = std::min<Real>(minBounds.z, mHull[i].vertex[n]->position.z); maxBounds.x = std::max<Real>(maxBounds.x, mHull[i].vertex[n]->position.x); maxBounds.y = std::max<Real>(maxBounds.y, mHull[i].vertex[n]->position.y); maxBounds.z = std::max<Real>(maxBounds.z, mHull[i].vertex[n]->position.z); } } /// Create vertex data structure for 8 vertices shared between submeshes mesh->sharedVertexData = new VertexData(); mesh->sharedVertexData->vertexCount = mHull.size() * 3; /// Create declaration (memory format) of vertex data VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration; size_t offset = 0; // 1st buffer decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); /// Allocate vertex buffer of the requested number of vertices (vertexCount) /// and bytes per vertex (offset) HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, mesh->sharedVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the vertex data to the card vbuf->writeData(0, vbuf->getSizeInBytes(), &vertexBuffer[0], true); /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding; bind->setBinding(0, vbuf); /// Allocate index buffer of the requested number of vertices (ibufCount) HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, indexBuffer.size(), HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the index data to the card ibuf->writeData(0, ibuf->getSizeInBytes(), &indexBuffer[0], true); /// Set parameters of the submesh subMesh->useSharedVertices = true; subMesh->indexData->indexBuffer = ibuf; subMesh->indexData->indexCount = indexBuffer.size(); subMesh->indexData->indexStart = 0; /// Set bounding information (for culling) mesh->_setBounds(AxisAlignedBox(minBounds, maxBounds)); mesh->_setBoundingSphereRadius(maxBounds.distance(minBounds) / 2.0f); /// Set material to transparent blue subMesh->setMaterialName("Examples/TransparentBlue50"); /// Notify -Mesh object that it has been loaded mesh->load(); return mesh; }
void BasicTutorial2::createColourCube() { /// Create the mesh via the MeshManager Ogre::MeshPtr msh = MeshManager::getSingleton().createManual("ColourCube", "General"); /// Create one submesh SubMesh* sub = msh->createSubMesh(); const float sqrt13 = 0.577350269f; /* sqrt(1/3) */ /// Define the vertices (8 vertices, each have 3 floats for position and 3 for normal) const size_t nVertices = 8; const size_t vbufCount = 3*2*nVertices; float vertices[vbufCount] = { -100.0,100.0,-100.0, //0 position -sqrt13,sqrt13,-sqrt13, //0 normal 100.0,100.0,-100.0, //1 position sqrt13,sqrt13,-sqrt13, //1 normal 100.0,-100.0,-100.0, //2 position sqrt13,-sqrt13,-sqrt13, //2 normal -100.0,-100.0,-100.0, //3 position -sqrt13,-sqrt13,-sqrt13, //3 normal -100.0,100.0,100.0, //4 position -sqrt13,sqrt13,sqrt13, //4 normal 100.0,100.0,100.0, //5 position sqrt13,sqrt13,sqrt13, //5 normal 100.0,-100.0,100.0, //6 position sqrt13,-sqrt13,sqrt13, //6 normal -100.0,-100.0,100.0, //7 position -sqrt13,-sqrt13,sqrt13, //7 normal }; RenderSystem* rs = Root::getSingleton().getRenderSystem(); RGBA colours[nVertices]; RGBA *pColour = colours; // Use render system to convert colour value since colour packing varies rs->convertColourValue(ColourValue(1.0,0.0,0.0), pColour++); //0 colour rs->convertColourValue(ColourValue(1.0,1.0,0.0), pColour++); //1 colour rs->convertColourValue(ColourValue(0.0,1.0,0.0), pColour++); //2 colour rs->convertColourValue(ColourValue(0.0,0.0,0.0), pColour++); //3 colour rs->convertColourValue(ColourValue(1.0,0.0,1.0), pColour++); //4 colour rs->convertColourValue(ColourValue(1.0,1.0,1.0), pColour++); //5 colour rs->convertColourValue(ColourValue(0.0,1.0,1.0), pColour++); //6 colour rs->convertColourValue(ColourValue(0.0,0.0,1.0), pColour++); //7 colour /// Define 12 triangles (two triangles per cube face) /// The values in this table refer to vertices in the above table const size_t ibufCount = 36; unsigned short faces[ibufCount] = { 0,2,3, 0,1,2, 1,6,2, 1,5,6, 4,6,5, 4,7,6, 0,7,4, 0,3,7, 0,5,1, 0,4,5, 2,7,3, 2,6,7 }; /// 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 VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration; size_t offset = 0; // 1st buffer 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); /// Allocate vertex buffer of the requested number of vertices (vertexCount) /// and bytes per vertex (offset) HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// 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); // 2nd buffer offset = 0; decl->addElement(1, offset, VET_COLOUR, VES_DIFFUSE); offset += VertexElement::getTypeSize(VET_COLOUR); /// 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_STATIC_WRITE_ONLY); /// Upload the vertex data to the card vbuf->writeData(0, vbuf->getSizeInBytes(), colours, true); /// Set vertex buffer binding so buffer 1 is bound to our colour buffer bind->setBinding(1, vbuf); /// Allocate index buffer of the requested number of vertices (ibufCount) HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, ibufCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the index data to the card ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); /// Set parameters of the submesh sub->useSharedVertices = true; sub->indexData->indexBuffer = ibuf; sub->indexData->indexCount = ibufCount; sub->indexData->indexStart = 0; /// Set bounding information (for culling) msh->_setBounds(AxisAlignedBox(-100,-100,-100,100,100,100)); msh->_setBoundingSphereRadius(Math::Sqrt(3*100*100)); /// Notify -Mesh object that it has been loaded msh->load(); }
FlexObj::FlexObj(node_t *nds, int numtexcoords, Vector3* texcoords, int numtriangles, int* triangles, int numsubmeshes, int* subtexindex, int* subtriindex, char* texname, char* name, int* subisback, char* backtexname, char* transtexname) { unsigned int i; int j; triangleCount = numtriangles; /* //okay, we munch a bit the data to optimize submesh count Vector3* texcoords=(Vector3*)malloc(sizeof(Vector3)*numtexcoords); int* triangles=(int*)malloc(sizeof(int)*3*numtriangles); int numsubmeshes=3; int subtexindex[4]; int subtriindex[4]; int subisback[3]={0,1,2}; int numtex[3]={0,0,0}; int numtri[3]={0,0,0}; int postex[3]={0,0,0}; int postri[3]={0,0,0}; for (j=0; j<onumsubmeshes; j++) { int type=0; // if (j<numsubmeshes-1) { type=osubisback[j+1]; } numtex[type]+=osubtexindex[j+1]-osubtexindex[j]; numtri[type]+=osubtriindex[j+1]-osubtriindex[j]; } postex[0]=0; postex[1]=numtex[0]; postex[2]=numtex[0]+numtex[1]; subtexindex[0]=0; subtexindex[1]=numtex[0]; subtexindex[2]=numtex[0]+numtex[1]; subtexindex[3]=numtex[0]+numtex[1]+numtex[2]; postri[0]=0; postri[1]=numtri[0]; postri[2]=numtri[0]+numtri[1]; subtriindex[0]=0; subtriindex[1]=numtri[0]; subtriindex[2]=numtri[0]+numtri[1]; subtriindex[3]=numtri[0]+numtri[1]+numtri[2]; for (j=0; j<onumsubmeshes; j++) { int type=0; if (j<numsubmeshes-1) { type=osubisback[j+1]; } for (i=0; i<osubtexindex[j+1]-osubtexindex[j]; i++) { texcoords[postex[type]]=otexcoords[osubtexindex[j]+i]; } postex[type]+=osubtexindex[j+1]-osubtexindex[j]; for (i=0; i<osubtriindex[j+1]-osubtriindex[j]; i++) { int k; for (k=0; k<3; k++) triangles[postri[type]*3+k]=otriangles[(osubtriindex[j]+i)*3+k]; } postri[type]+=osubtriindex[j+1]-osubtriindex[j]; } */ //finished munching gEnv->sceneManager=gEnv->sceneManager; nodes=nds; /// Create the mesh via the MeshManager msh = MeshManager::getSingleton().createManual(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,new ResourceBuffer()); /// Create submeshes subs=(SubMesh**)malloc(numsubmeshes*sizeof(SubMesh*)); for (j=0; j<numsubmeshes; j++) { subs[j] = msh->createSubMesh(); //materials if (j<numsubmeshes-1) { if (subisback[j+1]==0) subs[j]->setMaterialName(texname); if (subisback[j+1]==1) subs[j]->setMaterialName(backtexname); if (subisback[j+1]==2) subs[j]->setMaterialName(transtexname); } else subs[j]->setMaterialName(texname); }; /// Define the vertices (8 vertices, each consisting of 3 groups of 3 floats nVertices = numtexcoords; 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)); nodeIDs=(int*)malloc(nVertices*sizeof(int)); //define node ids for (i=0; i<nVertices; i++) { nodeIDs[i]=(int)(texcoords[i].x); } //textures coordinates for (i=0; i<nVertices; i++) { covertices[i].texcoord=Vector2(texcoords[i].y,texcoords[i].z); } /// Define triangles /// The values in this table refer to vertices in the above table ibufCount = 3*numtriangles; faces=(unsigned short*)malloc(ibufCount*sizeof(unsigned short)); for (i=0; i<ibufCount; i++) { faces[i]=findID(i/3, triangles[i], numsubmeshes, subtexindex, subtriindex); } sref=(float*)malloc(numtriangles*sizeof(float)); for (i=0; i<(unsigned int)numtriangles;i++) { Vector3 v1, v2; v1=nodes[nodeIDs[faces[i*3+1]]].RelPosition-nodes[nodeIDs[faces[i*3]]].RelPosition; v2=nodes[nodeIDs[faces[i*3+2]]].RelPosition-nodes[nodeIDs[faces[i*3]]].RelPosition; v1=v1.crossProduct(v2); sref[i]=v1.length()*2.0; } //update coords updateVertices(); /// Create vertex data structure for 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); /// Set parameters of the submeshes for (j=0; j<numsubmeshes; j++) { int smcount=3*(subtriindex[j+1]-subtriindex[j]); subs[j]->useSharedVertices = true; /// Allocate index buffer of the requested number of vertices (ibufCount) HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, smcount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the index data to the card ibuf->writeData(0, ibuf->getSizeInBytes(), &faces[subtriindex[j]*3], true); subs[j]->indexData->indexBuffer = ibuf; subs[j]->indexData->indexCount = smcount; subs[j]->indexData->indexStart = 0; } /// Set bounding information (for culling) msh->_setBounds(AxisAlignedBox(-100,-100,-100,100,100,100), true); //msh->_setBoundingSphereRadius(100); /// Notify Mesh object that it has been loaded msh->load(); msh->buildEdgeList(); }
// Convert Nif::NiTriShape to Ogre::SubMesh, attached to the given // mesh. static void createOgreMesh(Mesh *mesh, NiTriShape *shape, const String &material) { NiTriShapeData *data = shape->data.getPtr(); SubMesh *sub = mesh->createSubMesh(shape->name.toString()); int nextBuf = 0; // This function is just one long stream of Ogre-barf, but it works // great. // Add vertices int numVerts = data->vertices.length / 3; sub->vertexData = new VertexData(); sub->vertexData->vertexCount = numVerts; sub->useSharedVertices = false; VertexDeclaration *decl = sub->vertexData->vertexDeclaration; decl->addElement(nextBuf, 0, VET_FLOAT3, VES_POSITION); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( VertexElement::getTypeSize(VET_FLOAT3), numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY); vbuf->writeData(0, vbuf->getSizeInBytes(), data->vertices.ptr, true); VertexBufferBinding* bind = sub->vertexData->vertexBufferBinding; bind->setBinding(nextBuf++, vbuf); // Vertex normals if(data->normals.length) { decl->addElement(nextBuf, 0, VET_FLOAT3, VES_NORMAL); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( VertexElement::getTypeSize(VET_FLOAT3), numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY); vbuf->writeData(0, vbuf->getSizeInBytes(), data->normals.ptr, true); bind->setBinding(nextBuf++, vbuf); } // Vertex colors if(data->colors.length) { const float *colors = data->colors.ptr; RenderSystem* rs = Root::getSingleton().getRenderSystem(); std::vector<RGBA> colorsRGB(numVerts); RGBA *pColour = &colorsRGB.front(); for(int i=0; i<numVerts; i++) { rs->convertColourValue(ColourValue(colors[0],colors[1],colors[2], colors[3]),pColour++); colors += 4; } decl->addElement(nextBuf, 0, VET_COLOUR, VES_DIFFUSE); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( VertexElement::getTypeSize(VET_COLOUR), numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY); vbuf->writeData(0, vbuf->getSizeInBytes(), &colorsRGB.front(), true); bind->setBinding(nextBuf++, vbuf); } // Texture UV coordinates if(data->uvlist.length) { decl->addElement(nextBuf, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( VertexElement::getTypeSize(VET_FLOAT2), numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY); vbuf->writeData(0, vbuf->getSizeInBytes(), data->uvlist.ptr, true); bind->setBinding(nextBuf++, vbuf); } // Triangle faces int numFaces = data->triangles.length; if(numFaces) { HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer(HardwareIndexBuffer::IT_16BIT, numFaces, HardwareBuffer::HBU_STATIC_WRITE_ONLY); ibuf->writeData(0, ibuf->getSizeInBytes(), data->triangles.ptr, true); sub->indexData->indexBuffer = ibuf; sub->indexData->indexCount = numFaces; sub->indexData->indexStart = 0; } // Set material if one was given if(!material.empty()) sub->setMaterialName(material); /* Old commented D code. Might be useful when reimplementing animation. // Assign this submesh to the given bone VertexBoneAssignment v; v.boneIndex = ((Bone*)bone)->getHandle(); v.weight = 1.0; std::cerr << "+ Assigning bone index " << v.boneIndex << "\n"; for(int i=0; i < numVerts; i++) { v.vertexIndex = i; sub->addBoneAssignment(v); } */ }
// Convert Nif::NiTriShape to Ogre::SubMesh, attached to the given // mesh. void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std::list<VertexBoneAssignment> &vertexBoneAssignments) { // cout << "s:" << shape << "\n"; NiTriShapeData *data = shape->data.getPtr(); SubMesh *sub = mesh->createSubMesh(shape->name.toString()); int nextBuf = 0; // This function is just one long stream of Ogre-barf, but it works // great. // Add vertices int numVerts = data->vertices.length / 3; sub->vertexData = new VertexData(); sub->vertexData->vertexCount = numVerts; sub->useSharedVertices = false; VertexDeclaration *decl = sub->vertexData->vertexDeclaration; decl->addElement(nextBuf, 0, VET_FLOAT3, VES_POSITION); HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( VertexElement::getTypeSize(VET_FLOAT3), numVerts, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false); if(flip) { float *datamod = new float[data->vertices.length]; //std::cout << "Shape" << shape->name.toString() << "\n"; for(int i = 0; i < numVerts; i++) { int index = i * 3; const float *pos = data->vertices.ptr + index; Ogre::Vector3 original = Ogre::Vector3(*pos ,*(pos+1), *(pos+2)); original = mTransform * original; mBoundingBox.merge(original); datamod[index] = original.x; datamod[index+1] = original.y; datamod[index+2] = original.z; } vbuf->writeData(0, vbuf->getSizeInBytes(), datamod, false); delete [] datamod; } else { vbuf->writeData(0, vbuf->getSizeInBytes(), data->vertices.ptr, false); } VertexBufferBinding* bind = sub->vertexData->vertexBufferBinding; bind->setBinding(nextBuf++, vbuf); if (data->normals.length) { decl->addElement(nextBuf, 0, VET_FLOAT3, VES_NORMAL); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( VertexElement::getTypeSize(VET_FLOAT3), numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); if(flip) { Quaternion rotation = mTransform.extractQuaternion(); rotation.normalise(); float *datamod = new float[data->normals.length]; for(int i = 0; i < numVerts; i++) { int index = i * 3; const float *pos = data->normals.ptr + index; Ogre::Vector3 original = Ogre::Vector3(*pos ,*(pos+1), *(pos+2)); original = rotation * original; if (mNormaliseNormals) { original.normalise(); } datamod[index] = original.x; datamod[index+1] = original.y; datamod[index+2] = original.z; } vbuf->writeData(0, vbuf->getSizeInBytes(), datamod, false); delete [] datamod; } else { vbuf->writeData(0, vbuf->getSizeInBytes(), data->normals.ptr, false); } bind->setBinding(nextBuf++, vbuf); } // Vertex colors if (data->colors.length) { const float *colors = data->colors.ptr; RenderSystem* rs = Root::getSingleton().getRenderSystem(); std::vector<RGBA> colorsRGB(numVerts); RGBA *pColour = &colorsRGB.front(); for (int i=0; i<numVerts; i++) { rs->convertColourValue(ColourValue(colors[0],colors[1],colors[2], colors[3]),pColour++); colors += 4; } decl->addElement(nextBuf, 0, VET_COLOUR, VES_DIFFUSE); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( VertexElement::getTypeSize(VET_COLOUR), numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY); vbuf->writeData(0, vbuf->getSizeInBytes(), &colorsRGB.front(), true); bind->setBinding(nextBuf++, vbuf); } if (data->uvlist.length) { decl->addElement(nextBuf, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( VertexElement::getTypeSize(VET_FLOAT2), numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY,false); if(flip) { float *datamod = new float[data->uvlist.length]; for(unsigned int i = 0; i < data->uvlist.length; i+=2){ float x = *(data->uvlist.ptr + i); float y = *(data->uvlist.ptr + i + 1); datamod[i] =x; datamod[i + 1] =y; } vbuf->writeData(0, vbuf->getSizeInBytes(), datamod, false); delete [] datamod; } else vbuf->writeData(0, vbuf->getSizeInBytes(), data->uvlist.ptr, false); bind->setBinding(nextBuf++, vbuf); } // Triangle faces - The total number of triangle points int numFaces = data->triangles.length; if (numFaces) { sub->indexData->indexCount = numFaces; sub->indexData->indexStart = 0; HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer(HardwareIndexBuffer::IT_16BIT, numFaces, HardwareBuffer::HBU_STATIC_WRITE_ONLY, true); if(flip && mFlipVertexWinding && sub->indexData->indexCount % 3 == 0){ sub->indexData->indexBuffer = ibuf; uint16 *datamod = new uint16[numFaces]; int index = 0; for (size_t i = 0; i < sub->indexData->indexCount; i+=3) { const short *pos = data->triangles.ptr + index; uint16 i0 = (uint16) *(pos+0); uint16 i1 = (uint16) *(pos+1); uint16 i2 = (uint16) *(pos+2); //std::cout << "i0: " << i0 << "i1: " << i1 << "i2: " << i2 << "\n"; datamod[index] = i2; datamod[index+1] = i1; datamod[index+2] = i0; index += 3; } ibuf->writeData(0, ibuf->getSizeInBytes(), datamod, false); delete [] datamod; } else ibuf->writeData(0, ibuf->getSizeInBytes(), data->triangles.ptr, false); sub->indexData->indexBuffer = ibuf; } // Set material if one was given if (!material.empty()) sub->setMaterialName(material); //add vertex bone assignments for (std::list<VertexBoneAssignment>::iterator it = vertexBoneAssignments.begin(); it != vertexBoneAssignments.end(); it++) { sub->addBoneAssignment(*it); } if(mSkel.isNull()) needBoneAssignments.push_back(sub); }