/// <summary> /// Uses a priority queue to sort based on distance. /// 1. Puts all of the meshes into the priority queue. /// 2. Pops out based on least distance, adding to the MeshList. Once it gets too big, it gets added to listofMeshes. /// 3. Above, in update, goes through the listofMeshes which should also be in order. /// </summary> #region Private Methods private void AddToList(MeshList testList, List <MeshList> listofMeshes) { List <int> sentList = new List <int>(); SimplePriorityQueue <GameObject, float> priorityq = new SimplePriorityQueue <GameObject, float>(); for (int i = 0; i < transform.childCount; i++) { priorityq.Enqueue(transform.GetChild(i).gameObject, GetDistance(transform.GetChild(i).gameObject, Camera)); } int counter = 0; while (priorityq.Count != 0) { GameObject gameObject = priorityq.Dequeue(); if (testList.Meshes.Count <= 40) { AddMeshProto(gameObject, testList, sentList); } else if (counter == transform.childCount - 1) { listofMeshes.Add(testList); testList = new MeshList(); } else { listofMeshes.Add(testList); testList = new MeshList(); } counter++; } }
public void SetMesh(MeshList meshList) { if (meshList == MeshList.Box) { mesh.InitMesh("./res/BOX.obj"); } if (meshList == MeshList.Sphere) { mesh.InitMesh("./res/SPHERE.obj"); Console.WriteLine("./res/SPHERE.obj " + mesh.PrintVerticesLength()); } if (meshList == MeshList.Monkey) { mesh.InitMesh("./res/MONKEY.obj"); Console.WriteLine("./res/MONKEY.obj " + mesh.PrintVerticesLength()); } if (meshList == MeshList.Rock) { mesh.InitMesh("./res/ROCK.obj"); Console.WriteLine("./res/ROCK.obj " + mesh.PrintVerticesLength()); } if (meshList == MeshList.Godzilla) { mesh.InitMesh("./res/GODZILLA.obj"); Console.WriteLine("./res/GODZILLA.obj " + mesh.PrintVerticesLength()); } }
public void SortMeshList(Vector3 cameraPosition, BoundingFrustum viewFrustum) { // Sort meses in a front to back order from the camera IComparer <Mesh> comp = new MeshDistanceComparer(cameraPosition, viewFrustum); MeshList.Sort(comp); }
internal static void DrawNodeToImage_NewPipeline(out byte[] imageRawBytes, Node node, int width, int height) { Application.EnableMSAA = false; MeshBuffer meshBuffer = new MeshBuffer(); MeshList meshList = new MeshList(); BuiltinGeometryRenderer geometryRenderer = new BuiltinGeometryRenderer(); using (var context = new RenderContextForTest(width, height)) { RenderContext renderContext = new RenderContext(geometryRenderer, meshList); //This must be called after the RenderContextForTest is created, for uploading textures to GPU via OpenGL. node.Render(renderContext); //rebuild mesh buffer meshBuffer.Clear(); meshBuffer.Init(); meshBuffer.Build(meshList); //draw mesh buffer to screen context.Clear(); context.DrawMeshes(meshBuffer); imageRawBytes = context.GetRenderedRawBytes(); } }
internal static void DrawNodesToImage(out byte[] imageRawBytes, IList <Node> nodes, int width, int height) { MeshBuffer meshBuffer = new MeshBuffer(); MeshList meshList = new MeshList(); IPrimitiveRenderer primitiveRenderer = new BuiltinPrimitiveRenderer(); using (var context = new RenderContextForTest(width, height)) { //This must be called after the context is created, for creating textures when the OpenGL context is built. foreach (var node in nodes) { node.Draw(primitiveRenderer, meshList); } //rebuild mesh buffer meshBuffer.Clear(); meshBuffer.Init(); meshBuffer.Build(meshList); //draw mesh buffer to screen context.Clear(); context.DrawMeshes(meshBuffer); imageRawBytes = context.GetRenderedRawBytes(); } }
internal static void CheckRectangle(Brush brush, Pen pen, Rect rectangle, int width, int height, [CallerMemberName] string methodName = "unknown") { Application.EnableMSAA = false; MeshBuffer meshBuffer = new MeshBuffer(); MeshList meshList = new MeshList(); BuiltinGeometryRenderer renderer = new BuiltinGeometryRenderer(); byte[] bytes; using (var context = new RenderContextForTest(width, height)) { renderer.OnBeforeRead(); renderer.DrawRectangle(brush, pen, rectangle);//This must be called after the RenderContextForTest is created, for uploading textures to GPU via OpenGL. renderer.OnAfterRead(meshList); //rebuild mesh buffer meshBuffer.Clear(); meshBuffer.Init(); meshBuffer.Append(meshList); //draw mesh buffer to screen context.Clear(); context.DrawMeshes(meshBuffer); bytes = context.GetRenderedRawBytes(); } Util.CheckExpectedImage(bytes, width, height, $"{RootDir}{nameof(DrawRectangle)}\\{methodName}.png"); }
public BigMesh AllocateBigMeshForMaterial(MaterialDef matDef) { var it = MeshList.Find(it => it.matDef == matDef); if (it == null) { var textureIndex = -1; if (!matDef.nodraw) { textureIndex = AllocatedMaterialDefs.Count; AllocatedMaterialDefs.Add(matDef); } var newOne = new BigMesh { matDef = matDef, textureIndex = textureIndex, }; MeshList.Add(newOne); return(newOne); } else { return(it); } }
public void DrawPrimitiveList(List <Primitive> primitiveList, bool useBoxModel, Rect nodeRect, StyleRuleSet ruleSet, MeshList meshList) { Rect rect = nodeRect; if (useBoxModel) { GetBoxes(nodeRect, ruleSet, out var bRect, out var pRect, out rect); var shapeMesh = MeshPool.ShapeMeshPool.Get(); shapeMesh.Clear(); shapeMesh.CommandBuffer.Add(DrawCommand.Default); var imageMesh = MeshPool.ImageMeshPool.Get(); imageMesh.Clear(); this.DrawBoxModelPrimitive(shapeMesh, imageMesh, bRect, pRect, rect, ruleSet); meshList.AddOrUpdateShapeMesh(shapeMesh); meshList.AddOrUpdateImageMesh(imageMesh); } foreach (var primitive in primitiveList) { switch (primitive) { case PathPrimitive p: { var shapeMesh = MeshPool.ShapeMeshPool.Get(); shapeMesh.Clear(); shapeMesh.CommandBuffer.Add(DrawCommand.Default); this.DrawPathPrimitive(shapeMesh, p, (Vector)rect.Location); meshList.AddOrUpdateShapeMesh(shapeMesh); } break; case TextPrimitive t: { var textMesh = MeshPool.TextMeshPool.Get(); textMesh.Clear(); this.DrawTextPrimitive(textMesh, t, rect, ruleSet, primitive.Offset); meshList.AddOrUpdateTextMesh(textMesh); } break; case ImagePrimitive i: { var imageMesh = MeshPool.ImageMeshPool.Get(); imageMesh.Clear(); this.DrawImagePrimitive(imageMesh, i, rect, ruleSet, primitive.Offset); meshList.AddOrUpdateImageMesh(imageMesh); } break; default: throw new ArgumentOutOfRangeException(); } } }
protected override void Parse(Stream s) { BinaryReader br = new BinaryReader(s); string tag = FOURCC(br.ReadUInt32()); if (tag != Tag) { throw new InvalidDataException(string.Format("Invalid Tag read: '{0}'; expected: '{1}'; at 0x{1:X8}", tag, Tag, s.Position)); } mVersion = br.ReadUInt32(); mMeshes = new MeshList(handler, this, s); }
void Awake() { _transform = transform; _meshParent = GameObject.Find("Meshes"); _editPointsParent = GameObject.Find("EditPoints"); _editPoints = new List<Vector3>(); _meshList = new MeshList(_meshParent, meshPrefab); _fov = new FOV(_transform); _eventSystem = GameObject.Find("EventSystem").GetComponent<EventSystem>(); }
private static void NodeImageMesh(MeshList list) { var meshes = list.ImageMeshes; foreach (var mesh in meshes) { var cmds = mesh.CommandBuffer; for (var i = 0; i < cmds.Count; i++) { NodeDrawCommand(mesh, i); } } }
internal static void DrawNodeTreeToImage(out byte[] imageRawBytes, Node root, int width, int height, Rect clipRect) { if (root == null) { throw new ArgumentNullException(nameof(root)); } MeshBuffer meshBuffer = new MeshBuffer(); MeshList meshList = new MeshList(); BuiltinGeometryRenderer geometryRenderer = new BuiltinGeometryRenderer(); using (var context = new RenderContextForTest(width, height)) { if (root is Node rootNode) { using (var dc = rootNode.RenderOpen()) { dc.DrawBoxModel(rootNode.RuleSet, rootNode.Rect); } } root.Foreach(visual => { if (!(visual is Node node)) { return(true); } using (var dc = node.RenderOpen()) { dc.DrawBoxModel(node.RuleSet, node.Rect); } return(true); }); //This must be called after the context is created, for uploading textures to GPU via OpenGL. root.Render(new RenderContext(geometryRenderer, meshList)); //rebuild mesh buffer meshBuffer.Clear(); meshBuffer.Init(); meshBuffer.Build(meshList); //draw mesh buffer to screen context.Clear(); context.DrawMeshes(meshBuffer); imageRawBytes = context.GetRenderedRawBytes(); } }
public override Stream UnParse() { MemoryStream s = new MemoryStream(); BinaryWriter bw = new BinaryWriter(s); bw.Write((uint)FOURCC(Tag)); bw.Write(mVersion); if (mMeshes == null) { mMeshes = new MeshList(handler, this); } mMeshes.UnParse(s); return(s); }
/// <summary> /// Goes here after receiving a signal /// </summary> public static void ReadCallBack(IAsyncResult res) { UdpClient client = (UdpClient)res.AsyncState; IPEndPoint RemoteIPEndPoint = new IPEndPoint(IPAddress.Any, listenPort); Console.WriteLine("----------------------"); Console.WriteLine("UDP Connection made. Receiving data..."); byte[] received = client.EndReceive(res, ref RemoteIPEndPoint); listenPort = ((IPEndPoint)client.Client.LocalEndPoint).Port; Console.WriteLine("Data received from: {0} at Port: {1}", RemoteIPEndPoint.Address.ToString(), listenPort.ToString()); Console.WriteLine("Sending back changed position for debugging/testing purposes..."); using (MemoryStream ms = new MemoryStream()) { ms.Write(received, 0, received.Length); ms.Position = 0; if (listenPort == 8888) { replyPort = 9999; MessageParser<RobotStructure> parser = new MessageParser<RobotStructure>(() => new RobotStructure()); receivedStructure = parser.ParseFrom(ms); receivedStructure.RootJointID = 1; ms.Position = 0; SendBackStructure(receivedStructure); } else if (listenPort == 7777) { replyPort = 6666; MessageParser<PositionList> parser = new MessageParser<PositionList>(() => new PositionList()); receivedList = parser.ParseFrom(ms); receivedList.PList[0].Rotation = 30; ms.Position = 0; SendBackPositions(receivedList); } else if (listenPort == 1234) { replyPort = 4321; MessageParser<MeshList> parser = new MessageParser<MeshList>(() => new MeshList()); receivedMeshes = parser.ParseFrom(ms); Console.WriteLine("RECEIVED MESHES... LENGTH = {0}", receivedMeshes.Meshes.Count); StartBoth.ListeningMessage(); StartBoth._MeshListening = false; } } }
private void InstantiateChunks(TERRAIN.ETerrain[,] _startTerrain) { terrainChunks = new TerrainChunk[terrainDimension, terrainDimension]; terrainChunkStorage = new MeshList <TerrainChunk>(); int halfDim = GetTerrainDimCenter(); for (int x = 0; x < terrainDimension; x++) { for (int z = 0; z < terrainDimension; z++) { terrainChunks[x, z] = new TerrainChunk(_startTerrain[x, z], new Vector3(planetData.GetTerrainSize().x *(x - halfDim), 0, planetData.GetTerrainSize().y *(z - halfDim)) + currentCenter, planetData.GetTerrainSize(), this); } } terrainChunkStorage.SetCenter(terrainChunks[halfDim, halfDim]); //first do the middle line for (int x = 0; x < halfDim; x++) { terrainChunkStorage.AddLeft(-x, 0, terrainChunks[halfDim - x - 1, halfDim]); terrainChunkStorage.AddRight(x, 0, terrainChunks[halfDim + x + 1, halfDim]); } //the in parallel always do the line above and below in one set for (int y = 0; y < halfDim; y++) { terrainChunkStorage.AddAbove(0, y, terrainChunks[halfDim, halfDim + y + 1]); terrainChunkStorage.AddBelow(0, -y, terrainChunks[halfDim, halfDim - y - 1]); for (int x = 0; x < halfDim; x++) { terrainChunkStorage.AddLeft(-x, y + 1, terrainChunks[halfDim - x - 1, halfDim + y + 1]); terrainChunkStorage.AddRight(x, y + 1, terrainChunks[halfDim + x + 1, halfDim + y + 1]); } for (int x = 0; x < halfDim; x++) { terrainChunkStorage.AddLeft(-x, -(y + 1), terrainChunks[halfDim - x - 1, halfDim - y - 1]); terrainChunkStorage.AddRight(x, -(y + 1), terrainChunks[halfDim + x + 1, halfDim - y - 1]); } } ReloadChunkArrayFromStorage(); currentStoragePosition = new Vector2Int(0, 0); }
public void Build(MeshList meshList) { foreach (var mesh in meshList.ShapeMeshes) { this.ShapeMesh.Append(mesh); } foreach (var mesh in meshList.ImageMeshes) { this.ImageMesh.Append(mesh); } foreach (var textMesh in meshList.TextMeshes) { this.TextMesh.Append(textMesh, Vector.Zero); } }
private void Update() { // Iterate through this when sending the Meshes (pieces of info) List <MeshList> listOfMeshList = new List <MeshList>(); MeshList sendList = new MeshList(); // Send upon keydown if (Input.GetKeyDown(KeyCode.Space)) { AddToList(sendList, listOfMeshList); foreach (MeshList list in listOfMeshList) { ClientUDP <MeshList> .UDPSend(1234, list); } } }
private static void ConvertMeshList(MeshList meshList, Node node, int nodeIndex, List <Node> nodes, Assimp.Scene aiScene, Assimp.Node aiNode) { var meshStartIndex = aiScene.Meshes.Count; foreach (var mesh in meshList) { switch (mesh.Type) { case MeshType.Type1: aiScene.Meshes.AddRange(ConvertMeshType1(( MeshType1 )mesh, node, nodeIndex)); break; case MeshType.Type2: aiScene.Meshes.AddRange(ConvertMeshType2(( MeshType2 )mesh, nodes)); break; case MeshType.Type3: break; case MeshType.Type4: aiScene.Meshes.Add(ConvertMeshType4(( MeshType4 )mesh, node, nodeIndex)); break; case MeshType.Type5: aiScene.Meshes.AddRange(ConvertMeshType5(( MeshType5 )mesh, node, nodes, nodeIndex)); break; case MeshType.Type7: aiScene.Meshes.Add(ConvertMeshType7(( MeshType7 )mesh, nodes)); break; case MeshType.Type8: aiScene.Meshes.Add(ConvertMeshType8(( MeshType8 )mesh, node, nodeIndex)); break; } } var meshEndIndex = aiScene.Meshes.Count; for (int i = meshStartIndex; i < meshEndIndex; i++) { var meshNode = new Assimp.Node($"mesh_{i:D2}", aiScene.RootNode); meshNode.MeshIndices.Add(i); meshNode.Parent.Children.Add(meshNode); } }
/// <summary> /// Sets up the controls for the scene /// </summary> /// <param name="scene"></param> private void SetupScene(SBScene scene) { Viewport.Scene = scene; BoneTree.LoadFromScene(scene); MeshList.LoadFromScene(scene); RightPane.Contents.Clear(); if (scene.HasBones) { RightPane.Contents.Add(BoneEditor); RightPane.Contents.Add(new Splitter() { Dock = DockStyle.Top }); } if (scene.HasMesh) { RightPane.Contents.Add(MeshPanel); RightPane.Contents.Add(new Splitter() { Dock = DockStyle.Top }); } if (scene.HasMesh) { RightPane.Contents.Add(MeshList); RightPane.Contents.Add(new Splitter() { Dock = DockStyle.Top }); } if (scene.HasBones) { RightPane.Contents.Add(BoneTree); RightPane.Contents.Add(new Splitter() { Dock = DockStyle.Top }); } }
internal static void DrawNodeTreeToImage(out byte[] imageRawBytes, Node root, int width, int height, Rect clipRect) { MeshBuffer meshBuffer = new MeshBuffer(); MeshList meshList = new MeshList(); var primitiveRenderer = new BuiltinPrimitiveRenderer(); using (var context = new RenderContextForTest(width, height)) { //This must be called after the context is created, for uploading textures to GPU via OpenGL. root.Foreach(n => primitiveRenderer.Draw(n, clipRect, meshList)); //rebuild mesh buffer meshBuffer.Clear(); meshBuffer.Init(); meshBuffer.Build(meshList); //draw mesh buffer to screen context.Clear(); context.DrawMeshes(meshBuffer); imageRawBytes = context.GetRenderedRawBytes(); } }
internal static void DrawDrawingVisualToImage(out byte[] imageRawBytes, int width, int height, DrawingVisual drawingVisual) { //convert geometries inside the drawingVisual's content to meshes stored in a MeshList with a BuiltinGeometryRenderer MeshList meshList = new MeshList(); using BuiltinGeometryRenderer geometryRenderer = new BuiltinGeometryRenderer(); RenderContext renderContext = new RenderContext(geometryRenderer, meshList); drawingVisual.RenderContent(renderContext); //merge meshes in the MeshList to a MeshBuffer MeshBuffer meshBuffer = new MeshBuffer(); meshBuffer.Clear(); meshBuffer.Init(); meshBuffer.Build(meshList); //created a mesh IRenderer Application.Init(); var window = Application.PlatformContext.CreateWindow(Point.Zero, new Size(100, 100), WindowTypes.Hidden); var renderer = Application.PlatformContext.CreateRenderer() as Win32OpenGLRenderer;//TEMP HACK Debug.Assert(renderer != null, nameof(renderer) + " != null"); renderer.Init(window.Pointer, window.ClientSize); //clear the canvas and draw mesh in the MeshBuffer with the mesh renderer renderer.Clear(Color.White); renderer.StartDrawMeshToImage(width, height); imageRawBytes = renderer.DrawMeshToImage(width, height, meshBuffer.ShapeMesh, OpenGLMaterial.shapeMaterial); renderer.EndDrawMeshToImage(); //clear native resources: window and IRenderer renderer.ShutDown(); window.Close(); }
/// <summary> /// Adds a MeshProto into a MeshList for sending over. /// </summary> private void AddMeshProto(GameObject meshObject, MeshList meshList, List <int> confirmed) { MeshProto newMeshProto = new MeshProto(); Mesh sharedMesh = meshObject.GetComponent <MeshCollider>().sharedMesh; // Don't know if null is a problem but... yea temp fix if (sharedMesh != null) { foreach (int triangle in sharedMesh.triangles) { newMeshProto.Triangles.Add(triangle); confirmed.Add(triangle); if (confirmed.Contains(triangle) == false) { ProtoVector3 newVector = new ProtoVector3(); newVector.X = sharedMesh.vertices[triangle].x; newVector.Y = sharedMesh.vertices[triangle].y; newVector.Z = sharedMesh.vertices[triangle].z; newMeshProto.Vertices[triangle] = (newVector); } } } meshList.Meshes.Add(newMeshProto); }
private void ConvertMeshRenderer(MeshRenderer meshR) { var mesh = GetMesh(meshR); if (mesh == null) { return; } var iMesh = new ImportedMesh(); assetsfileList.TryGetGameObject(meshR.m_GameObject, out var m_GameObject2); assetsfileList.TryGetTransform(m_GameObject2.m_Transform, out var meshTransform); iMesh.Name = GetTransformPath(meshTransform); iMesh.SubmeshList = new List <ImportedSubmesh>(); var subHashSet = new HashSet <int>(); var combine = false; int firstSubMesh = 0; if (meshR.m_StaticBatchInfo?.subMeshCount > 0) { firstSubMesh = meshR.m_StaticBatchInfo.firstSubMesh; var finalSubMesh = meshR.m_StaticBatchInfo.firstSubMesh + meshR.m_StaticBatchInfo.subMeshCount; for (int i = meshR.m_StaticBatchInfo.firstSubMesh; i < finalSubMesh; i++) { subHashSet.Add(i); } combine = true; } else if (meshR.m_SubsetIndices?.Length > 0) { firstSubMesh = (int)meshR.m_SubsetIndices.Min(x => x); foreach (var index in meshR.m_SubsetIndices) { subHashSet.Add((int)index); } combine = true; } int firstFace = 0; for (int i = 0; i < mesh.m_SubMeshes.Count; i++) { int numFaces = (int)mesh.m_SubMeshes[i].indexCount / 3; if (subHashSet.Count > 0 && !subHashSet.Contains(i)) { firstFace += numFaces; continue; } var submesh = mesh.m_SubMeshes[i]; var iSubmesh = new ImportedSubmesh(); Material mat = null; if (i - firstSubMesh < meshR.m_Materials.Length) { if (assetsfileList.TryGetPD(meshR.m_Materials[i - firstSubMesh], out var MaterialPD)) { mat = new Material(MaterialPD); } } ImportedMaterial iMat = ConvertMaterial(mat); iSubmesh.Material = iMat.Name; iSubmesh.VertexList = new List <ImportedVertex>((int)submesh.vertexCount); var vertexColours = mesh.m_Colors != null && (mesh.m_Colors.Length == mesh.m_VertexCount * 3 || mesh.m_Colors.Length == mesh.m_VertexCount * 4); for (var j = mesh.m_SubMeshes[i].firstVertex; j < mesh.m_SubMeshes[i].firstVertex + mesh.m_SubMeshes[i].vertexCount; j++) { var iVertex = vertexColours ? new ImportedVertexWithColour() : new ImportedVertex(); //Vertices int c = 3; if (mesh.m_Vertices.Length == mesh.m_VertexCount * 4) { c = 4; } iVertex.Position = new Vector3(-mesh.m_Vertices[j * c], mesh.m_Vertices[j * c + 1], mesh.m_Vertices[j * c + 2]); //Normals if (mesh.m_Normals?.Length > 0) { if (mesh.m_Normals.Length == mesh.m_VertexCount * 3) { c = 3; } else if (mesh.m_Normals.Length == mesh.m_VertexCount * 4) { c = 4; } iVertex.Normal = new Vector3(-mesh.m_Normals[j * c], mesh.m_Normals[j * c + 1], mesh.m_Normals[j * c + 2]); } //Colors if (vertexColours) { if (mesh.m_Colors.Length == mesh.m_VertexCount * 3) { ((ImportedVertexWithColour)iVertex).Colour = new Color4(mesh.m_Colors[j * 3], mesh.m_Colors[j * 3 + 1], mesh.m_Colors[j * 3 + 2], 1.0f); } else { ((ImportedVertexWithColour)iVertex).Colour = new Color4(mesh.m_Colors[j * 4], mesh.m_Colors[j * 4 + 1], mesh.m_Colors[j * 4 + 2], mesh.m_Colors[j * 4 + 3]); } } //UV if (mesh.m_UV1 != null && mesh.m_UV1.Length == mesh.m_VertexCount * 2) { iVertex.UV = new[] { mesh.m_UV1[j * 2], -mesh.m_UV1[j * 2 + 1] }; } else if (mesh.m_UV2 != null && mesh.m_UV2.Length == mesh.m_VertexCount * 2) { iVertex.UV = new[] { mesh.m_UV2[j * 2], -mesh.m_UV2[j * 2 + 1] }; } //Tangent if (mesh.m_Tangents != null && mesh.m_Tangents.Length == mesh.m_VertexCount * 4) { iVertex.Tangent = new Vector4(-mesh.m_Tangents[j * 4], mesh.m_Tangents[j * 4 + 1], mesh.m_Tangents[j * 4 + 2], mesh.m_Tangents[j * 4 + 3]); } //BoneInfluence if (mesh.m_Skin.Length > 0) { var inf = mesh.m_Skin[j]; iVertex.BoneIndices = new byte[inf.Count]; iVertex.Weights = new float[inf.Count]; for (var k = 0; k < inf.Count; k++) { iVertex.BoneIndices[k] = (byte)inf[k].boneIndex; iVertex.Weights[k] = inf[k].weight; } } iSubmesh.VertexList.Add(iVertex); } //Face iSubmesh.FaceList = new List <ImportedFace>(numFaces); var end = firstFace + numFaces; for (int f = firstFace; f < end; f++) { var face = new ImportedFace(); face.VertexIndices = new int[3]; face.VertexIndices[0] = (int)(mesh.m_Indices[f * 3 + 2] - submesh.firstVertex); face.VertexIndices[1] = (int)(mesh.m_Indices[f * 3 + 1] - submesh.firstVertex); face.VertexIndices[2] = (int)(mesh.m_Indices[f * 3] - submesh.firstVertex); iSubmesh.FaceList.Add(face); } firstFace = end; iMesh.SubmeshList.Add(iSubmesh); } if (meshR is SkinnedMeshRenderer sMesh) { //Bone iMesh.BoneList = new List <ImportedBone>(sMesh.m_Bones.Length); /*if (sMesh.m_Bones.Length >= 256) * { * throw new Exception("Too many bones (" + mesh.m_BindPose.Length + ")"); * }*/ for (int i = 0; i < sMesh.m_Bones.Length; i++) { var bone = new ImportedBone(); if (assetsfileList.TryGetTransform(sMesh.m_Bones[i], out var m_Transform)) { if (assetsfileList.TryGetGameObject(m_Transform.m_GameObject, out var m_GameObject)) { bone.Name = m_GameObject.m_Name; } } //No first use m_BoneNameHashes, because it may be wrong if (string.IsNullOrEmpty(bone.Name)) { var boneHash = mesh.m_BoneNameHashes[i]; bone.Name = GetNameFromBonePathHashes(boneHash); if (string.IsNullOrEmpty(bone.Name)) { bone.Name = avatar?.FindBoneName(boneHash); } if (string.IsNullOrEmpty(bone.Name)) { //throw new Exception("A Bone could neither be found by hash in Avatar nor by index in SkinnedMeshRenderer."); continue; } } var om = new float[4, 4]; var m = mesh.m_BindPose[i]; om[0, 0] = m[0, 0]; om[0, 1] = -m[1, 0]; om[0, 2] = -m[2, 0]; om[0, 3] = m[3, 0]; om[1, 0] = -m[0, 1]; om[1, 1] = m[1, 1]; om[1, 2] = m[2, 1]; om[1, 3] = m[3, 1]; om[2, 0] = -m[0, 2]; om[2, 1] = m[1, 2]; om[2, 2] = m[2, 2]; om[2, 3] = m[3, 2]; om[3, 0] = -m[0, 3]; om[3, 1] = m[1, 3]; om[3, 2] = m[2, 3]; om[3, 3] = m[3, 3]; bone.Matrix = om; iMesh.BoneList.Add(bone); } //Morphs if (mesh.m_Shapes != null) { foreach (var channel in mesh.m_Shapes.channels) { morphChannelInfo[channel.nameHash] = channel.name; } if (mesh.m_Shapes.shapes.Count > 0) { ImportedMorph morph = null; string lastGroup = ""; for (int i = 0; i < mesh.m_Shapes.channels.Count; i++) { string group = BlendShapeNameGroup(mesh, i); if (group != lastGroup) { morph = new ImportedMorph(); MorphList.Add(morph); morph.Name = iMesh.Name; morph.ClipName = group; morph.Channels = new List <Tuple <float, int, int> >(mesh.m_Shapes.channels.Count); morph.KeyframeList = new List <ImportedMorphKeyframe>(mesh.m_Shapes.shapes.Count); lastGroup = group; } morph.Channels.Add(new Tuple <float, int, int>(i < sMesh.m_BlendShapeWeights.Count ? sMesh.m_BlendShapeWeights[i] : 0f, morph.KeyframeList.Count, mesh.m_Shapes.channels[i].frameCount)); for (int frameIdx = 0; frameIdx < mesh.m_Shapes.channels[i].frameCount; frameIdx++) { ImportedMorphKeyframe keyframe = new ImportedMorphKeyframe(); keyframe.Name = BlendShapeNameExtension(mesh, i) + "_" + frameIdx; int shapeIdx = mesh.m_Shapes.channels[i].frameIndex + frameIdx; keyframe.VertexList = new List <ImportedVertex>((int)mesh.m_Shapes.shapes[shapeIdx].vertexCount); keyframe.MorphedVertexIndices = new List <ushort>((int)mesh.m_Shapes.shapes[shapeIdx].vertexCount); keyframe.Weight = shapeIdx < mesh.m_Shapes.fullWeights.Count ? mesh.m_Shapes.fullWeights[shapeIdx] : 100f; int lastVertIndex = (int)(mesh.m_Shapes.shapes[shapeIdx].firstVertex + mesh.m_Shapes.shapes[shapeIdx].vertexCount); for (int j = (int)mesh.m_Shapes.shapes[shapeIdx].firstVertex; j < lastVertIndex; j++) { var morphVert = mesh.m_Shapes.vertices[j]; ImportedVertex vert = GetSourceVertex(iMesh.SubmeshList, (int)morphVert.index); ImportedVertex destVert = new ImportedVertex(); Vector3 morphPos = morphVert.vertex; morphPos.X *= -1; destVert.Position = vert.Position + morphPos; Vector3 morphNormal = morphVert.normal; morphNormal.X *= -1; destVert.Normal = morphNormal; Vector4 morphTangent = new Vector4(morphVert.tangent, 0); morphTangent.X *= -1; destVert.Tangent = morphTangent; keyframe.VertexList.Add(destVert); keyframe.MorphedVertexIndices.Add((ushort)morphVert.index); } morph.KeyframeList.Add(keyframe); } } } } } //TODO if (combine) { assetsfileList.TryGetGameObject(meshR.m_GameObject, out var m_GameObject); foreach (var root in FrameList) { var frame = ImportedHelpers.FindFrame(m_GameObject.m_Name, root); if (frame?.Parent != null) { var parent = frame; while (true) { if (parent.Parent != null) { parent = parent.Parent; } else { frame.LocalRotation = parent.LocalRotation; frame.LocalScale = parent.LocalScale; frame.LocalPosition = parent.LocalPosition; break; } } } break; } } MeshList.Add(iMesh); }
public IEnumerable <MaterialDef> GetMaterialDefList() => MeshList.Select(one => one.matDef);
public static void CombineChildMeshes(this GameObject gameObject) { MeshFilter[] meshFilters = gameObject.GetComponentsInChildren <MeshFilter>(); List <MeshList> meshLists = new List <MeshList>(); //List<Material> materials = new List<Material>(); Matrix4x4 goMatrix = gameObject.transform.worldToLocalMatrix; for (int i = 0; i < meshFilters.Length; i++) { var mr = meshFilters[i].GetComponent <MeshRenderer>(); MeshList ml; int vertexCount = meshFilters[i].sharedMesh.vertexCount; bool done = false; for (int mlindex = 0; mlindex < meshLists.Count; mlindex++) { if (meshLists[mlindex].material == mr.sharedMaterial && meshLists[mlindex].totalVertices + vertexCount < MAX_INDICES) { meshLists[mlindex].AddInstance(meshFilters[i], goMatrix); Object.Destroy(mr); Object.Destroy(meshFilters[i]); done = true; break; } } if (done) { continue; } ml = new MeshList(); ml.material = mr.sharedMaterial; ml.AddInstance(meshFilters[i], goMatrix); meshLists.Add(ml); //meshFilters[i].gameObject.SetActive(false); Object.Destroy(mr); Object.Destroy(meshFilters[i]); } // combine meshes for (int i = 0; i < meshLists.Count; i++) { var go = gameObject.CreateChild(); MeshFilter mf = go.AddComponent <MeshFilter>(); MeshRenderer mr = go.AddComponent <MeshRenderer>(); Mesh m = new Mesh(); m.CombineMeshes(meshLists[i].instances.ToArray()); mf.sharedMesh = m; mr.sharedMaterial = meshLists[i].material; } }
private void ConvertMeshRenderer(MeshRenderer meshR) { var mesh = GetMesh(meshR); if (mesh == null) { return; } var iMesh = new ImportedMesh(); assetsfileList.TryGetGameObject(meshR.m_GameObject, out var m_GameObject2); assetsfileList.TryGetTransform(m_GameObject2.m_Transform, out var meshTransform); iMesh.Name = GetTransformPath(meshTransform); iMesh.SubmeshList = new List <ImportedSubmesh>(mesh.m_SubMeshes.Count); int sum = 0; for (int i = 0; i < mesh.m_SubMeshes.Count; i++) { var submesh = mesh.m_SubMeshes[i]; var iSubmesh = new ImportedSubmesh(); iSubmesh.Index = i; iSubmesh.Visible = true; Material mat = null; if (i < meshR.m_Materials.Length) { if (assetsfileList.TryGetPD(meshR.m_Materials[i], out var MaterialPD)) { mat = new Material(MaterialPD); } } ImportedMaterial iMat = ConvertMaterial(mat); iSubmesh.Material = iMat.Name; iSubmesh.VertexList = new List <ImportedVertex>((int)submesh.vertexCount); var vertexColours = mesh.m_Colors != null && mesh.m_Colors.Length > 0; for (var j = mesh.m_SubMeshes[i].firstVertex; j < mesh.m_SubMeshes[i].firstVertex + mesh.m_SubMeshes[i].vertexCount; j++) { var iVertex = vertexColours ? new ImportedVertexWithColour() : new ImportedVertex(); //Vertices int c = 3; if (mesh.m_Vertices.Length == mesh.m_VertexCount * 4) { c = 4; } iVertex.Position = new Vector3(-mesh.m_Vertices[j * c], mesh.m_Vertices[j * c + 1], mesh.m_Vertices[j * c + 2]); //Normals if (mesh.m_Normals != null && mesh.m_Normals.Length > 0) { if (mesh.m_Normals.Length == mesh.m_VertexCount * 3) { c = 3; } else if (mesh.m_Normals.Length == mesh.m_VertexCount * 4) { c = 4; } iVertex.Normal = new Vector3(-mesh.m_Normals[j * c], mesh.m_Normals[j * c + 1], mesh.m_Normals[j * c + 2]); } //Colors if (vertexColours) { if (mesh.m_Colors.Length == mesh.m_VertexCount * 3) { ((ImportedVertexWithColour)iVertex).Colour = new Color4(mesh.m_Colors[j * 3], mesh.m_Colors[j * 3 + 1], mesh.m_Colors[j * 3 + 2], 1.0f); } else { ((ImportedVertexWithColour)iVertex).Colour = new Color4(mesh.m_Colors[j * 4], mesh.m_Colors[j * 4 + 1], mesh.m_Colors[j * 4 + 2], mesh.m_Colors[j * 4 + 3]); } } //UV if (mesh.m_UV1 != null && mesh.m_UV1.Length == mesh.m_VertexCount * 2) { iVertex.UV = new[] { mesh.m_UV1[j * 2], -mesh.m_UV1[j * 2 + 1] }; } else if (mesh.m_UV2 != null && mesh.m_UV2.Length == mesh.m_VertexCount * 2) { iVertex.UV = new[] { mesh.m_UV2[j * 2], -mesh.m_UV2[j * 2 + 1] }; } //Tangent if (mesh.m_Tangents != null) { iVertex.Tangent = new Vector4(-mesh.m_Tangents[j * 4], mesh.m_Tangents[j * 4 + 1], mesh.m_Tangents[j * 4 + 2], mesh.m_Tangents[j * 4 + 3]); } //BoneInfluence if (mesh.m_Skin.Length > 0) { var inf = mesh.m_Skin[j]; iVertex.BoneIndices = new byte[inf.Count]; iVertex.Weights = new float[inf.Count]; for (var k = 0; k < inf.Count; k++) { iVertex.BoneIndices[k] = (byte)inf[k].boneIndex; iVertex.Weights[k] = inf[k].weight; } } iSubmesh.VertexList.Add(iVertex); } //Face int numFaces = (int)mesh.m_SubMeshes[i].indexCount / 3; iSubmesh.FaceList = new List <ImportedFace>(numFaces); var end = sum + numFaces; for (int f = sum; f < end; f++) { var face = new ImportedFace(); face.VertexIndices = new int[3]; face.VertexIndices[0] = (int)(mesh.m_Indices[f * 3 + 2] - submesh.firstVertex); face.VertexIndices[1] = (int)(mesh.m_Indices[f * 3 + 1] - submesh.firstVertex); face.VertexIndices[2] = (int)(mesh.m_Indices[f * 3] - submesh.firstVertex); iSubmesh.FaceList.Add(face); } sum = end; iMesh.SubmeshList.Add(iSubmesh); } if (meshR is SkinnedMeshRenderer sMesh) { //Bone iMesh.BoneList = new List <ImportedBone>(sMesh.m_Bones.Length); /*if (sMesh.m_Bones.Length >= 256) * { * throw new Exception("Too many bones (" + mesh.m_BindPose.Length + ")"); * }*/ for (int i = 0; i < sMesh.m_Bones.Length; i++) { var bone = new ImportedBone(); if (assetsfileList.TryGetTransform(sMesh.m_Bones[i], out var m_Transform)) { if (assetsfileList.TryGetGameObject(m_Transform.m_GameObject, out var m_GameObject)) { bone.Name = m_GameObject.m_Name; } } //No first use m_BoneNameHashes, because it may be wrong if (string.IsNullOrEmpty(bone.Name)) { var boneHash = mesh.m_BoneNameHashes[i]; bone.Name = GetNameFromBonePathHashes(boneHash); if (string.IsNullOrEmpty(bone.Name)) { bone.Name = avatar?.FindBoneName(boneHash); } if (string.IsNullOrEmpty(bone.Name)) { throw new Exception("A Bone could neither be found by hash in Avatar nor by index in SkinnedMeshRenderer."); } } var om = new Matrix(); for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { om[x, y] = mesh.m_BindPose[i][x, y]; } } var m = Matrix.Transpose(om); m.Decompose(out var s, out var q, out var t); t.X *= -1; q.Y *= -1; q.Z *= -1; bone.Matrix = Matrix.Scaling(s) * Matrix.RotationQuaternion(q) * Matrix.Translation(t); iMesh.BoneList.Add(bone); } //Morphs foreach (var channel in mesh.m_Shapes.channels) { morphChannelInfo.Add(channel.nameHash, channel.name); } if (mesh.m_Shapes.shapes.Count > 0) { ImportedMorph morph = null; string lastGroup = ""; for (int i = 0; i < mesh.m_Shapes.channels.Count; i++) { string group = BlendShapeNameGroup(mesh, i); if (group != lastGroup) { morph = new ImportedMorph(); MorphList.Add(morph); morph.Name = iMesh.Name; morph.ClipName = group; morph.Channels = new List <Tuple <float, int, int> >(mesh.m_Shapes.channels.Count); morph.KeyframeList = new List <ImportedMorphKeyframe>(mesh.m_Shapes.shapes.Count); lastGroup = group; } morph.Channels.Add(new Tuple <float, int, int>(i < sMesh.m_BlendShapeWeights.Count ? sMesh.m_BlendShapeWeights[i] : 0f, morph.KeyframeList.Count, mesh.m_Shapes.channels[i].frameCount)); for (int frameIdx = 0; frameIdx < mesh.m_Shapes.channels[i].frameCount; frameIdx++) { ImportedMorphKeyframe keyframe = new ImportedMorphKeyframe(); keyframe.Name = BlendShapeNameExtension(mesh, i) + "_" + frameIdx; int shapeIdx = mesh.m_Shapes.channels[i].frameIndex + frameIdx; keyframe.VertexList = new List <ImportedVertex>((int)mesh.m_Shapes.shapes[shapeIdx].vertexCount); keyframe.MorphedVertexIndices = new List <ushort>((int)mesh.m_Shapes.shapes[shapeIdx].vertexCount); keyframe.Weight = shapeIdx < mesh.m_Shapes.fullWeights.Count ? mesh.m_Shapes.fullWeights[shapeIdx] : 100f; int lastVertIndex = (int)(mesh.m_Shapes.shapes[shapeIdx].firstVertex + mesh.m_Shapes.shapes[shapeIdx].vertexCount); for (int j = (int)mesh.m_Shapes.shapes[shapeIdx].firstVertex; j < lastVertIndex; j++) { var morphVert = mesh.m_Shapes.vertices[j]; ImportedVertex vert = GetSourceVertex(iMesh.SubmeshList, (int)morphVert.index); ImportedVertex destVert = new ImportedVertex(); Vector3 morphPos = morphVert.vertex; morphPos.X *= -1; destVert.Position = vert.Position + morphPos; Vector3 morphNormal = morphVert.normal; morphNormal.X *= -1; destVert.Normal = morphNormal; Vector4 morphTangent = new Vector4(morphVert.tangent, 0); morphTangent.X *= -1; destVert.Tangent = morphTangent; keyframe.VertexList.Add(destVert); keyframe.MorphedVertexIndices.Add((ushort)morphVert.index); } morph.KeyframeList.Add(keyframe); } } } } MeshList.Add(iMesh); }
private void ConvertMeshRenderer(Renderer meshR) { var mesh = GetMesh(meshR); if (mesh == null) { return; } var iMesh = new ImportedMesh(); meshR.m_GameObject.TryGet(out var m_GameObject2); iMesh.Path = GetTransformPath(m_GameObject2.m_Transform); iMesh.SubmeshList = new List <ImportedSubmesh>(); var subHashSet = new HashSet <int>(); var combine = false; int firstSubMesh = 0; if (meshR.m_StaticBatchInfo?.subMeshCount > 0) { firstSubMesh = meshR.m_StaticBatchInfo.firstSubMesh; var finalSubMesh = meshR.m_StaticBatchInfo.firstSubMesh + meshR.m_StaticBatchInfo.subMeshCount; for (int i = meshR.m_StaticBatchInfo.firstSubMesh; i < finalSubMesh; i++) { subHashSet.Add(i); } combine = true; } else if (meshR.m_SubsetIndices?.Length > 0) { firstSubMesh = (int)meshR.m_SubsetIndices.Min(x => x); foreach (var index in meshR.m_SubsetIndices) { subHashSet.Add((int)index); } combine = true; } int firstFace = 0; for (int i = 0; i < mesh.m_SubMeshes.Length; i++) { int numFaces = (int)mesh.m_SubMeshes[i].indexCount / 3; if (subHashSet.Count > 0 && !subHashSet.Contains(i)) { firstFace += numFaces; continue; } var submesh = mesh.m_SubMeshes[i]; var iSubmesh = new ImportedSubmesh(); Material mat = null; if (i - firstSubMesh < meshR.m_Materials.Length) { if (meshR.m_Materials[i - firstSubMesh].TryGet(out var m_Material)) { mat = m_Material; } } ImportedMaterial iMat = ConvertMaterial(mat); iSubmesh.Material = iMat.Name; iSubmesh.VertexList = new List <ImportedVertex>((int)submesh.vertexCount); var vertexColours = mesh.m_Colors != null && (mesh.m_Colors.Length == mesh.m_VertexCount * 3 || mesh.m_Colors.Length == mesh.m_VertexCount * 4); for (var j = mesh.m_SubMeshes[i].firstVertex; j < mesh.m_SubMeshes[i].firstVertex + mesh.m_SubMeshes[i].vertexCount; j++) { var iVertex = vertexColours ? new ImportedVertexWithColour() : new ImportedVertex(); //Vertices int c = 3; if (mesh.m_Vertices.Length == mesh.m_VertexCount * 4) { c = 4; } iVertex.Position = new Vector3(-mesh.m_Vertices[j * c], mesh.m_Vertices[j * c + 1], mesh.m_Vertices[j * c + 2]); //Normals if (mesh.m_Normals?.Length > 0) { if (mesh.m_Normals.Length == mesh.m_VertexCount * 3) { c = 3; } else if (mesh.m_Normals.Length == mesh.m_VertexCount * 4) { c = 4; } iVertex.Normal = new Vector3(-mesh.m_Normals[j * c], mesh.m_Normals[j * c + 1], mesh.m_Normals[j * c + 2]); } //Colors if (vertexColours) { if (mesh.m_Colors.Length == mesh.m_VertexCount * 3) { ((ImportedVertexWithColour)iVertex).Colour = new Color(mesh.m_Colors[j * 3], mesh.m_Colors[j * 3 + 1], mesh.m_Colors[j * 3 + 2], 1.0f); } else { ((ImportedVertexWithColour)iVertex).Colour = new Color(mesh.m_Colors[j * 4], mesh.m_Colors[j * 4 + 1], mesh.m_Colors[j * 4 + 2], mesh.m_Colors[j * 4 + 3]); } } //UV if (mesh.m_UV0 != null && mesh.m_UV0.Length == mesh.m_VertexCount * 2) { iVertex.UV = new[] { mesh.m_UV0[j * 2], mesh.m_UV0[j * 2 + 1] }; } else if (mesh.m_UV1 != null && mesh.m_UV1.Length == mesh.m_VertexCount * 2) { iVertex.UV = new[] { mesh.m_UV1[j * 2], mesh.m_UV1[j * 2 + 1] }; } //Tangent if (mesh.m_Tangents != null && mesh.m_Tangents.Length == mesh.m_VertexCount * 4) { iVertex.Tangent = new Vector4(-mesh.m_Tangents[j * 4], mesh.m_Tangents[j * 4 + 1], mesh.m_Tangents[j * 4 + 2], -mesh.m_Tangents[j * 4 + 3]); } //BoneInfluence if (mesh.m_Skin?.Length > 0) { var inf = mesh.m_Skin[j]; iVertex.BoneIndices = new int[4]; iVertex.Weights = new float[4]; for (var k = 0; k < 4; k++) { iVertex.BoneIndices[k] = inf.boneIndex[k]; iVertex.Weights[k] = inf.weight[k]; } } iSubmesh.VertexList.Add(iVertex); } //Face iSubmesh.FaceList = new List <ImportedFace>(numFaces); var end = firstFace + numFaces; for (int f = firstFace; f < end; f++) { var face = new ImportedFace(); face.VertexIndices = new int[3]; face.VertexIndices[0] = (int)(mesh.m_Indices[f * 3 + 2] - submesh.firstVertex); face.VertexIndices[1] = (int)(mesh.m_Indices[f * 3 + 1] - submesh.firstVertex); face.VertexIndices[2] = (int)(mesh.m_Indices[f * 3] - submesh.firstVertex); iSubmesh.FaceList.Add(face); } firstFace = end; iMesh.SubmeshList.Add(iSubmesh); } if (meshR is SkinnedMeshRenderer sMesh) { //Bone if (sMesh.m_Bones.Length > 0) { var boneMax = Math.Min(sMesh.m_Bones.Length, mesh.m_BindPose.Length); iMesh.BoneList = new List <ImportedBone>(boneMax); for (int i = 0; i < boneMax; i++) { var bone = new ImportedBone(); if (sMesh.m_Bones[i].TryGet(out var m_Transform)) { bone.Path = GetTransformPath(m_Transform); } if (!string.IsNullOrEmpty(bone.Path)) { var convert = Matrix4x4.Scale(new Vector3(-1, 1, 1)); bone.Matrix = convert * mesh.m_BindPose[i] * convert; iMesh.BoneList.Add(bone); } } } if (iMesh.BoneList == null || iMesh.BoneList.Count == 0) { if (mesh.m_BindPose.Length > 0 && mesh.m_BoneNameHashes?.Length > 0) { var boneMax = Math.Min(mesh.m_BindPose.Length, mesh.m_BoneNameHashes.Length); iMesh.BoneList = new List <ImportedBone>(boneMax); for (int i = 0; i < boneMax; i++) { var bone = new ImportedBone(); var boneHash = mesh.m_BoneNameHashes[i]; var path = GetPathFromHash(boneHash); bone.Path = FixBonePath(path); if (!string.IsNullOrEmpty(bone.Path)) { var convert = Matrix4x4.Scale(new Vector3(-1, 1, 1)); bone.Matrix = convert * mesh.m_BindPose[i] * convert; iMesh.BoneList.Add(bone); } } } } //Morphs if (mesh.m_Shapes?.channels?.Length > 0) { var morph = new ImportedMorph(); MorphList.Add(morph); morph.Path = iMesh.Path; morph.Channels = new List <ImportedMorphChannel>(mesh.m_Shapes.channels.Length); for (int i = 0; i < mesh.m_Shapes.channels.Length; i++) { var channel = new ImportedMorphChannel(); morph.Channels.Add(channel); var shapeChannel = mesh.m_Shapes.channels[i]; channel.Name = shapeChannel.name; channel.KeyframeList = new List <ImportedMorphKeyframe>(shapeChannel.frameCount); var frameEnd = shapeChannel.frameIndex + shapeChannel.frameCount; for (int frameIdx = shapeChannel.frameIndex; frameIdx < frameEnd; frameIdx++) { var keyframe = new ImportedMorphKeyframe(); channel.KeyframeList.Add(keyframe); keyframe.Weight = mesh.m_Shapes.fullWeights[frameIdx]; var shape = mesh.m_Shapes.shapes[frameIdx]; keyframe.hasNormals = shape.hasNormals; keyframe.hasTangents = shape.hasTangents; keyframe.VertexList = new List <ImportedMorphVertex>((int)shape.vertexCount); var vertexEnd = shape.firstVertex + shape.vertexCount; for (uint j = shape.firstVertex; j < vertexEnd; j++) { var destVertex = new ImportedMorphVertex(); keyframe.VertexList.Add(destVertex); var morphVertex = mesh.m_Shapes.vertices[j]; destVertex.Index = morphVertex.index; var sourceVertex = GetSourceVertex(iMesh.SubmeshList, (int)morphVertex.index); destVertex.Vertex = new ImportedVertex(); var morphPos = morphVertex.vertex; destVertex.Vertex.Position = sourceVertex.Position + new Vector3(-morphPos.X, morphPos.Y, morphPos.Z); if (shape.hasNormals) { var morphNormal = morphVertex.normal; destVertex.Vertex.Normal = new Vector3(-morphNormal.X, morphNormal.Y, morphNormal.Z); } if (shape.hasTangents) { var morphTangent = morphVertex.tangent; destVertex.Vertex.Tangent = new Vector4(-morphTangent.X, morphTangent.Y, morphTangent.Z, 0); } } } } } } //TODO combine mesh if (combine) { meshR.m_GameObject.TryGet(out var m_GameObject); var frame = RootFrame.FindChild(m_GameObject.m_Name); if (frame != null) { frame.LocalPosition = RootFrame.LocalPosition; frame.LocalRotation = RootFrame.LocalRotation; while (frame.Parent != null) { frame = frame.Parent; frame.LocalPosition = RootFrame.LocalPosition; frame.LocalRotation = RootFrame.LocalRotation; } } } MeshList.Add(iMesh); }
private void ConvertMeshRenderer(Renderer meshR) { var mesh = GetMesh(meshR); if (mesh == null) { return; } var iMesh = new ImportedMesh(); meshR.m_GameObject.TryGet(out var m_GameObject2); iMesh.Path = GetTransformPath(m_GameObject2.m_Transform); iMesh.SubmeshList = new List <ImportedSubmesh>(); var subHashSet = new HashSet <int>(); var combine = false; int firstSubMesh = 0; if (meshR.m_StaticBatchInfo?.subMeshCount > 0) { firstSubMesh = meshR.m_StaticBatchInfo.firstSubMesh; var finalSubMesh = meshR.m_StaticBatchInfo.firstSubMesh + meshR.m_StaticBatchInfo.subMeshCount; for (int i = meshR.m_StaticBatchInfo.firstSubMesh; i < finalSubMesh; i++) { subHashSet.Add(i); } combine = true; } else if (meshR.m_SubsetIndices?.Length > 0) { firstSubMesh = (int)meshR.m_SubsetIndices.Min(x => x); foreach (var index in meshR.m_SubsetIndices) { subHashSet.Add((int)index); } combine = true; } iMesh.hasNormal = mesh.m_Normals?.Length > 0; iMesh.hasUV = new bool[8]; for (int uv = 0; uv < 8; uv++) { iMesh.hasUV[uv] = mesh.GetUV(uv)?.Length > 0; } iMesh.hasTangent = mesh.m_Tangents != null && mesh.m_Tangents.Length == mesh.m_VertexCount * 4; iMesh.hasColor = mesh.m_Colors?.Length > 0; int firstFace = 0; for (int i = 0; i < mesh.m_SubMeshes.Length; i++) { int numFaces = (int)mesh.m_SubMeshes[i].indexCount / 3; if (subHashSet.Count > 0 && !subHashSet.Contains(i)) { firstFace += numFaces; continue; } var submesh = mesh.m_SubMeshes[i]; var iSubmesh = new ImportedSubmesh(); Material mat = null; if (i - firstSubMesh < meshR.m_Materials.Length) { if (meshR.m_Materials[i - firstSubMesh].TryGet(out var m_Material)) { mat = m_Material; } } ImportedMaterial iMat = ConvertMaterial(mat); iSubmesh.Material = iMat.Name; iSubmesh.VertexList = new List <ImportedVertex>((int)submesh.vertexCount); for (var j = mesh.m_SubMeshes[i].firstVertex; j < mesh.m_SubMeshes[i].firstVertex + mesh.m_SubMeshes[i].vertexCount; j++) { var iVertex = new ImportedVertex(); //Vertices int c = 3; if (mesh.m_Vertices.Length == mesh.m_VertexCount * 4) { c = 4; } iVertex.Vertex = new Vector3(-mesh.m_Vertices[j * c], mesh.m_Vertices[j * c + 1], mesh.m_Vertices[j * c + 2]); //Normals if (iMesh.hasNormal) { if (mesh.m_Normals.Length == mesh.m_VertexCount * 3) { c = 3; } else if (mesh.m_Normals.Length == mesh.m_VertexCount * 4) { c = 4; } iVertex.Normal = new Vector3(-mesh.m_Normals[j * c], mesh.m_Normals[j * c + 1], mesh.m_Normals[j * c + 2]); } //UV iVertex.UV = new float[8][]; for (int uv = 0; uv < 8; uv++) { if (iMesh.hasUV[uv]) { var m_UV = mesh.GetUV(uv); if (m_UV.Length == mesh.m_VertexCount * 2) { c = 2; } else if (m_UV.Length == mesh.m_VertexCount * 3) { c = 3; } iVertex.UV[uv] = new[] { m_UV[j * c], m_UV[j * c + 1] }; } } //Tangent if (iMesh.hasTangent) { iVertex.Tangent = new Vector4(-mesh.m_Tangents[j * 4], mesh.m_Tangents[j * 4 + 1], mesh.m_Tangents[j * 4 + 2], mesh.m_Tangents[j * 4 + 3]); } //Colors if (iMesh.hasColor) { if (mesh.m_Colors.Length == mesh.m_VertexCount * 3) { iVertex.Color = new Color(mesh.m_Colors[j * 3], mesh.m_Colors[j * 3 + 1], mesh.m_Colors[j * 3 + 2], 1.0f); } else { iVertex.Color = new Color(mesh.m_Colors[j * 4], mesh.m_Colors[j * 4 + 1], mesh.m_Colors[j * 4 + 2], mesh.m_Colors[j * 4 + 3]); } } //BoneInfluence if (mesh.m_Skin?.Length > 0) { var inf = mesh.m_Skin[j]; iVertex.BoneIndices = new int[4]; iVertex.Weights = new float[4]; for (var k = 0; k < 4; k++) { iVertex.BoneIndices[k] = inf.boneIndex[k]; iVertex.Weights[k] = inf.weight[k]; } } iSubmesh.VertexList.Add(iVertex); } //Face iSubmesh.FaceList = new List <ImportedFace>(numFaces); var end = firstFace + numFaces; for (int f = firstFace; f < end; f++) { var face = new ImportedFace(); face.VertexIndices = new int[3]; face.VertexIndices[0] = (int)(mesh.m_Indices[f * 3 + 2] - submesh.firstVertex); face.VertexIndices[1] = (int)(mesh.m_Indices[f * 3 + 1] - submesh.firstVertex); face.VertexIndices[2] = (int)(mesh.m_Indices[f * 3] - submesh.firstVertex); iSubmesh.FaceList.Add(face); } firstFace = end; iMesh.SubmeshList.Add(iSubmesh); } if (meshR is SkinnedMeshRenderer sMesh) { //Bone /* * 0 - None * 1 - m_Bones * 2 - m_BoneNameHashes */ var boneType = 0; if (sMesh.m_Bones.Length > 0) { if (sMesh.m_Bones.Length == mesh.m_BindPose.Length) { var verifiedBoneCount = sMesh.m_Bones.Count(x => x.TryGet(out _)); if (verifiedBoneCount > 0) { boneType = 1; } if (verifiedBoneCount != sMesh.m_Bones.Length) { //尝试使用m_BoneNameHashes 4.3 and up if (mesh.m_BindPose.Length > 0 && (mesh.m_BindPose.Length == mesh.m_BoneNameHashes?.Length)) { //有效bone数量是否大于SkinnedMeshRenderer var verifiedBoneCount2 = mesh.m_BoneNameHashes.Count(x => FixBonePath(GetPathFromHash(x)) != null); if (verifiedBoneCount2 > verifiedBoneCount) { boneType = 2; } } } } else { //Logger.Error(""); } } else { //尝试使用m_BoneNameHashes 4.3 and up if (mesh.m_BindPose.Length > 0 && (mesh.m_BindPose.Length == mesh.m_BoneNameHashes?.Length)) { boneType = 2; } } if (boneType == 1) { var boneCount = sMesh.m_Bones.Length; iMesh.BoneList = new List <ImportedBone>(boneCount); for (int i = 0; i < boneCount; i++) { var bone = new ImportedBone(); if (sMesh.m_Bones[i].TryGet(out var m_Transform)) { bone.Path = GetTransformPath(m_Transform); } var convert = Matrix4x4.Scale(new Vector3(-1, 1, 1)); bone.Matrix = convert * mesh.m_BindPose[i] * convert; iMesh.BoneList.Add(bone); } } else if (boneType == 2) { var boneCount = mesh.m_BindPose.Length; iMesh.BoneList = new List <ImportedBone>(boneCount); for (int i = 0; i < boneCount; i++) { var bone = new ImportedBone(); var boneHash = mesh.m_BoneNameHashes[i]; var path = GetPathFromHash(boneHash); bone.Path = FixBonePath(path); var convert = Matrix4x4.Scale(new Vector3(-1, 1, 1)); bone.Matrix = convert * mesh.m_BindPose[i] * convert; iMesh.BoneList.Add(bone); } } //Morphs if (mesh.m_Shapes?.channels?.Length > 0) { var morph = new ImportedMorph(); MorphList.Add(morph); morph.Path = iMesh.Path; morph.Channels = new List <ImportedMorphChannel>(mesh.m_Shapes.channels.Length); for (int i = 0; i < mesh.m_Shapes.channels.Length; i++) { var channel = new ImportedMorphChannel(); morph.Channels.Add(channel); var shapeChannel = mesh.m_Shapes.channels[i]; var blendShapeName = "blendShape." + shapeChannel.name; var crc = new SevenZip.CRC(); var bytes = Encoding.UTF8.GetBytes(blendShapeName); crc.Update(bytes, 0, (uint)bytes.Length); morphChannelNames[crc.GetDigest()] = blendShapeName; channel.Name = shapeChannel.name; channel.KeyframeList = new List <ImportedMorphKeyframe>(shapeChannel.frameCount); var frameEnd = shapeChannel.frameIndex + shapeChannel.frameCount; for (int frameIdx = shapeChannel.frameIndex; frameIdx < frameEnd; frameIdx++) { var keyframe = new ImportedMorphKeyframe(); channel.KeyframeList.Add(keyframe); keyframe.Weight = mesh.m_Shapes.fullWeights[frameIdx]; var shape = mesh.m_Shapes.shapes[frameIdx]; keyframe.hasNormals = shape.hasNormals; keyframe.hasTangents = shape.hasTangents; keyframe.VertexList = new List <ImportedMorphVertex>((int)shape.vertexCount); var vertexEnd = shape.firstVertex + shape.vertexCount; for (uint j = shape.firstVertex; j < vertexEnd; j++) { var destVertex = new ImportedMorphVertex(); keyframe.VertexList.Add(destVertex); var morphVertex = mesh.m_Shapes.vertices[j]; destVertex.Index = morphVertex.index; var sourceVertex = GetSourceVertex(iMesh.SubmeshList, (int)morphVertex.index); destVertex.Vertex = new ImportedVertex(); var morphPos = morphVertex.vertex; destVertex.Vertex.Vertex = sourceVertex.Vertex + new Vector3(-morphPos.X, morphPos.Y, morphPos.Z); if (shape.hasNormals) { var morphNormal = morphVertex.normal; destVertex.Vertex.Normal = new Vector3(-morphNormal.X, morphNormal.Y, morphNormal.Z); } if (shape.hasTangents) { var morphTangent = morphVertex.tangent; destVertex.Vertex.Tangent = new Vector4(-morphTangent.X, morphTangent.Y, morphTangent.Z, 0); } } } } } } //TODO combine mesh if (combine) { meshR.m_GameObject.TryGet(out var m_GameObject); var frame = RootFrame.FindChild(m_GameObject.m_Name); if (frame != null) { frame.LocalPosition = RootFrame.LocalPosition; frame.LocalRotation = RootFrame.LocalRotation; while (frame.Parent != null) { frame = frame.Parent; frame.LocalPosition = RootFrame.LocalPosition; frame.LocalRotation = RootFrame.LocalRotation; } } } MeshList.Add(iMesh); }
public void DrawPrimitive(Geometry geometry, bool useBoxModel, Rect nodeRect, StyleRuleSet ruleSet, MeshList meshList) { Rect rect = nodeRect; if (useBoxModel) { GetBoxes(nodeRect, ruleSet, out var bRect, out var pRect, out rect); var shapeMesh = MeshPool.ShapeMeshPool.Get(); shapeMesh.Clear(); shapeMesh.CommandBuffer.Add(DrawCommand.Default); var imageMesh = MeshPool.ImageMeshPool.Get(); imageMesh.Clear(); this.DrawBoxModelPrimitive(shapeMesh, imageMesh, bRect, pRect, rect, ruleSet); meshList.AddOrUpdateShapeMesh(shapeMesh); meshList.AddOrUpdateImageMesh(imageMesh); } if (geometry == null) { return; } switch (geometry) { case PathGeometry p: { var shapeMesh = MeshPool.ShapeMeshPool.Get(); shapeMesh.Clear(); shapeMesh.CommandBuffer.Add(DrawCommand.Default); this.DrawPathPrimitive(shapeMesh, p, (Vector)rect.Location); meshList.AddOrUpdateShapeMesh(shapeMesh); } break; case TextGeometry t: { var textMesh = MeshPool.TextMeshPool.Get(); textMesh.Clear(); this.DrawTextPrimitive(textMesh, t, rect, ruleSet, geometry.Offset); meshList.AddOrUpdateTextMesh(textMesh); } break; case ImageGeometry i: { var imageMesh = MeshPool.ImageMeshPool.Get(); imageMesh.Clear(); this.DrawImagePrimitive(imageMesh, i, rect, ruleSet, geometry.Offset); meshList.AddOrUpdateImageMesh(imageMesh); } break; default: throw new ArgumentOutOfRangeException(); } }
public MLOD(EventHandler handler, uint version, MeshList meshes) : base(handler, null) { mVersion = version; mMeshes = meshes; }
public void Raycast(MeshList meshList) { colPoints.Clear(); colAngles.Clear(); Vector3 hitPoint; bool collided; Vector3 newDirection; Vector3 point; // Prvo idemo po rubovima for (int i = 0; i < _Edges.Length; i++) { hitPoint = _GetCollisionPoint(_Edges[i], out collided); colPoints.Add(hitPoint); colAngles.Add(_CalculateAngle(hitPoint)); } // Onda idemo po poligonima for (int i = 0; i < meshList.meshes.Count; i++) { for (int j = 0; j < meshList.meshes[i].points.Count; j++) { point = meshList.meshes[i].points[j]; hitPoint = _GetCollisionPoint(point, out collided); colPoints.Add(hitPoint); colAngles.Add(_CalculateAngle(hitPoint)); // Za svaku točku u poligonu tražimo i lijevo/desno (TODO: samo za rubne!) newDirection = Quaternion.AngleAxis(.1f, Vector3.forward) * point; hitPoint = _GetCollisionPoint(newDirection, out collided); colPoints.Add(hitPoint); colAngles.Add(_CalculateAngle(hitPoint)); newDirection = Quaternion.AngleAxis(-.1f, Vector3.forward) * point; hitPoint = _GetCollisionPoint(newDirection, out collided); colPoints.Add(hitPoint); colAngles.Add(_CalculateAngle(hitPoint)); } } // Sortiramo liste po kutevima for (int i = 0; i < colAngles.Count - 1; i++) { for (int j = i + 1; j < colAngles.Count; j++) { if (colAngles[j] < colAngles[i]) { Vector3 temp = colPoints[i]; colPoints[i] = colPoints[j]; colPoints[j] = temp; float tempF = colAngles[i]; colAngles[i] = colAngles[j]; colAngles[j] = tempF; } } } // Dodajemo na prvo mjesto i poziciju igrača colPoints.Insert(0, _player.position); colAngles.Insert(0, 0f); }
public static bool Draw(this BuiltinPrimitiveRenderer primitiveRenderer, Visual visual, Rect rootClipRect, MeshList meshList) { if (!visual.ActiveInTree) { return(false); } if (visual is Node) { var clipRect = visual.GetClipRect(rootClipRect); if (visual.IsClipped(clipRect)) { return(false); } } visual.Draw(primitiveRenderer, meshList); return(true); }