public List <string> GetSubMeshDefaultMaterials(string currentEntity) { List <string> defaultMaterials = new List <string>(); if (!mMgr.HasEntity(currentEntity)) { return(defaultMaterials); } try { Mesh currentMesh = mMgr.GetEntity(currentEntity).GetMesh(); Mesh.SubMeshIterator meshIter = currentMesh.GetSubMeshIterator(); while (meshIter.MoveNext()) { defaultMaterials.Add(meshIter.Current.MaterialName); } } catch (Exception e) { //error while trying to get submesh details, print out error for now - todo, change later to be more user friendly defaultMaterials.Add(e.Message); } return(defaultMaterials); }
/**************** New Functions Begin ***************/ /// <summary> /// Generate navmesh by entity /// </summary> /// <param name="ent">Ogre Entity</param> /// <returns>Navmesh</returns> public static Navmesh LoadNavmesh(Entity ent) { bool addedSharedVertex = false; vertices.Clear(); faces.Clear(); MeshPtr mesh = ent.GetMesh(); Mesh.SubMeshIterator subIterator = mesh.GetSubMeshIterator(); uint vertexNum = 0; uint vertexOffset = mesh.sharedVertexData.vertexStart; MyVector3 <float>[] verticeArray = new MyVector3 <float> [vertexNum]; VertexElement posElem = mesh.sharedVertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_POSITION); HardwareVertexBufferSharedPtr vertexBuffer = mesh.sharedVertexData.vertexBufferBinding.GetBuffer(posElem.Source); while (subIterator.MoveNext()) { SubMesh subMesh = subIterator.Current; VertexData vertexData = subMesh.useSharedVertices ? mesh.sharedVertexData : subMesh.vertexData; HardwareIndexBufferSharedPtr indexBuffer = subMesh.indexData.indexBuffer; HardwareIndexBuffer.IndexType indexType = indexBuffer.Type; uint indexCount = subMesh.indexData.indexCount; uint trisNum = indexCount / 3; uint[] indcies = new uint[indexCount]; uint indexOffset = subMesh.indexData.indexStart; if (subMesh.useSharedVertices) { if (!addedSharedVertex) { vertexNum += mesh.sharedVertexData.vertexCount; addedSharedVertex = true; } } else { vertexNum += subMesh.vertexData.vertexCount; } unsafe { uint * pLong = (uint *)(indexBuffer.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY)); ushort *pShort = (ushort *)pLong; for (int i = 0; i < indexCount; i++) { if (indexType == HardwareIndexBuffer.IndexType.IT_32BIT) { indcies[indexOffset] = pLong[i] + vertexNum; } else { indcies[indexOffset] = pShort[i] + vertexNum; } indexOffset++; } } int indexLength = indcies.Length / 3; for (int i = 0; i < indexLength; i++) { faces.Add(new MyVector3 <ushort>( (ushort)indcies[i * 3 + 0], (ushort)indcies[i * 3 + 1], (ushort)indcies[i * 3 + 2] )); } indexBuffer.Unlock(); if (subMesh.vertexData != null) { vertexNum = subMesh.vertexData.vertexCount; vertexOffset = subMesh.vertexData.vertexStart; verticeArray = new MyVector3 <float> [vertexNum]; posElem = subMesh.vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_POSITION); vertexBuffer = subMesh.vertexData.vertexBufferBinding.GetBuffer(posElem.Source); unsafe { byte * vertexMemory = (byte *)vertexBuffer.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY); float *pVertexBuffer; for (int i = 0; i < vertexNum; i++) { posElem.BaseVertexPointerToElement(vertexMemory, &pVertexBuffer); verticeArray[vertexOffset] = (new MyVector3 <float>( pVertexBuffer[0], pVertexBuffer[1], pVertexBuffer[2] )); vertexMemory += vertexBuffer.VertexSize; vertexOffset++; } } for (int i = 0; i < verticeArray.Length; i++) { vertices.Add(verticeArray[i]); } vertexBuffer.Unlock(); } } vertexNum = mesh.sharedVertexData.vertexCount; vertexOffset = mesh.sharedVertexData.vertexStart; verticeArray = new MyVector3 <float> [vertexNum]; posElem = mesh.sharedVertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_POSITION); vertexBuffer = mesh.sharedVertexData.vertexBufferBinding.GetBuffer(posElem.Source); unsafe { byte * vertexMemory = (byte *)vertexBuffer.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY); float *pVertexBuffer; for (int i = 0; i < vertexNum; i++) { posElem.BaseVertexPointerToElement(vertexMemory, &pVertexBuffer); verticeArray[vertexOffset] = (new MyVector3 <float>( pVertexBuffer[0], pVertexBuffer[1], pVertexBuffer[2] )); vertexMemory += vertexBuffer.VertexSize; vertexOffset++; } } for (int i = 0; i < verticeArray.Length; i++) { vertices.Add(verticeArray[i]); } vertexBuffer.Unlock(); return(GenerateNavmesh()); }
//Keeping this code in case I need to use it for the Level Editor //Instead of changing the Scale on each model to look roughly the same, I know change where the camera is located //Whereas I might want it the other way in the level editor because I'll care about relative sizes of the models //public void AutoScale(string currentEntity, double renderWindowHeight, double renderWindowWidth) //{ // if (!mMgr.HasEntity(currentEntity)) // return; // Entity ent = mMgr.GetEntity(currentEntity); // Mesh currentMesh = ent.GetMesh(); //helpful: foo.numlod, numSubMeshes, numAnimations // float posYScale = (float)((renderWindowHeight / 2) / (currentMesh.Bounds.Center.y + currentMesh.Bounds.HalfSize.y)); // float posXScale = (float)((renderWindowWidth / 2) / (currentMesh.Bounds.Center.x + currentMesh.Bounds.HalfSize.x)); // float negYScale = (float)((renderWindowHeight / 2) / (currentMesh.Bounds.Center.y - currentMesh.Bounds.HalfSize.y)) * -1; // float negXScale = (float)((renderWindowWidth / 2) / (currentMesh.Bounds.Center.x - currentMesh.Bounds.HalfSize.x)) * -1; // //Figure out the limiting scale, use that one // if (posYScale <= posXScale && posYScale <= negYScale && posYScale <= negXScale) // Scale(posYScale, posYScale, posYScale, currentMesh.Name); // else if (posXScale <= posYScale && posXScale <= negYScale && posXScale <= negXScale) // Scale(posXScale, posXScale, posXScale, currentMesh.Name); // else if (negYScale <= posXScale && negYScale <= posYScale && negYScale <= negXScale) // Scale(negYScale, negYScale, negYScale, currentMesh.Name); // else // Scale(negXScale, negXScale, negXScale, currentMesh.Name); //} //todo - do I need to add camera, viewport, etc... stuff to this? private void RedrawScene(string attachedEntityName, string meshName, List <KeyValuePair <int, string> > materialNames, string sceneNodeName, float currentScale, bool?autoScale, double renderWindowHeight, double renderWindowWidth) { mMgr.ClearScene(); SceneNode node = null; mAnimationState = null; //I think by default it'll have the materials set as long as they are found - this is needed if we want to change the materials used... Entity ent = mMgr.CreateEntity(attachedEntityName, meshName); Mesh currentMesh = ent.GetMesh(); //helpful: foo.numlod, numSubMeshes, numAnimations try { uint cnt = ent.NumSubEntities; uint meshCounter = 0; Mesh.SubMeshIterator testIter = ent.GetMesh().GetSubMeshIterator(); while (testIter.MoveNext()) { string assignedMaterialName = materialNames.FirstOrDefault(n => n.Key == (int)meshCounter).Value; if (meshCounter < cnt && assignedMaterialName != null) { ent.GetSubEntity(meshCounter).SetMaterialName(assignedMaterialName); } meshCounter++; // SubMesh foobar = testIter.Current; // foobar.SetMaterialName(foobar.MaterialName); } } catch (Exception ex) { ent.SetMaterialName(materialNames[0].Value); //todo, fix logic } //ent.SetMaterialName("Examples/DarkMaterial"); node = mMgr.RootSceneNode.CreateChildSceneNode(sceneNodeName); node.AttachObject(ent); //todo - make this a debug toggle (or perhaps a checkbox on the UI) node.ShowBoundingBox = true; //todo - is this a good way of doing this? float z = 0; if (ent.BoundingBox.Size.z > ent.BoundingBox.Size.x && ent.BoundingBox.Size.z > ent.BoundingBox.Size.y) { z = ent.BoundingBox.Size.z; } else if (ent.BoundingBox.Size.y > ent.BoundingBox.Size.x && ent.BoundingBox.Size.y > ent.BoundingBox.Size.z) { z = ent.BoundingBox.Size.y; } else { z = ent.BoundingBox.Size.x; } //Since mCameraAutoAspectRatio = true, it means: mCamera.AspectRatio = (float)(renderWindowWidth / renderWindowHeight); //By doing this I remove the need for scaling the object - unless you're zooming in/out mCamera.Position = new Vector3(ent.BoundingBox.Center.x, ent.BoundingBox.Center.y, z * 2); //*2 for buffer mCamera.LookAt(ent.BoundingBox.Center); mCamera.NearClipDistance = ent.BoundingBox.Size.z / 3; //Create a single point light source Light light2 = mMgr.CreateLight("MainLight"); light2.Position = new Vector3(0, 10, -25); light2.Type = Light.LightTypes.LT_POINT; light2.SetDiffuseColour(1.0f, 1.0f, 1.0f); light2.SetSpecularColour(0.1f, 0.1f, 0.1f); }