public GeometryFrame(RenderWareStream.Frame src, RenderWareStream.Atomic atomic) { Source = src; Name = src.Name != null ? src.Name.Value : DefaultName; ParentIndex = src.ParentIndex; GeometryIndex = atomic == null ? -1 : (int)atomic.GeometryIndex; Position = Types.Convert(src.Position); Rotation = UnityEngine.Quaternion.LookRotation(Types.Convert(src.MatrixForward), Types.Convert(src.MatrixUp)); }
private Geometry(RenderWareStream.Geometry geom, Mesh mesh, TextureDictionary[] textureDictionaries) { Mesh = mesh; if (geom.Skinning != null) { Mesh.boneWeights = Types.Convert(geom.Skinning.VertexBoneIndices, geom.Skinning.VertexBoneWeights); SkinToBoneMatrices = Types.Convert(geom.Skinning.SkinToBoneMatrices); } _geom = geom; _textureDictionaries = textureDictionaries; _materials = new Dictionary <MaterialFlags, UnityEngine.Material[]>(); }
private static Mesh Convert(RenderWareStream.Geometry src) { var mesh = new Mesh(); // ReSharper disable ConvertClosureToMethodGroup mesh.vertices = src.Vertices.Select(x => Types.Convert(x)).ToArray(); if (src.Normals != null) { mesh.normals = src.Normals.Select(x => Types.Convert(x)).ToArray(); } if (src.Colours != null) { mesh.colors32 = src.Colours.Select(x => Types.Convert(x)).ToArray(); } if (src.TexCoords != null && src.TexCoords.Length > 0) { mesh.uv = src.TexCoords[0].Select(x => Types.Convert(x)).ToArray(); } // ReSharper restore ConvertClosureToMethodGroup if (src.Normals == null) { mesh.normals = CalculateNormals(src, mesh.vertices); } mesh.subMeshCount = src.MaterialSplits.Length; var isTriangleStrip = (src.Flags & GeometryFlag.TriangleStrips) == GeometryFlag.TriangleStrips; var subMesh = 0; foreach (var split in src.MaterialSplits) { var indices = isTriangleStrip ? FromTriangleStrip(split.FaceIndices) : split.FaceIndices; mesh.SetIndices(indices, MeshTopology.Triangles, subMesh++); } mesh.RecalculateBounds(); return(mesh); }
private static UnityEngine.Material Convert(RenderWareStream.Material src, TextureDictionary[] txds, MaterialFlags flags) { LoadedTexture diffuse; LoadedTexture mask = null; var overrideAlpha = (flags & MaterialFlags.OverrideAlpha) == MaterialFlags.OverrideAlpha; var vehicle = (flags & MaterialFlags.Vehicle) == MaterialFlags.Vehicle; if (!overrideAlpha && src.Colour.A != 255) { flags |= MaterialFlags.Alpha; } if (src.TextureCount > 0) { var tex = src.Textures[0]; diffuse = txds.GetDiffuse(tex.TextureName); if (src.TextureCount > 1) { Debug.LogFormat("Something has {0} textures!", src.TextureCount); } if (diffuse == null) { Debug.LogWarningFormat("Unable to find texture {0}", tex.TextureName); } if (!string.IsNullOrEmpty(tex.MaskName)) { mask = txds.GetAlpha(tex.MaskName) ?? diffuse; } else if (vehicle) { mask = diffuse; } if (!overrideAlpha && mask != null && mask.HasAlpha) { flags |= MaterialFlags.Alpha; } } else { diffuse = WhiteTex; } var shader = GetShader(flags); var mat = new UnityEngine.Material(shader); var clr = Types.Convert(src.Colour); if (vehicle) { var found = false; for (var i = 1; i < _sKeyColors.Length; ++i) { var key = _sKeyColors[i]; if (key.r != clr.r || key.g != clr.g || key.b != clr.b) { continue; } mat.SetInt(CarColorIndexId, i); found = true; break; } if (found) { mat.color = Color.white; } else { mat.color = clr; } } else { mat.color = clr; } if (diffuse != null) { mat.SetTexture(MainTexId, diffuse.Texture); } if (mask != null) { mat.SetTexture(MaskTexId, mask.Texture); } mat.SetFloat(MetallicId, src.Specular); mat.SetFloat(SmoothnessId, src.Smoothness); return(mat); }
private static UnityEngine.AnimationClip Convert(Clip animation, FrameContainer frames, out UVector3 rootStart, out UVector3 rootEnd) { var clip = new UnityEngine.AnimationClip(); clip.legacy = true; var rotateAxes = new[] { new { Name = "x", Mask = new UVector4(1f, 0f, 0f, 0f) }, new { Name = "y", Mask = new UVector4(0f, 1f, 0f, 0f) }, new { Name = "z", Mask = new UVector4(0f, 0f, 1f, 0f) }, new { Name = "w", Mask = new UVector4(0f, 0f, 0f, 1f) } }; var translateAxes = new[] { new { Name = "x", Mask = new UVector3(1f, 0f, 0f) }, new { Name = "y", Mask = new UVector3(0f, 1f, 0f) }, new { Name = "z", Mask = new UVector3(0f, 0f, 1f) }, }; var root = animation.Bones.FirstOrDefault(x => x.BoneId == 0); if (root != null && root.FrameCount > 0) { rootStart = Types.Convert(root.Frames.First().Translation); rootEnd = Types.Convert(root.Frames.Last().Translation); } else { rootStart = rootEnd = UVector3.zero; } foreach (var bone in animation.Bones) { var bFrames = bone.Frames; var frame = frames.GetByBoneId(bone.BoneId); string bonePath = frame.Path; var axisAngle = bFrames.ToDictionary(x => x, x => { var q = Types.Convert(x.Rotation); float ang; UnityEngine.Vector3 axis; q.ToAngleAxis(out ang, out axis); return(new UVector4(q.x, q.y, q.z, q.w)); }); foreach (var axis in rotateAxes) { var keys = bFrames .Select(x => new Keyframe(x.Time * TimeScale, UVector4.Dot(axisAngle[x], axis.Mask))) .ToArray(); clip.SetCurve(bonePath, typeof(Transform), "localRotation." + axis.Name, new UnityEngine.AnimationCurve(keys)); } var converted = bFrames.Select(x => Types.Convert(x.Translation)).ToArray(); if (!converted.Any(x => !x.Equals(UVector3.zero))) { continue; } var anyVelocities = false; var deltaVals = converted.Select((x, i) => { var prev = Math.Max(0, i - 1); var next = Math.Min(i + 1, converted.Length - 1); var prevTime = bFrames[prev].Time * TimeScale; var nextTime = bFrames[next].Time * TimeScale; return(prevTime == nextTime || !(anyVelocities = true) ? UVector3.zero : (converted[next] - converted[prev]) / (nextTime - prevTime)); }).ToArray(); foreach (var translateAxis in translateAxes) { var positions = bFrames .Select((x, i) => new Keyframe(x.Time * TimeScale, UVector3.Dot(frame.transform.localPosition + converted[i], translateAxis.Mask))) .ToArray(); var deltas = bFrames.Select((x, i) => new Keyframe(x.Time * TimeScale, UVector3.Dot(deltaVals[i], translateAxis.Mask))).ToArray(); clip.SetCurve(bonePath, typeof(Transform), "localPosition." + translateAxis.Name, new UnityEngine.AnimationCurve(positions)); if (!anyVelocities) { continue; } clip.SetCurve(bonePath, typeof(BFrame), "LocalVelocity." + translateAxis.Name, new UnityEngine.AnimationCurve(deltas)); } } clip.wrapMode = WrapMode.Loop; clip.EnsureQuaternionContinuity(); return(clip); }