Ejemplo n.º 1
0
	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;
	}
Ejemplo n.º 2
0
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();
}
Ejemplo n.º 3
0
	//------------------------------------------------------------------------------------
	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;
	}
Ejemplo n.º 4
0
	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;
	}
Ejemplo n.º 5
0
	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];
	}
Ejemplo n.º 6
0
	//------------------------------------------------------------------------------------
	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);
	}
Ejemplo n.º 7
0
 SubMesh *addSubMesh(GLenum mode, size_t first, size_t count)
 {
     SubMesh *res = addSubMesh();
     res->setMode(mode);
     res->setFirstIndex(first);
     res->setIndexCount(count);
     return res;
 }
Ejemplo n.º 8
0
	//------------------------------------------------------------------------------------
	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;
}
Ejemplo n.º 10
0
    //-----------------------------------------------------------------------
    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);
    }
Ejemplo n.º 11
0
	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());
			}
		}
	}
Ejemplo n.º 12
0
	//----------------------------------------------------------------------------------------
	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;
		}
	}
Ejemplo n.º 13
0
	//-----------------------------------------------------------------------------
	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;


	}
Ejemplo n.º 14
0
//-----------------------------------------------------------------------
void Entity::buildSubEntityList(Mesh* mesh, SubEntityList* sublist) {
  // Create SubEntities
  int i, numSubMeshes;
  SubMesh* subMesh;
  SubEntity* subEnt;

  numSubMeshes = mesh->getNumSubMeshes();
  for (i = 0; i < numSubMeshes; ++i) {
    subMesh = mesh->getSubMesh(i);
    subEnt = new SubEntity();
    subEnt->mParentEntity = this;
    subEnt->mSubMesh = subMesh;
    if (subMesh->isMatInitialised())
      subEnt->setMaterialName(subMesh->getMaterialName());
    sublist->push_back(subEnt);
  }
}
Ejemplo n.º 15
0
	//------------------------------------------------------------------------------------
	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;
	}
Ejemplo n.º 16
0
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;
}
Ejemplo n.º 17
0
	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());
				}
			}
		}
	}
Ejemplo n.º 18
0
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);
}
Ejemplo n.º 19
0
	//------------------------------------------------------------------------------------
	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;
	}
Ejemplo n.º 20
0
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 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;
 }
Ejemplo n.º 21
0
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);
}
Ejemplo n.º 22
0
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();
}
Ejemplo n.º 23
0
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);
        }
    }

}
Ejemplo n.º 24
0
	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;
	}
Ejemplo n.º 25
0
    //-----------------------------------------------------------------------
    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);
		}
	}
}
Ejemplo n.º 27
0
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;
}
Ejemplo n.º 28
0
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();
}