Example #1
0
void OgreSample8App::setupModes()
{
    StringVector matNames;

    matNames.push_back("Examples/BumpMapping/MultiLight");
    matNames.push_back("Examples/BumpMapping/MultiLightSpecular");
    matNames.push_back("Examples/OffsetMapping/Specular");
    matNames.push_back("Examples/ShowUV");
    matNames.push_back("Examples/ShowNormals");
    matNames.push_back("Examples/ShowTangents");

    matNames.push_back("RTSS/NormalMapping_SinglePass");
    matNames.push_back("RTSS/NormalMapping_MultiPass");

    mPossibilities["ogrehead.mesh"] = matNames;
    mPossibilities["knot.mesh"] = matNames;

    matNames.clear();
    matNames.push_back("Examples/Athene/NormalMapped");
    matNames.push_back("Examples/Athene/NormalMappedSpecular");
    matNames.push_back("Examples/Athene/NormalMappedSpecular");
    matNames.push_back("Examples/ShowUV");
    matNames.push_back("Examples/ShowNormals");
    matNames.push_back("Examples/ShowTangents");
    matNames.push_back("RTSS/Athene/NormalMapping_SinglePass");
    matNames.push_back("RTSS/Athene/NormalMapping_MultiPass");

    mPossibilities["athene.mesh"] = matNames;

    for (std::map<Ogre::String,Ogre::StringVector>::iterator it = mPossibilities.begin(); it != mPossibilities.end(); it++)
    {
        Ogre::MeshPtr mesh = MeshManager::getSingleton().load(it->first,ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);

        unsigned short src,dest;
        if (!mesh->suggestTangentVectorBuildParams(VES_TANGENT,src,dest))
        {
            mesh->buildTangentVectors(VES_TANGENT,src,dest);
        }
        Entity* ent = mSceneMgr->createEntity(mesh->getName(),mesh->getName());
        ent->setMaterialName(it->second.front());
    }

    mMeshMenu->addItem(new CEGUI::ListboxTextItem("athene.mesh"));
    mMeshMenu->addItem(new CEGUI::ListboxTextItem("ogrehead.mesh"));
    mMeshMenu->addItem(new CEGUI::ListboxTextItem("knot.mesh"));
    mMeshMenu->setItemSelectState(size_t(0),true);

    const char * a = mMeshMenu->getSelectedItem()->getText().c_str();
    Ogre::StringVector::iterator it = mPossibilities[a].begin();
    Ogre::StringVector::iterator itEnd = mPossibilities[mMeshMenu->getSelectedItem()->getText().c_str()].end();

    for (; it != itEnd; it++)
    {
        mMaterialMenu->addItem(new ListboxTextItem(it->c_str()));
    }
    mMaterialMenu->setItemSelectState(size_t(0),true);
    mSceneMgr->getEntity(mMeshMenu->getSelectedItem()->getText().c_str())->setMaterialName(mMaterialMenu->getSelectedItem()->getText().c_str());
}
Example #2
0
NxEntity * NxNode::CreateNxBox( const std::string & BoxName, const Nx::Vector3 & Dimensions, const Nx::Vector3 & NumSegments  )
{
	Ogre::MeshPtr NxMesh = NxMeshManager::getSingleton().CreateBox( BoxName, Dimensions, NumSegments );

	unsigned short src, dest;
	if (!NxMesh->suggestTangentVectorBuildParams(VES_TANGENT, src, dest)){
		NxMesh->buildTangentVectors(VES_TANGENT, src, dest);		
	}

	NxEntity * c = new NxEntity( this, BoxName );
	mNxEntities.insert( NxEntityList::value_type( BoxName, c ) );
	return c;
}
Example #3
0
NxEntity * NxNode::CreateNxCone( const std::string & ConeName, float Radius, float Height )
{
	Ogre::MeshPtr NxMesh = NxMeshManager::getSingleton().CreateCone( ConeName, Radius, Height  );

	unsigned short src, dest;
	if (!NxMesh->suggestTangentVectorBuildParams(VES_TANGENT, src, dest)){
		NxMesh->buildTangentVectors(VES_TANGENT, src, dest);		
	}

	NxEntity * c = new NxEntity( this, ConeName );
	mNxEntities.insert( NxEntityList::value_type( ConeName, c ) );
	return c;
}
Example #4
0
NxEntity * NxNode::CreateNxCapsule( const std::string & CapsuleName, const Nx::Vector2 & Dimensions )
{
	Ogre::MeshPtr NxMesh = NxMeshManager::getSingleton().CreateCapsule( CapsuleName, Dimensions.x, Dimensions.y-(Dimensions.x*2) );
	//Ogre::MeshPtr NxMesh = NxMeshFactory::getSingleton().CreateCapsule( CapsuleName, Dimensions.x, Dimensions.y, mScene->GetNxSceneManager() );

	unsigned short src, dest;
	if (!NxMesh->suggestTangentVectorBuildParams(VES_TANGENT, src, dest)){
		NxMesh->buildTangentVectors(VES_TANGENT, src, dest);		
	}

	NxEntity * c = new NxEntity( this, CapsuleName );
	mNxEntities.insert( NxEntityList::value_type( CapsuleName, c ) );
	return c;
}
Example #5
0
NxEntity * NxNode::CreateNxPlane( const std::string & PlaneName, const Nx::Vector2 & Dimensions, const Nx::Vector2 & NumSegments )
{
	Ogre::MeshPtr NxMesh = NxMeshManager::getSingleton().CreatePlane( PlaneName, Dimensions, NumSegments );	

	/*AxisAlignedBox boxer;
	boxer.setInfinite();
	NxMesh->_setBounds(boxer);*/

	unsigned short src, dest;
	if (!NxMesh->suggestTangentVectorBuildParams(VES_TANGENT, src, dest)){
		NxMesh->buildTangentVectors(VES_TANGENT, src, dest);		
	}

	NxEntity * c = new NxEntity( this, PlaneName );
	mNxEntities.insert( NxEntityList::value_type( PlaneName, c ) );
	return c;
}
Example #6
0
NxEntity * NxNode::CreateNxSphere( const std::string & SphereName, float Radius, unsigned int numRings, unsigned int numSegments , float uTile, float vTile )
{
	Ogre::MeshPtr NxMesh = NxMeshManager::getSingleton().CreateSphere( SphereName, Radius, numRings, numSegments, uTile, vTile );

	unsigned short src, dest;
	if (!NxMesh->suggestTangentVectorBuildParams(VES_TANGENT, src, dest)){
		NxMesh->buildTangentVectors(VES_TANGENT, src, dest);		
	}

	/*
	Ogre::Mesh::LodValueList lodDList;
	lodDList.push_back(4.0);
	lodDList.push_back(8.0);
	//lodDList.push_back(128.0);
	Ogre::ProgressiveMesh::generateLodLevels( NxMesh.getPointer(),lodDList, Ogre::ProgressiveMesh::VRQ_PROPORTIONAL, 0.5);
	*/



	NxEntity * c = new NxEntity( this, SphereName );
	mNxEntities.insert( NxEntityList::value_type( SphereName, c ) );
	return c;
}
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);
	}
}