예제 #1
0
void GraphicsResourceMesh::setMaterialNames(GraphicsResourceMesh* resourcePtr)
{
  Ogre::ResourcePtr meshResource = Ogre::MeshManager::getSingleton().getByName(resourcePtr->getID());
  Ogre::Mesh* meshPtr = static_cast<Ogre::Mesh *>(&*meshResource);
  Ogre::Mesh::SubMeshIterator currSubMeshIter = meshPtr->getSubMeshIterator();

  while (currSubMeshIter.hasMoreElements()) {
    Ogre::SubMesh *curSubMesh = currSubMeshIter.getNext();

    if (!OPTION_ENABLE_TEXTURES->as<bool>()) {
      curSubMesh->setMaterialName("BaseWhiteTexture");
    }
    else {
      const Ogre::String& curMatName = curSubMesh->getMaterialName();
      int pos = curMatName.find_last_of(':');
      if (pos != -1) {
        String start = curMatName.substr(0, pos);
        String ending = curMatName.substr(pos);
        std::map<String, String>::iterator itr = resourcePtr->mMaterialNames.find(start);
        if (itr != resourcePtr->mMaterialNames.end())
          curSubMesh->setMaterialName(itr->second + ending);
      }
    }
  }
}
예제 #2
0
void OgreMeshAsset::SetDefaultMaterial()
{
    if (!ogreMesh.get())
        return;

    for(unsigned short i = 0; i < ogreMesh->getNumSubMeshes(); ++i)
    {
        Ogre::SubMesh *submesh = ogreMesh->getSubMesh(i);
        if (submesh)
            submesh->setMaterialName("LitTextured");
    }
}
예제 #3
0
void OgreMeshAsset::SetDefaultMaterial()
{
    if (ogreMesh.isNull())
        return;

//    originalMaterials.clear();
    for (uint i = 0; i < ogreMesh->getNumSubMeshes(); ++i)
    {
        Ogre::SubMesh *submesh = ogreMesh->getSubMesh(i);
        if (submesh)
        {
//            originalMaterials.push_back(submesh->getMaterialName().c_str());
            submesh->setMaterialName("LitTextured");
        }
    }
}
예제 #4
0
Ogre::SubMesh *EMDOgre::createOgreSubmesh(EMDTriangles *triangles, Ogre::MeshPtr mesh, std::string material_name) {
	Ogre::SubMesh *sub = mesh->createSubMesh();
  sub->setMaterialName(name + "_" + material_name + ".material");
	const size_t ibufCount = triangles->faces.size();
	unsigned short *faces = (unsigned short *)malloc(sizeof(unsigned short) * ibufCount);
	for (size_t i = 0; i<ibufCount; i++) {
		faces[i] = triangles->faces[i];
	}

	Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, ibufCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
	ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);
	sub->useSharedVertices = true;
	sub->indexData->indexBuffer = ibuf;
	sub->indexData->indexCount = ibufCount;
	sub->indexData->indexStart = 0;
	free(faces);
	return sub;
}
예제 #5
0
void MapView::createTerrain()
{
	unsigned int sizeX = mMap->getTerrainSize().x;
	unsigned int sizeZ = mMap->getTerrainSize().z;

	mTileX = 33;
	mTileZ = 33;

	unsigned int tileCount = ((sizeX - 1) / (mTileX - 1)) * ((sizeZ - 1) / (mTileZ - 1));
	unsigned int vertexPerTile = mTileX * mTileZ;
	unsigned int trianglesPerTile = (mTileX - 1) * (mTileZ - 1) * 2;

	mMeshes.resize(tileCount);
	mEntities.resize(tileCount);
	mSceneNodes.resize(tileCount);

	// vertexPerTile * 3 vertices * 2 texture coordinates * 3 colours * 3 normals
	VertexVector vertices(vertexPerTile * 11);

	// trianglesPerTile * 3 indices per each triangle
	IndexVector indices[3] =
	{
		IndexVector(trianglesPerTile * 3    ),
		IndexVector(trianglesPerTile * 3 / 4),
		IndexVector(trianglesPerTile * 3 / 8)
	};

	unsigned int vertexIndex, indexIndex = 0, tileIndex = 0;

	for (unsigned int zIndex = 0; zIndex < mTileZ - 1; ++zIndex)
	{
		for (unsigned int xIndex = 0; xIndex < mTileX - 1; ++xIndex)
		{
			indices[0][indexIndex++] =  zIndex      * mTileX + xIndex;
			indices[0][indexIndex++] = (zIndex + 1) * mTileX + xIndex;
			indices[0][indexIndex++] =  zIndex      * mTileX + xIndex + 1;

			indices[0][indexIndex++] = (zIndex + 1) * mTileX + xIndex;
			indices[0][indexIndex++] = (zIndex + 1) * mTileX + xIndex + 1;
			indices[0][indexIndex++] =  zIndex      * mTileX + xIndex + 1;
		}
	}

	indexIndex = 0;

	for (unsigned int zIndex = 0; zIndex < mTileZ - 1; zIndex += 2)
	{
		for (unsigned int xIndex = 0; xIndex < mTileX - 1; xIndex += 2)
		{
			indices[1][indexIndex++] =  zIndex      * mTileX + xIndex;
			indices[1][indexIndex++] = (zIndex + 2) * mTileX + xIndex;
			indices[1][indexIndex++] =  zIndex      * mTileX + xIndex + 2;

			indices[1][indexIndex++] = (zIndex + 2) * mTileX + xIndex;
			indices[1][indexIndex++] = (zIndex + 2) * mTileX + xIndex + 2;
			indices[1][indexIndex++] =  zIndex      * mTileX + xIndex + 2;
		}
	}

	indexIndex = 0;

	for (unsigned int zIndex = 0; zIndex < mTileZ - 1; zIndex += 4)
	{
		for (unsigned int xIndex = 0; xIndex < mTileX - 1; xIndex += 4)
		{
			indices[2][indexIndex++] =  zIndex      * mTileX + xIndex;
			indices[2][indexIndex++] = (zIndex + 4) * mTileX + xIndex;
			indices[2][indexIndex++] =  zIndex      * mTileX + xIndex + 4;

			indices[2][indexIndex++] = (zIndex + 4) * mTileX + xIndex;
			indices[2][indexIndex++] = (zIndex + 4) * mTileX + xIndex + 4;
			indices[2][indexIndex++] =  zIndex      * mTileX + xIndex + 4;
		}
	}

	float scaleX = mMap->getSize().x / (float)(sizeX - 1);
	float scaleZ = mMap->getSize().z / (float)(sizeZ - 1);

	for (unsigned int zTile = 0; zTile < (sizeZ - 1); zTile += (mTileZ - 1))
	{
		for (unsigned int xTile = 0; xTile < (sizeX - 1); xTile += (mTileX - 1))
		{
			vertexIndex = 0;

			for (unsigned int zVertex = zTile; zVertex < zTile + mTileZ; ++zVertex)
			{
				for (unsigned int xVertex = xTile; xVertex < xTile + mTileX; ++xVertex)
				{
					float yVertex = mMap->getTerrainData()[zVertex * sizeX + xVertex];

					vertices[vertexIndex++] = (float)xVertex * scaleX;
					vertices[vertexIndex++] = (float)yVertex;
					vertices[vertexIndex++] = (float)zVertex * scaleZ;

					vertices[vertexIndex++] = (float)xVertex / (float)(sizeX - 1);
					vertices[vertexIndex++] = (float)zVertex / (float)(sizeZ - 1);

					vertices[vertexIndex++] = 1.0f;
					vertices[vertexIndex++] = 1.0f;
					vertices[vertexIndex++] = 1.0f;

					vertices[vertexIndex++] = 0.0f;
					vertices[vertexIndex++] = 1.0f;
					vertices[vertexIndex++] = 0.0f;
				}
			}

			std::string name =
				"MapView_" + Convert::ToString(mID) +
				"_Tile_" + Convert::ToString(tileIndex);

			// Create mesh.
			mMeshes[tileIndex] = Ogre::MeshManager::getSingleton().createManual(
				name, "General").get();

			// Create one submesh.
			Ogre::SubMesh* subMesh = mMeshes[tileIndex]->createSubMesh();

			// Create vertex data structure for vertices shared between submeshes.
			mMeshes[tileIndex]->sharedVertexData = new Ogre::VertexData();
			mMeshes[tileIndex]->sharedVertexData->vertexCount = vertexPerTile;

			// Create declaration (memory format) of vertex data.
			Ogre::VertexDeclaration* decl =
				mMeshes[tileIndex]->sharedVertexData->vertexDeclaration;

			size_t offset = 0;

			// 1st buffer
			decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
			offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);

			decl->addElement(0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES);
			offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);

			decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_DIFFUSE);
			offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);

			decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
			offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);

			// Allocate vertex buffer of the requested number of vertices (vertexPerTile)
			// and bytes per vertex (offset).
			Ogre::HardwareVertexBufferSharedPtr vbuf =
				Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
				offset, vertexPerTile, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

			// Upload the vertex data to the card
			vbuf->writeData(0, vbuf->getSizeInBytes(), &(vertices.front()), true);

			// Set vertex buffer binding so buffer 0 is bound to our vertex buffer.
			Ogre::VertexBufferBinding* bind =
				mMeshes[tileIndex]->sharedVertexData->vertexBufferBinding; 
			bind->setBinding(0, vbuf);

			// Allocate index buffer of the requested number of vertices .
			Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().
				createIndexBuffer(
				Ogre::HardwareIndexBuffer::IT_16BIT, 
				trianglesPerTile * 3,
				Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

			// Upload the index data to the card.
			ibuf->writeData(0, ibuf->getSizeInBytes(), &(indices[0].front()), true);

			/// Set parameters of the submesh
			subMesh->useSharedVertices = true;
			subMesh->indexData->indexBuffer = ibuf;
			subMesh->indexData->indexCount = indices[0].size();
			subMesh->indexData->indexStart = 0;
			subMesh->setMaterialName("terrain");

			float xMin = vertices[0];
			float yMin = vertices[1];
			float zMin = vertices[2];

			float xMax = vertices[0];
			float yMax = vertices[1];
			float zMax = vertices[2];

			for (unsigned int i = 0; i < vertexPerTile * 11; i += 11)
			{
				if (vertices[i    ] < xMin) xMin = vertices[i    ]; else
				if (vertices[i    ] > xMax) xMax = vertices[i    ];

				if (vertices[i + 1] < yMin) yMin = vertices[i + 1]; else
				if (vertices[i + 1] > yMax) yMax = vertices[i + 1];

				if (vertices[i + 2] < zMin) zMin = vertices[i + 2]; else
				if (vertices[i + 2] > zMax) zMax = vertices[i + 2];
			}

			// Set bounding information (for culling).
			mMeshes[tileIndex]->_setBounds(Ogre::AxisAlignedBox(xMin, yMin, zMin, xMax, yMax, zMax));
			mMeshes[tileIndex]->_setBoundingSphereRadius(1.0f);

			// Notify Mesh object that it has been loaded.
			mMeshes[tileIndex]->load();

			// Create entity.
			mEntities[tileIndex] = createEntity(name, name);
			mEntities[tileIndex]->setCastShadows(false);
			mEntities[tileIndex]->setUserAny(Ogre::Any(this));

			// Create scene node.
			mSceneNodes[tileIndex] = createSceneNode();
			mSceneNodes[tileIndex]->attachObject(mEntities[tileIndex]);

			// Advance to next tile.
			tileIndex++;
		}
	}
}
예제 #6
0
void NIFMeshLoader::createSubMesh(Ogre::Mesh *mesh, const Nif::NiTriShape *shape)
{
    const Nif::NiTriShapeData *data = shape->data.getPtr();
    const Nif::NiSkinInstance *skin = (shape->skin.empty() ? NULL : shape->skin.getPtr());
    std::vector<Ogre::Vector3> srcVerts = data->vertices;
    std::vector<Ogre::Vector3> srcNorms = data->normals;
    Ogre::HardwareBuffer::Usage vertUsage = Ogre::HardwareBuffer::HBU_STATIC;
    bool vertShadowBuffer = false;

    bool geomMorpherController = false;
    if(!shape->controller.empty())
    {
        Nif::ControllerPtr ctrl = shape->controller;
        do {
            if(ctrl->recType == Nif::RC_NiGeomMorpherController)
            {
                vertUsage = Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY;
                vertShadowBuffer = true;
                geomMorpherController = true;
                break;
            }
        } while(!(ctrl=ctrl->next).empty());
    }

    if(skin != NULL)
    {
        vertUsage = Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY;
        vertShadowBuffer = true;

        // Only set a skeleton when skinning. Unskinned meshes with a skeleton will be
        // explicitly attached later.
        mesh->setSkeletonName(mName);

        // Convert vertices and normals to bone space from bind position. It would be
        // better to transform the bones into bind position, but there doesn't seem to
        // be a reliable way to do that.
        std::vector<Ogre::Vector3> newVerts(srcVerts.size(), Ogre::Vector3(0.0f));
        std::vector<Ogre::Vector3> newNorms(srcNorms.size(), Ogre::Vector3(0.0f));

        const Nif::NiSkinData *data = skin->data.getPtr();
        const Nif::NodeList &bones = skin->bones;
        for(size_t b = 0;b < bones.length();b++)
        {
            Ogre::Matrix4 mat;
            mat.makeTransform(data->bones[b].trafo.trans, Ogre::Vector3(data->bones[b].trafo.scale),
                              Ogre::Quaternion(data->bones[b].trafo.rotation));
            mat = bones[b]->getWorldTransform() * mat;

            const std::vector<Nif::NiSkinData::VertWeight> &weights = data->bones[b].weights;
            for(size_t i = 0;i < weights.size();i++)
            {
                size_t index = weights[i].vertex;
                float weight = weights[i].weight;

                newVerts.at(index) += (mat*srcVerts[index]) * weight;
                if(newNorms.size() > index)
                {
                    Ogre::Vector4 vec4(srcNorms[index][0], srcNorms[index][1], srcNorms[index][2], 0.0f);
                    vec4 = mat*vec4 * weight;
                    newNorms[index] += Ogre::Vector3(&vec4[0]);
                }
            }
        }

        srcVerts = newVerts;
        srcNorms = newNorms;
    }
    else
    {
        Ogre::SkeletonManager *skelMgr = Ogre::SkeletonManager::getSingletonPtr();
        if(skelMgr->getByName(mName).isNull())
        {
            // No skinning and no skeleton, so just transform the vertices and
            // normals into position.
            Ogre::Matrix4 mat4 = shape->getWorldTransform();
            for(size_t i = 0;i < srcVerts.size();i++)
            {
                Ogre::Vector4 vec4(srcVerts[i].x, srcVerts[i].y, srcVerts[i].z, 1.0f);
                vec4 = mat4*vec4;
                srcVerts[i] = Ogre::Vector3(&vec4[0]);
            }
            for(size_t i = 0;i < srcNorms.size();i++)
            {
                Ogre::Vector4 vec4(srcNorms[i].x, srcNorms[i].y, srcNorms[i].z, 0.0f);
                vec4 = mat4*vec4;
                srcNorms[i] = Ogre::Vector3(&vec4[0]);
            }
        }
    }

    // Set the bounding box first
    BoundsFinder bounds;
    bounds.add(&srcVerts[0][0], srcVerts.size());
    if(!bounds.isValid())
    {
        float v[3] = { 0.0f, 0.0f, 0.0f };
        bounds.add(&v[0], 1);
    }

    mesh->_setBounds(Ogre::AxisAlignedBox(bounds.minX()-0.5f, bounds.minY()-0.5f, bounds.minZ()-0.5f,
                                          bounds.maxX()+0.5f, bounds.maxY()+0.5f, bounds.maxZ()+0.5f));
    mesh->_setBoundingSphereRadius(bounds.getRadius());

    // This function is just one long stream of Ogre-barf, but it works
    // great.
    Ogre::HardwareBufferManager *hwBufMgr = Ogre::HardwareBufferManager::getSingletonPtr();
    Ogre::HardwareVertexBufferSharedPtr vbuf;
    Ogre::HardwareIndexBufferSharedPtr ibuf;
    Ogre::VertexBufferBinding *bind;
    Ogre::VertexDeclaration *decl;
    int nextBuf = 0;

    Ogre::SubMesh *sub = mesh->createSubMesh();

    // Add vertices
    sub->useSharedVertices = false;
    sub->vertexData = new Ogre::VertexData();
    sub->vertexData->vertexStart = 0;
    sub->vertexData->vertexCount = srcVerts.size();

    decl = sub->vertexData->vertexDeclaration;
    bind = sub->vertexData->vertexBufferBinding;
    if(srcVerts.size())
    {
        vbuf = hwBufMgr->createVertexBuffer(Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3),
                                            srcVerts.size(), vertUsage, vertShadowBuffer);
        vbuf->writeData(0, vbuf->getSizeInBytes(), &srcVerts[0][0], true);

        decl->addElement(nextBuf, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
        bind->setBinding(nextBuf++, vbuf);
    }

    // Vertex normals
    if(srcNorms.size())
    {
        vbuf = hwBufMgr->createVertexBuffer(Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3),
                                            srcNorms.size(), vertUsage, vertShadowBuffer);
        vbuf->writeData(0, vbuf->getSizeInBytes(), &srcNorms[0][0], true);

        decl->addElement(nextBuf, 0, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
        bind->setBinding(nextBuf++, vbuf);
    }

    // Vertex colors
    const std::vector<Ogre::Vector4> &colors = data->colors;
    if(colors.size())
    {
        Ogre::RenderSystem *rs = Ogre::Root::getSingleton().getRenderSystem();
        std::vector<Ogre::RGBA> colorsRGB(colors.size());
        for(size_t i = 0;i < colorsRGB.size();i++)
        {
            Ogre::ColourValue clr(colors[i][0], colors[i][1], colors[i][2], colors[i][3]);
            rs->convertColourValue(clr, &colorsRGB[i]);
        }
        vbuf = hwBufMgr->createVertexBuffer(Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR),
                                            colorsRGB.size(), Ogre::HardwareBuffer::HBU_STATIC);
        vbuf->writeData(0, vbuf->getSizeInBytes(), &colorsRGB[0], true);
        decl->addElement(nextBuf, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
        bind->setBinding(nextBuf++, vbuf);
    }

    // Texture UV coordinates
    size_t numUVs = data->uvlist.size();
    if (numUVs)
    {
        size_t elemSize = Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);

        for(size_t i = 0; i < numUVs; i++)
            decl->addElement(nextBuf, elemSize*i, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, i);

        vbuf = hwBufMgr->createVertexBuffer(decl->getVertexSize(nextBuf), srcVerts.size(),
                                            Ogre::HardwareBuffer::HBU_STATIC);

        std::vector<Ogre::Vector2> allUVs;
        allUVs.reserve(srcVerts.size()*numUVs);
        for (size_t vert = 0; vert<srcVerts.size(); ++vert)
            for(size_t i = 0; i < numUVs; i++)
                allUVs.push_back(data->uvlist[i][vert]);

        vbuf->writeData(0, elemSize*srcVerts.size()*numUVs, &allUVs[0], true);

        bind->setBinding(nextBuf++, vbuf);
    }

    // Triangle faces
    const std::vector<short> &srcIdx = data->triangles;
    if(srcIdx.size())
    {
        ibuf = hwBufMgr->createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, srcIdx.size(),
                                           Ogre::HardwareBuffer::HBU_STATIC);
        ibuf->writeData(0, ibuf->getSizeInBytes(), &srcIdx[0], true);
        sub->indexData->indexBuffer = ibuf;
        sub->indexData->indexCount = srcIdx.size();
        sub->indexData->indexStart = 0;
    }

    // Assign bone weights for this TriShape
    if(skin != NULL)
    {
        Ogre::SkeletonPtr skel = Ogre::SkeletonManager::getSingleton().getByName(mName);

        const Nif::NiSkinData *data = skin->data.getPtr();
        const Nif::NodeList &bones = skin->bones;
        for(size_t i = 0;i < bones.length();i++)
        {
            Ogre::VertexBoneAssignment boneInf;
            boneInf.boneIndex = skel->getBone(bones[i]->name)->getHandle();

            const std::vector<Nif::NiSkinData::VertWeight> &weights = data->bones[i].weights;
            for(size_t j = 0;j < weights.size();j++)
            {
                boneInf.vertexIndex = weights[j].vertex;
                boneInf.weight = weights[j].weight;
                sub->addBoneAssignment(boneInf);
            }
        }
    }

    const Nif::NiTexturingProperty *texprop = NULL;
    const Nif::NiMaterialProperty *matprop = NULL;
    const Nif::NiAlphaProperty *alphaprop = NULL;
    const Nif::NiVertexColorProperty *vertprop = NULL;
    const Nif::NiZBufferProperty *zprop = NULL;
    const Nif::NiSpecularProperty *specprop = NULL;
    const Nif::NiWireframeProperty *wireprop = NULL;
    bool needTangents = false;

    shape->getProperties(texprop, matprop, alphaprop, vertprop, zprop, specprop, wireprop);
    std::string matname = NIFMaterialLoader::getMaterial(data, mesh->getName(), mGroup,
                                                         texprop, matprop, alphaprop,
                                                         vertprop, zprop, specprop,
                                                         wireprop, needTangents);
    if(matname.length() > 0)
        sub->setMaterialName(matname);

    // build tangents if the material needs them
    if (needTangents)
    {
        unsigned short src,dest;
        if (!mesh->suggestTangentVectorBuildParams(Ogre::VES_TANGENT, src,dest))
            mesh->buildTangentVectors(Ogre::VES_TANGENT, src,dest);
    }

    // Create a dummy vertex animation track if there's a geom morpher controller
    // This is required to make Ogre create the buffers we will use for software vertex animation
    if (srcVerts.size() && geomMorpherController)
        mesh->createAnimation("dummy", 0)->createVertexTrack(1, sub->vertexData, Ogre::VAT_MORPH);
}
예제 #7
0
void MilkshapePlugin::doExportMesh(msModel* pModel)
{


    // Create singletons
    Ogre::SkeletonManager skelMgr;
    Ogre::DefaultHardwareBufferManager defHWBufMgr;
	Ogre::LogManager& logMgr = Ogre::LogManager::getSingleton();
	Ogre::MeshManager meshMgr;


    //
    // choose filename
    //
    OPENFILENAME ofn;
    memset (&ofn, 0, sizeof (OPENFILENAME));

    char szFile[MS_MAX_PATH];
    char szFileTitle[MS_MAX_PATH];
    char szDefExt[32] = "mesh";
    char szFilter[128] = "OGRE .mesh Files (*.mesh)\0*.mesh\0All Files (*.*)\0*.*\0\0";
    szFile[0] = '\0';
    szFileTitle[0] = '\0';

    ofn.lStructSize = sizeof (OPENFILENAME);
    ofn.lpstrDefExt = szDefExt;
    ofn.lpstrFilter = szFilter;
    ofn.lpstrFile = szFile;
    ofn.nMaxFile = MS_MAX_PATH;
    ofn.lpstrFileTitle = szFileTitle;
    ofn.nMaxFileTitle = MS_MAX_PATH;
    ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
    ofn.lpstrTitle = "Export to OGRE Mesh";

    if (!::GetSaveFileName (&ofn))
        return /*0*/;

    logMgr.logMessage("Creating Mesh object...");
    Ogre::MeshPtr ogreMesh = Ogre::MeshManager::getSingleton().create("export", 
        Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
    logMgr.logMessage("Mesh object created.");

    bool foundBoneAssignment = false;

    // No shared geometry
    int i;
	int wh, numbones;
	int intweight[3], intbones[3];
    size_t j;
    Ogre::Vector3 min, max, currpos;
    Ogre::Real maxSquaredRadius;
    bool first = true;
    for (i = 0; i < msModel_GetMeshCount (pModel); i++)
    {
        msMesh *pMesh = msModel_GetMeshAt (pModel, i);

        logMgr.logMessage("Creating SubMesh object...");
        Ogre::SubMesh* ogreSubMesh = ogreMesh->createSubMesh();
        logMgr.logMessage("SubMesh object created.");
        // Set material
        logMgr.logMessage("Getting SubMesh Material...");
        int matIdx = msMesh_GetMaterialIndex(pMesh);

        if (matIdx == -1)
        {
            // No material, use blank
            ogreSubMesh->setMaterialName("BaseWhite");
            logMgr.logMessage("No Material, using default 'BaseWhite'.");
        }
        else
        {

            msMaterial *pMat = msModel_GetMaterialAt(pModel, matIdx);
            ogreSubMesh->setMaterialName(pMat->szName);
            logMgr.logMessage("SubMesh Material Done.");
        }


        logMgr.logMessage("Setting up geometry...");
        // Set up mesh geometry
        ogreSubMesh->vertexData = new Ogre::VertexData();
        ogreSubMesh->vertexData->vertexCount = msMesh_GetVertexCount (pMesh);
        ogreSubMesh->vertexData->vertexStart = 0;
        Ogre::VertexBufferBinding* bind = ogreSubMesh->vertexData->vertexBufferBinding;
        Ogre::VertexDeclaration* decl = ogreSubMesh->vertexData->vertexDeclaration;
        // Always 1 texture layer, 2D coords
        #define POSITION_BINDING 0
        #define NORMAL_BINDING 1
        #define TEXCOORD_BINDING 2
        decl->addElement(POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
        decl->addElement(NORMAL_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
        decl->addElement(TEXCOORD_BINDING, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES);
        // Create buffers
        Ogre::HardwareVertexBufferSharedPtr pbuf = Ogre::HardwareBufferManager::getSingleton().
            createVertexBuffer(decl->getVertexSize(POSITION_BINDING), ogreSubMesh->vertexData->vertexCount,
                Ogre::HardwareBuffer::HBU_DYNAMIC, false);
        Ogre::HardwareVertexBufferSharedPtr nbuf = Ogre::HardwareBufferManager::getSingleton().
            createVertexBuffer(decl->getVertexSize(NORMAL_BINDING), ogreSubMesh->vertexData->vertexCount,
                Ogre::HardwareBuffer::HBU_DYNAMIC, false);
        Ogre::HardwareVertexBufferSharedPtr tbuf = Ogre::HardwareBufferManager::getSingleton().
            createVertexBuffer(decl->getVertexSize(TEXCOORD_BINDING), ogreSubMesh->vertexData->vertexCount,
                Ogre::HardwareBuffer::HBU_DYNAMIC, false);
        bind->setBinding(POSITION_BINDING, pbuf);
        bind->setBinding(NORMAL_BINDING, nbuf);
        bind->setBinding(TEXCOORD_BINDING, tbuf);

        ogreSubMesh->useSharedVertices = false;

        float* pPos = static_cast<float*>(
            pbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));

        logMgr.logMessage("Doing positions and texture coords...");
        for (j = 0; j < ogreSubMesh->vertexData->vertexCount; ++j)
        {
            logMgr.logMessage("Doing vertex " + Ogre::StringConverter::toString(j));
            msVertex *pVertex = msMesh_GetVertexAt (pMesh, (int)j);
			msVertexEx *pVertexEx=msMesh_GetVertexExAt(pMesh, (int)j);
            msVec3 Vertex;
            msVertex_GetVertex (pVertex, Vertex);

            *pPos++ = Vertex[0];
            *pPos++ = Vertex[1];
            *pPos++ = Vertex[2];
            // Deal with bounds
            currpos = Ogre::Vector3(Vertex[0], Vertex[1], Vertex[2]);
            if (first)
            {
                min = max = currpos;
                maxSquaredRadius = currpos.squaredLength();
                first = false;
            }
            else
            {
                min.makeFloor(currpos);
                max.makeCeil(currpos);
                maxSquaredRadius = std::max(maxSquaredRadius, currpos.squaredLength());
            }

            int boneIdx = msVertex_GetBoneIndex(pVertex);
            if (boneIdx != -1)
            {
				foundBoneAssignment = true;
				numbones = 1;
				intbones[0] = intbones[1] = intbones[2] = -1;
				intweight[0] = intweight[1] = intweight[2] = 0;
				for(wh = 0; wh < 3; ++wh) 
				{
					intbones[wh] = msVertexEx_GetBoneIndices(pVertexEx, wh);
					if(intbones[wh] == -1) 
						break;

					++numbones;
					intweight[wh] = msVertexEx_GetBoneWeights(pVertexEx, wh);

				} // for(k)
				Ogre::VertexBoneAssignment vertAssign;
				vertAssign.boneIndex = boneIdx;
				vertAssign.vertexIndex = (unsigned int)j;
				if(numbones == 1) 
				{
					vertAssign.weight = 1.0;
				} // single assignment
				else 
				{
					vertAssign.weight=(Ogre::Real)intweight[0]/100.0;
				}
				ogreSubMesh->addBoneAssignment(vertAssign);
				if(numbones > 1) 
				{
					// this somewhat contorted logic is because the first weight [0] matches to the bone assignment
					// located with pVertex. The next two weights [1][2] match up to the first two bones found
					// with pVertexEx [0][1]. The weight for the fourth bone, if present, is the unassigned weight
					for(wh = 0; wh < 3; wh++) 
					{
						boneIdx = intbones[wh];
						if(boneIdx == -1) 
							break;
						vertAssign.boneIndex = boneIdx;
						vertAssign.vertexIndex = (unsigned int)j;
						if(wh == 2) 
						{ 
							// fourth weight is 1.0-(sumoffirstthreeweights)
							vertAssign.weight = 1.0-(((Ogre::Real)intweight[0]/100.0)+
								((Ogre::Real)intweight[1]/100.0)+((Ogre::Real)intweight[2]/100.0));
						}
						else 
						{
							vertAssign.weight=(Ogre::Real)intweight[wh+1];
						}
						ogreSubMesh->addBoneAssignment(vertAssign);
					} // for(k)
				} // if(numbones)
			}

        }
        pbuf->unlock();

        float* pTex = static_cast<float*>(
            tbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
        logMgr.logMessage("Doing uvs, normals and indexes (v2)...");

        // Aargh, Milkshape uses stupid separate normal indexes for the same vertex like 3DS
        // Normals aren't described per vertex but per triangle vertex index
        // Pain in the arse, we have to do vertex duplication again if normals differ at a vertex (non smooth)
        // WHY don't people realise this format is a pain for passing to 3D APIs in vertex buffers?
        float* pNorm = static_cast<float*>(
            nbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
        ogreSubMesh->indexData->indexCount = msMesh_GetTriangleCount (pMesh) * 3;
        // Always use 16-bit buffers, Milkshape can't handle more anyway
        Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().
            createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT,
            ogreSubMesh->indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
        ogreSubMesh->indexData->indexBuffer = ibuf;
        unsigned short *pIdx = static_cast<unsigned short*>(
            ibuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
        for (j = 0; j < ogreSubMesh->indexData->indexCount; j+=3)
        {
            msTriangle *pTriangle = msMesh_GetTriangleAt (pMesh, (int)j/3);
			msTriangleEx *pTriangleEx=msMesh_GetTriangleExAt(pMesh, (int)j/3);
            word nIndices[3];
            msTriangle_GetVertexIndices (pTriangle, nIndices);
            msVec3 Normal;
            msVec2 uv;
            int k, vertIdx;

            for (k = 0; k < 3; ++k)
            {
                vertIdx = nIndices[k];
                // Face index
                pIdx[j+k] = vertIdx;

                // Vertex normals
                // For the moment, ignore any discrepancies per vertex
				msTriangleEx_GetNormal(pTriangleEx, k, &Normal[0]);
				msTriangleEx_GetTexCoord(pTriangleEx, k, &uv[0]);
				pTex[(vertIdx*2)]=uv[0];
				pTex[(vertIdx*2)+1]=uv[1];
                pNorm[(vertIdx*3)] = Normal[0];
                pNorm[(vertIdx*3)+1] = Normal[1];
                pNorm[(vertIdx*3)+2] = Normal[2];
            }

        } // Faces
        nbuf->unlock();
        ibuf->unlock();
        tbuf->unlock();

        // Now use Ogre's ability to reorganise the vertex buffers the best way
        Ogre::VertexDeclaration* newDecl = 
            ogreSubMesh->vertexData->vertexDeclaration->getAutoOrganisedDeclaration(
                foundBoneAssignment, false);
        Ogre::BufferUsageList bufferUsages;
        for (size_t u = 0; u <= newDecl->getMaxSource(); ++u)
            bufferUsages.push_back(Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
        ogreSubMesh->vertexData->reorganiseBuffers(newDecl, bufferUsages);


        logMgr.logMessage("Geometry done.");
    } // SubMesh

    // Set bounds
    ogreMesh->_setBoundingSphereRadius(Ogre::Math::Sqrt(maxSquaredRadius));
    ogreMesh->_setBounds(Ogre::AxisAlignedBox(min, max), false);


    // Keep hold of a Skeleton pointer for deletion later
    // Mesh uses Skeleton pointer for skeleton name
    Ogre::SkeletonPtr pSkel;

    if (exportSkeleton && foundBoneAssignment)
    {
        // export skeleton, also update mesh to point to it
        pSkel = doExportSkeleton(pModel, ogreMesh);
    }
    else if (!exportSkeleton && foundBoneAssignment)
    {
        // We've found bone assignments, but skeleton is not to be exported
        // Prompt the user to find the skeleton
        if (!locateSkeleton(ogreMesh))
            return;

    }

    // Export
    logMgr.logMessage("Creating MeshSerializer..");
    Ogre::MeshSerializer serializer;
    logMgr.logMessage("MeshSerializer created.");

    // Generate LODs if required
    if (generateLods)
    {
        // Build LOD depth list
        Ogre::Mesh::LodDistanceList distList;
        float depth = 0;
        for (unsigned short depthidx = 0; depthidx < numLods; ++depthidx)
        {
            depth += lodDepthIncrement;
            distList.push_back(depth);
        }

        ogreMesh->generateLodLevels(distList, lodReductionMethod, lodReductionAmount);
    }

    if (generateEdgeLists)
    {
        ogreMesh->buildEdgeList();
    }

    if (generateTangents)
    {
		unsigned short src, dest;
		ogreMesh->suggestTangentVectorBuildParams(tangentSemantic, src, dest);
		ogreMesh->buildTangentVectors(tangentSemantic, src, dest, tangentsSplitMirrored, tangentsSplitRotated, tangentsUseParity);
    }

    // Export
    Ogre::String msg;
	msg  = "Exporting mesh data to file '" + Ogre::String(szFile) + "'";
    logMgr.logMessage(msg);
    serializer.exportMesh(ogreMesh.getPointer(), szFile);
    logMgr.logMessage("Export successful");

    Ogre::MeshManager::getSingleton().remove(ogreMesh->getHandle());
    if (!pSkel.isNull())
        Ogre::SkeletonManager::getSingleton().remove(pSkel->getHandle());

	if (exportMaterials && msModel_GetMaterialCount(pModel) > 0)
	{
		doExportMaterials(pModel);
	}
}
예제 #8
0
    bool OgreMeshResource::SetData(Foundation::AssetPtr source)
    {
        if (!source)
        {
            OgreRenderingModule::LogError("Null source asset data pointer");     
            return false;
        }
        if (!source->GetSize())
        {
            OgreRenderingModule::LogError("Zero sized mesh asset");     
            return false;
        }
                
        try
        {
            if (ogre_mesh_.isNull())
            {   
                ogre_mesh_ = Ogre::MeshManager::getSingleton().createManual(
                    id_, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
                if (ogre_mesh_.isNull())
                {
                    OgreRenderingModule::LogError("Failed to create mesh " + id_);
                    return false; 
                }   
                ogre_mesh_->setAutoBuildEdgeLists(false);
            }

            Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream((void*)source->GetData(), source->GetSize(), false));
            Ogre::MeshSerializer serializer;
            serializer.importMesh(stream, ogre_mesh_.getPointer());
            
            // Generate tangents to mesh
            try
            {
                unsigned short src, dest;
                if (!ogre_mesh_->suggestTangentVectorBuildParams(Ogre::VES_TANGENT, src, dest))
                    ogre_mesh_->buildTangentVectors(Ogre::VES_TANGENT, src, dest);
            }
            catch (...) {}
            
            // Generate extremity points to submeshes, 1 should be enough
            try
            {
                for(uint i = 0; i < ogre_mesh_->getNumSubMeshes(); ++i)
                {
                    Ogre::SubMesh *smesh = ogre_mesh_->getSubMesh(i);
                    if (smesh)
                        smesh->generateExtremes(1);
                }
            }
            catch (...) {}
            
            // Assign default materials that won't complain
            original_materials_.clear();
            for (uint i = 0; i < ogre_mesh_->getNumSubMeshes(); ++i)
            {
                Ogre::SubMesh* submesh = ogre_mesh_->getSubMesh(i);
                if (submesh)
                {
                    original_materials_.push_back(submesh->getMaterialName());
                    submesh->setMaterialName("UnlitTextured");
                }
            }
            
        }
        catch (Ogre::Exception &e)
        {
            OgreRenderingModule::LogError("Failed to create mesh " + id_ + ": " + std::string(e.what()));
            RemoveMesh();
            return false;
        }

        OgreRenderingModule::LogDebug("Ogre mesh " + id_ + " created");
        return true;
    }
예제 #9
0
 // Write submesh data to an Ogre compatible mesh
 bool Submesh::createOgreSubmesh(Ogre::MeshPtr pMesh,const ParamList& params)
 {
     size_t i,j;
     bool stat;
     // Create a new submesh
     Ogre::SubMesh* pSubmesh;
     if (m_name != "")
         pSubmesh = pMesh->createSubMesh(m_name.c_str());
     else
         pSubmesh = pMesh->createSubMesh();
     // Set material
     pSubmesh->setMaterialName(m_pMaterial->name().c_str());
     // Set use shared geometry flag
     pSubmesh->useSharedVertices = params.useSharedGeom;
     // Create vertex data for current submesh
     pSubmesh->vertexData = new Ogre::VertexData();
     // Set number of indexes
     pSubmesh->indexData->indexCount = 3*m_faces.size();
     pSubmesh->vertexData->vertexCount = m_vertices.size();
     // Check if we need to use 32 bit indexes
     bool use32BitIndexes = false;
     if (m_vertices.size() > 65536 || params.useSharedGeom)
     {
         use32BitIndexes = true;
     }
     // Create a new index buffer
     pSubmesh->indexData->indexBuffer = 
         Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
             use32BitIndexes ? Ogre::HardwareIndexBuffer::IT_32BIT : Ogre::HardwareIndexBuffer::IT_16BIT,
             pSubmesh->indexData->indexCount,
             Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
     // Fill the index buffer with faces data
     if (use32BitIndexes)
     {
         Ogre::uint32* pIdx = static_cast<Ogre::uint32*>(
             pSubmesh->indexData->indexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD));
         for (i=0; i<m_faces.size(); i++)
         {
             *pIdx++ = static_cast<Ogre::uint32>(m_faces[i].v[0]);
             *pIdx++ = static_cast<Ogre::uint32>(m_faces[i].v[1]);
             *pIdx++ = static_cast<Ogre::uint32>(m_faces[i].v[2]);
         }
         pSubmesh->indexData->indexBuffer->unlock();
     }
     else
     {
         Ogre::uint16* pIdx = static_cast<Ogre::uint16*>(
             pSubmesh->indexData->indexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD));
         for (i=0; i<m_faces.size(); i++)
         {
             *pIdx++ = static_cast<Ogre::uint16>(m_faces[i].v[0]);
             *pIdx++ = static_cast<Ogre::uint16>(m_faces[i].v[1]);
             *pIdx++ = static_cast<Ogre::uint16>(m_faces[i].v[2]);
         }
         pSubmesh->indexData->indexBuffer->unlock();
     }
     // Define vertex declaration (only if we're not using shared geometry)
     if(!params.useSharedGeom)
     {
         Ogre::VertexDeclaration* pDecl = pSubmesh->vertexData->vertexDeclaration;
         unsigned buf = 0;
         size_t offset = 0;
         // Add vertex position
         pDecl->addElement(buf, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
         offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
         // Add vertex normal
         if (params.exportVertNorm)
         {
             pDecl->addElement(buf, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
             offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
         }
         // Add vertex colour
         if(params.exportVertCol)
         {
             pDecl->addElement(buf, offset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
             offset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR);
         }
         // Add texture coordinates
         for (i=0; i<m_vertices[0].texcoords.size(); i++)
         {
             Ogre::VertexElementType uvType = Ogre::VertexElement::multiplyTypeCount(Ogre::VET_FLOAT1, 2);
             pDecl->addElement(buf, offset, uvType, Ogre::VES_TEXTURE_COORDINATES, static_cast<unsigned short>(i));
             offset += Ogre::VertexElement::getTypeSize(uvType);
         }
         Ogre::VertexDeclaration* pOptimalDecl = pDecl->getAutoOrganisedDeclaration(
             params.exportVBA, params.exportBlendShapes || params.exportVertAnims, false);
         // Fill the vertex buffer using the newly created vertex declaration
         stat = createOgreVertexBuffer(pSubmesh,pDecl,m_vertices);
         // Write vertex bone assignements list
         if (params.exportVBA)
         {
             // Create a new vertex bone assignements list
             Ogre::SubMesh::VertexBoneAssignmentList vbas;
             // Scan list of shared geometry vertices
             for (i=0; i<m_vertices.size(); i++)
             {
                 vertex v = m_vertices[i];
                 // Add all bone assignemnts for every vertex to the bone assignements list
                 for (j=0; j<v.vbas.size(); j++)
                 {
                     Ogre::VertexBoneAssignment vba;
                     vba.vertexIndex = static_cast<unsigned int>(i);
                     vba.boneIndex = v.vbas[j].jointIdx;
                     vba.weight = v.vbas[j].weight;
                     vbas.insert(Ogre::SubMesh::VertexBoneAssignmentList::value_type(i, vba));
                 }
             }
             // Rationalise the bone assignements list
             pSubmesh->parent->_rationaliseBoneAssignments(pSubmesh->vertexData->vertexCount,vbas);
             // Add bone assignements to the submesh
             for (Ogre::SubMesh::VertexBoneAssignmentList::iterator bi = vbas.begin(); bi != vbas.end(); bi++)
             {
                 pSubmesh->addBoneAssignment(bi->second);
             }
             pSubmesh->_compileBoneAssignments();
         }
         pSubmesh->vertexData->reorganiseBuffers(pOptimalDecl);
     }
     return true;
 }
예제 #10
0
FlexObj::FlexObj(node_t *nds, std::vector<CabTexcoord>& texcoords, int numtriangles, 
                 int* triangles, std::vector<CabSubmesh>& submesh_defs, 
                 char* texname, const char* name, char* backtexname, char* transtexname)
{
    m_triangle_count = numtriangles;

    m_all_nodes=nds;
    // Create the mesh via the MeshManager
    m_mesh = MeshManager::getSingleton().createManual(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

    // Create submeshes
    m_submeshes.reserve(submesh_defs.size());
    for (size_t j=0; j<submesh_defs.size(); j++)
    {
        Ogre::SubMesh* submesh = m_mesh->createSubMesh();
        switch (submesh_defs[j].backmesh_type)
        {
        case CabSubmesh::BACKMESH_OPAQUE:      submesh->setMaterialName(backtexname);  break;
        case CabSubmesh::BACKMESH_TRANSPARENT: submesh->setMaterialName(transtexname); break;
        default:                               submesh->setMaterialName(texname);
        }
        m_submeshes.push_back(submesh);
    };

    // Define the m_vertices_raw (8 vertices, each consisting of 3 groups of 3 floats
    m_vertex_count = texcoords.size();
    m_vertices_raw=(float*)malloc(((2*3+2)*m_vertex_count)*sizeof(float));
    m_vertex_nodes=(int*)malloc(m_vertex_count*sizeof(int));
    
    for (size_t i=0; i<m_vertex_count; i++)
    {
        m_vertex_nodes[i] = texcoords[i].node_id; //define node ids
        m_vertices[i].texcoord=Vector2(texcoords[i].texcoord_u, texcoords[i].texcoord_v); //textures coordinates
    }

    // Define triangles
    // The values in this table refer to vertices in the above table
    m_index_count = 3*numtriangles;
    m_indices=(unsigned short*)malloc(m_index_count*sizeof(unsigned short));
    for (size_t i=0; i<m_index_count; i++)
    {
        m_indices[i]=ComputeVertexPos(i/3, triangles[i], submesh_defs);
    }

    m_s_ref=(float*)malloc(numtriangles*sizeof(float));

    for (size_t i=0; i<(unsigned int)numtriangles;i++)
    {
        Ogre::Vector3 base_pos = m_all_nodes[m_vertex_nodes[m_indices[i*3]]].RelPosition;
        Ogre::Vector3 v1       = m_all_nodes[m_vertex_nodes[m_indices[i*3+1]]].RelPosition - base_pos;
        Ogre::Vector3 v2       = m_all_nodes[m_vertex_nodes[m_indices[i*3+2]]].RelPosition - base_pos;
        m_s_ref[i]=v1.crossProduct(v2).length()*2.0;
    }

    this->UpdateMesh(); // Initialize the dynamic mesh

    // Create vertex data structure for vertices shared between submeshes
    m_mesh->sharedVertexData = new VertexData();
    m_mesh->sharedVertexData->vertexCount = m_vertex_count;

    // Create declaration (memory format) of vertex data
    m_vertex_format = m_mesh->sharedVertexData->vertexDeclaration;
    size_t offset = 0;
    m_vertex_format->addElement(0, offset, VET_FLOAT3, VES_POSITION);
    offset += VertexElement::getTypeSize(VET_FLOAT3);
    m_vertex_format->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
    offset += VertexElement::getTypeSize(VET_FLOAT3);
    m_vertex_format->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
    offset += VertexElement::getTypeSize(VET_FLOAT2);

    // Allocate vertex buffer of the requested number of vertices (vertexCount)
    // and bytes per vertex (offset)
    m_hw_vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
        offset, m_mesh->sharedVertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);

    // Upload the vertex data to the card
    m_hw_vbuf->writeData(0, m_hw_vbuf->getSizeInBytes(), m_vertices_raw, true);

    // Set vertex buffer binding so buffer 0 is bound to our vertex buffer
    VertexBufferBinding* bind = m_mesh->sharedVertexData->vertexBufferBinding;
    bind->setBinding(0, m_hw_vbuf);

    // Set parameters of the submeshes
    for (size_t j=0; j<m_submeshes.size(); j++)
    {
        size_t index_count;
        if (j == 0)
            index_count = 3*submesh_defs[j].cabs_pos;
        else
            index_count = 3*(submesh_defs[j].cabs_pos-submesh_defs[j-1].cabs_pos); // 3 indices per triangle

        m_submeshes[j]->useSharedVertices = true;
        HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().createIndexBuffer(
             HardwareIndexBuffer::IT_16BIT,
             index_count,
             HardwareBuffer::HBU_STATIC_WRITE_ONLY);

        // Upload the index data to the card
        unsigned short* faces_ptr;
        if (j == 0)
            faces_ptr = &m_indices[0];
        else
            faces_ptr = &m_indices[submesh_defs[j-1].cabs_pos * 3];

        ibuf->writeData(0, ibuf->getSizeInBytes(), faces_ptr, true);
        m_submeshes[j]->indexData->indexBuffer = ibuf;
        m_submeshes[j]->indexData->indexCount = index_count;
        m_submeshes[j]->indexData->indexStart = 0;
    }

    // Set bounding information (for culling)
    m_mesh->_setBounds(AxisAlignedBox(-100,-100,-100,100,100,100), true);

    // Notify Mesh object that it has been loaded
    m_mesh->load();
}
예제 #11
0
	Mesh* OgreSubsystem::createMesh(const MeshData& data,String name)
	{
		 String nombre = name;
		if(name=="AUTO_NAME_ME")
		{
			nombre = "OryxSceneNodeAutoNamed"+StringUtils::toString(mAutoNameIndex);
			++mAutoNameIndex;
		}

		using namespace Ogre;

		bool hasVertexColor = data.getDiffuse();
		bool hasNormals = data.getNormals();

		int numFaces = data.indices.size()/3;
		int numVertices = data.vertices.size()/3;

		HardwareVertexBufferSharedPtr posVertexBuffer;
		HardwareVertexBufferSharedPtr normVertexBuffer;
		std::vector<HardwareVertexBufferSharedPtr> texcoordsVertexBuffer;
		HardwareVertexBufferSharedPtr diffuseVertexBuffer;
		HardwareIndexBufferSharedPtr indexBuffer;

		Ogre::Mesh* m = Ogre::MeshManager::getSingletonPtr()->createManual(
		nombre,ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME).get();

		Ogre::SubMesh* sm = m->createSubMesh();
		sm->useSharedVertices = false;
		sm->vertexData = new VertexData();
		sm->vertexData->vertexStart = 0;
		sm->vertexData->vertexCount = numVertices;

		Ogre::VertexDeclaration* vdecl = sm->vertexData->vertexDeclaration;
		Ogre::VertexBufferBinding* vbind = sm->vertexData->vertexBufferBinding;

		size_t bufferCount = 0;

		vdecl->addElement(bufferCount, 0, VET_FLOAT3, VES_POSITION);

		if(hasNormals)
			vdecl->addElement(++bufferCount, 0, VET_FLOAT3, VES_NORMAL);

		if(hasVertexColor)
			vdecl->addElement(++bufferCount, 0, VET_FLOAT4, VES_DIFFUSE);

		for(int i=0;i<data.texcoords.size();++i)
			vdecl->addElement(++bufferCount, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES,i);

		bufferCount = 0;

		// Positions
		posVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer(
			3*sizeof(float),numVertices,Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);

		vbind->setBinding(bufferCount, posVertexBuffer);

		float* vertices = data.getVertices();
		float* normals = data.getNormals();
		float* diffuse = data.getDiffuse();
		unsigned short* indices = data.getIndices();

		posVertexBuffer->writeData(0,posVertexBuffer->getSizeInBytes(),vertices, true);

		// Normals
		if(hasNormals)
		{
			normVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer(
			3*sizeof(float),numVertices,HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);

			vbind->setBinding(++bufferCount, normVertexBuffer);

			normVertexBuffer->writeData(0,normVertexBuffer->getSizeInBytes(),normals, true);
		}

		if(hasVertexColor)
		{
			diffuseVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer(
			4*sizeof(float),numVertices,HardwareBuffer::HBU_STATIC_WRITE_ONLY);

			vbind->setBinding(++bufferCount, diffuseVertexBuffer);

			diffuseVertexBuffer->writeData(0,diffuseVertexBuffer->getSizeInBytes(), diffuse, true);
		}

		// Texcoords
		for(int i=0;i<data.texcoords.size();++i)
		{
			texcoordsVertexBuffer.push_back(HardwareBufferManager::getSingleton().createVertexBuffer(
			2*sizeof(float),numVertices,HardwareBuffer::HBU_STATIC_WRITE_ONLY));

			vbind->setBinding(++bufferCount, texcoordsVertexBuffer[i]);

			texcoordsVertexBuffer[i]->writeData(0,sizeof(float)*data.texcoords[i].size(),&data.texcoords[i][0], false);
		}

		if(!data.indices.empty())
		{
			// Prepare buffer for indices
			indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(
			HardwareIndexBuffer::IT_16BIT,3*numFaces,HardwareBuffer::HBU_STATIC_WRITE_ONLY, true);

			//unsigned short *faceVertexIndices = (unsigned short*)
			//indexBuffer->lock(0, numFaces*3*2, HardwareBuffer::HBL_DISCARD);

			// Set index buffer for this submesh
			sm->indexData->indexBuffer = indexBuffer;
			sm->indexData->indexStart = 0;
			sm->indexData->indexCount = 3*numFaces;

			indexBuffer->writeData(0,indexBuffer->getSizeInBytes(),indices,true);
		}

		//vdecl->sort();

		m->load();
		m->touch();

		m->_setBounds(AxisAlignedBox(data.bbox[0],data.bbox[1],data.bbox[2],
        data.bbox[3],data.bbox[4],data.bbox[5]), false);

		sm->setMaterialName("Terrain");

		Ogre::Entity* ent = mSceneManager->createEntity(nombre,m->getName());
		Ogre::SceneNode* node = mSceneManager->createSceneNode(nombre);
		node->attachObject(ent);
		ent->setCastShadows(false);
		Mesh* mm = new Mesh(nombre,node,ent);
		mSceneNodes.push_back(mm);
		return mm;
	}
예제 #12
0
void WaterObjectView::createLine()
{
	size_t verticesCount = ((mWaterObject->getPointCount() - 1) * mSegments + 1) * 2;
	size_t verticesSize = verticesCount * 5;
	size_t indicesSize = ((mWaterObject->getPointCount() - 1) * mSegments) * 6;

	verticesCount = mWaterObject->getPointCount() * 2;
	verticesSize = verticesCount * 5;
	indicesSize = (mWaterObject->getPointCount() - 1) * 6;

	Ogre::Real* vertices  = new Ogre::Real[verticesSize];
	Ogre::uint16* indices = new Ogre::uint16[indicesSize];

	unsigned int i, index = 0;

	// Prepare vertices.
	for (i = 0; i < mWaterObject->getPointCount(); ++i)
	{
		const Point3D& point3D = mWaterObject->getPoint(i);

		vertices[index++] = point3D.x - mWaterObject->getWidth() * 0.5f;
		vertices[index++] = point3D.y;
		vertices[index++] = point3D.z + 1.0f;

		vertices[index++] = point3D.x - mWaterObject->getWidth() * 0.5f;;
		vertices[index++] = point3D.z;

		vertices[index++] = point3D.x + mWaterObject->getWidth() * 0.5f;
		vertices[index++] = point3D.y;
		vertices[index++] = point3D.z + 1.0f;

		vertices[index++] = point3D.x + mWaterObject->getWidth() * 0.5f;
		vertices[index++] = point3D.z;
	}

	index = 0;

	// Prepare indices.
	for (i = 0; i < verticesCount - 2; i += 2)
	{
		indices[index++] = (Ogre::uint16)i;
		indices[index++] = (Ogre::uint16)i + 2;
		indices[index++] = (Ogre::uint16)i + 1;

		indices[index++] = (Ogre::uint16)i + 2;
		indices[index++] = (Ogre::uint16)i + 3;
		indices[index++] = (Ogre::uint16)i + 1;
	}

	// Create mesh.
	mMesh = Ogre::MeshManager::getSingleton().createManual(
		Ogre::StringConverter::toString(mID), "General").get();

	// Create one submesh.
	Ogre::SubMesh* sub = mMesh->createSubMesh();

	// Create vertex data structure for 8 vertices shared between submeshes.
	mMesh->sharedVertexData = new Ogre::VertexData();
	mMesh->sharedVertexData->vertexCount = verticesCount;

	// Create declaration (memory format) of vertex data.
	Ogre::VertexDeclaration* decl = mMesh->sharedVertexData->vertexDeclaration;
	size_t offset = 0;

	// 1st buffer
	decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
	offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);

	decl->addElement(0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES);
	offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);

	/// Allocate vertex buffer of the requested number of vertices (vertexCount) 
	/// and bytes per vertex (offset)
	Ogre::HardwareVertexBufferSharedPtr vbuf =
		Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
		offset, mMesh->sharedVertexData->vertexCount,
		Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	/// Upload the vertex data to the card
	vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);

	/// Set vertex buffer binding so buffer 0 is bound to our vertex buffer
	Ogre::VertexBufferBinding* bind =
		mMesh->sharedVertexData->vertexBufferBinding; 
	bind->setBinding(0, vbuf);

	/// Allocate index buffer of the requested number of vertices (ibufCount).
	Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().
		createIndexBuffer(
		Ogre::HardwareIndexBuffer::IT_16BIT, 
		indicesSize, 
		Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	/// Upload the index data to the card.
	ibuf->writeData(0, ibuf->getSizeInBytes(), indices, true);

	/// Set parameters of the submesh.
	sub->useSharedVertices = true;
	sub->indexData->indexBuffer = ibuf;
	sub->indexData->indexCount = indicesSize;
	sub->indexData->indexStart = 0;
	sub->setMaterialName("Ocean2_Cg");

	float xMin = vertices[0];
	float yMin = vertices[1];
	float zMin = vertices[2];

	float xMax = vertices[0];
	float yMax = vertices[1];
	float zMax = vertices[2];

	for (i = 0; i < verticesSize; i += 5)
	{
		if (vertices[i    ] < xMin) xMin = vertices[i    ]; else
		if (vertices[i    ] > xMax) xMax = vertices[i    ];

		if (vertices[i + 1] < yMin) yMin = vertices[i + 1]; else
		if (vertices[i + 1] > yMax) yMax = vertices[i + 1];

		if (vertices[i + 2] < zMin) zMin = vertices[i + 2]; else
		if (vertices[i + 2] > zMax) zMax = vertices[i + 2];
	}

	/// Set bounding information (for culling).
	mMesh->_setBounds(Ogre::AxisAlignedBox(xMin, yMin, zMin, xMax, yMax, zMax));
	mMesh->_setBoundingSphereRadius(1.0f);

	/// Notify Mesh object that it has been loaded.
	mMesh->load();

	delete [] vertices;
	delete [] indices;
}
예제 #13
0
bool Terrain::createTerrain()
{

	if(mMainViewport == NULL) 
		mMainViewport = Core::getSingleton().mCamera->getViewport();
	Ogre::CompositorManager::getSingleton().addCompositor(mMainViewport, "DemoCompositor");
	Ogre::CompositorManager::getSingleton().setCompositorEnabled(mMainViewport, "DemoCompositor", true);

	mMapData = MapDataManager::getSingletonPtr();
	DataLibrary* datalib = DataLibrary::getSingletonPtr();
	int terrainszie = mMapData->getMapSize() + 2 * MAPBOLDER + 1;

	Core::getSingleton().mSceneMgr->setSkyBox(true, "SkyBox",200);

	Ogre::GpuSharedParametersPtr sharedparams = Ogre::GpuProgramManager::getSingleton().getSharedParameters("TestSharedParamsName");
	float border = mMapData->getMapSize() * 12.0f;
	sharedparams->setNamedConstant("border", border);

	//创建灯光
	Core::getSingleton().mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f));
	mLight = Core::getSingleton().mSceneMgr->createLight("TerrainLight");
	mLight->setType(Ogre::Light::LT_DIRECTIONAL);
	mLight->setPosition(-500.0f,500.0f, 500.0f);
	mLight->setDirection(1.0f, -1.0f, -1.0f);
	mLight->setDiffuseColour(Ogre::ColourValue(0.5f, 0.5f,0.5f));
	mLight->setSpecularColour(Ogre::ColourValue(0.8f, 0.8f,0.8f));

	//设置深度图投影
	Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton().getByName("shadowdepthmap");
	if(tex.isNull())
		tex = Ogre::TextureManager::getSingleton().createManual("shadowdepthmap",
			Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, 2048, 2048, 0, Ogre::PF_FLOAT16_R, Ogre::TU_RENDERTARGET);
	mShadowDepthMapTarget = tex->getBuffer()->getRenderTarget();
	Ogre::Viewport* vp = mShadowDepthMapTarget->addViewport(CameraContral::getSingleton().getShadowMapCamera());
	vp->setSkiesEnabled(false);
	vp->setOverlaysEnabled(false);
	vp->setVisibilityMask(VISMASK_OPAQUE);
	vp->setMaterialScheme("WriteDepthMap");
	vp->setBackgroundColour(Ogre::ColourValue(1.0f,1.0f,1.0f));
	mShadowDepthMapTarget->addListener(this);
	//弱爆了……
	Ogre::MaterialPtr mat;
	mat = Ogre::MaterialManager::getSingleton().getByName("TerrainTile");
	Ogre::AliasTextureNamePairList texAliasList;
	std::string texname;
	datalib->getData("GameData/BattleData/MapData/Ground/G0Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse",texname));
	datalib->getData("GameData/BattleData/MapData/Ground/G1Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse1",texname));
	datalib->getData("GameData/BattleData/MapData/Ground/G2Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse2",texname));
	datalib->getData("GameData/BattleData/MapData/Ground/G3Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse3",texname));
	mat->applyTextureAliases(texAliasList);
	texAliasList.clear();

	mat = Ogre::MaterialManager::getSingleton().getByName("CliffMat1");
	datalib->getData("GameData/BattleData/MapData/Ground/G0Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse",texname));
	texAliasList.insert(std::make_pair("Diffuse1","Cliff.tga"));
	mat->applyTextureAliases(texAliasList);
	texAliasList.clear();

	mat = Ogre::MaterialManager::getSingleton().getByName("CliffMat2");
	datalib->getData("GameData/BattleData/MapData/Ground/G1Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse",texname));
	texAliasList.insert(std::make_pair("Diffuse1","Cliff.tga"));
	mat->applyTextureAliases(texAliasList);
	texAliasList.clear();

	mat = Ogre::MaterialManager::getSingleton().getByName("CliffMat3");
	datalib->getData("GameData/BattleData/MapData/Ground/G2Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse",texname));
	texAliasList.insert(std::make_pair("Diffuse1","Cliff.tga"));
	mat->applyTextureAliases(texAliasList);
	texAliasList.clear();

	mat = Ogre::MaterialManager::getSingleton().getByName("CliffMat4");
	datalib->getData("GameData/BattleData/MapData/Ground/G3Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse",texname));
	texAliasList.insert(std::make_pair("Diffuse1","Cliff.tga"));
	mat->applyTextureAliases(texAliasList);
	texAliasList.clear();

	mat = Ogre::MaterialManager::getSingleton().getByName("BankMat1");
	datalib->getData("GameData/BattleData/MapData/Ground/G0Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse",texname));
	texAliasList.insert(std::make_pair("Diffuse1","Cliff.tga"));
	mat->applyTextureAliases(texAliasList);
	texAliasList.clear();

	mat = Ogre::MaterialManager::getSingleton().getByName("BankMat2");
	datalib->getData("GameData/BattleData/MapData/Ground/G1Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse",texname));
	texAliasList.insert(std::make_pair("Diffuse1","Cliff.tga"));
	mat->applyTextureAliases(texAliasList);
	texAliasList.clear();

	mat = Ogre::MaterialManager::getSingleton().getByName("BankMat3");
	datalib->getData("GameData/BattleData/MapData/Ground/G2Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse",texname));
	texAliasList.insert(std::make_pair("Diffuse1","Cliff.tga"));
	mat->applyTextureAliases(texAliasList);
	texAliasList.clear();

	mat = Ogre::MaterialManager::getSingleton().getByName("BankMat4");
	datalib->getData("GameData/BattleData/MapData/Ground/G3Tex",texname);
	texAliasList.insert(std::make_pair("Diffuse",texname));
	texAliasList.insert(std::make_pair("Diffuse1","Cliff.tga"));
	mat->applyTextureAliases(texAliasList);
	texAliasList.clear();

	//创建地面Mesh
	mTerrainNode = Core::getSingleton().mSceneMgr->getRootSceneNode()->createChildSceneNode("TerrainNode");

	int numVertices = terrainszie * terrainszie * VERTEX_QUAD;
	int numIndex = terrainszie * terrainszie * VERTEX_PREQUAD;
	Ogre::MeshPtr mTerrainMesh = Ogre::MeshManager::getSingleton().createManual("TerrianMesh",
		Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
	Ogre::SubMesh* subMesh  = mTerrainMesh->createSubMesh();
	subMesh->useSharedVertices=false;
	subMesh->setMaterialName("TerrainTile");

	// 创建顶点数据结构
	subMesh->vertexData = new Ogre::VertexData();
	subMesh->vertexData->vertexStart = 0;
	subMesh->vertexData->vertexCount = numVertices;

	//顶点声明与缓冲区绑定
	Ogre::VertexDeclaration* vdecl = subMesh->vertexData->vertexDeclaration;
	Ogre::VertexBufferBinding* vbind = subMesh->vertexData->vertexBufferBinding;

	//设置顶点数据结构
	size_t offsetUV = 0;
	vdecl->addElement(VERTEX_POS_BINDING, 0, Ogre::VET_FLOAT3,Ogre::VES_POSITION);//向顶点添加一个位置元素
	vdecl->addElement(VERTEX_NOM_BINDING, 0, Ogre::VET_FLOAT3,Ogre::VES_NORMAL);
	for(int i = 0 ; i < TEXTURE_COUNT ; i ++)
	{
		offsetUV += vdecl->addElement (VERTEX_UV_BINDING, offsetUV, Ogre::VET_FLOAT2,  Ogre::VES_TEXTURE_COORDINATES , i).getSize();
	}

	// 创建世界坐标顶点缓冲区
	Ogre::HardwareVertexBufferSharedPtr vbufPos =
		Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
		vdecl->getVertexSize(VERTEX_POS_BINDING),
		numVertices,
		Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
	vbind->setBinding(VERTEX_POS_BINDING, vbufPos);

	Ogre::HardwareVertexBufferSharedPtr vbufNOM =
		Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
		vdecl->getVertexSize(VERTEX_NOM_BINDING),
		numVertices,
		Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
	vbind->setBinding(VERTEX_NOM_BINDING, vbufNOM);

	// 创建纹理坐标顶点缓冲区
	Ogre::HardwareVertexBufferSharedPtr vbufUV =
		Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
		vdecl->getVertexSize(VERTEX_UV_BINDING),
		numVertices,
		Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
	vbind->setBinding(VERTEX_UV_BINDING, vbufUV);

	// 创建索引缓冲区
	Ogre::HardwareIndexBufferSharedPtr indexBuffer =
		Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
		Ogre::HardwareIndexBuffer::IT_16BIT ,
		numIndex,
		Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	//创建地形
	float* pBufferPos = (float*)vbufPos->lock(Ogre::HardwareBuffer::HBL_DISCARD);
	float* pBufferUV = (float*)vbufUV->lock(Ogre::HardwareBuffer::HBL_DISCARD);
	float* pBufferNom = (float*)vbufNOM->lock(Ogre::HardwareBuffer::HBL_DISCARD);

	float startpos = - terrainszie * TILESIZE / 2;
	for(int y = 0 ; y < terrainszie; y ++)
	{
		for(int x = 0 ; x < terrainszie; x ++)
		{
			createTile(x, y, startpos + x * TILESIZE, startpos + y * TILESIZE, pBufferPos, pBufferUV, pBufferNom);
			pBufferPos += 3 * VERTEX_QUAD ;
			pBufferNom += 3 * VERTEX_QUAD ;
			pBufferUV += 2 * VERTEX_QUAD * 4;
		}
	}

	vbufNOM->unlock();
	vbufUV->unlock();
	vbufPos->unlock();

	//写入索引信息
	// 锁定索引缓冲区
	Ogre::ushort* pIdx = (Ogre::ushort*)indexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
	for(int y = 0 ; y < terrainszie ; y ++)
	{
		for(int x = 0 ; x < terrainszie ; x ++)
		{
			Ogre::ushort iIndexTopLeft = (x + y * terrainszie) * VERTEX_QUAD;
			Ogre::ushort iIndexTopRight = iIndexTopLeft + 1;
			Ogre::ushort iIndexBottomLeft = iIndexTopLeft + 2;
			Ogre::ushort iIndexBottomRight = iIndexTopLeft + 3;
			*pIdx++ = iIndexBottomLeft;
			*pIdx++ = iIndexBottomRight;
			*pIdx++ = iIndexTopLeft;

			*pIdx++ = iIndexBottomRight;
			*pIdx++ = iIndexTopRight;
			*pIdx++ = iIndexTopLeft;
		}
	}
	indexBuffer->unlock();
	//设置模型的的索引数据
	subMesh->indexData->indexBuffer = indexBuffer;
	subMesh->indexData->indexStart = 0;
	subMesh->indexData->indexCount =numIndex;

	Ogre::AxisAlignedBox meshBounds(startpos,0,startpos,
		-startpos,5,-startpos);
	mTerrainMesh->_setBounds(meshBounds);

	mTerrainEntity = Core::getSingleton().mSceneMgr->createEntity("TerrianMesh");
	mTerrainNode->attachObject(mTerrainEntity);
	mTerrainEntity->setQueryFlags(QUERYMASK_TERRAIN);
	mTerrainNode->setPosition(0,0,0);

	//创建水面
	tex = Ogre::TextureManager::getSingleton().getByName("reflection");
	if(tex.isNull())
		tex = Ogre::TextureManager::getSingleton().createManual("reflection",
			Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, 512, 512, 0, Ogre::PF_R8G8B8, Ogre::TU_RENDERTARGET);
	mReflectionTarget = tex->getBuffer()->getRenderTarget();
	mReflectionTarget->addViewport(Core::getSingleton().mCamera)->setOverlaysEnabled(false);
	mReflectionTarget->addListener(this);
// 	mat = Ogre::MaterialManager::getSingleton().getByName("ReflectionWater");
// 	tech = mat->getTechnique(0);
// 	pass = tech->getPass(0);
// 	tu =  pass->getTextureUnitState(1);
// 	tu->setTextureName(tex->getName());

	mWaterPlane = Ogre::Plane(Ogre::Vector3::UNIT_Y, WATERHEIGHT);

	mWaterNode = Core::getSingleton().mSceneMgr->getRootSceneNode()->createChildSceneNode("WaterNode");
	mWaterObject = Core::getSingleton().mSceneMgr->createManualObject("WaterObject");

	mWaterObject->begin("DemoWater",Ogre::RenderOperation::OT_TRIANGLE_LIST);
	startpos += TILESIZE/2;
	for(int y = 0; y < terrainszie; y++)
		for(int x = 0; x < terrainszie; x++)
		{
			if(mMapData->getTerrainType(x -MAPBOLDER, y -MAPBOLDER ) == Water)
			{
				mWaterObject->position(startpos + x * TILESIZE, 0.0f, startpos + y * TILESIZE);
				mWaterObject->colour(1.0f,1.0f,1.0f);
				mWaterObject->normal(0.0f,1.0f,0.0f);
				mWaterObject->textureCoord(0.0f,0.0f);
				mWaterObject->position(startpos + (x+1) * TILESIZE, 0.0f, startpos + (y+1) * TILESIZE);
				mWaterObject->colour(1.0f,1.0f,1.0f);
				mWaterObject->normal(0.0f,1.0f,0.0f);
				mWaterObject->textureCoord(1.0f,1.0f);
				mWaterObject->position(startpos + (x+1) * TILESIZE, 0.0f, startpos + y * TILESIZE);
				mWaterObject->colour(1.0f,1.0f,1.0f);
				mWaterObject->normal(0.0f,1.0f,0.0f);
				mWaterObject->textureCoord(1.0f,0.0f);
				mWaterObject->position(startpos + (x+1) * TILESIZE, 0.0f, startpos + (y+1) * TILESIZE);
				mWaterObject->colour(1.0f,1.0f,1.0f);
				mWaterObject->normal(0.0f,1.0f,0.0f);
				mWaterObject->textureCoord(1.0f,1.0f);
				mWaterObject->position(startpos + x * TILESIZE, 0.0f, startpos + y * TILESIZE);
				mWaterObject->colour(1.0f,1.0f,1.0f);
				mWaterObject->normal(0.0f,1.0f,0.0f);
				mWaterObject->textureCoord(0.0f,0.0f);
				mWaterObject->position(startpos + x * TILESIZE, 0.0f, startpos + (y+1) * TILESIZE);
				mWaterObject->colour(1.0f,1.0f,1.0f);
				mWaterObject->normal(0.0f,1.0f,0.0f);
				mWaterObject->textureCoord(0.0f,1.0f);
			}
		}
	mWaterObject->end();

	mWaterNode->attachObject(mWaterObject);
	mWaterNode->setPosition(0,WATERHEIGHT,0);


	//设置摄像机移动范围
	
	float minx = 0.0f;// = ( - (float)(terrainszie - 2 * MAPBOLDER) / 2.0f - 1.0f) * TILESIZE ;
	getWorldCoords(0,0,minx,minx);
	minx -= TILESIZE/2;
	CameraContral::getSingleton().setMoveRect(minx, minx);
	CameraContral::getSingleton().resetCamera();

	//深度投影测试
// 	Ogre::MeshManager::getSingleton().createPlane("testplane", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
// 		mWaterPlane, 64, 64, 1, 1, true, 1, 1, 1, Ogre::Vector3::UNIT_Z);
// 	Ogre::Entity* testent = Core::getSingleton().mSceneMgr->createEntity("testplaneent", "testplane");
// 	testent->setMaterialName("DepthTest");
// 	Ogre::SceneNode* testnode = Core::getSingleton().mSceneMgr->getRootSceneNode()->createChildSceneNode();
// 	testnode->attachObject(testent);
// 	testnode->setPosition(0.0f,10.0f,0.0f);
	return true;
}