bool Model::SetMaterial(const String& subMeshName, Material* material) { SubMesh* subMesh = m_mesh->GetSubMesh(subMeshName); if (!subMesh) { NazaraError("Mesh has no submesh \"" + subMeshName + '"'); return false; } unsigned int matIndex = subMesh->GetMaterialIndex(); if (matIndex >= m_matCount) { NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount) + ')'); return false; } unsigned int index = m_skin * m_matCount + matIndex; if (material) m_materials[index] = material; else m_materials[index] = Material::GetDefault(); return true; }
void FixedRenderer::updateSkinning(Mesh * mesh, Armature * armature) { unsigned int s; unsigned int sSize = mesh->getSubMeshsNumber(); for(s=0; s<sSize; s++) { SubMesh * subMesh = &mesh->getSubMeshs()[s]; // data Vector3 * vertices = subMesh->getVertices(); if(! vertices) continue; SkinData * skinData = subMesh->getSkinData(); if(armature && skinData) { unsigned int verticesSize = subMesh->getVerticesSize(); Vector3 * skinVertices = getVertices(verticesSize); computeSkinning(armature, skinData, vertices, NULL, NULL, skinVertices, NULL, NULL); subMesh->getBoundingBox()->initFromPoints(skinVertices, verticesSize); } } mesh->updateBoundingBox(); }
//------------------------------------------------------------------------------------ Mesh* SceneManager::CreatePlaneMesh( float w, float h ) { float halfW = w / 2; float halfH = h / 2; SVertex vert[4] = { SVertex(VEC3(-w,0,+h), VEC2(0,0), VEC3::UNIT_Y), SVertex(VEC3(+w,0,+h), VEC2(1,0), VEC3::UNIT_Y), SVertex(VEC3(+w,0,-h), VEC2(1,1), VEC3::UNIT_Y), SVertex(VEC3(-w,0,-h), VEC2(0,1), VEC3::UNIT_Y), }; DWORD dwIndex[6] = {0,1,3,1,2,3}; Mesh* pMesh = new Mesh; SubMesh* pSubmesh = new SubMesh; pSubmesh->InitVertData(eVertexType_General, vert, 4, true); pSubmesh->InitIndexData(dwIndex, 6, true); pMesh->AddSubMesh(pSubmesh); return pMesh; }
bool Model::SetMaterial(unsigned int skinIndex, const String& subMeshName, Material* material) { #if NAZARA_GRAPHICS_SAFE if (skinIndex >= m_skinCount) { NazaraError("Skin index out of range (" + String::Number(skinIndex) + " >= " + String::Number(m_skinCount)); return false; } #endif SubMesh* subMesh = m_mesh->GetSubMesh(subMeshName); if (!subMesh) { NazaraError("Mesh has no submesh \"" + subMeshName + '"'); return false; } unsigned int matIndex = subMesh->GetMaterialIndex(); if (matIndex >= m_matCount) { NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount)); return false; } unsigned int index = skinIndex * m_matCount + matIndex; if (material) m_materials[index] = material; else m_materials[index] = Material::GetDefault(); return true; }
Material* Model::GetMaterial(const String& subMeshName) const { #if NAZARA_GRAPHICS_SAFE if (!m_mesh) { NazaraError("Model has no mesh"); return nullptr; } #endif SubMesh* subMesh = m_mesh->GetSubMesh(subMeshName); if (!subMesh) { NazaraError("Mesh has no submesh \"" + subMeshName + '"'); return nullptr; } unsigned int matIndex = subMesh->GetMaterialIndex(); if (matIndex >= m_matCount) { NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount) + ')'); return nullptr; } return m_materials[m_skin * m_matCount + matIndex]; }
//------------------------------------------------------------------------------------ void Sky::_InitMesh() { SVertex* vert = new SVertex[8]; DWORD* pIndices = new DWORD[6*2*3]; if(!vert || !pIndices) throw std::exception("Error!Not enough memory!"); vert[0].pos.Set(-1, -1, -1); vert[1].pos.Set( 1, -1, -1); vert[2].pos.Set( 1, -1, 1); vert[3].pos.Set(-1, -1, 1); vert[4].pos.Set(-1, 1, -1); vert[5].pos.Set( 1, 1, -1); vert[6].pos.Set( 1, 1, 1); vert[7].pos.Set(-1, 1, 1); pIndices[0] = 0; pIndices[1] = 2; pIndices[2] = 1; pIndices[3] = 0; pIndices[4] = 3; pIndices[5] = 2; pIndices[6] = 5; pIndices[7] = 7; pIndices[8] = 4; pIndices[9] = 5; pIndices[10] = 6; pIndices[11] = 7; pIndices[12] = 3; pIndices[13] = 6; pIndices[14] = 2; pIndices[15] = 3; pIndices[16] = 7; pIndices[17] = 6; pIndices[18] = 1; pIndices[19] = 4; pIndices[20] = 0; pIndices[21] = 1; pIndices[22] = 5; pIndices[23] = 4; pIndices[24] = 0; pIndices[25] = 7; pIndices[26] = 3; pIndices[27] = 0; pIndices[28] = 4; pIndices[29] = 7; pIndices[30] = 2; pIndices[31] = 5; pIndices[32] = 1; pIndices[33] = 2; pIndices[34] = 6; pIndices[35] = 5; m_pMesh = new Mesh; SubMesh* pSubMesh = new SubMesh; pSubMesh->InitVertData(eVertexType_General, vert, 8, true); pSubMesh->InitIndexData(pIndices, 6*2*3, true); m_pMesh->AddSubMesh(pSubMesh); SAFE_DELETE_ARRAY(vert); SAFE_DELETE_ARRAY(pIndices); Neo::Material* pMaterial = new Neo::Material; pMaterial->SetTexture(0, new Neo::D3D11Texture(GetResPath("Skybox.dds"), eTextureType_CubeMap)); pMaterial->InitShader(GetResPath("Sky.hlsl"), GetResPath("Sky.hlsl"), eShaderFlag_EnableClipPlane); pSubMesh->SetMaterial(pMaterial); pMaterial->Release(); D3D11_SAMPLER_DESC& sampler = pMaterial->GetSamplerStateDesc(0); sampler.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; sampler.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; pMaterial->SetSamplerStateDesc(0, sampler); m_pEntity = new Entity(m_pMesh); m_pEntity->SetCastShadow(false); m_pEntity->SetReceiveShadow(false); }
SubMesh *addSubMesh(GLenum mode, size_t first, size_t count) { SubMesh *res = addSubMesh(); res->setMode(mode); res->setFirstIndex(first); res->setIndexCount(count); return res; }
//------------------------------------------------------------------------------------ void TerrainQuadTreeNode::CreateEntity() { // Create the entity. if (isRenderedAtCurrentLod() && !mEntity) { Mesh* pMesh = new Mesh; SubMesh* pSubmesh = new SubMesh; pMesh->SetPrimitiveType(ePrimitive_TriangleStrip); pSubmesh->InitTerrainVertData(getVertexDataRecord()->gpuPosVertexBuf, getVertexDataRecord()->gpuDeltaVertexBuf, mLodLevels[mCurrentLod]->pIndexBuf, mLodLevels[mCurrentLod]->nIndexCount); pMesh->AddSubMesh(pSubmesh); mEntity = new Entity(pMesh); mEntity->SetCastShadow(false); // vertex data is generated in terrain space mEntity->SetPosition(mTerrain->getPosition()); static uint32 iMat = 0; ++iMat; char szMatName[64]; sprintf_s(szMatName, 64, "Mtl_TerrainSector_%d", iMat); Material* pMaterial = MaterialManager::GetSingleton().NewMaterial(szMatName, eVertexType_Terrain); pMaterial->SetTexture(0, mTerrain->getTerrainNormalMap()); pMaterial->SetTexture(1, mTerrain->getLayerBlendTexture(0)); SSamplerDesc& samDesc = pMaterial->GetSamplerStateDesc(0); samDesc.AddressU = eTextureAddressMode_WRAP; samDesc.AddressV = eTextureAddressMode_WRAP; samDesc.Filter = SF_MIN_MAG_MIP_LINEAR; pMaterial->SetSamplerStateDesc(0, samDesc); pMaterial->SetSamplerStateDesc(1, samDesc); for (uint32 i = 0; i < mTerrain->getLayerCount(); ++i) { pMaterial->SetTexture(2+i*2, g_env.pRenderer->GetRenderSys()->LoadTexture(mTerrain->getLayerTextureName(i, 0), eTextureType_2D, 0, true)); pMaterial->SetTexture(2+i*2+1, g_env.pRenderer->GetRenderSys()->LoadTexture(mTerrain->getLayerTextureName(i, 1))); pMaterial->SetSamplerStateDesc(2 + i * 2, samDesc); pMaterial->SetSamplerStateDesc(2 + i * 2 + 1, samDesc); } pMaterial->InitShader("Terrain", eShader_Terrain, 0, nullptr, "VS_GBuffer", "PS_GBuffer"); mEntity->SetMaterial(pMaterial); } if (mChildren[0]) { mChildren[0]->CreateEntity(); mChildren[1]->CreateEntity(); mChildren[2]->CreateEntity(); mChildren[3]->CreateEntity(); } }
//----------------------------------------------------------------------- bool HardwareSkinningFactory::extractSkeletonData(const Entity* pEntity, size_t subEntityIndex, ushort& boneCount, ushort& weightCount) { bool isValidData = false; boneCount = 0; weightCount = 0; //Check if we have pose animation which the HS sub render state does not //know how to handle bool hasVertexAnim = pEntity->getMesh()->hasVertexAnimation(); //gather data on the skeleton if (!hasVertexAnim && pEntity->hasSkeleton()) { //get weights count MeshPtr pMesh = pEntity->getMesh(); RenderOperation ro; SubMesh* pSubMesh = pMesh->getSubMesh(subEntityIndex); pSubMesh->_getRenderOperation(ro,0); //get the largest bone assignment boneCount = ushort(std::max(pMesh->sharedBlendIndexToBoneIndexMap.size(), pSubMesh->blendIndexToBoneIndexMap.size())); //go over vertex deceleration //check that they have blend indices and blend weights const VertexElement* pDeclWeights = ro.vertexData->vertexDeclaration->findElementBySemantic(VES_BLEND_WEIGHTS,0); const VertexElement* pDeclIndexes = ro.vertexData->vertexDeclaration->findElementBySemantic(VES_BLEND_INDICES,0); if ((pDeclWeights != NULL) && (pDeclIndexes != NULL)) { isValidData = true; switch (pDeclWeights->getType()) { case VET_FLOAT1: weightCount = 1; break; case VET_USHORT2_NORM: case VET_FLOAT2: weightCount = 2; break; case VET_FLOAT3: weightCount = 3; break; case VET_USHORT4_NORM: case VET_UBYTE4_NORM: case VET_FLOAT4: weightCount = 4; break; default: isValidData = false; break; } } } return isValidData; }
//----------------------------------------------------------------------- void Node::getRenderOperation(RenderOperation& op) { SubMesh* pSubMesh = 0; MeshPtr pMesh = MeshManager::getSingleton().getByName("axes.mesh"); if (pMesh.isNull()) { pMesh = MeshManager::getSingleton().load("axes.mesh", ResourceGroupManager::BOOTSTRAP_RESOURCE_GROUP_NAME); } pSubMesh = pMesh->getSubMesh(0); pSubMesh->_getRenderOperation(op); }
void PS_Mesh::_update(Particle * p) { Float3 Position = p->Position; if (mParent->IsLocalSpace()) Position.TransformA(mParent->GetParent()->GetWorldTM()); mMesh->SetPosition(Position); mMesh->SetOpacity(p->Color.a); mMesh->SetRotationEx(p->Rotation); mMesh->SetScale(p->Size); mMesh->_updateTM(); int blendMode = mParent->GetBlendMode(); for (int i = 0; i < mMesh->GetSubMeshCount(); ++i) { SubMesh * submesh = mMesh->GetSubMesh(i); Material * mtl = submesh->GetMaterial(); mtl->diffuse = Float3(p->Color.r, p->Color.g, p->Color.b); if (mParent->_getTexture() != NULL) { mtl->maps[eMapType::DIFFUSE] = mParent->_getTexture(); } if (mParent->GetShaderEnable()) { mtl->depthMode = eDepthMode::N_LESS_EQUAL; if (blendMode == PS_BlendMode::ADD) { mtl->blendMode = eBlendMode::ADD; } else if (blendMode == PS_BlendMode::ALPHA_BLEND) { mtl->blendMode = eBlendMode::ALPHA_BLEND; } else if (blendMode == PS_BlendMode::COLOR_BLEND) { mtl->blendMode = eBlendMode::COLOR_BLEND; } else { mtl->blendMode = eBlendMode::OPACITY; mtl->depthMode = eDepthMode::LESS_EQUAL; } submesh->SetShaderFX(mParent->_getShaderFX()); submesh->SetRenderCallBack(eRenderCallBack::SHADER, mParent->GetShader().c_ptr()); } } }
//---------------------------------------------------------------------------------------- D3D11RenderTarget::D3D11RenderTarget() :m_pRenderSystem(g_env.pRenderSystem) ,m_pRenderTexture(nullptr) ,m_clearColor(SColor::BLACK) ,m_bClearColor(true) ,m_bClearZBuffer(true) ,m_bHasDepthBuffer(false) ,m_bNoFrameBuffer(false) ,m_bUpdateRatioAspect(true) ,m_phaseFlag(eRenderPhase_Geometry) ,m_pDepthStencil(nullptr) ,m_sizeRatio(0, 0) { // Create screen quad static bool bCreate = false; if (!bCreate) { m_pQuadMesh = new Mesh; SubMesh* pSubMesh = new SubMesh; SVertex v[4] = { SVertex(VEC3(-1,1,0), VEC2(0,0)), SVertex(VEC3(1,1,0), VEC2(1,0)), SVertex(VEC3(-1,-1,0), VEC2(0,1)), SVertex(VEC3(1,-1,0), VEC2(1,1)) }; DWORD index[6] = { 0,1,2, 1,3,2 }; // Store index to frustum far corner v[0].normal.x = 0; v[1].normal.x = 1; v[2].normal.x = 2; v[3].normal.x = 3; pSubMesh->InitVertData(eVertexType_General, v, ARRAYSIZE(v), true); pSubMesh->InitIndexData(index, ARRAYSIZE(index), true); m_pQuadMesh->AddSubMesh(pSubMesh); m_pQuadEntity = new Entity(m_pQuadMesh); m_pQuadEntity->SetCastShadow(false); m_pQuadEntity->SetReceiveShadow(false); bCreate = true; } }
//----------------------------------------------------------------------------- MeshPtr ManualObject::convertToMesh(const String& meshName, const String& groupName) { if (mCurrentSection) { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "You cannot call convertToMesh() whilst you are in the middle of " "defining the object; call end() first.", "ManualObject::convertToMesh"); } if (mSectionList.empty()) { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "No data defined to convert to a mesh.", "ManualObject::convertToMesh"); } MeshPtr m = MeshManager::getSingleton().createManual(meshName, groupName); for (SectionList::iterator i = mSectionList.begin(); i != mSectionList.end(); ++i) { ManualObjectSection* sec = *i; RenderOperation* rop = sec->getRenderOperation(); SubMesh* sm = m->createSubMesh(); sm->useSharedVertices = false; sm->operationType = rop->operationType; sm->setMaterialName(sec->getMaterialName(), groupName); // Copy vertex data; replicate buffers too sm->vertexData = rop->vertexData->clone(true); // Copy index data; replicate buffers too; delete the default, old one to avoid memory leaks // check if index data is present if (rop->indexData) { // Copy index data; replicate buffers too; delete the default, old one to avoid memory leaks OGRE_DELETE sm->indexData; sm->indexData = rop->indexData->clone(true); } } // update bounds m->_setBounds(mAABB); m->_setBoundingSphereRadius(mRadius); m->load(); return m; }
//----------------------------------------------------------------------- void Entity::buildSubEntityList(Mesh* mesh, SubEntityList* sublist) { // Create SubEntities int i, numSubMeshes; SubMesh* subMesh; SubEntity* subEnt; numSubMeshes = mesh->getNumSubMeshes(); for (i = 0; i < numSubMeshes; ++i) { subMesh = mesh->getSubMesh(i); subEnt = new SubEntity(); subEnt->mParentEntity = this; subEnt->mSubMesh = subMesh; if (subMesh->isMatInitialised()) subEnt->setMaterialName(subMesh->getMaterialName()); sublist->push_back(subEnt); } }
//------------------------------------------------------------------------------------ Decal::Decal(const VEC3& pos, float size, const QUATERNION& rot) : m_vPos(pos) , m_fSize(size) , m_pMaterial(nullptr) { if (!m_pUnitCube) { SVertex vert[8] = { SVertex(VEC3(-0.5f, -0.5f, +0.5f), VEC2(0, 0)), SVertex(VEC3(+0.5f, -0.5f, +0.5f), VEC2(0, 0)), SVertex(VEC3(+0.5f, -0.5f, -0.5f), VEC2(0, 0)), SVertex(VEC3(-0.5f, -0.5f, -0.5f), VEC2(0, 0)), SVertex(VEC3(-0.5f, +0.5f, +0.5f), VEC2(0, 0)), SVertex(VEC3(+0.5f, +0.5f, +0.5f), VEC2(0, 0)), SVertex(VEC3(+0.5f, +0.5f, -0.5f), VEC2(0, 0)), SVertex(VEC3(-0.5f, +0.5f, -0.5f), VEC2(0, 0)), }; DWORD dwIndex[36] = { 0,2,1,0,3,2, // bottom 4,5,7,5,6,7, // top 4,7,0,7,3,0, // left 6,5,2,5,1,2, // right 7,6,3,6,2,3, // behind 5,4,1,4,0,1, // front }; Mesh* pMesh = new Mesh; SubMesh* pSubmesh = new SubMesh; pSubmesh->InitVertData(eVertexType_General, vert, 8, true); pSubmesh->InitIndexData(dwIndex, 36, true); pMesh->AddSubMesh(pSubmesh); m_pUnitCube = new Entity(pMesh); m_pUnitCube->SetCastShadow(false); m_pCB_Decal = g_env.pRenderer->GetRenderSys()->CreateConstantBuffer(sizeof(cBufferDecal), 10); } m_cbDecal.matRotation = rot.ToRotationMatrix().Transpose(); m_cbDecal.fProjClip = 10000.f; }
bool Mesh::load(const std::string& fname) { std::ifstream fi(fname.c_str()); assert(fi); int subCnt = 0; { StreamBlockReader r("MeshDescription", fi); if (!r.read("subCount", &subCnt)) assert(0); } while (subCnt-- > 0) { SubMesh *sub = new SubMesh(); fi >> *sub; sub->genVertexNormals(); sub->genTriangleNormals(); addSubMesh(sub); } m_fname = fname; return !!fi; }
void EtoileMeshPassTextureInputSocket::retrieve(Texture* signal) { if(signal == NULL) return; GLMeshRenderPass* plugin = (GLMeshRenderPass*)(this->getNode()); std::vector<RenderUnit*>& units = plugin->getRenderUnits(); for(unsigned int i = 0; i < units.size(); ++i) { RenderUnit* unit = units[i]; MeshRenderUnit* munit = dynamic_cast<MeshRenderUnit*>(unit); if(munit != NULL) { Mesh* m = munit->getMesh(); for(unsigned int j = 0; j < m->getSubMeshList().size(); ++j) { SubMesh* submesh = m->getSubMeshList()[j]; Material* mt = submesh->getMaterial(); mt->removeTexture(this->getName()); } } } }
RenderViewer::RenderViewer() { mLayout = new MGUI::Layout(NULL, NULL); mTextBox = new MGUI::TextBox(NULL, mLayout); mTextBox->SetAlign(MGUI::eAlign::LEFT | MGUI::eAlign::BOTTOM); // create grid mesh mGridMesh = new Mesh(); SubMesh * pMeshBuffer = mGridMesh->NewSubMesh(); pMeshBuffer->GetRenderOp()->vertexDeclarations[0].AddElement(eVertexSemantic::POSITION, eVertexType::FLOAT2); pMeshBuffer->GetRenderOp()->vertexBuffers[0] = HWBufferManager::Instance()->NewVertexBuffer(2 * sizeof(float), (GRID_SIZE + 1) * 2 * 2); int index = 0; float * data = (float *)pMeshBuffer->GetRenderOp()->vertexBuffers[0]->Lock(eLockFlag::WRITE); { float _s = -GRID_SIZE / 2 * METER_LEN; float _e = GRID_SIZE / 2 * METER_LEN; float y = _s; float dy = METER_LEN; for (int i = 0; i < GRID_SIZE + 1; ++i) { data[index++] = _s; data[index++] = y; data[index++] = _e; data[index++] = y; y += dy; } float x = _s; float dx = METER_LEN; for (int i = 0; i < GRID_SIZE + 1; ++i) { data[index++] = x; data[index++] = _s; data[index++] = x; data[index++] = _e; x += dx; } } pMeshBuffer->GetRenderOp()->vertexBuffers[0]->Unlock(); pMeshBuffer->GetRenderOp()->primCount = (GRID_SIZE + 1) * 2; pMeshBuffer->GetRenderOp()->primType = ePrimType::LINE_LIST; ShaderFX * pShaderFX = ShaderFXManager::Instance()->Load("Grid", "Grid.mfx"); d_assert(pShaderFX != NULL); pMeshBuffer->SetShaderFX(pShaderFX); mGridMesh->SetLocalAabb(Aabb::Infinite); Layout(); World::Instance()->E_RenderEnd += new cListener0<RenderViewer>(this, &RenderViewer::OnUpdate); }
//------------------------------------------------------------------------------------ bool SceneManager::Init() { m_camera = new Camera; m_camera->SetAspectRatio(m_pRenderSystem->GetWndWidth() / (float)m_pRenderSystem->GetWndHeight()); m_sunLight.lightDir.Set(1, -1, 2); m_sunLight.lightDir.Normalize(); m_sunLight.lightColor.Set(0.8f, 0.8f, 0.8f); m_pSSAO = new SSAO; { m_pDebugRTMesh = new Mesh; SubMesh* pSubMesh = new SubMesh; SVertex v[4] = { SVertex(VEC3(0.5f,1.0f,0), VEC2(0,0)), SVertex(VEC3(1.0f,1.0f,0), VEC2(1,0)), SVertex(VEC3(0.5f,0.4f,0), VEC2(0,1)), SVertex(VEC3(1.0f,0.4f,0), VEC2(1,1)) }; DWORD index[6] = { 0,1,2, 1,3,2 }; pSubMesh->InitVertData(eVertexType_General, v, ARRAYSIZE(v), true); pSubMesh->InitIndexData(index, ARRAYSIZE(index), true); m_pDebugRTMesh->AddSubMesh(pSubMesh); m_pDebugRTMaterial = new Material; m_pDebugRTMaterial->InitShader(GetResPath("DebugRT.hlsl"), GetResPath("DebugRT.hlsl")); pSubMesh->SetMaterial(m_pDebugRTMaterial); } _InitAllScene(); return true; }
//---------------------------------------------------------------------------- //---------------------------------------------------------------------------- bool Mesh::Build(const MeshDescriptor& in_meshDesc) { bool bSuccess = true; //set the bounds SetBounds(in_meshDesc.mvMinBounds, in_meshDesc.mvMaxBounds); if (in_meshDesc.mFeatures.mbHasAnimationData == true) { m_skeleton = SkeletonUPtr(new Skeleton()); m_skeleton->Build(in_meshDesc.m_skeletonDesc); } //iterate through each mesh int count = 0; for (auto it = in_meshDesc.mMeshes.begin(); it != in_meshDesc.mMeshes.end(); ++it) { //caclulate the mesh capacities u32 udwVertexDataCapacity = it->mudwNumVertices * in_meshDesc.mVertexDeclaration.GetTotalSize(); u32 udwIndexDataCapacity = it->mudwNumIndices * in_meshDesc.mudwIndexSize; //prepare the mesh if it needs it, otherwise just update the vertex and index declarations. SubMesh* newSubMesh = CreateSubMesh(it->mstrName); newSubMesh->Prepare(Core::Application::Get()->GetRenderSystem(), in_meshDesc.mVertexDeclaration, in_meshDesc.mudwIndexSize, udwVertexDataCapacity, udwIndexDataCapacity, BufferAccess::k_read, it->ePrimitiveType); //check that the buffers are big enough to hold this data. if not throw an error. if (udwVertexDataCapacity <= newSubMesh->GetInternalMeshBuffer()->GetVertexCapacity() && udwIndexDataCapacity <= newSubMesh->GetInternalMeshBuffer()->GetIndexCapacity()) { newSubMesh->Build(it->mpVertexData, it->mpIndexData, it->mudwNumVertices, it->mudwNumIndices, it->mvMinBounds, it->mvMaxBounds); } else { CS_LOG_ERROR("Sub mesh data exceeds its buffer capacity. Mesh will return empty!"); bSuccess = false; } //add the skeleton controller if (in_meshDesc.mFeatures.mbHasAnimationData == true) { InverseBindPosePtr ibp(new InverseBindPose()); ibp->mInverseBindPoseMatrices = it->mInverseBindPoseMatrices; newSubMesh->SetInverseBindPose(ibp); } count++; } CalcVertexAndIndexCounts(); //return success return bSuccess; }
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); }
Mesh *GrassLoader::generateGrass_SPRITE(PageInfo &page, GrassLayer *layer, float *grassPositions, unsigned int grassCount) { //Calculate the number of quads to be added unsigned int quadCount; quadCount = grassCount; // check for overflows of the uint16's unsigned int maxUInt16 = std::numeric_limits<uint16>::max(); if(grassCount > maxUInt16) { LogManager::getSingleton().logMessage("grass count overflow: you tried to use more than " + StringConverter::toString(maxUInt16) + " (thats the maximum) grass meshes for one page"); return 0; } if(quadCount > maxUInt16) { LogManager::getSingleton().logMessage("quad count overflow: you tried to use more than " + StringConverter::toString(maxUInt16) + " (thats the maximum) grass meshes for one page"); return 0; } //Create manual mesh to store grass quads MeshPtr mesh = MeshManager::getSingleton().createManual(getUniqueID(), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); SubMesh *subMesh = mesh->createSubMesh(); subMesh->useSharedVertices = false; //Setup vertex format information subMesh->vertexData = new VertexData; subMesh->vertexData->vertexStart = 0; subMesh->vertexData->vertexCount = 4 * quadCount; VertexDeclaration* dcl = subMesh->vertexData->vertexDeclaration; size_t offset = 0; dcl->addElement(0, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); dcl->addElement(0, offset, VET_FLOAT4, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT4); dcl->addElement(0, offset, VET_COLOUR, VES_DIFFUSE); offset += VertexElement::getTypeSize(VET_COLOUR); dcl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES); offset += VertexElement::getTypeSize(VET_FLOAT2); //Populate a new vertex buffer with grass HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton() .createVertexBuffer(offset, subMesh->vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); float* pReal = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD)); //Calculate size variance float rndWidth = layer->maxWidth - layer->minWidth; float rndHeight = layer->maxHeight - layer->minHeight; float minY = Math::POS_INFINITY, maxY = Math::NEG_INFINITY; float *posPtr = grassPositions; //Position array "iterator" for (uint16 i = 0; i < grassCount; ++i) { //Get the x and z positions from the position array float x = *posPtr++; float z = *posPtr++; //Calculate height float y; if (heightFunction){ y = heightFunction(x, z, heightFunctionUserData); } else { y = 0; } float x1 = (x - page.centerPoint.x); float z1 = (z - page.centerPoint.z); //Get the color at the grass position uint32 color; if (layer->colorMap) color = layer->colorMap->getColorAt(x, z, layer->mapBounds); else color = 0xFFFFFFFF; //Calculate size float rnd = *posPtr++; //The same rnd value is used for width and height to maintain aspect ratio float halfXScale = (layer->minWidth + rndWidth * rnd) * 0.5f; float scaleY = (layer->minHeight + rndHeight * rnd); //Randomly mirror grass textures float uvLeft, uvRight; if (*posPtr++ > 0.5f){ uvLeft = 0; uvRight = 1; } else { uvLeft = 1; uvRight = 0; } //Add vertices *pReal++ = x1; *pReal++ = y; *pReal++ = z1; //center position *pReal++ = -halfXScale; *pReal++ = scaleY; *pReal++ = 0; *pReal++ = 0; //normal (used to store relative corner positions) *((uint32*)pReal++) = color; //color *pReal++ = uvLeft; *pReal++ = 0; //uv *pReal++ = x1; *pReal++ = y; *pReal++ = z1; //center position *pReal++ = +halfXScale; *pReal++ = scaleY; *pReal++ = 0; *pReal++ = 0; //normal (used to store relative corner positions) *((uint32*)pReal++) = color; //color *pReal++ = uvRight; *pReal++ = 0; //uv *pReal++ = x1; *pReal++ = y; *pReal++ = z1; //center position *pReal++ = -halfXScale; *pReal++ = 0.0f; *pReal++ = 0; *pReal++ = 0; //normal (used to store relative corner positions) *((uint32*)pReal++) = color; //color *pReal++ = uvLeft; *pReal++ = 1; //uv *pReal++ = x1; *pReal++ = y; *pReal++ = z1; //center position *pReal++ = +halfXScale; *pReal++ = 0.0f; *pReal++ = 0; *pReal++ = 0; //normal (used to store relative corner positions) *((uint32*)pReal++) = color; //color *pReal++ = uvRight; *pReal++ = 1; //uv //Update bounds if (y < minY) minY = y; if (y + scaleY > maxY) maxY = y + scaleY; } vbuf->unlock(); subMesh->vertexData->vertexBufferBinding->setBinding(0, vbuf); //Populate index buffer subMesh->indexData->indexStart = 0; subMesh->indexData->indexCount = 6 * quadCount; subMesh->indexData->indexBuffer = HardwareBufferManager::getSingleton() .createIndexBuffer(HardwareIndexBuffer::IT_16BIT, subMesh->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); uint16* pI = static_cast<uint16*>(subMesh->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD)); for (uint16 i = 0; i < quadCount; ++i) { uint16 offset = i * 4; *pI++ = 0 + offset; *pI++ = 2 + offset; *pI++ = 1 + offset; *pI++ = 1 + offset; *pI++ = 2 + offset; *pI++ = 3 + offset; } subMesh->indexData->indexBuffer->unlock(); //subMesh->setBuildEdgesEnabled(autoEdgeBuildEnabled); //Finish up mesh AxisAlignedBox bounds(page.bounds.left - page.centerPoint.x, minY, page.bounds.top - page.centerPoint.z, page.bounds.right - page.centerPoint.x, maxY, page.bounds.bottom - page.centerPoint.z); mesh->_setBounds(bounds); Vector3 temp = bounds.getMaximum() - bounds.getMinimum(); mesh->_setBoundingSphereRadius(temp.length() * 0.5f); LogManager::getSingleton().setLogDetail(static_cast<LoggingLevel>(0)); mesh->setAutoBuildEdgeLists(autoEdgeBuildEnabled); mesh->load(); LogManager::getSingleton().setLogDetail(LL_NORMAL); //Apply grass material to mesh subMesh->setMaterialName(layer->material->getName()); //Return the mesh return mesh.getPointer(); }
void initialize(int vehicle_id, float * params) { di = new DisplayInterface(); { for (unsigned int z=0;z<miurabody0_meshes.size();z++) { Mesh m = miurabody0_meshes[z]; SubMeshData * smd = new SubMeshData; smd->t1 = normalmap[0]; smd->u1 = GL_TEXTURE1; smd->t2 = texture[0]; smd->u2 = GL_TEXTURE2; smd->Kd[0] = params[0]; smd->Kd[1] = params[1]; smd->Kd[2] = params[2]; smd->Kd[3] = params[3]; smd->Ka[0] = params[4]; smd->Ka[1] = params[5]; smd->Ka[2] = params[6]; smd->Ka[3] = params[7]; smd->Ks[0] = params[8]; smd->Ks[1] = params[9]; smd->Ks[2] = params[10]; smd->Ks[3] = params[11]; smd->shininess = params[12]; smd->cast_shadows[1] = 1; glGenBuffers(3, smd->vboid); makeModelVBO_Arrays(smd->vboid, m.p_vertices, m.p_normals, m.p_textures, m.p_faces, m.faces_size, GL_STATIC_DRAW); smd->faces_size = m.faces_size; smd->samplers[0] = reflectionmap[0]; vboids.push_back(smd->vboid[0]); vboids.push_back(smd->vboid[1]); vboids.push_back(smd->vboid[2]); SubMesh * sm = new SubMesh; sm->callback = d_miura0; sm->set_data(smd); di->add_submesh(sm); } } ///////////////////////////////////////////////////// { for (unsigned int i=0;i<miurabody1_meshes.size();i++) { Mesh m = miurabody1_meshes[i]; SubMeshData * smd = new SubMeshData; glGenBuffers(3, smd->vboid); makeModelVBO_Arrays(smd->vboid, m.p_vertices, m.p_normals, m.p_textures, m.p_faces, m.faces_size, GL_STATIC_DRAW); smd->faces_size = m.faces_size; vboids.push_back(smd->vboid[0]); vboids.push_back(smd->vboid[1]); vboids.push_back(smd->vboid[2]); smd->Kd[0] = 0.01f; smd->Kd[1] = 0.01f; smd->Kd[2] = 0.01f; smd->Kd[3] = 1.0f; smd->Ka[0] = 0.02f; smd->Ka[1] = 0.02f; smd->Ka[2] = 0.02f; smd->Ka[3] = 1.0f; smd->Ks[0] = 0.4f; smd->Ks[1] = 0.4f; smd->Ks[2] = 0.4f; smd->Ks[3] = 1.0f; smd->shininess = 10.0f; smd->cast_shadows[1] = 1; SubMesh * sm = new SubMesh; sm->callback = d_miura2; sm->set_data(smd); di->add_submesh(sm); } } ///////////////////////////////////////////////// { for (unsigned int i=0;i<miurachrome0_meshes.size();i++) { Mesh m = miurachrome0_meshes[i]; SubMeshData * smd = new SubMeshData; glGenBuffers(3, smd->vboid); makeModelVBO_Arrays(smd->vboid, m.p_vertices, m.p_normals, m.p_textures, m.p_faces, m.faces_size, GL_STATIC_DRAW); smd->faces_size = m.faces_size; vboids.push_back(smd->vboid[0]); vboids.push_back(smd->vboid[1]); vboids.push_back(smd->vboid[2]); smd->Kd[0] = 0.40f; smd->Kd[1] = 0.40f; smd->Kd[2] = 0.40f; smd->Kd[3] = 1.0f; smd->Ka[0] = 0.25f; smd->Ka[1] = 0.25f; smd->Ka[2] = 0.25f; smd->Ka[3] = 1.0f; smd->Ks[0] = 0.774597f; smd->Ks[1] = 0.774597f; smd->Ks[2] = 0.774597f; smd->Ks[3] = 1.0f; smd->shininess = 76.8f; smd->t2 = reflectionmap[0]; smd->u2 = GL_TEXTURE2; SubMesh * sm = new SubMesh; sm->callback = d_miura1; sm->set_data(smd); di->add_submesh(sm); } } }
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; }
//----------------------------------------------------------------------- void MeshInformer::getEntityTriangles(const Entity* entity, std::vector<Vector3>& vertices, std::vector<size_t>& indices, std::vector<size_t>* indexOffsets) { size_t numVertices = 0, numIndices = 0; getEntityStatistics(entity, numVertices, numIndices); size_t vertex_offset = vertices.size(); size_t index_offset = indices.size(); vertices.resize(vertex_offset + numVertices); indices.resize(index_offset + numIndices); // Software blended vertex data available only if animation enabled, and software animation are // used by internally engine, or user requested software animation. bool useBlended = entity->_isAnimated() && (!entity->isHardwareAnimationEnabled() || entity->getSoftwareAnimationRequests() > 0); // Use skinned vertex data only if blended data available and skeleton animation enabled. bool useSkinned = useBlended && entity->_isSkeletonAnimated(); Vector3* pVertices = &vertices[0]; size_t* pIndices = &indices[0]; size_t shared_vertex_offset = vertex_offset; bool added_shared_vertex = false; size_t numSubEntities = entity->getNumSubEntities(); for (size_t i = 0; i < numSubEntities; ++i) { SubEntity* subEntity = entity->getSubEntity(i); if (!subEntity->isVisible()) { // Skip non-visible sub-entity continue; } SubMesh* subMesh = subEntity->getSubMesh(); if (indexOffsets) { indexOffsets->push_back(index_offset); } if (subMesh->operationType == RenderOperation::OT_TRIANGLE_LIST || subMesh->operationType == RenderOperation::OT_TRIANGLE_STRIP || subMesh->operationType == RenderOperation::OT_TRIANGLE_FAN) { size_t current_vertex_offset; if (subMesh->useSharedVertices) { if (!added_shared_vertex) { size_t vertexCount = getVertices(pVertices + vertex_offset, useSkinned ? entity->_getSkelAnimVertexData() : useBlended && subMesh->parent->getSharedVertexDataAnimationType() != VAT_NONE ? entity->_getSoftwareVertexAnimVertexData() : subMesh->parent->sharedVertexData); shared_vertex_offset = vertex_offset; vertex_offset += vertexCount; added_shared_vertex = true; } current_vertex_offset = shared_vertex_offset; } else { size_t vertexCount = getVertices(pVertices + vertex_offset, useSkinned ? subEntity->_getSkelAnimVertexData() : useBlended && subMesh->getVertexAnimationType() != VAT_NONE ? subEntity->_getSoftwareVertexAnimVertexData() : subMesh->vertexData); current_vertex_offset = vertex_offset; vertex_offset += vertexCount; } size_t index_count = getTriangles(pIndices + index_offset, subMesh->indexData, current_vertex_offset, subMesh->operationType); index_offset += index_count; } } }
void MeshSerializerTests::assertMeshClone(Mesh* a, Mesh* b, MeshVersion version /*= MESH_VERSION_LATEST*/) { // TODO: Compare skeleton // TODO: Compare animations // TODO: Compare pose animations // CPPUNIT_ASSERT(a->getGroup() == b->getGroup()); // CPPUNIT_ASSERT(a->getName() == b->getName()); #ifndef OGRE_TEST_XMLSERIALIZER // XML serializer fails on these! CPPUNIT_ASSERT(isEqual(a->getBoundingSphereRadius(), b->getBoundingSphereRadius())); CPPUNIT_ASSERT(isEqual(a->getBounds().getMinimum(), b->getBounds().getMinimum())); CPPUNIT_ASSERT(isEqual(a->getBounds().getMaximum(), b->getBounds().getMaximum())); #else StringStream str; Real val1 = a->getBoundingSphereRadius(); Real val2 = b->getBoundingSphereRadius(); Real diff = (val1 > val2) ? (val1 / val2) : (val2 / val1); if (diff > 1.1) { str << "bound sphere diff: " << diff << std::endl; } val1 = a->getBounds().getMinimum().length(); val2 = b->getBounds().getMinimum().length(); diff = (val1 > val2) ? (val1 / val2) : (val2 / val1); if (diff > 1.1) { str << "bound min diff: " << diff << std::endl; } val1 = a->getBounds().getMaximum().length(); val2 = b->getBounds().getMaximum().length(); diff = (val1 > val2) ? (val1 / val2) : (val2 / val1); if (diff > 1.1) { str << "bound max diff: " << diff << std::endl; } if (!str.str().empty()) { StringStream str2; str2 << std::endl << "Mesh name: " << b->getName() << std::endl; str2 << str.str(); std::cout << str2.str(); // OutputDebugStringA(str2.str().c_str()); } #endif /* ifndef OGRE_TEST_XMLSERIALIZER */ // AutobuildEdgeLists is not saved to mesh file. You need to set it after loading a mesh! // CPPUNIT_ASSERT(a->getAutoBuildEdgeLists() == b->getAutoBuildEdgeLists()); CPPUNIT_ASSERT(isHashMapClone(a->getSubMeshNameMap(), b->getSubMeshNameMap())); assertVertexDataClone(a->sharedVertexData, b->sharedVertexData); CPPUNIT_ASSERT(a->getCreator() == b->getCreator()); CPPUNIT_ASSERT(a->getIndexBufferUsage() == b->getIndexBufferUsage()); CPPUNIT_ASSERT(a->getSharedVertexDataAnimationIncludesNormals() == b->getSharedVertexDataAnimationIncludesNormals()); CPPUNIT_ASSERT(a->getSharedVertexDataAnimationType() == b->getSharedVertexDataAnimationType()); CPPUNIT_ASSERT(a->getVertexBufferUsage() == b->getVertexBufferUsage()); CPPUNIT_ASSERT(a->hasVertexAnimation() == b->hasVertexAnimation()); #ifndef OGRE_TEST_XMLSERIALIZER CPPUNIT_ASSERT(a->isEdgeListBuilt() == b->isEdgeListBuilt()); // <== OgreXMLSerializer is doing post processing to generate edgelists! #endif // !OGRE_TEST_XMLSERIALIZER if ((a->getNumLodLevels() > 1 || b->getNumLodLevels() > 1) && ((version < MESH_VERSION_1_8 || (!isLodMixed(a) && !isLodMixed(b))) && // mixed lod only supported in v1.10+ (version < MESH_VERSION_1_4 || (a->getLodStrategy() == DistanceLodStrategy::getSingletonPtr() && b->getLodStrategy() == DistanceLodStrategy::getSingletonPtr())))) { // Lod Strategy only supported in v1.41+ CPPUNIT_ASSERT(a->getNumLodLevels() == b->getNumLodLevels()); CPPUNIT_ASSERT(a->hasManualLodLevel() == b->hasManualLodLevel()); CPPUNIT_ASSERT(a->getLodStrategy() == b->getLodStrategy()); int numLods = a->getNumLodLevels(); for (int i = 0; i < numLods; i++) { if (version != MESH_VERSION_1_0 && a->getAutoBuildEdgeLists() == b->getAutoBuildEdgeLists()) { assertEdgeDataClone(a->getEdgeList(i), b->getEdgeList(i)); } else if (a->getLodLevel(i).edgeData != NULL && b->getLodLevel(i).edgeData != NULL) { assertEdgeDataClone(a->getLodLevel(i).edgeData, b->getLodLevel(i).edgeData); } assertLodUsageClone(a->getLodLevel(i), b->getLodLevel(i)); } } CPPUNIT_ASSERT(a->getNumSubMeshes() == b->getNumSubMeshes()); int numLods = std::min(a->getNumLodLevels(), b->getNumLodLevels()); int numSubmeshes = a->getNumSubMeshes(); for (int i = 0; i < numSubmeshes; i++) { SubMesh* aSubmesh = a->getSubMesh(i); SubMesh* bSubmesh = b->getSubMesh(i); CPPUNIT_ASSERT(aSubmesh->getMaterialName() == bSubmesh->getMaterialName()); CPPUNIT_ASSERT(aSubmesh->isMatInitialised() == bSubmesh->isMatInitialised()); CPPUNIT_ASSERT(aSubmesh->useSharedVertices == bSubmesh->useSharedVertices); CPPUNIT_ASSERT(aSubmesh->getVertexAnimationIncludesNormals() == bSubmesh->getVertexAnimationIncludesNormals()); CPPUNIT_ASSERT(aSubmesh->getVertexAnimationType() == bSubmesh->getVertexAnimationType()); CPPUNIT_ASSERT(aSubmesh->getTextureAliasCount() == bSubmesh->getTextureAliasCount()); CPPUNIT_ASSERT(isContainerClone(aSubmesh->blendIndexToBoneIndexMap, bSubmesh->blendIndexToBoneIndexMap)); // TODO: Compare getBoneAssignments and getTextureAliases for (int n = 0; n < numLods; n++) { if (a->_isManualLodLevel(n)) { continue; } RenderOperation aop, bop; aSubmesh->_getRenderOperation(aop, n); bSubmesh->_getRenderOperation(bop, n); assertIndexDataClone(aop.indexData, bop.indexData); assertVertexDataClone(aop.vertexData, bop.vertexData); CPPUNIT_ASSERT(aop.operationType == bop.operationType); CPPUNIT_ASSERT(aop.useIndexes == bop.useIndexes); } } }
Mesh* MeshManager::parseMD5(string filename, char* buffer, int lenght){ Mesh* resultMesh = new Mesh(filename, getNewId()); int numJoints = 0; int numMeshes = 0; int numVerts = 0; int numTris = 0; int numWeights = 0; unsigned int idSubMesh = 0; int n = 0; copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//autoincrease i while (buffer[n] != '\0'){ if(strncmp(tempBuffer, "MD5Version", 10) == 0){ copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); //resultMesh->versionMD5 = (int) atoi(tempBuffer); //logInf("md5 version %s", tempBuffer); } else if(strncmp(tempBuffer, "commandline", 11) == 0){ skipLine(buffer, &n); } else if(strncmp(tempBuffer, "numJoints", 9) == 0){ copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); numJoints = (int) atoi(tempBuffer); resultMesh->joints.reserve(numJoints); } else if(strncmp(tempBuffer, "numMeshes", 9) == 0){ copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); numMeshes = (int) atoi(tempBuffer); resultMesh->subMeshes.reserve(numMeshes); } else if(strncmp(tempBuffer, "joints", 6) == 0){ copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); //read the '{' character Mesh::Joint auxJoint; for(int i = 0; i < numJoints; i++){ copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); auxJoint.jointName = tempBuffer; copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); auxJoint.jointParentID = (int) atoi(tempBuffer); copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);// '(' char copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); auxJoint.jointPos.x = (float) fast_atof(tempBuffer); copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); auxJoint.jointPos.y = (float) fast_atof(tempBuffer); copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); auxJoint.jointPos.z = (float) fast_atof(tempBuffer); copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);// ')' char copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);// '(' char copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); auxJoint.jointOrient.x = (float) fast_atof(tempBuffer); copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); auxJoint.jointOrient.y = (float) fast_atof(tempBuffer); copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); auxJoint.jointOrient.z = (float) fast_atof(tempBuffer); skipLine(buffer, &n); removeQuotes(&(auxJoint.jointName)); computeQuaternionW(&(auxJoint.jointOrient)); resultMesh->joints.push_back(auxJoint); } } else if(strncmp(tempBuffer, "mesh", 4) == 0){ SubMesh* auxSubMesh = new SubMesh(idSubMesh); idSubMesh++; copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);// char { copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); while(strncmp(tempBuffer, "}", 1) != 0){ if(strncmp(tempBuffer, "shader", 6) == 0){ ///////////////TODO //shader factory //used to set the texture!! be careful copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); auxSubMesh->setSubMeshTextureName(tempBuffer); skipLine(buffer, &n); } else if(strncmp(tempBuffer, "numverts", 8) == 0){ copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); numVerts = (int) atoi(tempBuffer); glm::vec2 textCoord; glm::i32vec2 weightStartAndCount; for(int i = 0; i < numVerts; ++i){ copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//"vert" copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//id (sorted) copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//'(' copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); textCoord.x = (float) fast_atof(tempBuffer); copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); textCoord.y = (float) fast_atof(tempBuffer); copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//')' copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); weightStartAndCount.x = (int) atoi(tempBuffer); copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); weightStartAndCount.y = (int) atoi(tempBuffer); auxSubMesh->textureCoord.push_back(textCoord); auxSubMesh->weightsIndex.push_back(weightStartAndCount); } } else if(strncmp(tempBuffer, "numtris", 7) == 0){ copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); numTris = (int) atoi(tempBuffer); glm::i32vec3 tri; auxSubMesh->elements.reserve(numTris); for (int i = 0; i < numTris; ++i){ copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); tri.x = (int) atoi(tempBuffer); copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); tri.z = (int) atoi(tempBuffer); copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); tri.y = (int) atoi(tempBuffer); auxSubMesh->elements.push_back(tri); } } else if(strncmp(tempBuffer, "numweights", 10) == 0){ copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); numWeights = (int) atoi(tempBuffer); SubMesh::Weight auxWeight; auxSubMesh->weights.reserve(numWeights); for (int i = 0; i < numWeights; ++i){ //logInf("Weight[%i]",i); copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//weight copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//id (sorted) copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//id joint auxWeight.weightJointID = (int) atoi(tempBuffer); copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//bias auxWeight.weightBias = (float) fast_atof(tempBuffer); copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//'(' copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); auxWeight.weightPos.x = (float) fast_atof(tempBuffer); copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); auxWeight.weightPos.y = (float) fast_atof(tempBuffer); copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); auxWeight.weightPos.z = (float) fast_atof(tempBuffer); copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//')' auxSubMesh->weights.push_back(auxWeight); //logInf("Weight[%i]",i); } } else if(strncmp(tempBuffer, "//", 2) == 0){ skipLine(buffer, &n); } copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n); } prepareSubMeshVertex(resultMesh, auxSubMesh); prepareSubMeshNormals(resultMesh, auxSubMesh); resultMesh->subMeshes.push_back(auxSubMesh); } copyNextWord(tempBuffer, BUFFERSIZE, buffer, &n);//autoincrease i if(n>=lenght)break; } return resultMesh; }
void MeshBuilder::end() { assert(!m_bIsSharedVertices && !m_currentSubMesh.strName.empty() && "You must call begin() before you call end()"); assert(!m_currentSubMesh.bUseSharedVertices || m_mesh->sharedVertexData); // Declarations std::map<unsigned short, std::vector<tElement> >::iterator iterSource, iterSourceEnd; std::vector<tVertex>::iterator iterVertex, iterVertexEnd; HardwareVertexBufferSharedPtr vbuffer; VertexData* pVertexData; // If a temporary vertex is pending, add it to the list if (m_bTempVertexPending) copyTempVertexToBuffer(); m_bFirstVertex = false; m_bAutomaticDeclaration = false; m_bIsSharedVertices = false; // Create the submesh SubMesh* pSubMesh = m_mesh->createSubMesh(m_currentSubMesh.strName); pSubMesh->setMaterialName(m_currentSubMesh.strMaterial); pSubMesh->useSharedVertices = m_currentSubMesh.bUseSharedVertices; pSubMesh->operationType = m_currentSubMesh.opType; // Initializes the vertex declaration if necessary if (!m_currentSubMesh.bUseSharedVertices) { pSubMesh->vertexData = createVertexData(); pVertexData = pSubMesh->vertexData; } else { pVertexData = m_mesh->sharedVertexData; } // Add the vertices into their buffers VertexBufferBinding::VertexBufferBindingMap bindings = pVertexData->vertexBufferBinding->getBindings(); for (iterSource = m_currentSubMesh.verticesElements.begin(), iterSourceEnd = m_currentSubMesh.verticesElements.end(); iterSource != iterSourceEnd; ++iterSource) { unsigned int vertexIndex = 0; for (iterVertex = m_currentSubMesh.vertices.begin(), iterVertexEnd = m_currentSubMesh.vertices.end(); iterVertex != iterVertexEnd; ++iterVertex) { if ((iterVertex->blendingDim > 0) && !m_mesh->getSkeletonName().empty()) { VertexBoneAssignment ass; ass.vertexIndex = vertexIndex; for (unsigned int i = 0; i < iterVertex->blendingDim; ++i) { ass.boneIndex = iterVertex->blendingIndices[i]; ass.weight = iterVertex->blendingWeights[i]; pSubMesh->addBoneAssignment(ass); } } ++vertexIndex; } } // Add the indices into their buffer pSubMesh->indexData->indexCount = m_currentSubMesh.indices.size(); pSubMesh->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( HardwareIndexBuffer::IT_16BIT, m_currentSubMesh.indices.size(), m_currentSubMesh.indexBufferInfo.usage, m_currentSubMesh.indexBufferInfo.bUseShadowBuffer); pSubMesh->indexData->indexBuffer->writeData(0, m_currentSubMesh.indices.size() * sizeof(unsigned short), &m_currentSubMesh.indices[0]); // Update the AABB and the radius of the mesh m_mesh->_setBounds(toOgre(m_AABB)); m_mesh->_setBoundingSphereRadius(m_radius); // Reset the internal state m_currentSubMesh.strName = ""; m_currentSubMesh.strMaterial = ""; m_currentSubMesh.bUseSharedVertices = false; m_currentSubMesh.indexBufferInfo.usage = HardwareBuffer::HBU_STATIC_WRITE_ONLY; m_currentSubMesh.indexBufferInfo.bUseShadowBuffer = false; m_currentSubMesh.verticesElements.clear(); m_currentSubMesh.vertexBufferInfos.clear(); m_currentSubMesh.vertices.clear(); m_currentSubMesh.indices.clear(); }
/* ******************************************************************************* | implement of CGrassSticks ******************************************************************************* */ void CGrassSticks::createGrassMesh() { MeshPtr mesh = MeshManager::getSingleton().createManual(GRASS_MESH_NAME, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); // create a submesh with the grass material SubMesh* sm = mesh->createSubMesh(); sm->setMaterialName("Examples/GrassBlades"); sm->useSharedVertices = false; sm->vertexData = OGRE_NEW VertexData(); sm->vertexData->vertexStart = 0; sm->vertexData->vertexCount = 12; sm->indexData->indexCount = 18; // specify a vertex format declaration for our mesh: 3 floats for position, 3 floats for normal, 2 floats for UV VertexDeclaration* decl = sm->vertexData->vertexDeclaration; decl->addElement(0, 0, VET_FLOAT3, VES_POSITION); decl->addElement(0, sizeof(float) * 3, VET_FLOAT3, VES_NORMAL); decl->addElement(0, sizeof(float) * 6, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); // create a vertex buffer HardwareVertexBufferSharedPtr vb = HardwareBufferManager::getSingleton().createVertexBuffer (decl->getVertexSize(0), sm->vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); GrassVertex* verts = (GrassVertex*)vb->lock(HardwareBuffer::HBL_DISCARD); // start filling in vertex data for (unsigned int i = 0; i < 3; i++) // each grass mesh consists of 3 planes { // planes intersect along the Y axis with 60 degrees between them Real x = Math::Cos(Degree(i * 60)) * GRASS_WIDTH / 2; Real z = Math::Sin(Degree(i * 60)) * GRASS_WIDTH / 2; for (unsigned int j = 0; j < 4; j++) // each plane has 4 vertices { GrassVertex& vert = verts[i * 4 + j]; vert.x = j < 2 ? -x : x; vert.y = j % 2 ? 0 : GRASS_HEIGHT; vert.z = j < 2 ? -z : z; // all normals point straight up vert.nx = 0; vert.ny = 1; vert.nz = 0; vert.u = j < 2 ? 0 : 1; vert.v = j % 2; } } vb->unlock(); // commit vertex changes sm->vertexData->vertexBufferBinding->setBinding(0, vb); // bind vertex buffer to our submesh // create an index buffer sm->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer (HardwareIndexBuffer::IT_16BIT, sm->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // start filling in index data Ogre::uint16* indices = (Ogre::uint16*)sm->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD); for (unsigned int i = 0; i < 3; i++) // each grass mesh consists of 3 planes { unsigned int off = i * 4; // each plane consists of 2 triangles *indices++ = 0 + off; *indices++ = 3 + off; *indices++ = 1 + off; *indices++ = 0 + off; *indices++ = 2 + off; *indices++ = 3 + off; } sm->indexData->indexBuffer->unlock(); // commit index changes // update mesh AABB Ogre::AxisAlignedBox aabb; aabb.setExtents(-1,-1,-1,1,1,1); mesh->_setBounds(aabb); // Ogre::MeshSerializer serial; // serial.exportMesh(mesh.getPointer(), "grass.mesh"); }
void Andu::AnduGLWidget::newGLList( int listIdx, Caca::Mesh* pMesh, GLenum renderType /*= GL_TRIANGLES*/, map<int, vector<QColor> > *pVertexColorMap /*= 0*/, map<int, vector<QColor> > *pPatchColorMap /*= 0*/) { makeCurrent(); // glNewList(2, GL_COMPILE); // glutWireCube (1.0); // glEndList(); printf("new gl list %d\n", listIdx); glPushAttrib(GL_LIGHTING); glPushAttrib(GL_LIGHT0); glNewList(listIdx, GL_COMPILE); glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); // glEnable (GL_BLEND); Patch p; MeshVertex v1,v2,v3; //glColor4f(0,0.5,0.5,0.0); GLfloat mat[] = { 0.5, 0.5, 0.5, 1.0 }; //glMaterialfv(GL_FRONT, GL_AMBIENT, mat); for(int j = 0; j < pMesh->GetSubMeshCount(); j++) { SubMesh* pSubMesh = pMesh->GetSubMesh(j); const std::list<Patch>& patchList = pSubMesh->GetPatchList(); vector<QColor> *pPatchColorVec = 0; if(pPatchColorMap) { auto iter = pPatchColorMap->find(j); if(iter != pPatchColorMap->end()) { pPatchColorVec = &(iter->second); } } vector<QColor> *pVertexColorVec = 0; if(pVertexColorMap) { auto iter = pVertexColorMap->find(j); if(iter != pVertexColorMap->end()) { pVertexColorVec = &(iter->second); } } int patchIdx = 0; for(std::list<Patch>::const_iterator i = patchList.begin(); i != patchList.end() ; i++) { MeshVertex v1 = pSubMesh->GetVertex(i->vertexIndexOne); MeshVertex v2 = pSubMesh->GetVertex(i->vertexIndexTwo); MeshVertex v3 = pSubMesh->GetVertex(i->vertexIndexThree); glPushAttrib(GL_CURRENT_BIT); glBegin(renderType); QColor patchColor; if(pPatchColorVec) { patchColor = pPatchColorVec->at(patchIdx); qglColor(patchColor); } if(!patchColor.isValid() && pVertexColorVec) { qglColor(pVertexColorVec->at(i->vertexIndexOne)); } glNormal3f(v1.normal.x,v1.normal.y,v1.normal.z); glVertex3f(v1.pos.x,v1.pos.y,v1.pos.z); if(!patchColor.isValid() && pVertexColorVec) { qglColor(pVertexColorVec->at(i->vertexIndexThree)); } glNormal3f(v3.normal.x,v3.normal.y,v3.normal.z); glVertex3f(v3.pos.x,v3.pos.y,v3.pos.z); if(!patchColor.isValid() && pVertexColorVec) { qglColor(pVertexColorVec->at(i->vertexIndexTwo)); } glNormal3f(v2.normal.x,v2.normal.y,v2.normal.z); glVertex3f(v2.pos.x,v2.pos.y,v2.pos.z); glEnd(); glPopAttrib(); patchIdx++; } } glEndList(); glPopAttrib(); glPopAttrib(); }