private Mesh Build3DOMesh(_3DO threedo, _3DOMesh tdMesh, HierarchyNode hierarchyNode) { var mesh = new Mesh(); var vertices = new List <Vector3>(); var uvs = new List <Vector2>(); var normals = new List <Vector3>(); var triangles = new List <int>(); var atlasPosSize = new List <Vector4>(); for (var faceIndex = 0; faceIndex < tdMesh.Faces.Length; faceIndex++) { var face = tdMesh.Faces[faceIndex]; var viStart = vertices.Count; var matName = threedo.Materials[face.Material].ToLower(); if (!_materialLookup.ContainsKey(matName)) { throw new Exception("Material " + matName + " not cached. Cannot continue."); } var material = _materialLookup[matName]; foreach (VertexGroup t in face.Vertices) { var vert = tdMesh.Vertices[t.VertexIndex]; var vert3 = new Vector3(-vert.x, vert.z, -vert.y); vertices.Add(hierarchyNode.Pivot + vert3); normals.Add(tdMesh.FaceNormals[faceIndex]); var uv = tdMesh.TextureVertices[t.TextureIndex]; atlasPosSize.Add(new Vector4(material.Rects[0].x, material.Rects[0].y, material.Rects[0].width, material.Rects[0].height)); uv.x = uv.x / material.Sizes[0].x; uv.y = uv.y / material.Sizes[0].y; uvs.Add(uv); } var numTriangles = face.Vertices.Length - 3 + 1; for (var t = 1; t <= numTriangles; t++) { triangles.Add(viStart + t); triangles.Add(viStart); triangles.Add(viStart + t + 1); } } mesh.SetVertices(vertices); mesh.SetUVs(0, uvs); mesh.SetUVs(1, atlasPosSize); mesh.SetNormals(normals); mesh.SetTriangles(triangles, 0); mesh.RecalculateBounds(); //mesh.RecalculateNormals(); return(mesh); }
private ThreedoLoadResult Load3DO(string filename) { var threedo = new _3DO(); threedo.Load3DO(filename, _gobManager.GetStream(@"3do\" + filename)); var geoset = threedo.Geosets.First(); var root = new GameObject(threedo.Name); var gameObjects = new List <GameObject>(); foreach (var hierarchyNode in threedo.HierarchyNodes) { var go = new GameObject(hierarchyNode.NodeName); hierarchyNode.Transform = go.transform; if (hierarchyNode.Mesh != -1) { var tdMesh = geoset.Meshes[hierarchyNode.Mesh]; go.AddComponent <MeshFilter>().sharedMesh = Build3DOMesh(threedo, tdMesh, hierarchyNode); go.AddComponent <MeshRenderer>().sharedMaterial = StandardMaterial; } gameObjects.Add(go); } for (int index = 0; index < threedo.HierarchyNodes.Length; index++) { var hierarchyNode = threedo.HierarchyNodes[index]; var go = gameObjects[index]; var parent = hierarchyNode.Parent == -1 ? root : gameObjects[hierarchyNode.Parent]; go.transform.position = hierarchyNode.Translation; go.transform.SetParent(parent.transform, false); } root.transform.localScale = new Vector3(10, 10, 10); //root.SetActive(false); var result = new ThreedoLoadResult { Threedo = threedo, GameObject = root }; _3DOCache.Add(filename, result); return(result); }
public AnimationClip Parse(_3DO threedo, Transform root, string filename, Stream dataStream) { var animationClip = new AnimationClip(); Name = Path.GetFileNameWithoutExtension(filename); string section = ""; int numFrames = 0; float fps = 1.0f; int currentNodeIdx = 0; string currentMeshName = null; int numEntries; AnimationCurve curveX, curveY, curveZ; AnimationCurve curveXR, curveYR, curveZR, curveWR; curveX = curveY = curveZ = curveXR = curveYR = curveZR = curveWR = null; using (sr = new StreamReader(dataStream)) { while (!sr.EndOfStream) { ReadLine(); if (_line == "") { continue; } else if (_line.StartsWith("SECTION: ")) { section = _line; } else if (section == "SECTION: HEADER") { switch (_args[0]) { case "FRAMES": numFrames = int.Parse(_args[1]); break; case "FPS": fps = float.Parse(_args[1]); break; } } else if (section == "SECTION: KEYFRAME NODES") { if (_args[0] == "NODES") { } else if (_args[0] == "NODE") { if (currentMeshName != null) { var transformPath = GetFullPathTo(root, threedo.HierarchyNodes[currentNodeIdx].Transform); animationClip.SetCurve(transformPath, typeof(Transform), "localPosition.x", curveX); animationClip.SetCurve(transformPath, typeof(Transform), "localPosition.y", curveY); animationClip.SetCurve(transformPath, typeof(Transform), "localPosition.z", curveZ); animationClip.SetCurve(transformPath, typeof(Transform), "localRotation.x", curveXR); animationClip.SetCurve(transformPath, typeof(Transform), "localRotation.y", curveYR); animationClip.SetCurve(transformPath, typeof(Transform), "localRotation.z", curveZR); animationClip.SetCurve(transformPath, typeof(Transform), "localRotation.w", curveWR); } currentNodeIdx = int.Parse(_args[1]); curveX = new AnimationCurve(); curveY = new AnimationCurve(); curveZ = new AnimationCurve(); curveXR = new AnimationCurve(); curveYR = new AnimationCurve(); curveZR = new AnimationCurve(); curveWR = new AnimationCurve(); curveX.postWrapMode = WrapMode.Loop; curveY.postWrapMode = WrapMode.Loop; curveZ.postWrapMode = WrapMode.Loop; curveXR.postWrapMode = WrapMode.Loop; curveYR.postWrapMode = WrapMode.Loop; curveZR.postWrapMode = WrapMode.Loop; } else if (_args[0] == "MESH" && _args[1] == "NAME") { currentMeshName = _args[2]; } else if (_args[0] == "ENTRIES") { numEntries = int.Parse(_args[1]); } else { // var entryNum = int.Parse(_args[0].Replace(":", "")); var frame = int.Parse(_args[1]); var flags = _args[2]; var x = float.Parse(_args[3]); var y = float.Parse(_args[4]); var z = float.Parse(_args[5]); var pitch = float.Parse(_args[6]); var yaw = float.Parse(_args[7]); var roll = float.Parse(_args[8]); curveX.AddKey(frame / fps, -x); curveY.AddKey(frame / fps, z); curveZ.AddKey(frame / fps, -y); if (curveX.length == 1) { curveX.AddKey(numFrames / fps, -x); curveY.AddKey(numFrames / fps, z); curveZ.AddKey(numFrames / fps, -y); } var quaternion = Quaternion.Euler(pitch, -yaw, roll); curveXR.AddKey(frame / fps, quaternion.x); curveYR.AddKey(frame / fps, quaternion.y); curveZR.AddKey(frame / fps, quaternion.z); curveWR.AddKey(frame / fps, quaternion.w); if (curveXR.length == 1) { curveXR.AddKey(numFrames / fps, quaternion.x); curveYR.AddKey(numFrames / fps, quaternion.y); curveZR.AddKey(numFrames / fps, quaternion.z); curveWR.AddKey(numFrames / fps, quaternion.w); } ReadLine(); // Skip delta frames } } } } if (currentMeshName != null) { var transformPath = GetFullPathTo(root, threedo.HierarchyNodes[currentNodeIdx].Transform); animationClip.SetCurve(transformPath, typeof(Transform), "localPosition.x", curveX); animationClip.SetCurve(transformPath, typeof(Transform), "localPosition.y", curveY); animationClip.SetCurve(transformPath, typeof(Transform), "localPosition.z", curveZ); animationClip.SetCurve(transformPath, typeof(Transform), "localRotation.x", curveXR); animationClip.SetCurve(transformPath, typeof(Transform), "localRotation.y", curveYR); animationClip.SetCurve(transformPath, typeof(Transform), "localRotation.z", curveZR); animationClip.SetCurve(transformPath, typeof(Transform), "localRotation.w", curveWR); } animationClip.legacy = true; animationClip.name = Name; animationClip.EnsureQuaternionContinuity(); animationClip.wrapMode = WrapMode.Loop; return(animationClip); }