Exemple #1
0
bool AssetsManager::exportMesh(Ogre::MeshPtr mesh, const std::string& filePath)
{
	if (filePath != "") {
		Ogre::MeshSerializer serializer;
		try {
			std::string dirname(filePath);
			size_t end = dirname.find_last_of("/\\");
			if (end != std::string::npos) {
				dirname = dirname.substr(0, end);
			}
			oslink::directory osdir(dirname);
			if (!osdir.isExisting()) {
				oslink::directory::mkdir(dirname.c_str());
			}
			serializer.exportMesh(mesh.get(), filePath);
			S_LOG_INFO("Exported mesh " << filePath);
		} catch (const Ogre::Exception& ex) {
			S_LOG_FAILURE("Error when exporting mesh " << mesh->getName() << "to path " << filePath <<"." << ex);
			return false;
		}
		return true;
	}
	return false;
}
// Call for an unload when list is already locked
void OLMeshTracker::MakeUnLoadedLocked(Ogre::String meshName, Ogre::String stringParam, Ogre::Entity* entityParam) {
	// see if in the loading list. Remove if  there.
	GenericQm* loadEntry = m_meshesToLoad->Find(meshName);
	if (loadEntry != NULL) {
		loadEntry->Abort();
		m_meshesToLoad->Remove(meshName);
	}
	// see if in the serialize list. Mark for unload if it's there
	GenericQm* serialEntry = m_meshesToSerialize->Find(meshName);
	if (serialEntry != NULL) {
		serialEntry->stringParam = "unload";
	}
	else {
		Ogre::MeshPtr meshP = Ogre::MeshManager::getSingleton().getByName(meshName);
		if (!meshP.isNull()) {
			if (meshP.useCount() == 1) {
				meshP->unload();
			}
			else {
				LG::Log("OLMeshTracker::MakeUnLoaded: Didn't unload mesh because count = %d", meshP.useCount());
			}
		}
	}
}
	//---------------------------------------------------------------------
	void MeshElement::setMaterialName(const Ogre::String &name)
	{
		mMaterialName = name;

		if (mEntity)
		{
			// if this is "none",we will use the origin material of the mesh
			if (mMaterialName == "none")
			{

				if ( false == mMeshName.empty() )
				{
					Ogre::MeshPtr currentMesh = Ogre::MeshManager::getSingleton().getByName(mMeshName);

					for ( unsigned short i=0; i<currentMesh->getNumSubMeshes(); ++i )
					{
						mEntity->getSubEntity(i)->setMaterialName( currentMesh->getSubMesh(i)->getMaterialName() );
					}
				}
			}		
			else
				mEntity->setMaterialName(mMaterialName);
		}		
	}
Exemple #4
0
void ESKOgre::createFakeEntity(Ogre::SceneManager *mSceneMgr) {
	Ogre::MeshPtr msh = Ogre::MeshManager::getSingleton().createManual(name + "_skeleton", XENOVIEWER_RESOURCE_GROUP);
	msh->setSkeletonName(name);

	Ogre::SubMesh* sub = msh->createSubMesh();
	const size_t nVertices = 3;
	const size_t nVertCount = 3;
	const size_t vbufCount = nVertCount*nVertices;
	float *vertices = (float *)malloc(sizeof(float)*vbufCount);

	for (size_t i = 0; i < nVertices; i++) {
		vertices[i*nVertCount] = 0.0;
		vertices[i*nVertCount + 1] = 0.0;
		vertices[i*nVertCount + 2] = 0.0;
	}

	const size_t ibufCount = 3;
	unsigned short *faces = (unsigned short *)malloc(sizeof(unsigned short) * ibufCount);

	for (size_t i = 0; i < ibufCount; i++) {
		faces[i] = i;
	}

	msh->sharedVertexData = new Ogre::VertexData();
	msh->sharedVertexData->vertexCount = nVertices;

	Ogre::VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration;
	size_t offset = 0;

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

	Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(offset, msh->sharedVertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
	vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);
	Ogre::VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding;
	bind->setBinding(0, vbuf);
	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;

	msh->_setBounds(Ogre::AxisAlignedBox(-100, -100, -100, 100, 100, 100));
	msh->_setBoundingSphereRadius(100);
	msh->load();

	free(faces);
	free(vertices);

	skeleton_entity = mSceneMgr->createEntity(name + "_skeleton");
	skeleton_node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
	skeleton_node->attachObject(skeleton_entity);
	skeleton_node->setVisible(false);
}
bool MilkshapePlugin::locateSkeleton(Ogre::MeshPtr& mesh)
{
    //
    // choose filename
    //
    OPENFILENAME ofn;
    memset (&ofn, 0, sizeof (OPENFILENAME));

    char szFile[MS_MAX_PATH];
    char szFileTitle[MS_MAX_PATH];
    char szDefExt[32] = "skeleton";
    char szFilter[128] = "OGRE .skeleton Files (*.skeleton)\0*.skeleton\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_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
    ofn.lpstrTitle = "Locate OGRE Skeleton (since you're not exporting it)";

    if (!::GetOpenFileName (&ofn))
        return false;

    // Strip off the path
    Ogre::String skelName = szFile;
    size_t lastSlash = skelName.find_last_of("\\");
    skelName = skelName.substr(lastSlash+1);

    Ogre::String msg = "Linking mesh to skeleton file '" + skelName + "'";
    Ogre::LogManager::getSingleton().logMessage(msg);

    // Create a dummy skeleton for Mesh to link to (saves it trying to load it)
    Ogre::SkeletonPtr pSkel = Ogre::SkeletonManager::getSingleton().create(skelName, 
        Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
    Ogre::LogManager::getSingleton().logMessage("Dummy Skeleton object created for link.");

    mesh->_notifySkeleton(pSkel);

    return true;

}
Exemple #6
0
std::string AssetsManager::resolveFilePathForMesh(Ogre::MeshPtr meshPtr)
{
	Ogre::ResourceGroupManager& manager = Ogre::ResourceGroupManager::getSingleton();
	const std::multimap<std::string, std::string>& locations = EmberOgre::getSingleton().getResourceLocations();

	for (std::multimap<std::string, std::string>::const_iterator I = locations.begin(); I != locations.end(); ++I) {
		std::string group = I->first;
		std::string fileName = meshPtr->getName();
		Ogre::FileInfoListPtr files = manager.findResourceFileInfo(group, fileName, false);
		for (Ogre::FileInfoList::const_iterator J = files->begin(); J != files->end(); ++J) {
			if (J->filename == fileName) {
				return I->second + J->filename;
			}
		}
	}
	return "";

}
        Indicator(const ObjectPtr &object, SceneManipulator *sceneManipulator)
			: mProxy(NULL)
        {
            assert(sceneManipulator);

			mUserAny = Ogre::Any();

			mProxy = new ObjectProxy(object);

            // 根据光源位置来定节点位置
            Ogre::Vector3 pos = VariantCast<Ogre::Vector3>(object->getProperty("position"));
            mIndicatorSceneNode = sceneManipulator->getIndicatorRootSceneNode()->createChildSceneNode(pos);

            Real radius = 5;
            int rings = 16;
            int segments = 16;

            Ogre::MeshPtr sphereMesh = createCommonSphere(radius, rings, segments);
            Ogre::MaterialPtr material = createPureColourMaterial(
                Ogre::ColourValue(1, 0, 0, 0.75)   );

            mIndicatorEntity = sceneManipulator->getSceneManager()->createEntity(mIndicatorSceneNode->getName(), sphereMesh->getName());
			//david-<<
            //mIndicatorEntity->setNormaliseNormals(true);
			//david->>
            mIndicatorEntity->setMaterialName(material->getName());
            setUserObject(mProxy);

            mIndicatorSceneNode->attachObject(mIndicatorEntity);

            // 选择时不考虑粒子系统的包围盒,用的是指示器的包围盒
            ParticleSystemObject *particleSystemObject = static_cast<ParticleSystemObject *> (object.get());
			Ogre::ParticleSystem *system = particleSystemObject->getParticleSystem();

            if (system)
				system->setQueryFlags(0);

            // 根据光源类型来挂接模型
            showIndicator(false);
        }
    void MergeMesh::addMesh( Ogre::MeshPtr mesh )
	{    
        if( mesh->getSkeleton().isNull() )
        {
			log( "Skipped: " + mesh->getName() + " has no skeleton" );
		    return;
        }

        if( m_BaseSkeleton.isNull() )
        {
            m_BaseSkeleton = mesh->getSkeleton();                    
            log( "Set: base skeleton (" + m_BaseSkeleton->getName()+")" );
        }

        if( mesh->getSkeleton() != m_BaseSkeleton )
        {
	        log( "Skipped: " + mesh->getName() + " has other skeleton ("+ mesh->getSkeleton()->getName() +")" );
            return;
        }

        m_Meshes.push_back( mesh );
	}
// ===============================================================================
// Someone wants to delete this mesh. Check to see if it's a shared mesh and decide if we
// should actually delete it or not.
void OLMeshTracker::DeleteMesh(Ogre::MeshPtr mesh) {
	Ogre::MeshManager::getSingleton().remove(mesh->getName());
}
Ogre::SkeletonPtr MilkshapePlugin::doExportSkeleton(msModel* pModel, Ogre::MeshPtr& mesh)
{
    Ogre::LogManager &logMgr = Ogre::LogManager::getSingleton();
    Ogre::String msg;

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

    char szFile[MS_MAX_PATH];
    char szFileTitle[MS_MAX_PATH];
    char szDefExt[32] = "skeleton";
    char szFilter[128] = "OGRE .skeleton Files (*.skeleton)\0*.skeleton\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 Skeleton";

    if (!::GetSaveFileName (&ofn))
        return Ogre::SkeletonPtr();

    // Strip off the path
    Ogre::String skelName = szFile;
    size_t lastSlash = skelName.find_last_of("\\");
    skelName = skelName.substr(lastSlash+1);

    // Set up
    logMgr.logMessage("Trying to create Skeleton object");
    Ogre::SkeletonPtr ogreskel = Ogre::SkeletonManager::getSingleton().create(skelName, 
        Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
    logMgr.logMessage("Skeleton object created");

    // Complete the details

    // Do the bones
    int numBones = msModel_GetBoneCount(pModel);
	msg = "Number of bones: " + Ogre::StringConverter::toString(numBones);
    logMgr.logMessage(msg);

    int i;
    // Create all the bones in turn
    for (i = 0; i < numBones; ++i)
    {
        msBone* bone = msModel_GetBoneAt(pModel, i);
        Ogre::Bone* ogrebone = ogreskel->createBone(bone->szName);

        msVec3 msBonePos, msBoneRot;
        msBone_GetPosition(bone, msBonePos);
        msBone_GetRotation(bone, msBoneRot);

        Ogre::Vector3 bonePos(msBonePos[0], msBonePos[1], msBonePos[2]);
        ogrebone->setPosition(bonePos);
        // Hmm, Milkshape has chosen a Euler angle representation of orientation which is not smart
        // Rotation Matrix or Quaternion would have been the smarter choice
        // Might we have Gimbal lock here? What order are these 3 angles supposed to be applied?
        // Grr, we'll try our best anyway...
        Ogre::Quaternion qx, qy, qz, qfinal;
        qx.FromAngleAxis(Ogre::Radian(msBoneRot[0]), Ogre::Vector3::UNIT_X);
        qy.FromAngleAxis(Ogre::Radian(msBoneRot[1]), Ogre::Vector3::UNIT_Y);
        qz.FromAngleAxis(Ogre::Radian(msBoneRot[2]), Ogre::Vector3::UNIT_Z);

        // Assume rotate by x then y then z
        qfinal = qz * qy * qx;
        ogrebone->setOrientation(qfinal);

		Ogre::LogManager::getSingleton().stream()
			<< "Bone #" << i << ": " <<
            "Name='" << bone->szName << "' " <<
            "Position: " << bonePos << " " <<
            "Ms3d Rotation: {" << msBoneRot[0] << ", " << msBoneRot[1] << ", " << msBoneRot[2] << "} " <<
            "Orientation: " << qfinal;


    }
    // Now we've created all the bones, link them up
    logMgr.logMessage("Establishing bone hierarchy..");
    for (i = 0; i < numBones; ++i)
    {
        msBone* bone = msModel_GetBoneAt(pModel, i);

        if (strlen(bone->szParentName) == 0)
        {
            // Root bone
            msg = "Root bone detected: Name='" + Ogre::String(bone->szName) + "' Index=" 
				+ Ogre::StringConverter::toString(i);
            logMgr.logMessage(msg);
        }
        else
        {
            Ogre::Bone* ogrechild = ogreskel->getBone(bone->szName);
            Ogre::Bone* ogreparent = ogreskel->getBone(bone->szParentName);

            if (ogrechild == 0)
            {
                msg = "Error: could not locate child bone '" +
					Ogre::String(bone->szName) + "'";
                logMgr.logMessage(msg);
                continue;
            }
            if (ogreparent == 0)
            {
                msg = "Error: could not locate parent bone '"
					+ Ogre::String(bone->szParentName) + "'";
                logMgr.logMessage(msg);
                continue;
            }
            // Make child
            ogreparent->addChild(ogrechild);
        }


    }
    logMgr.logMessage("Bone hierarchy established.");

    // Create the Animation(s)
    doExportAnimations(pModel, ogreskel);



    // Create skeleton serializer & export
    Ogre::SkeletonSerializer serializer;
    msg = "Exporting skeleton to " + Ogre::String(szFile);
    logMgr.logMessage(msg);
    serializer.exportSkeleton(ogreskel.getPointer(), szFile);
    logMgr.logMessage("Skeleton exported");


    msg = "Linking mesh to skeleton file '" + skelName + "'";
    Ogre::LogManager::getSingleton().logMessage(msg);

    mesh->_notifySkeleton(ogreskel);

    return ogreskel;

}
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);
	}
}
void CSaveSceneView::SceneNodeExplore(Ogre::SceneNode *SceneNode)
{
	Ogre::Entity *Entity = NULL;
	Ogre::Camera *Camera = NULL;
	Ogre::Light *Light = NULL;
	Ogre::ParticleSystem *ParticleSystem = NULL;
	Ogre::ManualObject *ManualObject = NULL;
	Ogre::BillboardSet *BillboardSet = NULL;

	xmlTextWriterStartElement(m_XmlWriter, BAD_CAST "SceneNode");
	
	Ogre::String SceneNodeName = SceneNode->getName();

	xmlTextWriterWriteAttribute(m_XmlWriter, 
										BAD_CAST "SceneNodeName",
										BAD_CAST SceneNodeName.c_str());

	Ogre::SceneNode::ObjectIterator obji = SceneNode->getAttachedObjectIterator();

	while (obji.hasMoreElements())
	{
		Ogre::MovableObject* mobj = obji.getNext();
	
		Ogre::String Type = mobj->getMovableType();
	
		if (Type == "Entity")
		{
			Entity = (Ogre::Entity *)(mobj);
			Ogre::String EntityName = Entity->getName();
			xmlTextWriterStartElement(m_XmlWriter, BAD_CAST "Entity");
			xmlTextWriterWriteAttribute(m_XmlWriter, 
										BAD_CAST "EntityName",
										BAD_CAST EntityName.c_str());

			Ogre::MeshPtr Mesh = Entity->getMesh();
			Ogre::String MeshName = Mesh->getName();
			xmlTextWriterWriteAttribute(m_XmlWriter, 
										BAD_CAST "MeshName",
										BAD_CAST MeshName.c_str());
			xmlTextWriterEndElement(m_XmlWriter); 
		}
		
		if (Type == "Camera")
		{
			Camera = (Ogre::Camera *)(mobj);
			Ogre::String CameraName = Camera->getName();
			xmlTextWriterStartElement(m_XmlWriter, BAD_CAST "Camera");
			
			xmlTextWriterWriteAttribute(m_XmlWriter, 
										BAD_CAST "CameraName",
										BAD_CAST CameraName.c_str());
			
			Ogre::Vector3 CameraPosition = Camera->getPosition();
			
			xmlTextWriterWriteFormatAttribute(m_XmlWriter, 
										BAD_CAST "XPosition",
										"%f",CameraPosition.x);
			xmlTextWriterWriteFormatAttribute(m_XmlWriter, 
										BAD_CAST "YPosition",
										"%f",CameraPosition.y);
			xmlTextWriterWriteFormatAttribute(m_XmlWriter, 
										BAD_CAST "ZPosition",
										"%f",CameraPosition.z);

			Ogre::Vector3 CameraDirection = Camera->getDirection();

			xmlTextWriterWriteFormatAttribute(m_XmlWriter, 
										BAD_CAST "XDirection",
										"%f",CameraDirection.x);
			xmlTextWriterWriteFormatAttribute(m_XmlWriter, 
										BAD_CAST "YDirection",
										"%f",CameraDirection.y);
			xmlTextWriterWriteFormatAttribute(m_XmlWriter, 
										BAD_CAST "ZDirection",
										"%f",CameraDirection.z);

			xmlTextWriterEndElement(m_XmlWriter); 
		}

		if (Type == "Light")
		{
			Light = (Ogre::Light *)(mobj);
		}

		if (Type == "ParticleSystem")
		{
			ParticleSystem = (Ogre::ParticleSystem *)(mobj);
		}

		if (Type == "ManualObject")
		{
			ManualObject = (Ogre::ManualObject *)(mobj);
		}

		if (Type == "BillboardSet")
		{
			BillboardSet = (Ogre::BillboardSet *)(mobj);
		}

	}

	Ogre::Node::ChildNodeIterator nodei = SceneNode->getChildIterator();

	while (nodei.hasMoreElements())
	{
		Ogre::SceneNode* node = (Ogre::SceneNode*)(nodei.getNext());
			// Add this subnode and its children...
		SceneNodeExplore(node);
	}

	xmlTextWriterEndElement(m_XmlWriter); //end SceneNode
}
void NxMeshManager::SetPivotTransform( Ogre::MeshPtr mesh, const Nx::Vector3 & Position, const Nx::Quaternion & Rotation, const Nx::Vector3 & Scale )
{
	//from mesh magick / mit licence
	 Nx::Matrix4 transform = Nx::Matrix4::IDENTITY;
	 Nx::Vector3 translate =  Nx::Vector3::ZERO;
	// Apply current transform to the mesh, to get the bounding box to
	// base te translation on.
	AxisAlignedBox aabb = getMeshAabb( mesh, transform);
	//if (alignment == "left")
	//{
	// 	translate = Vector3(-aabb.getMinimum().x, 0, 0);
	//}
	//else if (alignment == "center")
	//{
	//	translate = Vector3(-aabb.getCenter().x, 0, 0);
	//}
	//else if (alignment == "right")
	//{
	//	translate = Vector3(-aabb.getMaximum().x, 0, 0);
	//}

	//Position .. only support pivot down / centered
	//translate = Vector3(0, -aabb.getMinimum().y, 0);// pivot down

	translate = Position;
	 
	transform = Nx::Matrix4::getTrans(translate) * transform;

	//rotation
	transform = Nx::Matrix4(Rotation) * transform;

	//scale
	transform = Nx::Matrix4::getScale(Scale) * transform;

    // Check whether we have to flip vertex winding.
    // We do have to, if we changed our right hand base.
    // We can test it by using the cross product from X and Y and see, if it is a non-negative
    // projection on Z. Actually it should be exactly Z, as we don't do non-uniform scaling yet,
    // but the test is cheap either way.
    Nx::Matrix3 m3;
    transform.extract3x3Matrix(m3);

    if (m3.GetColumn(0).crossProduct(m3.GetColumn(1)).dotProduct(m3.GetColumn(2)) < 0)
    {
		LogMsg("SetPivotPosition : Flipping vertex winding ... "   );
    	mFlipVertexWinding = true;
    }

	//mTransform = transform;

	NxMat4toOgre( mTransform, transform ) ;


	mBoundingBox.setNull();

    if( mesh->sharedVertexData != NULL)
    {
        processVertexData( mesh->sharedVertexData);
	}else
	{
		LogMsg("mesh->sharedVertexData NULL");
	}

    for( int i = 0; i < mesh->getNumSubMeshes(); i++ )
    {
        SubMesh* submesh = mesh->getSubMesh(i);
        if( submesh->vertexData != NULL )
        {
			LogMsg("SetPivotPosition : Processing vertex data ... "   );
            processVertexData(submesh->vertexData);
		}else
		{
			LogMsg("submesh->vertexData NULL");
		}

        if (submesh->indexData != NULL)
        {
			LogMsg("SetPivotPosition : Processing Index data .."   );
        	processIndexData(submesh->indexData);
		}else
		{
			LogMsg("submesh->indexData NULL");
		}
    }

	//process pose
    for( unsigned short i = 0; i < mesh->getPoseCount(); ++i )
    {
		Ogre::Pose * pose =  mesh->getPose(i);
		Ogre::Matrix3 m3x3;
		mTransform.extract3x3Matrix(m3x3);

		Pose::VertexOffsetIterator it = pose->getVertexOffsetIterator();
		while (it.hasMoreElements()) {
			Ogre::Vector3 offset = it.peekNextValue();
			Ogre::Vector3 newOffset = m3x3 * offset;
			*it.peekNextValuePtr() = newOffset;
			it.moveNext();
		}
    }

	mesh->_setBounds( mBoundingBox, false );
  
}
Exemple #14
0
// Get the mesh information for the given mesh.
// Code found on this forum link: http://www.ogre3d.org/wiki/index.php/RetrieveVertexData
void CollisionTools::GetMeshInformation(const Ogre::MeshPtr mesh,
                                size_t &vertex_count,
                                Ogre::Vector3* &vertices,
                                size_t &index_count,
                                Ogre::uint32* &indices,
                                const Ogre::Vector3 &position,
                                const Ogre::Quaternion &orient,
                                const Ogre::Vector3 &scale)
{
    bool added_shared = false;
    size_t current_offset = 0;
    size_t shared_offset = 0;
    size_t next_offset = 0;
    size_t index_offset = 0;

    vertex_count = index_count = 0;

    // Calculate how many vertices and indices we're going to need
    for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
    {
        Ogre::SubMesh* submesh = mesh->getSubMesh( i );

        // We only need to add the shared vertices once
        if(submesh->useSharedVertices)
        {
            if( !added_shared )
            {
                vertex_count += mesh->sharedVertexData->vertexCount;
                added_shared = true;
            }
        }
        else
        {
            vertex_count += submesh->vertexData->vertexCount;
        }

        // Add the indices
        index_count += submesh->indexData->indexCount;
    }


    // Allocate space for the vertices and indices
    vertices = new Ogre::Vector3[vertex_count];
    indices = new Ogre::uint32[index_count];

    added_shared = false;

    // Run through the submeshes again, adding the data into the arrays
    for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
    {
        Ogre::SubMesh* submesh = mesh->getSubMesh(i);

        Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;

        if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared))
        {
            if(submesh->useSharedVertices)
            {
                added_shared = true;
                shared_offset = current_offset;
            }

            const Ogre::VertexElement* posElem =
                vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);

            Ogre::HardwareVertexBufferSharedPtr vbuf =
                vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());

            unsigned char* vertex =
                static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));

            // There is _no_ baseVertexPointerToElement() which takes an Ogre::Ogre::Real or a double
            //  as second argument. So make it float, to avoid trouble when Ogre::Ogre::Real will
            //  be comiled/typedefed as double:
            //      Ogre::Ogre::Real* pOgre::Real;
            float* pReal;

            for( size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
            {
                posElem->baseVertexPointerToElement(vertex, &pReal);

                Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]);

                vertices[current_offset + j] = (orient * (pt * scale)) + position;
            }

            vbuf->unlock();
            next_offset += vertex_data->vertexCount;
        }


        Ogre::IndexData* index_data = submesh->indexData;
        size_t numTris = index_data->indexCount / 3;
        Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;

        bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);

        Ogre::uint32*  pLong = static_cast<Ogre::uint32*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
        unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong);


        size_t offset = (submesh->useSharedVertices)? shared_offset : current_offset;

        if ( use32bitindexes )
        {
            for ( size_t k = 0; k < numTris*3; ++k)
            {
                indices[index_offset++] = pLong[k] + static_cast<Ogre::uint32>(offset);
            }
        }
        else
        {
            for ( size_t k = 0; k < numTris*3; ++k)
            {
                indices[index_offset++] = static_cast<Ogre::uint32>(pShort[k]) +
                    static_cast<Ogre::uint32>(offset);
            }
        }

        ibuf->unlock();
        current_offset = next_offset;
    }
}
Exemple #15
0
Ogre::MeshPtr
loadMesh(const Ogre::String& meshName, const Ogre::String& groupName,
         const Ogre::String& baseResourceName, const Ogre::String& baseGroupName)
{
    // Load the mesh
    Ogre::MeshPtr mesh = loadCorrelativeResource(
        meshName, groupName,
        baseResourceName, baseGroupName,
        Ogre::MeshManager::getSingleton());

    if (mesh.isNull())
    {
        OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND,
            "Unable to load mesh " + meshName,
            "loadMesh");
    }

    // Try to resolve skeleton resource
    if (mesh->hasSkeleton() && mesh->getSkeleton().isNull())
    {
        // resolve correlative with mesh
        Ogre::SkeletonPtr skeleton = loadCorrelativeResource(
            mesh->getSkeletonName(), groupName,
            mesh->getName(), mesh->getGroup(),
            Ogre::SkeletonManager::getSingleton());

        if (skeleton.isNull())
        {
            // resolve correlative with base resource
            skeleton = loadCorrelativeResource(
                mesh->getSkeletonName(), groupName,
                baseResourceName, baseGroupName,
                Ogre::SkeletonManager::getSingleton());
        }

        if (skeleton.isNull())
        {
            OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND,
                "Unable to load skeleton " + mesh->getSkeletonName() +
                " for mesh " + mesh->getName(),
                "loadMesh");
        }

        // Set to the actual name
        mesh->setSkeletonName(skeleton->getName());
    }

    return mesh;
}
Exemple #16
0
void Renderer::FindClosestPolygon(Ogre::Entity* entity, float& closestDistance,
                                       Ogre::Vector3& position, Ogre::Vector3& normal)
{
    closestDistance = std::numeric_limits<float>::max();    // default value (means
                                                            // nothing detected)

    // Get transformation
    Ogre::SceneNode* parentNode = entity->getParentSceneNode();
    Ogre::Vector3 parentPos;
    Ogre::Quaternion parentOrientation;
    Ogre::Vector3 parentScale;
    if (parentNode)
    {
        parentPos = parentNode->_getDerivedPosition();
        parentOrientation = parentNode->_getDerivedOrientation();
        parentScale = parentNode->_getDerivedScale();
    }
    else
    {
        parentPos = Ogre::Vector3::ZERO;
        parentOrientation = Ogre::Quaternion::IDENTITY;
        parentScale = Ogre::Vector3::UNIT_SCALE;
    }

    // Handle animated entities
    bool isAnimated = entity->hasSkeleton();
    if (isAnimated)
    {
        entity->addSoftwareAnimationRequest(false);
        entity->_updateAnimation();
    }

    // Loop through each submesh
    Ogre::MeshPtr mesh = entity->getMesh();
    for (uint i = 0; i < mesh->getNumSubMeshes(); ++i)
    {
        Ogre::SubMesh* subMesh = mesh->getSubMesh(i);

        // Ignore anything that isn't a triangle List
        if (subMesh->operationType != Ogre::RenderOperation::OT_TRIANGLE_LIST)
            continue;

        // Get the vertex data
        Ogre::VertexData* vertexData;
        if (subMesh->useSharedVertices)
        {
            if (isAnimated)
                vertexData = entity->_getSkelAnimVertexData();
            else
                vertexData = mesh->sharedVertexData;
        }
        else
        {
            if (isAnimated)
                vertexData = entity->getSubEntity(i)->_getSkelAnimVertexData();
            else
                vertexData = subMesh->vertexData;
        }

        // Get the size of one vertex
        const Ogre::VertexElement* posEl =
            vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
        Ogre::HardwareVertexBufferSharedPtr vBuff =
            vertexData->vertexBufferBinding->getBuffer(posEl->getSource());
        uint vertexSize = vBuff->getVertexSize();

        // Save pointer to first vertex
        short* pVertex = (short*)vBuff->lock(Ogre::HardwareBuffer::HBL_READ_ONLY);
        short* pStartVertex = pVertex;

        // Get the index buffer
        // If it is null then skip as it must be a point cloud
        Ogre::HardwareIndexBufferSharedPtr iBuff = subMesh->indexData->indexBuffer;

        if (iBuff.isNull())
            continue;

        uint* pLong = (uint*)iBuff->lock(Ogre::HardwareBuffer::HBL_READ_ONLY);
        uint16_t* pShort = (uint16_t*)pLong;

        // Look through each vertex and check each triangle with the ray
        Ogre::Vector3 vertexPos;
        Ogre::Vector3 vertex1;
        Ogre::Vector3 vertex2;
        float* pReal;
        uint index;
        for (uint k = 0; k < subMesh->indexData->indexCount; k++)
        {
            // Read index value
            if (iBuff->getType() == Ogre::HardwareIndexBuffer::IT_32BIT)    // if 32bit indexes
            {
                index = (uint)pLong[k];
            }
            else
            {
                index = (uint)pShort[k];
            }

            // Read referenced vertex
            pVertex = pStartVertex + (vertexSize * index);              // calculate pointer
            posEl->baseVertexPointerToElement(pVertex, &pReal);         // read vertex
            vertexPos = Ogre::Vector3(pReal[0], pReal[1], pReal[2]);    // read position values

            // Apply world transformations
            if (parentNode)
                vertexPos = (parentOrientation * (vertexPos * parentScale)) + parentPos;

            // Figure out triangle and calculate the distance if it's the closest
            switch (k % 3)
            {
            case 0:
                vertex1 = vertexPos;
                break;

            case 1:
                vertex2 = vertexPos;
                break;

            case 2:
                RayToTriangleCheck(vertex1, vertex2, vertexPos, closestDistance, position, normal);
                break;

            default:
                break;
            }
        }

        iBuff->unlock();
        vBuff->unlock();
    }

    if (isAnimated)
    {
        entity->removeSoftwareAnimationRequest(false);
    }
}
Exemple #17
0
void MeshUtils::meshBuffersToArrays(const Ogre::MeshPtr& mesh, Ogre::Vector3* vertices, unsigned long* indices)
{
	bool added_shared = false;
	size_t current_offset = 0;
	size_t shared_offset = 0;
	size_t next_offset = 0;
	size_t index_offset = 0;

	//const Ogre::Vector3 &position = ent->getParentNode()->_getDerivedPosition();
	//const Ogre::Quaternion &orient = ent->getParentNode()->_getDerivedOrientation();
	//const Ogre::Vector3 &scale = ent->getParentNode()->_getDerivedScale();

	const Ogre::Vector3 &position = Ogre::Vector3::ZERO;
	const Ogre::Quaternion &orient = Ogre::Quaternion::IDENTITY;
	const Ogre::Vector3 &scale = Ogre::Vector3::UNIT_SCALE;

	Ogre::Mesh::SubMeshIterator itr = mesh->getSubMeshIterator();
	while (itr.hasMoreElements()) {
			Ogre::SubMesh* submesh = itr.getNext();

			Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;

			if ((!submesh->useSharedVertices) || (submesh->useSharedVertices && !added_shared)) {
					if (submesh->useSharedVertices) {
							added_shared = true;
							shared_offset = current_offset;
						}

					const Ogre::VertexElement* posElem =
					    vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);

					Ogre::HardwareVertexBufferSharedPtr vbuf =
					    vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());

					unsigned char* vertex =
					    static_cast<unsigned char*> (vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));

					// There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or a double
					//  as second argument. So make it float, to avoid trouble when Ogre::Real will
					//  be comiled/typedefed as double:
					//      Ogre::Real* pReal;
					float* pReal;

					for (size_t k = 0; k < vertex_data->vertexCount; ++k, vertex += vbuf->getVertexSize()) {
							posElem->baseVertexPointerToElement(vertex, &pReal);

							Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]);

							vertices[current_offset + k] = (orient * (pt * scale)) + position;
							//vertices[current_offset + k] = pt;
						}

					vbuf->unlock();
					next_offset += vertex_data->vertexCount;
				}


			Ogre::IndexData* index_data = submesh->indexData;
			size_t numTris = index_data->indexCount / 3;
			Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;

			bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);

			unsigned long* pLong = static_cast<unsigned long*> (ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
			unsigned short* pShort = reinterpret_cast<unsigned short*> (pLong);


			size_t offset = (submesh->useSharedVertices) ? shared_offset : current_offset;

			if (use32bitindexes) {
					for (size_t k = 0; k < numTris * 3; ++k) {
							indices[index_offset++] = pLong[k] + static_cast<unsigned long> (offset);
						}
				} else {
					for (size_t k = 0; k < numTris * 3; ++k) {
							indices[index_offset++] = static_cast<unsigned long> (pShort[k]) +
							                          static_cast<unsigned long> (offset);
						}
				}

			ibuf->unlock();
			current_offset = next_offset;
		}
}
Ogre::SceneNode *TutorialApplication::loadBSP(std::shared_ptr<l2p::UModel> m, bool ignoreNonVisible) {
  l2p::Name name = m->package->name;
  std::vector<float> vertex_data;
  std::vector<uint32_t> index_buf;
  l2p::Box bounds;

  // Build vertex and index buffer.
  for (auto ni = m->nodes.begin(), ne = m->nodes.end(); ni != ne; ++ni) {
    l2p::BSPNode &n = *ni;
    l2p::BSPSurface &s = m->surfaces[n.surface];

    if (ignoreNonVisible && ignoreNode(m.get(), n, s))
      continue;

    uint32_t vert_start = vertex_data.size() / 8;

    const Ogre::Vector3 uvec = ogre_cast(m->vectors[s.U]);
    const Ogre::Vector3 vvec = ogre_cast(m->vectors[s.V]);
    const Ogre::Vector3 base = ogre_cast(m->points[s.base]);
    int usize = 0;
    int vsize = 0;
    std::shared_ptr<l2p::UTexture> mat = s.material;
    if (mat) {
      usize = mat->USize;
      vsize = mat->VSize;
    }

    if (usize == 0 || vsize == 0)
      usize = vsize = 64;

    // Vertex buffer.
    if (n.num_verticies > 0) {
      l2p::Vector Normal = m->vectors[s.normal];

      for (uint32_t vert_index = 0; vert_index < n.num_verticies; ++vert_index) {
        const l2p::Vector &pos = m->points[m->vertexes[n.vert_pool + vert_index].vertex];
        const Ogre::Vector3 dist(ogre_cast(pos) - base);
        const Ogre::Vector2 tcoord((dist | uvec) / float(usize), (dist | vvec) / float(vsize));
        bounds += pos;
        vertex_data.push_back(pos.X);
        vertex_data.push_back(pos.Y);
        vertex_data.push_back(pos.Z);
        vertex_data.push_back(Normal.X);
        vertex_data.push_back(Normal.Y);
        vertex_data.push_back(Normal.Z);
        vertex_data.push_back(tcoord.x);
        vertex_data.push_back(tcoord.y);
      }

      if (s.flags & l2p::PF_TwoSided) {
        for (uint32_t vert_index = 0; vert_index < n.num_verticies; ++vert_index) {
          const l2p::Vector &pos = m->points[m->vertexes[n.vert_pool + vert_index].vertex];
          const Ogre::Vector3 dist(ogre_cast(pos) - base);
          const Ogre::Vector2 tcoord((dist | uvec) / float(usize), (dist | vvec) / float(vsize));
          vertex_data.push_back(pos.X);
          vertex_data.push_back(pos.Y);
          vertex_data.push_back(pos.Z);
          vertex_data.push_back(Normal.X);
          vertex_data.push_back(Normal.Y);
          vertex_data.push_back(-Normal.Z);
          vertex_data.push_back(tcoord.x);
          vertex_data.push_back(tcoord.y);
        }
      }
    }

    // Index buffer.
    for (int verti = 2; verti < n.num_verticies; ++verti) {
      index_buf.push_back(vert_start);
      index_buf.push_back(vert_start + verti - 1);
      index_buf.push_back(vert_start + verti);
    }
    if (s.flags & l2p::PF_TwoSided) {
      for (int verti = 2; verti < n.num_verticies; ++verti) {
        index_buf.push_back(vert_start);
        index_buf.push_back(vert_start + verti);
        index_buf.push_back(vert_start + verti - 1);
      }
    }
  }

  if (vertex_data.size() == 0 || index_buf.size() == 0)
    return nullptr;

  Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().createManual(Ogre::String(name) + Ogre::String(m->name), "General");
  Ogre::VertexData  *data = new Ogre::VertexData();
  mesh->sharedVertexData = data;
  data->vertexCount = vertex_data.size() / 8;

  Ogre::VertexDeclaration *decl = data->vertexDeclaration;
  uint32_t offset = 0;
  decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
  offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
  decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
  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);

  Ogre::HardwareVertexBufferSharedPtr vbuf =
    Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
      offset,
      data->vertexCount,
      Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
  vbuf->writeData(0, vbuf->getSizeInBytes(), &vertex_data.front(), true);
  data->vertexBufferBinding->setBinding(0, vbuf);

  // Setup index buffer.
  Ogre::HardwareIndexBufferSharedPtr ibuf =
    Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
      Ogre::HardwareIndexBuffer::IT_32BIT,
      index_buf.size(),
      Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

  ibuf->writeData(0, ibuf->getSizeInBytes(), &index_buf.front(), true);
  Ogre::SubMesh *subMesh = mesh->createSubMesh();
  subMesh->useSharedVertices = true;
  subMesh->indexData->indexBuffer = ibuf;
  subMesh->indexData->indexCount  = index_buf.size();
  subMesh->indexData->indexStart  = 0;

  mesh->_setBounds(Ogre::AxisAlignedBox(bounds.min.X, bounds.min.Y, bounds.min.Z, bounds.max.X, bounds.max.Y, bounds.max.Z));
  mesh->_setBoundingSphereRadius((std::max(bounds.max.X - bounds.min.X, std::max(bounds.max.Y - bounds.min.Y, bounds.max.Z - bounds.min.Z))) / 2.0);

  mesh->load();

  Ogre::Entity *ent = mSceneMgr->createEntity(Ogre::String(name) + Ogre::String(m->name) + "E", Ogre::String(name) + Ogre::String(m->name));
  ent->setUserAny(Ogre::Any(static_cast<l2p::UObject*>(m.get())));
  ent->setMaterialName("StaticMesh/Default");
  Ogre::SceneNode *node = mUnrealCordNode->createChildSceneNode();
  node->attachObject(ent);

  return node;
}
	void BtOgreSoftBody::updateOgreMesh()
	{
		Ogre::Node *ogreNode = mEntity->getParentNode();
		
		//printf("updateOgreMesh %d %s %s\n", internalId, mEntity->getName().c_str(), ogreNode->getName().c_str());
		
		Ogre::MeshPtr mesh = mEntity->getMesh();
		Ogre::Mesh::SubMeshIterator subMeshI = mesh->getSubMeshIterator();
		Ogre::SubMesh* subMesh = NULL;
		
		Ogre::VertexData* vData = NULL;
		Ogre::VertexDeclaration* vDeclaration = NULL;
		const Ogre::VertexElement* vPosElement = NULL;
		
		bool isSharedVerticesAdded = false;
		unsigned short bufferIndex = 0;
		Ogre::HardwareVertexBufferSharedPtr vBuffer;
		
		// Can not do arithmetic operations on void*
		unsigned char* lockedMem = NULL;
		float* vPosition;
		
		btSoftBody::tNodeArray& btNodes = mSoftBody->m_nodes;
		//printf("Bullet nodes size %d\n", btNodes.size());
		
		int ogreVertexIdx = 0;
		
		while (subMeshI.hasMoreElements()) {
			subMesh = subMeshI.getNext();
			
			if (subMesh->useSharedVertices) {
				
				if (isSharedVerticesAdded) {
					continue;
				}
				
				vData = mesh->sharedVertexData;
				
				// We need to add shared vertices only once
				isSharedVerticesAdded = true;
			} else  {
				vData = subMesh->vertexData;
			}
			
			vDeclaration = vData->vertexDeclaration;
			vPosElement = vDeclaration->findElementBySemantic(Ogre::VES_POSITION);
			
			bufferIndex = vPosElement->getSource();
			vBuffer = vData->vertexBufferBinding->getBuffer(bufferIndex);
			
			// Lock the buffer before reading from it
			lockedMem = static_cast<unsigned char*>(vBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD));
			
			// Read each vertex
			for (unsigned int i = 0; i < vData->vertexCount; ++i) {
				vPosElement->baseVertexPointerToElement(lockedMem, &vPosition);
				
				int idx = getBulletIndex(ogreVertexIdx);
				
				*vPosition++ = btNodes[idx].m_x.x();
				*vPosition++ = btNodes[idx].m_x.y();
				*vPosition = btNodes[idx++].m_x.z();
				
				// Point to the next vertex
				lockedMem += vBuffer->getVertexSize();
				
				ogreVertexIdx++;
			}
			
			vBuffer->unlock();
		}
				
		btTransform transform = mSoftBody->getWorldTransform();
		btQuaternion rot = transform.getRotation();
	    ogreNode->setOrientation(rot.w(), rot.x(), rot.y(), rot.z());
	    btVector3 pos = transform.getOrigin();
	    ogreNode->setPosition(pos.x(), pos.y(), pos.z());
		
	}
void CSceletalAnimationView::EngineSetup(void)
{
	Ogre::Root *Root = ((CSceletalAnimationApp*)AfxGetApp())->m_Engine->GetRoot();
	Ogre::SceneManager *SceneManager = NULL;
	SceneManager = Root->createSceneManager(Ogre::ST_GENERIC, "Animation");
 
    //
    // Create a render window
    // This window should be the current ChildView window using the externalWindowHandle
    // value pair option.
    //

    Ogre::NameValuePairList parms;
    parms["externalWindowHandle"] = Ogre::StringConverter::toString((long)m_hWnd);
    parms["vsync"] = "true";

	CRect   rect;
    GetClientRect(&rect);
	Ogre::RenderTarget *RenderWindow = Root->getRenderTarget("Mouse Input");

	if (RenderWindow == NULL)
	{
	try
	{
		m_RenderWindow = Root->createRenderWindow("Mouse Input", rect.Width(), rect.Height(), false, &parms);
	}
    catch(...)
	{
		MessageBox("Cannot initialize\nCheck that graphic-card driver is up-to-date", "Initialize Render System", MB_OK | MB_ICONSTOP);
		exit(EXIT_SUCCESS);
	}
	}
// Load resources
	Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

    // Create the camera
    m_Camera = SceneManager->createCamera("Camera");
    m_Camera->setNearClipDistance(0.5);
	m_Camera->setFarClipDistance(5000); 
	m_Camera->setCastShadows(false);
	m_Camera->setUseRenderingDistance(true);
	m_Camera->setPosition(Ogre::Vector3(5.0, 5.0, 10.0));
	Ogre::SceneNode *CameraNode = NULL;
	CameraNode = SceneManager->getRootSceneNode()->createChildSceneNode("CameraNode");

	Ogre::Viewport* Viewport = NULL;
	
	if (0 == m_RenderWindow->getNumViewports())
	{
		Viewport = m_RenderWindow->addViewport(m_Camera);
		Viewport->setBackgroundColour(Ogre::ColourValue(0.8f, 0.8f, 0.8f));
	}

    // Alter the camera aspect ratio to match the viewport
    m_Camera->setAspectRatio(Ogre::Real(rect.Width()) / Ogre::Real(rect.Height()));
	m_Camera->lookAt(Ogre::Vector3(0.5, 0.5, 0.5));
	m_Camera->setPolygonMode(Ogre::PolygonMode::PM_WIREFRAME);

	Ogre::ManualObject* ManualObject = NULL;
	ManualObject = SceneManager->createManualObject("Animation");
	ManualObject->setDynamic(false);
    ManualObject->begin("BaseWhiteNoLighting", Ogre::RenderOperation::OT_TRIANGLE_LIST);
	//face 1
	ManualObject->position(0, 0, 0);//0
	ManualObject->position(1, 0, 0);//1
	ManualObject->position(1, 1, 0);//2
	ManualObject->triangle(0, 1, 2);//3
	
	ManualObject->position(0, 0, 0);//4
	ManualObject->position(1, 1, 0);//5
	ManualObject->position(0, 1, 0);//6
	ManualObject->triangle(3, 4, 5);//7
	//face 2
	ManualObject->position(0, 0, 1);//8
	ManualObject->position(1, 0, 1);//9
	ManualObject->position(1, 1, 1);//10
	ManualObject->triangle(6, 7, 8);//11

	ManualObject->position(0, 0, 1);//12
	ManualObject->position(1, 1, 1);//13
	ManualObject->position(0, 1, 1);//14
	ManualObject->triangle(9, 10, 11);//15
	//face 3
	ManualObject->position(0, 0, 0);//16
	ManualObject->position(1, 0, 0);//17
	ManualObject->position(1, 0, 1);//18
	ManualObject->triangle(12, 13, 14);//19

	ManualObject->position(0, 0, 0);
	ManualObject->position(1, 0, 1);
	ManualObject->position(0, 1, 1);
	ManualObject->triangle(15, 16, 17);
	//face 4
	ManualObject->position(1, 0, 0);
	ManualObject->position(1, 1, 0);
	ManualObject->position(1, 1, 1);
	ManualObject->triangle(18, 19, 20);

	ManualObject->position(1, 0, 0);
	ManualObject->position(1, 1, 1);
	ManualObject->position(1, 0, 1);
	ManualObject->triangle(21, 22, 23);
	//face 5
	ManualObject->position(0, 1, 0);
	ManualObject->position(1, 1, 0);
	ManualObject->position(0, 1, 1);
	ManualObject->triangle(24, 25, 26);

	ManualObject->position(1, 1, 0);
	ManualObject->position(1, 1, 1);
	ManualObject->position(0, 1, 1);
	ManualObject->triangle(27, 28, 29);
	
	//face 6
	ManualObject->position(0, 0, 0);
	ManualObject->position(0, 1, 1);
	ManualObject->position(0, 0, 1);
	ManualObject->triangle(30, 31, 32);

	ManualObject->position(0, 0, 0);
	ManualObject->position(0, 1, 0);
	ManualObject->position(0, 1, 1);
	ManualObject->triangle(33, 34, 35);

	ManualObject->end();
	Ogre::MeshPtr MeshPtr = ManualObject->convertToMesh("Animation");
	Ogre::SubMesh* sub = MeshPtr->getSubMesh(0);
	
	Ogre::SkeletonPtr Skeleton = Ogre::SkeletonManager::getSingleton().create("Skeleton", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
	MeshPtr.getPointer()->_notifySkeleton(Skeleton);
	Ogre::Bone *Root1 = NULL;
	Ogre::Bone *Child1 = NULL;
	Ogre::Bone *Child2 = NULL;

	Root1 = Skeleton.getPointer()->createBone("Root");
	Root1->setPosition(Ogre::Vector3(0.0, 0.0, 0.0));
	Root1->setOrientation(Ogre::Quaternion::IDENTITY);
	
	Child1 = Root1->createChild(1);
	Child1->setPosition(Ogre::Vector3(4.0, 0.0, 0.0));
	Child1->setOrientation(Ogre::Quaternion::IDENTITY);
	Child2 = Root1->createChild(2);
	Child2->setPosition(Ogre::Vector3(5.0, 0.0, 0.0));
	Child2->setOrientation(Ogre::Quaternion::IDENTITY);

	Ogre::VertexBoneAssignment Assignment;

	Assignment.boneIndex = 0;
	Assignment.vertexIndex = 0;
	Assignment.weight = 1.0;
	Skeleton->setBindingPose();

	sub->addBoneAssignment(Assignment);

	Assignment.vertexIndex = 1;
	sub->addBoneAssignment(Assignment);

	Assignment.vertexIndex = 2;
	sub->addBoneAssignment(Assignment);

	Ogre::Animation *Animation = MeshPtr->createAnimation("HandAnimation", 100.0);
	Ogre::NodeAnimationTrack *Track = Animation->createNodeTrack(0, Root1);
	Ogre::TransformKeyFrame *KeyFrame = NULL;

	for (float FrameTime = 0.0; FrameTime < 100.0; FrameTime += 0.1)
	{
		KeyFrame = Track->createNodeKeyFrame(FrameTime);
		KeyFrame->setTranslate(Ogre::Vector3(10.0, 0.0, 0.0));
	}

	Root1->setManuallyControlled(true);
	Child1->setManuallyControlled(true);
	Child2->setManuallyControlled(true);
	MeshPtr->load();

	MeshPtr.getPointer()->_notifySkeleton(Skeleton);
		
//	Ogre::SkeletonSerializer skeletonSerializer;
//	skeletonSerializer.exportSkeleton(Skeleton.get(), "C:\\Users\\Ilya\\Documents\\Visual Studio 2010\\Projects\\Recipes\\media\\models\\testskeleton.skeleton");
//	Ogre::MeshSerializer ser;
//    ser.exportMesh(MeshPtr.get(), "C:\\Users\\Ilya\\Documents\\Visual Studio 2010\\Projects\\Recipes\\media\\models\\testskeleton.mesh");

	Ogre::Entity *Entity = SceneManager->createEntity("Animation", "Animation"/*"testskeleton.mesh"*/);
	Ogre::SceneNode *SceneNode = SceneManager->getRootSceneNode()->createChildSceneNode();
	SceneNode->attachObject(Entity);
	Entity->setDisplaySkeleton(true);

	m_AnimationState = Entity->getAnimationState("HandAnimation");
	m_AnimationState->setEnabled(true);
	m_AnimationState->setLoop(true);
	
	m_Camera->setPolygonMode(Ogre::PolygonMode::PM_WIREFRAME);
	 
	Root->renderOneFrame();
}
Exemple #21
0
void PhysicsManager::getMeshInformation(Ogre::MeshPtr mesh,size_t &vertex_count,Vector3* &vertices, size_t &index_count, unsigned* &indices, const Ogre::Vector3 &position,  const Ogre::Quaternion &orient,const Ogre::Vector3 &scale)
{
	vertex_count = index_count = 0;

	bool added_shared = false;
	size_t current_offset = vertex_count;
	size_t shared_offset = vertex_count;
	size_t next_offset = vertex_count;
	size_t index_offset = index_count;
	size_t prev_vert = vertex_count;
	size_t prev_ind = index_count;

	// Calculate how many vertices and indices we're going to need
	for(int i = 0;i < mesh->getNumSubMeshes();i++)
	{
		SubMesh* submesh = mesh->getSubMesh(i);

		// We only need to add the shared vertices once
		if(submesh->useSharedVertices)
		{
			if(!added_shared)
			{
				VertexData* vertex_data = mesh->sharedVertexData;
				vertex_count += vertex_data->vertexCount;
				added_shared = true;
			}
		}
		else
		{
			VertexData* vertex_data = submesh->vertexData;
			vertex_count += vertex_data->vertexCount;
		}

		// Add the indices
		Ogre::IndexData* index_data = submesh->indexData;
		index_count += index_data->indexCount;
	}

	// Allocate space for the vertices and indices
	vertices = new Vector3[vertex_count];
	indices = new unsigned[index_count];

	added_shared = false;

	// Run through the submeshes again, adding the data into the arrays
	for(int i = 0;i < mesh->getNumSubMeshes();i++)
	{
		SubMesh* submesh = mesh->getSubMesh(i);

		Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;
		if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared))
		{
			if(submesh->useSharedVertices)
			{
				added_shared = true;
				shared_offset = current_offset;
			}

			const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
			Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
			unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
			Ogre::Real* pReal;

			for(size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
			{
				posElem->baseVertexPointerToElement(vertex, &pReal);

				Vector3 pt;

				pt.x = (*pReal++);
				pt.y = (*pReal++);
				pt.z = (*pReal++);

				pt = (orient * (pt * scale)) + position;

				vertices[current_offset + j].x = pt.x;
				vertices[current_offset + j].y = pt.y;
				vertices[current_offset + j].z = pt.z;
			}
			vbuf->unlock();
			next_offset += vertex_data->vertexCount;
		}

		Ogre::IndexData* index_data = submesh->indexData;

		size_t numTris = index_data->indexCount / 3;
		unsigned short* pShort;
		unsigned int* pInt;
		Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;
		bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);
		if (use32bitindexes) pInt = static_cast<unsigned int*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
		else pShort = static_cast<unsigned short*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));

		for(size_t k = 0; k < numTris; ++k)
		{
			size_t offset = (submesh->useSharedVertices)?shared_offset:current_offset;

			unsigned int vindex = use32bitindexes? *pInt++ : *pShort++;
			indices[index_offset + 0] = vindex + offset;
			vindex = use32bitindexes? *pInt++ : *pShort++;
			indices[index_offset + 1] = vindex + offset;
			vindex = use32bitindexes? *pInt++ : *pShort++;
			indices[index_offset + 2] = vindex + offset;

			index_offset += 3;
		}
		ibuf->unlock();
		current_offset = next_offset;
	}
}
    //-----------------------------------------------------------------------
    void InstanceManager::unshareVertices(const Ogre::MeshPtr &mesh)
    {
        // Retrieve data to copy bone assignments
        const Mesh::VertexBoneAssignmentList& boneAssignments = mesh->getBoneAssignments();
        Mesh::VertexBoneAssignmentList::const_iterator it = boneAssignments.begin();
        Mesh::VertexBoneAssignmentList::const_iterator end = boneAssignments.end();
        size_t curVertexOffset = 0;

        // Access shared vertices
        VertexData* sharedVertexData = mesh->sharedVertexData;

        for (size_t subMeshIdx = 0; subMeshIdx < mesh->getNumSubMeshes(); subMeshIdx++)
        {
            SubMesh *subMesh = mesh->getSubMesh(subMeshIdx);

            IndexData *indexData = subMesh->indexData;
            HardwareIndexBuffer::IndexType idxType = indexData->indexBuffer->getType();
            IndicesMap indicesMap = (idxType == HardwareIndexBuffer::IT_16BIT) ? getUsedIndices<uint16>(indexData) :
                                                                                 getUsedIndices<uint32>(indexData);


            VertexData *newVertexData = new VertexData();
            newVertexData->vertexCount = indicesMap.size();
            newVertexData->vertexDeclaration = sharedVertexData->vertexDeclaration->clone();

            for (size_t bufIdx = 0; bufIdx < sharedVertexData->vertexBufferBinding->getBufferCount(); bufIdx++) 
            {
                HardwareVertexBufferSharedPtr sharedVertexBuffer = sharedVertexData->vertexBufferBinding->getBuffer(bufIdx);
                size_t vertexSize = sharedVertexBuffer->getVertexSize();                

                HardwareVertexBufferSharedPtr newVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer
                    (vertexSize, newVertexData->vertexCount, sharedVertexBuffer->getUsage(), sharedVertexBuffer->hasShadowBuffer());

                uint8 *oldLock = (uint8*)sharedVertexBuffer->lock(0, sharedVertexData->vertexCount * vertexSize, HardwareBuffer::HBL_READ_ONLY);
                uint8 *newLock = (uint8*)newVertexBuffer->lock(0, newVertexData->vertexCount * vertexSize, HardwareBuffer::HBL_NORMAL);

                IndicesMap::iterator indIt = indicesMap.begin();
                IndicesMap::iterator endIndIt = indicesMap.end();
                for (; indIt != endIndIt; ++indIt)
                {
                    memcpy(newLock + vertexSize * indIt->second, oldLock + vertexSize * indIt->first, vertexSize);
                }

                sharedVertexBuffer->unlock();
                newVertexBuffer->unlock();

                newVertexData->vertexBufferBinding->setBinding(bufIdx, newVertexBuffer);
            }

            if (idxType == HardwareIndexBuffer::IT_16BIT)
            {
                copyIndexBuffer<uint16>(indexData, indicesMap);
            }
            else
            {
                copyIndexBuffer<uint32>(indexData, indicesMap);
            }

            // Store new attributes
            subMesh->useSharedVertices = false;
            subMesh->vertexData = newVertexData;

            // Transfer bone assignments to the submesh
            size_t offset = curVertexOffset + newVertexData->vertexCount;
            for (; it != end; ++it)
            {
                size_t vertexIdx = (*it).first;
                if (vertexIdx > offset)
                    break;

                VertexBoneAssignment boneAssignment = (*it).second;
                boneAssignment.vertexIndex = static_cast<unsigned int>(boneAssignment.vertexIndex - curVertexOffset);
                subMesh->addBoneAssignment(boneAssignment);
            }
            curVertexOffset = newVertexData->vertexCount + 1;
        }

        // Release shared vertex data
        delete mesh->sharedVertexData;
        mesh->sharedVertexData = NULL;
        mesh->clearBoneAssignments();
    }
Exemple #23
0
Ogre::Entity*
ModelFile::GetModel( const ModelInfo& info )
{
    VectorTexForGen textures;
    Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().create( info.data.name + "export", "General" );
    Ogre::SkeletonPtr skeleton = Ogre::SkeletonManager::getSingleton().create( info.data.name + "export", "General" );

    int number_of_bones = GetU8( 0x02 );
    int number_of_parts = GetU8( 0x03 );
    int offset_to_bones = GetU32LE( 0x0c );
    int offset_to_parts = GetU32LE( 0x10 );



    Ogre::Bone* root1 = skeleton->createBone( "0", 0 );
    Ogre::Bone* root2 = skeleton->createBone( "1", 1 );
    root1->addChild( root2 );

    for( int i = 0; i < number_of_bones; ++i )
    {
        Bone bone;
        bone.parent_id = ( i != 0 ) ? ( s8 )GetU8( offset_to_bones + i * 0x04 + 0x03 ) : -1;
        bone.length    = ( s16 )GetU16LE( offset_to_bones + i * 0x04 + 0x00 );
        m_Skeleton.push_back(bone);

        Ogre::Bone* bone1 = skeleton->createBone( Ogre::StringConverter::toString( i * 2 + 2 ), i * 2 + 2 );
        Ogre::Bone* bone2 = skeleton->createBone( Ogre::StringConverter::toString( i * 2 + 3 ), i * 2 + 3 );

        LOGGER->Log( "Add skeleton bone: bone_id = " + Ogre::StringConverter::toString( i ) + ", length = " + Ogre::StringConverter::toString( bone.length ) + ", parent = " + Ogre::StringConverter::toString( bone.parent_id ) + ".\n" );

        if( bone.parent_id == -1 )
        {
            skeleton->getBone( 1 )->addChild( bone1 );
        }
        else
        {
            skeleton->getBone( bone.parent_id * 2 + 3 )->addChild( bone1 );
        }
        bone1->addChild( bone2 );
    }



    AnimationExtractor( skeleton, info, m_Skeleton );



    // draw skeleton
    {
        //DrawSkeleton( m_Skeleton, mesh );
    }



    for( int i = 0; i < number_of_parts; ++i )
    {
        MeshExtractor( info.data, "ffix/field_model/" + info.data.name, this, offset_to_parts + i * 0x28, textures, mesh );
    }



    // <OGRE> ///////////////////////////////
    skeleton->optimiseAllAnimations();
    Ogre::SkeletonSerializer skeleton_serializer;
    skeleton_serializer.exportSkeleton( skeleton.getPointer(), "exported/models/field/units/" + info.data.name + ".skeleton" );

    // Update bounds
    Ogre::AxisAlignedBox aabb( -999, -999, -999, 999, 999, 999 );
    mesh->_setBounds( aabb, false );
    mesh->_setBoundingSphereRadius( 999 );

    mesh->setSkeletonName( "models/field/units/" + info.data.name + ".skeleton" );

    Ogre::MeshSerializer ser;
    ser.exportMesh( mesh.getPointer(), "exported/models/field/units/" + info.data.name + ".mesh" );



    // create and export textures for model
    //if (textures.size() > 0)
    {
        Vram* vram = new Vram();

        File* tex = new File( "./data/field/5/1b/2/4/1.tim" );
        LoadTimFileToVram( tex, 0, vram );
        delete tex;
        tex = new File( "./data/field/5/1b/2/4/2.tim" );
        LoadTimFileToVram( tex, 0, vram );
        delete tex;

        vram->Save( "1.jpg" );

        CreateTexture( vram, info.data, "exported/models/field/units/" + info.data.name + ".png", textures );

        delete vram;
    }



    CreateMaterial( "ffix/field_model/" + info.data.name, "exported/models/field/units/" + info.data.name + ".material", ( textures.size() > 0 ) ? "models/field/units/" + info.data.name + ".png" : "", "", "" );



    Ogre::SceneManager* scene_manager = Ogre::Root::getSingleton().getSceneManager( "Scene" );
    Ogre::Entity* thisEntity = scene_manager->createEntity( info.data.name, "models/field/units/" + info.data.name + ".mesh" );
    //thisEntity->setDisplaySkeleton(true);
    //thisEntity->setDebugDisplayEnabled(true);
    thisEntity->setVisible( false );
    thisEntity->getAnimationState( info.animations_name[ 0 ] )->setEnabled(true);
    thisEntity->getAnimationState( info.animations_name[ 0 ] )->setLoop(true);
    Ogre::SceneNode* thisSceneNode = scene_manager->getRootSceneNode()->createChildSceneNode();
    thisSceneNode->setPosition( 0, 0, 0 );
    thisSceneNode->roll( Ogre::Radian( Ogre::Degree( 180.0f ) ) );
    thisSceneNode->yaw( Ogre::Radian( Ogre::Degree( 120.0f ) ) );
    thisSceneNode->pitch( Ogre::Radian( Ogre::Degree(90.0f ) ) );
    thisSceneNode->attachObject( thisEntity );

    return thisEntity;
}
Exemple #24
0
void
MeshExtractor( const MeshData& mesh_data, const Ogre::String& material_name, File* file, int offset_to_data, VectorTexForGen& textures, const Ogre::MeshPtr& mesh )
{
    File* file12 = new File( "./data/field/5/1b/1/12/1" );
    u32 offset_to_clut_tex = 4 + file12->GetU32LE( 4 + 4 ) & 0x00ffffff;
    LOGGER->Log( "offset_to_clut_tex = \"" + HexToString( offset_to_clut_tex, 8, '0' ) + "\".\n" );
    u32 offset_to_tx_ty = offset_to_clut_tex + file12->GetU8( 4 + 7 ) * 4;
    LOGGER->Log( "offset_to_tx_ty = \"" + HexToString( offset_to_tx_ty, 8, '0' ) + "\".\n" );



    int number_of_monochrome_textured_quads = file->GetU16LE( offset_to_data + 0x02 );
    int number_of_monochrome_textured_triangles = file->GetU16LE( offset_to_data + 0x04 );
    int number_of_shaded_textured_quads = file->GetU16LE( offset_to_data + 0x06 );
    int number_of_shaded_textured_triangles = file->GetU16LE( offset_to_data + 0x08 );
    int number_of_gradated_quads = file->GetU16LE( offset_to_data + 0x0a );
    int number_of_gradated_triangles = file->GetU16LE( offset_to_data + 0x0c );
    int number_of_monochrome_quads = file->GetU16LE( offset_to_data + 0x0e );
    int number_of_monochrome_triangles = file->GetU16LE( offset_to_data + 0x10 );

    u32 pointer_to_vertex_groups = file->GetU32LE( offset_to_data + 0x14 );
    u32 pointer_to_vertex_data = file->GetU32LE( offset_to_data + 0x18 );
    u32 pointer_to_mesh_data = file->GetU32LE( offset_to_data + 0x1c );
    u32 pointer_to_texture_data = file->GetU32LE( offset_to_data + 0x20 );



    Ogre::SubMesh* sub_mesh = mesh->createSubMesh(/* name */);
    sub_mesh->setMaterialName( material_name );
    sub_mesh->useSharedVertices = false;
    sub_mesh->operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;

    // Allocate and prepare vertex data
    sub_mesh->vertexData = new Ogre::VertexData();
    sub_mesh->vertexData->vertexStart = 0;
    sub_mesh->vertexData->vertexCount = static_cast< size_t >(
        number_of_monochrome_textured_quads * 6 +
        number_of_monochrome_textured_triangles * 3/* +
        number_of_shaded_textured_quads * 6 +
        number_of_shaded_textured_triangles * 3 +
        number_of_gradated_quads * 6 +
        number_of_gradated_triangles * 3 +
        number_of_monochrome_quads * 6 +
        number_of_monochrome_triangles * 3*/ );

    sub_mesh->indexData = new Ogre::IndexData();
    sub_mesh->indexData->indexStart = 0;
    sub_mesh->indexData->indexCount = sub_mesh->vertexData->vertexCount;
    sub_mesh->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
        Ogre::HardwareIndexBuffer::IT_16BIT,
        sub_mesh->indexData->indexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    u16* idata = static_cast< u16* >( sub_mesh->indexData->indexBuffer->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );
    u32 cur_index = 0;

    Ogre::VertexDeclaration* decl = sub_mesh->vertexData->vertexDeclaration;
    Ogre::VertexBufferBinding* bind = sub_mesh->vertexData->vertexBufferBinding;
    // 1st buffer
    decl->addElement( POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
    Ogre::HardwareVertexBufferSharedPtr vbuf0 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( POSITION_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    bind->setBinding( POSITION_BINDING, vbuf0 );

    // 2nd buffer
    decl->addElement( COLOUR_BINDING, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE );
    Ogre::HardwareVertexBufferSharedPtr vbuf1 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( COLOUR_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    // Set vertex buffer binding so buffer 1 is bound to our colour buffer
    bind->setBinding( COLOUR_BINDING, vbuf1 );

    // 3rd buffer
    decl->addElement( TEXTURE_BINDING, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0 );
    Ogre::HardwareVertexBufferSharedPtr vbuf2 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( TEXTURE_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    bind->setBinding( TEXTURE_BINDING, vbuf2 );

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

    Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem();
    
    std::vector<Ogre::RGBA> coloursVec(sub_mesh->vertexData->vertexCount);

    Ogre::RGBA* colours = coloursVec.data();



    for( int i = 0; i < number_of_monochrome_textured_quads; ++i )
    {
        int index_a = file->GetU16LE( pointer_to_mesh_data + 0x0 );
        int index_b = file->GetU16LE( pointer_to_mesh_data + 0x2 );
        int index_c = file->GetU16LE( pointer_to_mesh_data + 0x4 );
        int index_d = file->GetU16LE( pointer_to_mesh_data + 0x6 );

        Ogre::Vector3 a( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x4 ) );
        Ogre::Vector3 b( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x4 ) );
        Ogre::Vector3 c( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x4 ) );
        Ogre::Vector3 d( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x4 ) );
        a /= 512;
        b /= 512;
        c /= 512;
        d /= 512;




        int image_id = file->GetU8( pointer_to_mesh_data + 0x13 );
        u16 blend = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 0 );
        u16 clut = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 2 );
        LOGGER->Log( "image_id = \"" + HexToString( image_id, 2, '0' ) + "\", clut = \"" + HexToString( clut, 4, '0' ) + "\", blend = \"" + HexToString( blend, 4, '0' ) + "\".\n" );
/*
        int clut_x = (clut & 0x003f) << 3;
        int clut_y = (clut & 0xffc0) >> 6;
        int bpp    = (tpage >> 0x7) & 0x3;
        int vram_x = (tpage & 0xf) * 64;
        int vram_y = ((tpage & 0x10) >> 4) * 256;
*/
        TexForGen texture;
        texture.palette_x = 128/*clut_x*/;
        texture.palette_y = 224/*clut_y*/;
        if( image_id == 1 )
        {
            texture.texture_x = 768/*vram_x*/;
        }
        else
        {
            texture.texture_x = 832/*vram_x*/;
        }
        texture.texture_y = 256/*vram_y*/;
        texture.bpp = BPP_8/*bpp*/;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at( 0, 0 );
        Ogre::Vector2 bt( 0, 0 );
        Ogre::Vector2 ct( 0, 0 );
        Ogre::Vector2 dt( 0, 0 );

        u16 vertex1_uv = file->GetU16LE( pointer_to_mesh_data + 0x8 );
        at.x = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        at.y = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        u16 vertex2_uv = file->GetU16LE( pointer_to_mesh_data + 0xa );
        bt.x = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        bt.y = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        u16 vertex3_uv = file->GetU16LE( pointer_to_mesh_data + 0xc );
        ct.x = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        ct.y = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        u16 vertex4_uv = file->GetU16LE( pointer_to_mesh_data + 0xe );
        dt.x = ( file->GetU8( pointer_to_texture_data + vertex4_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        dt.y = ( file->GetU8( pointer_to_texture_data + vertex4_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = d.x; *pPos++ = d.y; *pPos++ = d.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = dt.x; *tPos++ = dt.y;

        Ogre::ColourValue colour = Ogre::ColourValue( file->GetU8( pointer_to_mesh_data + 0x10 ) / 256.0f,
                                                      file->GetU8( pointer_to_mesh_data + 0x11 ) / 256.0f,
                                                      file->GetU8( pointer_to_mesh_data + 0x12 ) / 256.0f,
                                                      1.0f );

        rs->convertColourValue( colour, colours + cur_index + 0 );
        rs->convertColourValue( colour, colours + cur_index + 1 );
        rs->convertColourValue( colour, colours + cur_index + 2 );
        rs->convertColourValue( colour, colours + cur_index + 3 );
        rs->convertColourValue( colour, colours + cur_index + 4 );
        rs->convertColourValue( colour, colours + cur_index + 5 );

        idata[ cur_index + 0 ] = cur_index + 0;
        idata[ cur_index + 1 ] = cur_index + 1;
        idata[ cur_index + 2 ] = cur_index + 2;
        idata[ cur_index + 3 ] = cur_index + 3;
        idata[ cur_index + 4 ] = cur_index + 4;
        idata[ cur_index + 5 ] = cur_index + 5;

        Ogre::VertexBoneAssignment vba;
        vba.weight = 1.0f;

        vba.vertexIndex = cur_index + 0;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_a * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 1;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 2;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 3;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 4;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 5;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_d * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );



        cur_index += 6;
        pointer_to_mesh_data += 0x18;
    }



    for( int i = 0; i < number_of_monochrome_textured_triangles; ++i )
    {
        int index_a = file->GetU16LE( pointer_to_mesh_data + 0x0 );
        int index_b = file->GetU16LE( pointer_to_mesh_data + 0x2 );
        int index_c = file->GetU16LE( pointer_to_mesh_data + 0x4 );

        Ogre::Vector3 a( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x4 ) );
        Ogre::Vector3 b( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x4 ) );
        Ogre::Vector3 c( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x4 ) );
        a /= 512;
        b /= 512;
        c /= 512;

        int image_id = file->GetU8( pointer_to_mesh_data + 0x6 );
        u16 blend = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 0 );
        u16 clut = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 2 );
        LOGGER->Log( "image_id = \"" + HexToString( image_id, 2, '0' ) + "\", clut = \"" + HexToString( clut, 4, '0' ) + "\", blend = \"" + HexToString( blend, 4, '0' ) + "\".\n" );
/*
        int clut_x = (clut & 0x003f) << 3;
        int clut_y = (clut & 0xffc0) >> 6;
        int bpp    = (tpage >> 0x7) & 0x3;
        int vram_x = (tpage & 0xf) * 64;
        int vram_y = ((tpage & 0x10) >> 4) * 256;
*/

        TexForGen texture;
        texture.palette_x = 128/*clut_x*/;
        texture.palette_y = 224/*clut_y*/;
        if( image_id == 1 )
        {
            texture.texture_x = 768/*vram_x*/;
        }
        else
        {
            texture.texture_x = 832/*vram_x*/;
        }
        texture.texture_y = 256/*vram_y*/;
        texture.bpp = BPP_8/*bpp*/;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at( 0, 0 );
        Ogre::Vector2 bt( 0, 0 );
        Ogre::Vector2 ct( 0, 0 );

        u16 vertex1_uv = file->GetU16LE( pointer_to_mesh_data + 0xc );
        at.x = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        at.y = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        u16 vertex2_uv = file->GetU16LE( pointer_to_mesh_data + 0xe );
        bt.x = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        bt.y = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        u16 vertex3_uv = file->GetU16LE( pointer_to_mesh_data + 0x10 );
        ct.x = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        ct.y = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;

        Ogre::ColourValue colour = Ogre::ColourValue( file->GetU8( pointer_to_mesh_data + 0x08 ) / 256.0f,
                                                      file->GetU8( pointer_to_mesh_data + 0x09 ) / 256.0f,
                                                      file->GetU8( pointer_to_mesh_data + 0x0a ) / 256.0f,
                                                      1.0f );

        rs->convertColourValue( colour, colours + cur_index + 0 );
        rs->convertColourValue( colour, colours + cur_index + 1 );
        rs->convertColourValue( colour, colours + cur_index + 2 );

        idata[ cur_index + 0 ] = cur_index + 0;
        idata[ cur_index + 1 ] = cur_index + 1;
        idata[ cur_index + 2 ] = cur_index + 2;

        Ogre::VertexBoneAssignment vba;
        vba.weight = 1.0f;

        vba.vertexIndex = cur_index + 0;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_a * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 1;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 2;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );

        cur_index += 3;
        pointer_to_mesh_data += 0x14;
    }



    vbuf0->unlock();
    vbuf1->writeData( 0, vbuf1->getSizeInBytes(), colours, true );
    vbuf2->unlock();

    sub_mesh->indexData->indexBuffer->unlock();
    // Optimize index data
    sub_mesh->indexData->optimiseVertexCacheTriList();



    delete file12;
}
Exemple #25
0
    void Utils::GetMeshInformation(
        const Ogre::MeshPtr mesh,
        size_t &vertexCount,
        Ogre::Vector3* &vertices,
        size_t &indexCount,
        unsigned* &indices) 
    {
        bool addShared = false;
        size_t currentOffset = 0;
        size_t shared_offset = 0;
        size_t nextOffset = 0;
        size_t indexOffset = 0;


        vertexCount = indexCount = 0;

        for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) {
            Ogre::SubMesh* submesh = mesh->getSubMesh(i);
            if(submesh->useSharedVertices) {
                if( !addShared ) {
                    vertexCount += mesh->sharedVertexData->vertexCount;
                    addShared = true;
                }
            }
            else {
                vertexCount += submesh->vertexData->vertexCount;
            }
            indexCount += submesh->indexData->indexCount;
        }


        vertices = new Ogre::Vector3[vertexCount];
        indices = new unsigned[indexCount];

        addShared = false;

        for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) {
            Ogre::SubMesh* submesh = mesh->getSubMesh(i);

            Ogre::VertexData* vertexData = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;

            if ((!submesh->useSharedVertices) || (submesh->useSharedVertices && !addShared)) {
                if(submesh->useSharedVertices) {
                    addShared = true;
                    shared_offset = currentOffset;
                }

                const Ogre::VertexElement* posElem =
                    vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);

                Ogre::HardwareVertexBufferSharedPtr vbuf =
                    vertexData->vertexBufferBinding->getBuffer(posElem->getSource());

                unsigned char* vertex =
                    static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));

                float* pReal;

                for( size_t j = 0; j < vertexData->vertexCount; ++j, vertex += vbuf->getVertexSize()) {
                    posElem->baseVertexPointerToElement(vertex, &pReal);
                    Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]);
                    vertices[currentOffset + j] = pt;
                }
                
                vbuf->unlock();
                nextOffset += vertexData->vertexCount;
            }


            Ogre::IndexData* indexData = submesh->indexData;
            size_t numTris = indexData->indexCount / 3;
            Ogre::HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer;
            
            bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);

            unsigned long* pLong = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
            unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong);

            size_t offset = (submesh->useSharedVertices)? shared_offset : currentOffset;

            if ( use32bitindexes ) {
                for ( size_t k = 0; k < numTris*3; ++k) {
                    indices[indexOffset++] = pLong[k] + static_cast<unsigned long>(offset);
                }
            }
            else {
                for ( size_t k = 0; k < numTris*3; ++k) {
                    indices[indexOffset++] = static_cast<unsigned long>(pShort[k]) +
                                              static_cast<unsigned long>(offset);
                }
            }

            ibuf->unlock();
            currentOffset = nextOffset;
        }
    }
bool ModelBackgroundLoader::poll(const TimeFrame& timeFrame)
{
#if OGRE_THREAD_SUPPORT
	if (mState == LS_UNINITIALIZED) {
		//Start to load the meshes
		for (SubModelDefinitionsStore::const_iterator I_subModels = mModel.getDefinition()->getSubModelDefinitions().begin(); I_subModels != mModel.getDefinition()->getSubModelDefinitions().end(); ++I_subModels) {
			Ogre::MeshPtr meshPtr = static_cast<Ogre::MeshPtr> (Ogre::MeshManager::getSingleton().getByName((*I_subModels)->getMeshName()));
			if (meshPtr.isNull() || !meshPtr->isPrepared()) {
				try {
					Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().prepare(Ogre::MeshManager::getSingleton().getResourceType(), (*I_subModels)->getMeshName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener());
					if (ticket) {
						addTicket(ticket);
					}
				} catch (const std::exception& ex) {
					S_LOG_FAILURE("Could not load the mesh " << (*I_subModels)->getMeshName() << " when loading model " << mModel.getName() << "." << ex);
					continue;
				}
			}
		}
		mState = LS_MESH_PREPARING;
		return poll(timeFrame);
	} else if (mState == LS_MESH_PREPARING) {
		if (areAllTicketsProcessed()) {
			mState = LS_MESH_PREPARED;
			return poll(timeFrame);
		}
	} else if (mState == LS_MESH_PREPARED) {
		for (SubModelDefinitionsStore::const_iterator I_subModels = mModel.getDefinition()->getSubModelDefinitions().begin(); I_subModels != mModel.getDefinition()->getSubModelDefinitions().end(); ++I_subModels) {
			Ogre::MeshPtr meshPtr = static_cast<Ogre::MeshPtr> (Ogre::MeshManager::getSingleton().getByName((*I_subModels)->getMeshName()));
			if (!meshPtr.isNull()) {
				if (!meshPtr->isLoaded()) {
#if OGRE_THREAD_SUPPORT == 1
					Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().load(Ogre::MeshManager::getSingleton().getResourceType(), meshPtr->getName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener());
					if (ticket) {
						//						meshPtr->setBackgroundLoaded(true);
						addTicket(ticket);
					}
#else
					if (!timeFrame.isTimeLeft()) {
						return false;
					}
					try {
						meshPtr->load();
					} catch (const std::exception& ex) {
						S_LOG_FAILURE("Could not load the mesh " << meshPtr->getName() << " when loading model " << mModel.getName() << "." << ex);
						continue;
					}
#endif
				}
			}
		}
		mState = LS_MESH_LOADING;
		return poll(timeFrame);
	} else if (mState == LS_MESH_LOADING) {
		if (areAllTicketsProcessed()) {
			mState = LS_MESH_LOADED;
			return poll(timeFrame);
		}
	} else if (mState == LS_MESH_LOADED) {

		for (SubModelDefinitionsStore::const_iterator I_subModels = mModel.getDefinition()->getSubModelDefinitions().begin(); I_subModels != mModel.getDefinition()->getSubModelDefinitions().end(); ++I_subModels) {
			Ogre::MeshPtr meshPtr = static_cast<Ogre::MeshPtr> (Ogre::MeshManager::getSingleton().getByName((*I_subModels)->getMeshName()));
			if (!meshPtr.isNull()) {
				if (meshPtr->isLoaded()) {
					Ogre::Mesh::SubMeshIterator subMeshI = meshPtr->getSubMeshIterator();
					while (subMeshI.hasMoreElements()) {
						Ogre::SubMesh* submesh(subMeshI.getNext());
						Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(submesh->getMaterialName()));
						if (materialPtr.isNull() || !materialPtr->isPrepared()) {
//							S_LOG_VERBOSE("Preparing material " << materialPtr->getName());
							Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().prepare(Ogre::MaterialManager::getSingleton().getResourceType(),submesh->getMaterialName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener());
							if (ticket) {
								addTicket(ticket);
							}
						}
					}
				}
			}
			for (PartDefinitionsStore::const_iterator I_parts = (*I_subModels)->getPartDefinitions().begin(); I_parts != (*I_subModels)->getPartDefinitions().end(); ++I_parts) {
				if ((*I_parts)->getSubEntityDefinitions().size() > 0) {
					for (SubEntityDefinitionsStore::const_iterator I_subEntities = (*I_parts)->getSubEntityDefinitions().begin(); I_subEntities != (*I_parts)->getSubEntityDefinitions().end(); ++I_subEntities) {
						const std::string& materialName = (*I_subEntities)->getMaterialName();
						if (materialName != "") {
							Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(materialName));
							if (materialPtr.isNull() || !materialPtr->isPrepared()) {
//								S_LOG_VERBOSE("Preparing material " << materialName);
								Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().prepare(Ogre::MaterialManager::getSingleton().getResourceType(), materialName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener());
								if (ticket) {
									addTicket(ticket);
								}
							}
						}
					}
				}
			}
		}

		mState = LS_MATERIAL_PREPARING;
		return poll(timeFrame);
	} else if (mState == LS_MATERIAL_PREPARING) {
		if (areAllTicketsProcessed()) {
			mState = LS_MATERIAL_PREPARED;
			return poll(timeFrame);
		}
	} else if (mState == LS_MATERIAL_PREPARED) {
		for (SubModelDefinitionsStore::const_iterator I_subModels = mModel.getDefinition()->getSubModelDefinitions().begin(); I_subModels != mModel.getDefinition()->getSubModelDefinitions().end(); ++I_subModels) {
			Ogre::MeshPtr meshPtr = static_cast<Ogre::MeshPtr> (Ogre::MeshManager::getSingleton().getByName((*I_subModels)->getMeshName()));
			Ogre::Mesh::SubMeshIterator subMeshI = meshPtr->getSubMeshIterator();
			while (subMeshI.hasMoreElements()) {
				Ogre::SubMesh* submesh(subMeshI.getNext());
				Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(submesh->getMaterialName()));
				if (!materialPtr.isNull() && !materialPtr->isLoaded()) {

#if OGRE_THREAD_SUPPORT == 1
					Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().load(Ogre::MaterialManager::getSingleton().getResourceType(), materialPtr->getName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener());
					if (ticket) {
						//						materialPtr->setBackgroundLoaded(true);
						addTicket(ticket);
					}
#else
					Ogre::Material::TechniqueIterator techIter = materialPtr->getSupportedTechniqueIterator();
					while (techIter.hasMoreElements()) {
						Ogre::Technique* tech = techIter.getNext();
						Ogre::Technique::PassIterator passIter = tech->getPassIterator();
						while (passIter.hasMoreElements()) {
							Ogre::Pass* pass = passIter.getNext();
							Ogre::Pass::TextureUnitStateIterator tusIter = pass->getTextureUnitStateIterator();
							while (tusIter.hasMoreElements()) {
								Ogre::TextureUnitState* tus = tusIter.getNext();
								unsigned int frames = tus->getNumFrames();
								for (unsigned int i = 0; i < frames; ++i) {
									if (!timeFrame.isTimeLeft()) {
										return false;
									}
									//This will automatically load the texture.
//									S_LOG_VERBOSE("Loading texture " << tus->getTextureName());
									Ogre::TexturePtr texturePtr = tus->_getTexturePtr(i);
								}
							}
						}
					}
					if (!timeFrame.isTimeLeft()) {
						return false;
					}
//					S_LOG_VERBOSE("Loading material " << materialPtr->getName());
					materialPtr->load();
#endif

				}
			}
			for (PartDefinitionsStore::const_iterator I_parts = (*I_subModels)->getPartDefinitions().begin(); I_parts != (*I_subModels)->getPartDefinitions().end(); ++I_parts) {
				if ((*I_parts)->getSubEntityDefinitions().size() > 0) {
					for (SubEntityDefinitionsStore::const_iterator I_subEntities = (*I_parts)->getSubEntityDefinitions().begin(); I_subEntities != (*I_parts)->getSubEntityDefinitions().end(); ++I_subEntities) {
						const std::string& materialName = (*I_subEntities)->getMaterialName();
						if (materialName != "") {
							Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(materialName));
							if (!materialPtr.isNull() && !materialPtr->isLoaded()) {
#if OGRE_THREAD_SUPPORT == 1
								Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().load(Ogre::MaterialManager::getSingleton().getResourceType(), materialPtr->getName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener());
								if (ticket) {
									addTicket(ticket);
								}
#else
								Ogre::Material::TechniqueIterator techIter = materialPtr->getSupportedTechniqueIterator();
								while (techIter.hasMoreElements()) {
									Ogre::Technique* tech = techIter.getNext();
									Ogre::Technique::PassIterator passIter = tech->getPassIterator();
									while (passIter.hasMoreElements()) {
										Ogre::Pass* pass = passIter.getNext();
										Ogre::Pass::TextureUnitStateIterator tusIter = pass->getTextureUnitStateIterator();
										while (tusIter.hasMoreElements()) {
											Ogre::TextureUnitState* tus = tusIter.getNext();
											unsigned int frames = tus->getNumFrames();
											for (unsigned int i = 0; i < frames; ++i) {
												if (!timeFrame.isTimeLeft()) {
													return false;
												}
												//This will automatically load the texture.
//												S_LOG_VERBOSE("Loading texture " << tus->getTextureName());
												Ogre::TexturePtr texturePtr = tus->_getTexturePtr(i);
											}
										}
									}
								}
								if (!timeFrame.isTimeLeft()) {
									return false;
								}
//								S_LOG_VERBOSE("Loading material " << materialPtr->getName());
								materialPtr->load();
#endif
							}
						}
					}
				}
			}
		}

		mState = LS_MATERIAL_LOADING;
		return poll(timeFrame);
	} else if (mState == LS_MATERIAL_LOADING) {
		if (areAllTicketsProcessed()) {
			mState = LS_DONE;
			return true;
		}

	} else {
		return true;
	}
	return false;
#else
	//If there's no threading support, just return here.
	return true;
#endif
}
Exemple #27
0
void
MeshExtractor( const MeshData& mesh_data, const Ogre::String& material_name, File* file, int offset_to_data, VectorTexForGen& textures, const Ogre::MeshPtr& mesh, const Ogre::String& name, int bone_id )
{
    int offset_to_vertex     = offset_to_data;
    int offset_to_triangle_t = offset_to_vertex + 0x04 + file->GetU32LE( offset_to_vertex );
    int number_of_triangle_t = file->GetU16LE( offset_to_triangle_t );
    u16 tpage  = file->GetU16LE( offset_to_triangle_t + 0x02 );
    int offset_to_quad_t     = offset_to_triangle_t + 0x04 + number_of_triangle_t * 0x10;
    int number_of_quad_t     = file->GetU16LE( offset_to_quad_t );
    int offset_to_triangle   = offset_to_quad_t + 0x4 + number_of_quad_t * 0x14;
    int number_of_triangle   = file->GetU16LE( offset_to_triangle );
    int offset_to_quad       = offset_to_triangle + 0x4 + number_of_triangle * 0x14;
    int number_of_quad       = file->GetU16LE( offset_to_quad );

    Ogre::SubMesh* sub_mesh = mesh->createSubMesh( name );
    sub_mesh->setMaterialName( material_name );
    sub_mesh->useSharedVertices = false;
    sub_mesh->operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;

    // Allocate and prepare vertex data
    sub_mesh->vertexData = new Ogre::VertexData();
    sub_mesh->vertexData->vertexStart = 0;
    sub_mesh->vertexData->vertexCount = static_cast< size_t >( number_of_triangle_t * 3 + number_of_quad_t * 6 + number_of_triangle * 3 + number_of_quad * 6 );

    sub_mesh->indexData = new Ogre::IndexData();
    sub_mesh->indexData->indexStart = 0;
    sub_mesh->indexData->indexCount = sub_mesh->vertexData->vertexCount;
    sub_mesh->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
        Ogre::HardwareIndexBuffer::IT_16BIT,
        sub_mesh->indexData->indexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    u16* idata = static_cast< u16* >( sub_mesh->indexData->indexBuffer->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );
    u32 cur_index = 0;

    Ogre::VertexDeclaration* decl = sub_mesh->vertexData->vertexDeclaration;
    Ogre::VertexBufferBinding* bind = sub_mesh->vertexData->vertexBufferBinding;
    // 1st buffer
    decl->addElement( POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
    Ogre::HardwareVertexBufferSharedPtr vbuf0 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( POSITION_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    bind->setBinding( POSITION_BINDING, vbuf0 );

    // 2nd buffer
    decl->addElement( COLOUR_BINDING, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE );
    Ogre::HardwareVertexBufferSharedPtr vbuf1 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( COLOUR_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    // Set vertex buffer binding so buffer 1 is bound to our colour buffer
    bind->setBinding( COLOUR_BINDING, vbuf1 );

    // 3rd buffer
    decl->addElement( TEXTURE_BINDING, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0 );
    Ogre::HardwareVertexBufferSharedPtr vbuf2 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( TEXTURE_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    bind->setBinding( TEXTURE_BINDING, vbuf2 );

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

    Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem();
    Ogre::RGBA colours[ sub_mesh->vertexData->vertexCount ];



    // add textured triangle
    for (int j = 0; j < number_of_triangle_t; ++j)
    {
        int offset_a = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0x0);
        int offset_b = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0x2);
        int offset_c = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0x4);

        Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04));
        Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04));
        Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04));
        a /= 512;
        b /= 512;
        c /= 512;

        u16 clut = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0xa);
        int clut_x = (clut & 0x003f) << 3;
        int clut_y = (clut & 0xffc0) >> 6;
        int bpp    = (tpage >> 0x7) & 0x3;
        int vram_x = (tpage & 0xf) * 64;
        int vram_y = ((tpage & 0x10) >> 4) * 256;
        TexForGen texture;
        texture.palette_x = clut_x;
        texture.palette_y = clut_y;
        texture.texture_x = vram_x;
        texture.texture_y = vram_y;
        texture.bpp = ( BPP )bpp;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at(0, 0);
        Ogre::Vector2 bt(0, 0);
        Ogre::Vector2 ct(0, 0);

        int x = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x8) + texture.start_x;
        at.x = x / (float)mesh_data.tex_width;
        int y = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x9) + texture.start_y;
        at.y = y / (float)mesh_data.tex_height;
        x = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xc) + texture.start_x;
        bt.x = x / (float)mesh_data.tex_width;
        y = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xd) + texture.start_y;
        bt.y = y / (float)mesh_data.tex_height;
        x = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xe) + texture.start_x;
        ct.x = x / (float)mesh_data.tex_width;
        y = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xf) + texture.start_y;
        ct.y = y / (float)mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;

        Ogre::ColourValue colour = Ogre::ColourValue(file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x6) / 256.0f,
                                                     file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x6) / 256.0f,
                                                     file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x6) / 256.0f,
                                                     1.0f);

        rs->convertColourValue(colour, colours + cur_index + 0);
        rs->convertColourValue(colour, colours + cur_index + 1);
        rs->convertColourValue(colour, colours + cur_index + 2);

        idata[cur_index + 0] = cur_index + 0;
        idata[cur_index + 1] = cur_index + 1;
        idata[cur_index + 2] = cur_index + 2;

        cur_index += 3;
    }



    // add textured quad
    for (int j = 0; j < number_of_quad_t; ++j)
    {
        int offset_a = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x0);
        int offset_b = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x2);
        int offset_c = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x4);
        int offset_d = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x6);

        Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04));
        Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04));
        Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04));
        Ogre::Vector3 d((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 04));
        a /= 512;
        b /= 512;
        c /= 512;
        d /= 512;

        u16 clut = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0xa);
        int clut_x = (clut & 0x003f) << 3;
        int clut_y = (clut & 0xffc0) >> 6;
        int bpp    = (tpage >> 0x7) & 0x3;
        int vram_x = (tpage & 0xf) * 64;
        int vram_y = ((tpage & 0x10) >> 4) * 256;
        TexForGen texture;
        texture.palette_x = clut_x;
        texture.palette_y = clut_y;
        texture.texture_x = vram_x;
        texture.texture_y = vram_y;
        texture.bpp = ( BPP )bpp;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at(0, 0);
        Ogre::Vector2 bt(0, 0);
        Ogre::Vector2 ct(0, 0);
        Ogre::Vector2 dt(0, 0);

        int x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x8) + texture.start_x;
        at.x = x / (float)mesh_data.tex_width;
        int y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x9) + texture.start_y;
        at.y = y / (float)mesh_data.tex_height;

        x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xc) + texture.start_x;
        bt.x = x / (float)mesh_data.tex_width;
        y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xd) + texture.start_y;
        bt.y = y / (float)mesh_data.tex_height;

        x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xe) + texture.start_x;
        ct.x = x / (float)mesh_data.tex_width;
        y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xf) + texture.start_y;
        ct.y = y / (float)mesh_data.tex_height;

        x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x10) + texture.start_x;
        dt.x = x / (float)mesh_data.tex_width;
        y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x11) + texture.start_y;
        dt.y = y / (float)mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = d.x; *pPos++ = d.y; *pPos++ = d.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = dt.x; *tPos++ = dt.y;

        Ogre::ColourValue colour = Ogre::ColourValue(file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x12) / 256.0f,
                                                     file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x12) / 256.0f,
                                                     file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x12) / 256.0f,
                                                     1.0f);

        rs->convertColourValue(colour, colours + cur_index + 0);
        rs->convertColourValue(colour, colours + cur_index + 1);
        rs->convertColourValue(colour, colours + cur_index + 2);
        rs->convertColourValue(colour, colours + cur_index + 3);
        rs->convertColourValue(colour, colours + cur_index + 4);
        rs->convertColourValue(colour, colours + cur_index + 5);

        idata[cur_index + 0] = cur_index + 0;
        idata[cur_index + 1] = cur_index + 1;
        idata[cur_index + 2] = cur_index + 2;
        idata[cur_index + 3] = cur_index + 3;
        idata[cur_index + 4] = cur_index + 4;
        idata[cur_index + 5] = cur_index + 5;

        cur_index += 6;
    }



    // add color triangle
    for (int j = 0; j < number_of_triangle; ++j)
    {
        int offset_a = file->GetU16LE(offset_to_triangle + 0x4 + j * 0x14 + 0x0);
        int offset_b = file->GetU16LE(offset_to_triangle + 0x4 + j * 0x14 + 0x2);
        int offset_c = file->GetU16LE(offset_to_triangle + 0x4 + j * 0x14 + 0x4);

        Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04));
        Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04));
        Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04));
        a /= 512;
        b /= 512;
        c /= 512;

        TexForGen texture;
        texture.palette_x = 0;
        texture.palette_y = 0;
        texture.texture_x = 0;
        texture.texture_y = 0;
        texture.bpp = BPP_BLACK;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at(0, 0);
        Ogre::Vector2 bt(0, 0);
        Ogre::Vector2 ct(0, 0);

        at.x = bt.x = ct.x = texture.start_x / (float)mesh_data.tex_width;
        at.y = bt.y = ct.y = texture.start_y / (float)mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;

        Ogre::ColourValue a_colour = Ogre::ColourValue(file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x08) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x09) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0a) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0b) / 256.0f);
        Ogre::ColourValue b_colour = Ogre::ColourValue(file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0c) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0d) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0e) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0f) / 256.0f);
        Ogre::ColourValue c_colour = Ogre::ColourValue(file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x10) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x11) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x12) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x13) / 256.0f);

        rs->convertColourValue(a_colour, colours + cur_index + 0);
        rs->convertColourValue(c_colour, colours + cur_index + 1);
        rs->convertColourValue(b_colour, colours + cur_index + 2);

        idata[cur_index + 0] = cur_index + 0;
        idata[cur_index + 1] = cur_index + 1;
        idata[cur_index + 2] = cur_index + 2;

        cur_index += 3;
    }



    // add color quad
    for (int j = 0; j < number_of_quad; ++j)
    {
        int offset_a = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x0);
        int offset_b = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x2);
        int offset_c = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x4);
        int offset_d = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x6);

        Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04));
        Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04));
        Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04));
        Ogre::Vector3 d((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 04));
        a /= 512;
        b /= 512;
        c /= 512;
        d /= 512;

        TexForGen texture;
        texture.palette_x = 0;
        texture.palette_y = 0;
        texture.texture_x = 0;
        texture.texture_y = 0;
        texture.bpp = BPP_BLACK;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at(0, 0);
        Ogre::Vector2 bt(0, 0);
        Ogre::Vector2 ct(0, 0);
        Ogre::Vector2 dt(0, 0);

        at.x = bt.x = ct.x = dt.x = texture.start_x / (float)mesh_data.tex_width;
        at.y = bt.y = ct.y = dt.y = texture.start_y / (float)mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = d.x; *pPos++ = d.y; *pPos++ = d.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = dt.x; *tPos++ = dt.y;

        Ogre::ColourValue a_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x08) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x09) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0a) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0b) / 256.0f);
        Ogre::ColourValue b_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0c) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0d) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0e) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0f) / 256.0f);
        Ogre::ColourValue c_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x10) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x11) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x12) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x13) / 256.0f);
        Ogre::ColourValue d_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x14) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x15) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x16) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x17) / 256.0f);

        rs->convertColourValue(a_colour, colours + cur_index + 0);
        rs->convertColourValue(c_colour, colours + cur_index + 1);
        rs->convertColourValue(b_colour, colours + cur_index + 2);
        rs->convertColourValue(b_colour, colours + cur_index + 3);
        rs->convertColourValue(c_colour, colours + cur_index + 4);
        rs->convertColourValue(d_colour, colours + cur_index + 5);

        idata[cur_index + 0] = cur_index + 0;
        idata[cur_index + 1] = cur_index + 1;
        idata[cur_index + 2] = cur_index + 2;
        idata[cur_index + 3] = cur_index + 3;
        idata[cur_index + 4] = cur_index + 4;
        idata[cur_index + 5] = cur_index + 5;

        cur_index += 6;
    }

    vbuf0->unlock();
    vbuf1->writeData(0, vbuf1->getSizeInBytes(), colours, true);
    vbuf2->unlock();

    sub_mesh->indexData->indexBuffer->unlock();
    // Optimize index data
    sub_mesh->indexData->optimiseVertexCacheTriList();

    if (bone_id != -1)
    {
        LOGGER->Log("Assign bones to vertexes\n");

        int vertex_number = sub_mesh->vertexData->vertexCount;
        for( int i = 0; i < vertex_number; ++i )
        {
            Ogre::VertexBoneAssignment vba;
            vba.vertexIndex = i;
            vba.boneIndex = bone_id;
            vba.weight = 1.0f;
            sub_mesh->addBoneAssignment( vba );
        }
    }
}
// ===============================================================================
// We updated a mesh. Now we have to find all the scene nodes that use this mesh
// and tell them something changed.
void OLMeshTracker::UpdateSceneNodesForMesh(Ogre::String meshName) {
	Ogre::MeshPtr meshP = (Ogre::MeshPtr)Ogre::MeshManager::getSingleton().getByName(meshName);
	if (!meshP.isNull()) {
		UpdateSceneNodesForMesh(meshP);
	}
}
Exemple #29
0
void OgreExporter_c::ExportLevel(const WadLevel_c &level, const WadFile_c &file)
{	
	this->ExportLevelMaterials(level, file);

	Ogre::DefaultHardwareBufferManager hardwareBufferManager;
	Ogre::ManualObject manualMesh(level.GetName());	

	const LineDef_s *lineDefs = level.GetLineDefs();
	const size_t numLineDefs = level.GetNumLineDefs();

	const SideDef_s *sideDefs = level.GetSideDefs();
	const Sector_s *sectors = level.GetSectors();

	const Vertex_s *vertices = level.GetVertices();
	for(size_t i = 0;i < numLineDefs; ++i)
	{
		if(lineDefs[i].iLeftSideDef >= 0)
		{
			const SideDef_s &leftSide = sideDefs[lineDefs[i].iLeftSideDef];
			const Sector_s &leftSideSector = sectors[leftSide.iSector];

			const SideDef_s &rightSide = sideDefs[lineDefs[i].iRightSideDef];
			const Sector_s &rightSideSector = sectors[rightSide.iSector];


			if(leftSide.uMiddleTexture.uName != '-')
			{
				this->ExportWallMesh(manualMesh, leftSideSector.iFloorHeight, leftSideSector.iCeilHeight, leftSide.uMiddleTexture, leftSide.iOffsetX, leftSide.iOffsety, vertices, lineDefs[i], file);				
			}

			if(leftSide.uLowerTexture.uName != '-')
			{
				this->ExportWallMesh(manualMesh, leftSideSector.iFloorHeight, leftSideSector.iFloorHeight, leftSide.uLowerTexture, leftSide.iOffsetX, leftSide.iOffsety, vertices, lineDefs[i], file);				
			}

			if(leftSide.uUpperTexture.uName != '-')
			{
				this->ExportWallMesh(manualMesh, rightSideSector.iCeilHeight, leftSideSector.iCeilHeight, leftSide.uUpperTexture, leftSide.iOffsetX, leftSide.iOffsety, vertices, lineDefs[i], file);				
			}
		}
		
		if(lineDefs[i].iRightSideDef >= 0)
		{			
			const SideDef_s &rightSide = sideDefs[lineDefs[i].iRightSideDef];
			const Sector_s &rightSideSector = sectors[rightSide.iSector];

			if(rightSide.uLowerTexture.uName != '-')
			{
				const SideDef_s &leftSide = sideDefs[lineDefs[i].iLeftSideDef];
				const Sector_s &leftSideSector = sectors[leftSide.iSector];

				this->ExportWallMesh(manualMesh, rightSideSector.iFloorHeight, leftSideSector.iFloorHeight, rightSide.uLowerTexture, rightSide.iOffsetX, rightSide.iOffsety, vertices, lineDefs[i], file);				
			}	

			if(rightSide.uMiddleTexture.uName != '-')
			{
				this->ExportWallMesh(manualMesh, rightSideSector.iFloorHeight, rightSideSector.iCeilHeight, rightSide.uMiddleTexture, rightSide.iOffsetX, rightSide.iOffsety, vertices, lineDefs[i], file);				
			}		

			if(rightSide.uUpperTexture.uName != '-')
			{
				const SideDef_s &leftSide = sideDefs[lineDefs[i].iLeftSideDef];
				const Sector_s &leftSideSector = sectors[leftSide.iSector];

				this->ExportWallMesh(manualMesh, leftSideSector.iCeilHeight, rightSideSector.iCeilHeight, rightSide.uUpperTexture, rightSide.iOffsetX, rightSide.iOffsety, vertices, lineDefs[i], file);				
			}	
		}
	}

	namespace fs = boost::filesystem;

	fs::path path(strLevelDirectory);

	std::string levelName = level.GetName();
	levelName += ".mesh";

	path /= levelName;	

	Ogre::LogManager logManager;
	logManager.createLog("ogre.log", true, true, false);

	Ogre::ResourceGroupManager resourceGroupManager;
	Ogre::MeshManager meshManager;
	Ogre::LodStrategyManager logStrategyManager;
	Ogre::MeshPtr mesh = manualMesh.convertToMesh(level.GetName());

	Ogre::MeshSerializer serializer;
	serializer.exportMesh(mesh.get(), path.string());

	mesh.setNull();

	resourceGroupManager.shutdownAll();	

	this->CreateResourcesCfg();
}
Exemple #30
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;
 }