public RenderObjectUnity(AnimatorEditor editor, HashSet<string> meshNames) { HighlightSubmesh = new HashSet<int>(); highlightMaterial = new SlimDX.Direct3D9.Material(); highlightMaterial.Ambient = new Color4(1, 1, 1, 1); highlightMaterial.Diffuse = new Color4(1, 0, 1, 0); this.device = Gui.Renderer.Device; this.tweeningVertDec = new VertexDeclaration(this.device, TweeningWithoutNormalsVertexBufferFormat.ThreeStreams); Textures = new Texture[editor.Textures.Count]; Materials = new SlimDX.Direct3D9.Material[editor.Materials.Count]; rootFrame = CreateHierarchy(editor, meshNames, device, out meshFrames); AnimationController = new AnimationController(numFrames, 30, 30, 1); Frame.RegisterNamedMatrices(rootFrame, AnimationController); if (meshFrames.Count > 0) { Bounds = meshFrames[0].Bounds; for (int i = 1; i < meshFrames.Count; i++) { Bounds = BoundingBox.Merge(Bounds, meshFrames[i].Bounds); } } else { Bounds = new BoundingBox(); } }
public RenderObjectREM(remParser parser, remMesh mesh) { HighlightSubmesh = new HashSet<int>(); highlightMaterial = new Material(); highlightMaterial.Ambient = new Color4(1, 1, 1, 1); highlightMaterial.Diffuse = new Color4(1, 0, 1, 0); this.device = Gui.Renderer.Device; if (Textures.Count + parser.MATC.Count > Textures.Capacity) { Textures.Capacity += parser.MATC.Count; } Materials = new Material[parser.MATC.Count]; rootFrame = CreateHierarchy(parser, mesh, device, out meshFrames); AnimationController = new AnimationController(numFrames, 30, 30, 1); Frame.RegisterNamedMatrices(rootFrame, AnimationController); for (int i = 0; i < meshFrames.Count; i++) { if (i == 0) { Bounds = meshFrames[i].Bounds; } else { Bounds = BoundingBox.Merge(Bounds, meshFrames[i].Bounds); } } }
public RenderObjectODF(odfParser parser, HashSet<int> meshIDs) { HighlightSubmesh = new SortedSet<int>(); highlightMaterial = new Material(); highlightMaterial.Ambient = new Color4(1, 1, 1, 1); highlightMaterial.Diffuse = new Color4(1, 0, 1, 0); this.device = Gui.Renderer.Device; Textures = new Texture[parser.TextureSection != null ? parser.TextureSection.Count : 0]; TextureDic = new Dictionary<int, int>(parser.TextureSection != null ? parser.TextureSection.Count : 0); Materials = new Material[parser.MaterialSection.Count]; BoneMatrixDic = new Dictionary<string, Matrix>(); rootFrame = CreateHierarchy(parser, meshIDs, device, out meshFrames); AnimationController = new AnimationController(numFrames, 30, 30, 1); Frame.RegisterNamedMatrices(rootFrame, AnimationController); for (int i = 0; i < meshFrames.Count; i++) { if (i == 0) { Bounds = meshFrames[i].Bounds; } else { Bounds = BoundingBox.Merge(Bounds, meshFrames[i].Bounds); } } }
private AnimationFrame CreateHierarchy(xxParser parser, HashSet <string> meshNames, Device device, out List <AnimationFrame> meshFrames) { meshFrames = new List <AnimationFrame>(meshNames.Count); HashSet <string> extractFrames = xx.SearchHierarchy(parser.Frame, meshNames); AnimationFrame rootFrame = CreateFrame(parser.Frame, parser, extractFrames, meshNames, device, Matrix.Identity, meshFrames); SetupBoneMatrices(rootFrame, rootFrame); return(rootFrame); }
private void UpdateFrameMatrices(AnimationFrame frame, Matrix parentMatrix) { frame.CombinedTransform = frame.TransformationMatrix * parentMatrix; if (frame.Sibling != null) { UpdateFrameMatrices((AnimationFrame)frame.Sibling, parentMatrix); } if (frame.FirstChild != null) { UpdateFrameMatrices((AnimationFrame)frame.FirstChild, frame.CombinedTransform); } }
private void ResetPose(AnimationFrame frame) { frame.TransformationMatrix = frame.OriginalTransform; if (frame.Sibling != null) { ResetPose((AnimationFrame)frame.Sibling); } if (frame.FirstChild != null) { ResetPose((AnimationFrame)frame.FirstChild); } }
private void DrawMeshFrame(AnimationFrame frame) { if (frame.MeshContainer is AnimationMeshContainer) { AnimationMeshContainer animMeshContainer = (AnimationMeshContainer)frame.MeshContainer; if (animMeshContainer.BoneNames.Length > 0) { device.SetRenderState(RenderState.VertexBlend, VertexBlend.Weights3); device.SetRenderState(RenderState.IndexedVertexBlendEnable, true); // uncomment to emphazise bone weights and darken everything else // device.SetRenderState(RenderState.DiffuseMaterialSource, ColorSource.Color1); device.SetRenderState(RenderState.AmbientMaterialSource, ColorSource.Color1); for (int i = 0; i < animMeshContainer.BoneNames.Length; i++) { if (animMeshContainer.BoneFrames[i] != null) { device.SetTransform(i, animMeshContainer.BoneOffsets[i] * animMeshContainer.BoneFrames[i].CombinedTransform); } } } else { device.SetRenderState(RenderState.VertexBlend, VertexBlend.Disable); device.SetRenderState(RenderState.AmbientMaterialSource, ColorSource.Material); device.SetTransform(TransformState.World, frame.CombinedTransform); } submeshNum = 0; while (animMeshContainer != null) { DrawAnimationMeshContainer(animMeshContainer); animMeshContainer = (AnimationMeshContainer)animMeshContainer.NextMeshContainer; submeshNum++; } } else if (frame.MeshContainer is MorphMeshContainer) { MorphMeshContainer morphMeshContainer = (MorphMeshContainer)frame.MeshContainer; device.SetRenderState(RenderState.AmbientMaterialSource, ColorSource.Material); device.SetTransform(TransformState.World, frame.CombinedTransform); submeshNum = 0; DrawMorphMeshContainer(morphMeshContainer); } }
public RenderObjectXX(xxParser parser, HashSet <string> meshNames) { HighlightSubmesh = new HashSet <int>(); highlightMaterial = new Material(); highlightMaterial.Ambient = new Color4(1, 1, 1, 1); highlightMaterial.Diffuse = new Color4(1, 0, 1, 0); this.device = Gui.Renderer.Device; this.tweeningVertDec = new VertexDeclaration(this.device, TweeningMeshesVertexBufferFormat.ThreeStreams); Textures = new Texture[parser.TextureList.Count]; Materials = new Material[parser.MaterialList.Count]; rootFrame = CreateHierarchy(parser, meshNames, device, out meshFrames); AnimationController = new AnimationController(numFrames, 30, 30, 1); Frame.RegisterNamedMatrices(rootFrame, AnimationController); Bounds = meshFrames[0].Bounds; for (int i = 1; i < meshFrames.Count; i++) { Bounds = BoundingBox.Merge(Bounds, meshFrames[i].Bounds); } }
public RenderObjectXX(xxParser parser, HashSet<string> meshNames) { HighlightSubmesh = new HashSet<int>(); highlightMaterial = new Material(); highlightMaterial.Ambient = new Color4(1, 1, 1, 1); highlightMaterial.Diffuse = new Color4(1, 0, 1, 0); this.device = Gui.Renderer.Device; this.tweeningVertDec = new VertexDeclaration(this.device, TweeningMeshesVertexBufferFormat.ThreeStreams); Textures = new Texture[parser.TextureList.Count]; Materials = new Material[parser.MaterialList.Count]; rootFrame = CreateHierarchy(parser, meshNames, device, out meshFrames); AnimationController = new AnimationController(numFrames, 30, 30, 1); Frame.RegisterNamedMatrices(rootFrame, AnimationController); Bounds = meshFrames[0].Bounds; for (int i = 1; i < meshFrames.Count; i++) { Bounds = BoundingBox.Merge(Bounds, meshFrames[i].Bounds); } }
private void UpdateFrameMatrices(AnimationFrame frame, Matrix parentMatrix) { frame.CombinedTransform = frame.TransformationMatrix * parentMatrix; if (frame.Sibling != null) { UpdateFrameMatrices((AnimationFrame)frame.Sibling, parentMatrix); } if (frame.FirstChild != null) { UpdateFrameMatrices((AnimationFrame)frame.FirstChild, frame.CombinedTransform); } }
private void SetupBoneMatrices(AnimationFrame frame, AnimationFrame root) { AnimationMeshContainer mesh = (AnimationMeshContainer)frame.MeshContainer; if (mesh != null) { byte numBones = (byte)mesh.BoneNames.Length; AnimationFrame[] boneFrames = null; PositionBlendWeightIndexedColored[] boneLines = null; if (numBones > 0) { boneFrames = new AnimationFrame[numBones]; var boneDic = new Dictionary<string, byte>(); for (byte i = 0; i < numBones; i++) { string boneName = mesh.BoneNames[i]; AnimationFrame bone = (AnimationFrame)root.FindChild(boneName); boneFrames[i] = bone; boneDic.Add(boneName, i); } float boneWidth = 0.05f; int boneColor = Color.CornflowerBlue.ToArgb(); boneLines = new PositionBlendWeightIndexedColored[numBones * BoneObjSize]; for (byte i = 0; i < numBones; i++) { AnimationFrame bone = boneFrames[i]; byte boneParentId; if ((bone != null) && (bone.Parent != null) && boneDic.TryGetValue(bone.Parent.Name, out boneParentId)) { Matrix boneMatrix = Matrix.Invert(mesh.BoneOffsets[i]); Matrix boneParentMatrix = Matrix.Invert(mesh.BoneOffsets[boneParentId]); Vector3 bonePos = Vector3.TransformCoordinate(new Vector3(), boneMatrix); Vector3 boneParentPos = Vector3.TransformCoordinate(new Vector3(), boneParentMatrix); Vector3 direction = bonePos - boneParentPos; float scale = boneWidth * (1 + direction.Length() / 2); Vector3 perpendicular = direction.Perpendicular(); Vector3 cross = Vector3.Cross(direction, perpendicular); perpendicular = Vector3.Normalize(perpendicular) * scale; cross = Vector3.Normalize(cross) * scale; Vector3 bottomLeft = -perpendicular + -cross + boneParentPos; Vector3 bottomRight = -perpendicular + cross + boneParentPos; Vector3 topLeft = perpendicular + -cross + boneParentPos; Vector3 topRight = perpendicular + cross + boneParentPos; boneLines[i * BoneObjSize] = new PositionBlendWeightIndexedColored(bottomLeft, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 1] = new PositionBlendWeightIndexedColored(bottomRight, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 2] = new PositionBlendWeightIndexedColored(bottomRight, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 3] = new PositionBlendWeightIndexedColored(topRight, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 4] = new PositionBlendWeightIndexedColored(topRight, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 5] = new PositionBlendWeightIndexedColored(topLeft, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 6] = new PositionBlendWeightIndexedColored(topLeft, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 7] = new PositionBlendWeightIndexedColored(bottomLeft, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 8] = new PositionBlendWeightIndexedColored(bottomLeft, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 9] = new PositionBlendWeightIndexedColored(bonePos, i, boneColor); boneLines[(i * BoneObjSize) + 10] = new PositionBlendWeightIndexedColored(bottomRight, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 11] = new PositionBlendWeightIndexedColored(bonePos, i, boneColor); boneLines[(i * BoneObjSize) + 12] = new PositionBlendWeightIndexedColored(topLeft, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 13] = new PositionBlendWeightIndexedColored(bonePos, i, boneColor); boneLines[(i * BoneObjSize) + 14] = new PositionBlendWeightIndexedColored(topRight, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 15] = new PositionBlendWeightIndexedColored(bonePos, i, boneColor); } } } while (mesh != null) { if (mesh.NextMeshContainer == null) { mesh.BoneLines = boneLines; } mesh.BoneFrames = boneFrames; mesh = (AnimationMeshContainer)mesh.NextMeshContainer; } } if (frame.Sibling != null) { SetupBoneMatrices(frame.Sibling as AnimationFrame, root); } if (frame.FirstChild != null) { SetupBoneMatrices(frame.FirstChild as AnimationFrame, root); } }
private void ResetPose(AnimationFrame frame) { frame.TransformationMatrix = frame.OriginalTransform; if (frame.Sibling != null) { ResetPose((AnimationFrame)frame.Sibling); } if (frame.FirstChild != null) { ResetPose((AnimationFrame)frame.FirstChild); } }
private void SetupBoneMatrices(AnimationFrame frame, AnimationFrame root) { AnimationMeshContainer mesh = (AnimationMeshContainer)frame.MeshContainer; if (mesh != null) { byte numBones = (byte)mesh.BoneNames.Length; AnimationFrame[] boneFrames = null; PositionBlendWeightIndexedColored[] boneLines = null; if (numBones > 0) { boneFrames = new AnimationFrame[numBones]; var boneDic = new Dictionary <string, byte>(); for (byte i = 0; i < numBones; i++) { string boneName = mesh.BoneNames[i]; AnimationFrame bone = (AnimationFrame)root.FindChild(boneName); boneFrames[i] = bone; boneDic.Add(boneName, i); } float boneWidth = 0.05f; int boneColor = Color.CornflowerBlue.ToArgb(); boneLines = new PositionBlendWeightIndexedColored[numBones * BoneObjSize]; for (byte i = 0; i < numBones; i++) { AnimationFrame bone = boneFrames[i]; byte boneParentId; if ((bone != null) && (bone.Parent != null) && boneDic.TryGetValue(bone.Parent.Name, out boneParentId)) { Matrix boneMatrix = Matrix.Invert(mesh.BoneOffsets[i]); Matrix boneParentMatrix = Matrix.Invert(mesh.BoneOffsets[boneParentId]); Vector3 bonePos = Vector3.TransformCoordinate(new Vector3(), boneMatrix); Vector3 boneParentPos = Vector3.TransformCoordinate(new Vector3(), boneParentMatrix); Vector3 direction = bonePos - boneParentPos; float scale = boneWidth * (1 + direction.Length() / 2); Vector3 perpendicular = direction.Perpendicular(); Vector3 cross = Vector3.Cross(direction, perpendicular); perpendicular = Vector3.Normalize(perpendicular) * scale; cross = Vector3.Normalize(cross) * scale; Vector3 bottomLeft = -perpendicular + -cross + boneParentPos; Vector3 bottomRight = -perpendicular + cross + boneParentPos; Vector3 topLeft = perpendicular + -cross + boneParentPos; Vector3 topRight = perpendicular + cross + boneParentPos; boneLines[i * BoneObjSize] = new PositionBlendWeightIndexedColored(bottomLeft, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 1] = new PositionBlendWeightIndexedColored(bottomRight, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 2] = new PositionBlendWeightIndexedColored(bottomRight, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 3] = new PositionBlendWeightIndexedColored(topRight, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 4] = new PositionBlendWeightIndexedColored(topRight, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 5] = new PositionBlendWeightIndexedColored(topLeft, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 6] = new PositionBlendWeightIndexedColored(topLeft, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 7] = new PositionBlendWeightIndexedColored(bottomLeft, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 8] = new PositionBlendWeightIndexedColored(bottomLeft, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 9] = new PositionBlendWeightIndexedColored(bonePos, i, boneColor); boneLines[(i * BoneObjSize) + 10] = new PositionBlendWeightIndexedColored(bottomRight, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 11] = new PositionBlendWeightIndexedColored(bonePos, i, boneColor); boneLines[(i * BoneObjSize) + 12] = new PositionBlendWeightIndexedColored(topLeft, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 13] = new PositionBlendWeightIndexedColored(bonePos, i, boneColor); boneLines[(i * BoneObjSize) + 14] = new PositionBlendWeightIndexedColored(topRight, boneParentId, boneColor); boneLines[(i * BoneObjSize) + 15] = new PositionBlendWeightIndexedColored(bonePos, i, boneColor); } } } while (mesh != null) { if (mesh.NextMeshContainer == null) { mesh.BoneLines = boneLines; } mesh.BoneFrames = boneFrames; mesh = (AnimationMeshContainer)mesh.NextMeshContainer; } } if (frame.Sibling != null) { SetupBoneMatrices(frame.Sibling as AnimationFrame, root); } if (frame.FirstChild != null) { SetupBoneMatrices(frame.FirstChild as AnimationFrame, root); } }
private AnimationFrame CreateFrame(xxFrame frame, xxParser parser, HashSet <string> extractFrames, HashSet <string> meshNames, Device device, Matrix combinedParent, List <AnimationFrame> meshFrames) { AnimationFrame animationFrame = new AnimationFrame(); animationFrame.Name = frame.Name; animationFrame.TransformationMatrix = frame.Matrix; animationFrame.OriginalTransform = animationFrame.TransformationMatrix; animationFrame.CombinedTransform = combinedParent * animationFrame.TransformationMatrix; xxMesh mesh = frame.Mesh; if (meshNames.Contains(frame.Name) && (mesh != null)) { List <xxBone> boneList = mesh.BoneList; string[] boneNames = new string[boneList.Count]; Matrix[] boneOffsets = new Matrix[boneList.Count]; for (int i = 0; i < boneList.Count; i++) { xxBone bone = boneList[i]; boneNames[i] = bone.Name; boneOffsets[i] = bone.Matrix; } AnimationMeshContainer[] meshContainers = new AnimationMeshContainer[mesh.SubmeshList.Count]; Vector3 min = new Vector3(Single.MaxValue); Vector3 max = new Vector3(Single.MinValue); for (int i = 0; i < mesh.SubmeshList.Count; i++) { xxSubmesh submesh = mesh.SubmeshList[i]; List <xxFace> faceList = submesh.FaceList; List <xxVertex> vertexList = submesh.VertexList; Mesh animationMesh = new Mesh(device, faceList.Count, vertexList.Count, MeshFlags.Managed, PositionBlendWeightsIndexedNormalTexturedColoured.Format); using (DataStream indexStream = animationMesh.LockIndexBuffer(LockFlags.None)) { for (int j = 0; j < faceList.Count; j++) { ushort[] indices = faceList[j].VertexIndices; indexStream.Write(indices[0]); indexStream.Write(indices[2]); indexStream.Write(indices[1]); } animationMesh.UnlockIndexBuffer(); } FillVertexBuffer(animationMesh, vertexList, -1); var normalLines = new PositionBlendWeightsIndexedColored[vertexList.Count * 2]; for (int j = 0; j < vertexList.Count; j++) { xxVertex vertex = vertexList[j]; normalLines[j * 2] = new PositionBlendWeightsIndexedColored(vertex.Position, vertex.Weights3, vertex.BoneIndices, Color.Yellow.ToArgb()); normalLines[(j * 2) + 1] = new PositionBlendWeightsIndexedColored(vertex.Position + (vertex.Normal / 16), vertex.Weights3, vertex.BoneIndices, Color.Yellow.ToArgb()); min = Vector3.Minimize(min, vertex.Position); max = Vector3.Maximize(max, vertex.Position); } AnimationMeshContainer meshContainer = new AnimationMeshContainer(); meshContainer.Name = animationFrame.Name; meshContainer.MeshData = new MeshData(animationMesh); meshContainer.NormalLines = normalLines; meshContainers[i] = meshContainer; int matIdx = submesh.MaterialIndex; if ((matIdx >= 0) && (matIdx < parser.MaterialList.Count)) { int texIdx; if (!MatTexIndices.TryGetValue(matIdx, out texIdx)) { texIdx = -1; xxMaterial mat = parser.MaterialList[matIdx]; Material materialD3D = new Material(); materialD3D.Ambient = mat.Ambient; materialD3D.Diffuse = mat.Diffuse; materialD3D.Emissive = mat.Emissive; materialD3D.Specular = mat.Specular; materialD3D.Power = mat.Power; Materials[matIdx] = materialD3D; xxMaterialTexture matTex = mat.Textures[0]; string matTexName = matTex.Name; if (matTexName != String.Empty) { for (int j = 0; j < parser.TextureList.Count; j++) { xxTexture tex = parser.TextureList[j]; if (tex.Name == matTexName) { texIdx = j; if (Textures[j] == null) { ImportedTexture importedTex = xx.ImportedTexture(tex); Textures[j] = Texture.FromMemory(device, importedTex.Data); } break; } } } MatTexIndices.Add(matIdx, texIdx); } meshContainer.MaterialIndex = matIdx; meshContainer.TextureIndex = texIdx; } } for (int i = 0; i < (meshContainers.Length - 1); i++) { meshContainers[i].NextMeshContainer = meshContainers[i + 1]; } for (int i = 0; i < meshContainers.Length; i++) { meshContainers[i].BoneNames = boneNames; meshContainers[i].BoneOffsets = boneOffsets; } min = Vector3.TransformCoordinate(min, animationFrame.CombinedTransform); max = Vector3.TransformCoordinate(max, animationFrame.CombinedTransform); animationFrame.Bounds = new BoundingBox(min, max); animationFrame.MeshContainer = meshContainers[0]; meshFrames.Add(animationFrame); } for (int i = 0; i < frame.Count; i++) { xxFrame child = frame[i]; if (extractFrames.Contains(child.Name)) { AnimationFrame childAnimationFrame = CreateFrame(child, parser, extractFrames, meshNames, device, animationFrame.CombinedTransform, meshFrames); childAnimationFrame.Parent = animationFrame; animationFrame.AppendChild(childAnimationFrame); } } numFrames++; return(animationFrame); }
private void DrawMeshFrame(AnimationFrame frame) { if (frame.MeshContainer is AnimationMeshContainer) { AnimationMeshContainer animMeshContainer = (AnimationMeshContainer)frame.MeshContainer; if (animMeshContainer.BoneNames != null && animMeshContainer.BoneNames.Length > 0) { device.SetRenderState(RenderState.VertexBlend, VertexBlend.Weights3); device.SetRenderState(RenderState.IndexedVertexBlendEnable, true); device.SetRenderState(RenderState.DiffuseMaterialSource, ColorSource.Material); device.SetRenderState(RenderState.AmbientMaterialSource, ColorSource.Material); switch (Gui.Renderer.ShowBoneWeights) { case ShowBoneWeights.Weak: device.SetRenderState(RenderState.AmbientMaterialSource, ColorSource.Color1); break; case ShowBoneWeights.Strong: device.SetRenderState(RenderState.DiffuseMaterialSource, ColorSource.Color1); break; case ShowBoneWeights.Off: break; } for (int i = 0; i < animMeshContainer.BoneNames.Length; i++) { if (animMeshContainer.BoneFrames[i] != null) { device.SetTransform(i, animMeshContainer.BoneOffsets[i] * animMeshContainer.BoneFrames[i].CombinedTransform); } } } else { device.SetRenderState(RenderState.VertexBlend, VertexBlend.Disable); device.SetRenderState(RenderState.AmbientMaterialSource, ColorSource.Material); device.SetTransform(TransformState.World, frame.CombinedTransform * Matrix.Scaling(-1, 1, 1)); } submeshNum = 0; while (animMeshContainer != null) { DrawAnimationMeshContainer(animMeshContainer); animMeshContainer = (AnimationMeshContainer)animMeshContainer.NextMeshContainer; submeshNum++; } } else if (frame.MeshContainer is MorphMeshContainer) { MorphMeshContainer morphMeshContainer = (MorphMeshContainer)frame.MeshContainer; device.SetRenderState(RenderState.AmbientMaterialSource, ColorSource.Material); device.SetTransform(TransformState.World, frame.CombinedTransform * Matrix.Scaling(-1, 1, 1)); submeshNum = 0; while (morphMeshContainer != null) { DrawMorphMeshContainer(morphMeshContainer); morphMeshContainer = morphMeshContainer.NextMeshContainer as MorphMeshContainer; submeshNum++; } } }
private AnimationFrame CreateFrame(Transform frame, AnimatorEditor editor, HashSet<string> extractFrames, HashSet<string> meshNames, Device device, List<AnimationFrame> meshFrames, Dictionary<string, Tuple<Matrix, Matrix>> extractMatrices) { AnimationFrame animationFrame = new AnimationFrame(); animationFrame.Name = frame.GetTransformPath(); animationFrame.TransformationMatrix = Matrix.Scaling(frame.m_LocalScale) * Matrix.RotationQuaternion(frame.m_LocalRotation) * Matrix.Translation(frame.m_LocalPosition); animationFrame.OriginalTransform = animationFrame.TransformationMatrix; animationFrame.CombinedTransform = extractMatrices[animationFrame.Name].Item1; if (meshNames.Contains(animationFrame.Name)) { MeshRenderer meshR = frame.m_GameObject.instance.FindLinkedComponent(UnityClassID.SkinnedMeshRenderer); if (meshR == null) { meshR = frame.m_GameObject.instance.FindLinkedComponent(UnityClassID.MeshRenderer); } if (meshR != null) { Mesh mesh = Operations.GetMesh(meshR); if (mesh != null) { SkinnedMeshRenderer smr = meshR as SkinnedMeshRenderer; List<PPtr<Transform>> boneList = null; string[] boneNames = null; Matrix[] boneOffsets = null; if (smr != null && smr.m_Bones.Count > 0) { boneList = smr.m_Bones; int numBones = boneList.Count > 0 ? extractFrames.Count : 0; boneNames = new string[numBones]; boneOffsets = new Matrix[numBones]; if (numBones > 0) { string[] extractArray = new string[numBones]; extractFrames.CopyTo(extractArray); HashSet<string> extractCopy = new HashSet<string>(extractArray); int invalidBones = 0; for (int i = 0; i < boneList.Count; i++) { Transform bone = boneList[i].instance; if (bone == null || bone.m_GameObject.instance == null || !extractCopy.Remove(bone.GetTransformPath())) { invalidBones++; } else if (i < numBones) { boneNames[i] = bone.GetTransformPath(); boneOffsets[i] = Operations.Mirror(Matrix.Transpose(mesh.m_BindPose[i])); } } extractCopy.CopyTo(boneNames, boneList.Count - invalidBones); for (int i = boneList.Count; i < extractFrames.Count; i++) { boneOffsets[i] = extractMatrices[boneNames[i]].Item2; } } } AnimationMeshContainer[] meshContainers = new AnimationMeshContainer[mesh.m_SubMeshes.Count]; Vector3 min = new Vector3(Single.MaxValue); Vector3 max = new Vector3(Single.MinValue); Operations.vMesh vMesh = new Operations.vMesh(meshR, true, true); for (int i = 0; i < mesh.m_SubMeshes.Count; i++) { Operations.vSubmesh submesh = vMesh.submeshes[i]; List<Operations.vFace> faceList = submesh.faceList; List<Operations.vVertex> vertexList = submesh.vertexList; SlimDX.Direct3D9.Mesh animationMesh = null; PositionBlendWeightsIndexedColored[] normalLines = null; try { animationMesh = new SlimDX.Direct3D9.Mesh(device, faceList.Count, vertexList.Count, MeshFlags.Managed, PositionBlendWeightsIndexedNormalTexturedColoured.Format); using (DataStream indexStream = animationMesh.LockIndexBuffer(LockFlags.None)) { for (int j = 0; j < faceList.Count; j++) { ushort[] indices = faceList[j].index; indexStream.Write(indices[0]); indexStream.Write(indices[2]); indexStream.Write(indices[1]); } animationMesh.UnlockIndexBuffer(); } FillVertexBuffer(animationMesh, vertexList, -1); normalLines = new PositionBlendWeightsIndexedColored[vertexList.Count * 2]; for (int j = 0; j < vertexList.Count; j++) { Operations.vVertex vertex = vertexList[j]; byte[] bIdx; float[] bWeights; if (vertex.boneIndices != null) { bIdx = new byte[4] { (byte)vertex.boneIndices[0], (byte)vertex.boneIndices[1], (byte)vertex.boneIndices[2], (byte)vertex.boneIndices[3] }; bWeights = vertex.weights; } else { bIdx = new byte[4]; bWeights = new float[4]; } normalLines[j * 2] = new PositionBlendWeightsIndexedColored(vertex.position, bWeights, bIdx, Color.Yellow.ToArgb()); normalLines[(j * 2) + 1] = new PositionBlendWeightsIndexedColored(vertex.position + (vertex.normal / 64), bWeights, bIdx, Color.Yellow.ToArgb()); min = Vector3.Minimize(min, vertex.position); max = Vector3.Maximize(max, vertex.position); } } catch { Report.ReportLog("No display of submeshes with more than 64k vertices!"); } AnimationMeshContainer meshContainer = new AnimationMeshContainer(); if (animationMesh != null) { meshContainer.Name = animationFrame.Name; meshContainer.MeshData = new MeshData(animationMesh); meshContainer.NormalLines = normalLines; } meshContainers[i] = meshContainer; if (submesh.matList.Count > 0 && submesh.matList[0].instance != null) { Material mat = submesh.matList[0].instance; int matIdx = editor.Materials.IndexOf(mat); int texIdx; if (!MatTexIndices.TryGetValue(matIdx, out texIdx)) { texIdx = -1; SlimDX.Direct3D9.Material materialD3D = new SlimDX.Direct3D9.Material(); materialD3D.Ambient = GetColour(mat, "_SColor"); materialD3D.Diffuse = GetColour(mat, "_Color"); materialD3D.Emissive = GetColour(mat, "_ReflectColor"); materialD3D.Specular = GetColour(mat, "_SpecColor"); materialD3D.Power = GetFloat(mat, "_Shininess"); Materials[matIdx] = materialD3D; Texture2D matTex = GetTexture(mat, "_MainTex"); if (matTex != null) { texIdx = editor.Textures.IndexOf(matTex); if (Textures[texIdx] == null) { using (MemoryStream mem = new MemoryStream()) { matTex.Export(mem); mem.Position = 0; ImportedTexture image = new ImportedTexture(mem, matTex.m_Name); Textures[texIdx] = Texture.FromMemory(device, image.Data); } } } MatTexIndices.Add(matIdx, texIdx); } meshContainer.MaterialIndex = matIdx; meshContainer.TextureIndex = texIdx; } } for (int i = 0; i < (meshContainers.Length - 1); i++) { meshContainers[i].NextMeshContainer = meshContainers[i + 1]; } if (boneList != null) { for (int i = 0; i < meshContainers.Length; i++) { meshContainers[i].BoneNames = boneNames; meshContainers[i].BoneOffsets = boneOffsets; meshContainers[i].RealBones = boneList.Count; } } Matrix mirrorCombined = Operations.Mirror(animationFrame.CombinedTransform); min = Vector3.TransformCoordinate(min, mirrorCombined); max = Vector3.TransformCoordinate(max, mirrorCombined); animationFrame.Bounds = new BoundingBox(min, max); animationFrame.MeshContainer = meshContainers[0]; meshFrames.Add(animationFrame); } } } for (int i = 0; i < frame.Count; i++) { Transform child = frame[i]; if (extractFrames.Contains(child.GetTransformPath())) { AnimationFrame childAnimationFrame = CreateFrame(child, editor, extractFrames, meshNames, device, meshFrames, extractMatrices); childAnimationFrame.Parent = animationFrame; animationFrame.AppendChild(childAnimationFrame); } } numFrames++; return animationFrame; }
private AnimationFrame CreateFrame(remBone frame, remParser parser, HashSet<string> extractFrames, remMesh mesh, Device device, Matrix combinedParent, List<AnimationFrame> meshFrames) { AnimationFrame animationFrame = new AnimationFrame(); animationFrame.Name = frame.name.ToString(); animationFrame.TransformationMatrix = frame.matrix; animationFrame.OriginalTransform = animationFrame.TransformationMatrix; animationFrame.CombinedTransform = combinedParent * animationFrame.TransformationMatrix; if (frame.name == mesh.frame) { ExtendedMaterial[] materials = new ExtendedMaterial[mesh.numMats]; List<List<remVertex>> submeshVertLists = new List<List<remVertex>>(mesh.numMats); List<List<ushort>> submeshFaceLists = new List<List<ushort>>(mesh.numMats); List<int[]> submeshVertIndices = new List<int[]>(mesh.numMats); SplitMesh(mesh, submeshVertLists, submeshFaceLists, submeshVertIndices); remSkin boneList = rem.FindSkin(mesh.name, parser.SKIC); bool skinned = boneList != null; int numBones = skinned ? boneList.Count : 0; List<string> boneNamesList = new List<string>(numBones); List<Matrix> boneOffsetsList = new List<Matrix>(numBones); for (int boneIdx = 0; boneIdx < numBones; boneIdx++) { boneNamesList.Add(boneList[boneIdx].bone.ToString()); boneOffsetsList.Add(boneList[boneIdx].matrix); } List<string> boneFrameParentNames = new List<string>(numBones); List<Matrix> boneFrameParentMatrices = new List<Matrix>(numBones); for (int boneIdx = 0; boneIdx < numBones; boneIdx++) { remBone boneFrame = rem.FindFrame(boneList[boneIdx].bone, parser.BONC.rootFrame); if (boneFrame == null) { continue; } remBone boneFrameParent = boneFrame.Parent; if (!boneNamesList.Contains(boneFrameParent.name) && !boneFrameParentNames.Contains(boneFrameParent.name)) { boneFrameParentNames.Add(boneFrameParent.name); Matrix incompleteMeshFrameCorrection = Matrix.Invert(frame.matrix); boneFrameParentMatrices.Add(incompleteMeshFrameCorrection * Matrix.Invert(boneFrame.matrix) * boneList[boneIdx].matrix); } } boneNamesList.AddRange(boneFrameParentNames); string[] boneNames = boneNamesList.ToArray(); boneOffsetsList.AddRange(boneFrameParentMatrices); Matrix[] boneOffsets = boneOffsetsList.ToArray(); AnimationMeshContainer[] meshContainers = new AnimationMeshContainer[submeshFaceLists.Count]; Vector3 min = new Vector3(Single.MaxValue); Vector3 max = new Vector3(Single.MinValue); for (int i = 0; i < submeshFaceLists.Count; i++) { List<ushort> faceList = submeshFaceLists[i]; List<remVertex> vertexList = submeshVertLists[i]; Mesh animationMesh = new Mesh(device, faceList.Count, vertexList.Count, MeshFlags.Managed, PositionBlendWeightsIndexedNormalTexturedColoured.Format); using (DataStream indexStream = animationMesh.LockIndexBuffer(LockFlags.None)) { for (int j = 0; j < faceList.Count; j++) { indexStream.Write(faceList[j]); } animationMesh.UnlockIndexBuffer(); } byte[][] vertexBoneIndices = null; float[][] vertexWeights = ConvertVertexWeights(vertexList, submeshVertIndices[i], boneList, out vertexBoneIndices); FillVertexBuffer(animationMesh, vertexList, vertexWeights, vertexBoneIndices, -1); var normalLines = new PositionBlendWeightsIndexedColored[vertexList.Count * 2]; for (int j = 0; j < vertexList.Count; j++) { remVertex vertex = vertexList[j]; Vector3 position = vertex.Position; Vector3 normal = vertex.Normal; float[] boneWeights = vertexWeights[j]; normalLines[j * 2] = new PositionBlendWeightsIndexedColored(position, boneWeights, vertexBoneIndices[j], Color.Coral.ToArgb()); normalLines[(j * 2) + 1] = new PositionBlendWeightsIndexedColored(position + normal, boneWeights, vertexBoneIndices[j], Color.Blue.ToArgb()); #if !DONT_MIRROR position.Z *= -1f; #endif min = Vector3.Minimize(min, position); max = Vector3.Maximize(max, position); } AnimationMeshContainer meshContainer = new AnimationMeshContainer(); meshContainer.Name = animationFrame.Name; meshContainer.MeshData = new MeshData(animationMesh); meshContainer.NormalLines = normalLines; meshContainer.BoneNames = boneNames; meshContainer.BoneOffsets = boneOffsets; meshContainers[i] = meshContainer; remMaterial mat = rem.FindMaterial(mesh.materials[i], parser.MATC); if (mat != null) { Material material3D = new Material(); material3D.Ambient = new Color4(mat.ambient); material3D.Diffuse = new Color4(mat.diffuse); material3D.Emissive = new Color4(mat.emissive); material3D.Specular = new Color4(mat.specular); material3D.Power = mat.specularPower; int matIdx = parser.MATC.IndexOf(mat); Materials[matIdx] = material3D; meshContainer.MaterialIndex = matIdx; int texIdx = 0; if (mat.texture != null && !TextureDic.TryGetValue(mat.texture.ToString(), out texIdx)) { ImportedTexture importedTex = null; if (!ImportedTextures.TryGetValue(mat.texture.ToString(), out importedTex)) { importedTex = rem.ImportedTexture(mat.texture, parser.RemPath, true); if (importedTex == null) { Report.ReportLog("Export textures of TEXH.FPK!"); continue; } ImportedTextures.Add(mat.texture.ToString(), importedTex); } Texture memTex = Texture.FromMemory(device, importedTex.Data); texIdx = TextureDic.Count; TextureDic.Add(mat.texture.ToString(), texIdx); Textures.Add(memTex); } meshContainer.TextureIndex = texIdx; } } for (int i = 0; i < (meshContainers.Length - 1); i++) { meshContainers[i].NextMeshContainer = meshContainers[i + 1]; } min = Vector3.TransformCoordinate(min, animationFrame.CombinedTransform); max = Vector3.TransformCoordinate(max, animationFrame.CombinedTransform); animationFrame.Bounds = new BoundingBox(min, max); animationFrame.MeshContainer = meshContainers[0]; meshFrames.Add(animationFrame); } for (int i = 0; i < frame.Count; i++) { remBone child = frame[i]; if (extractFrames.Contains(child.name.ToString())) { AnimationFrame childAnimationFrame = CreateFrame(child, parser, extractFrames, mesh, device, animationFrame.CombinedTransform, meshFrames); childAnimationFrame.Parent = animationFrame; animationFrame.AppendChild(childAnimationFrame); } } numFrames++; return animationFrame; }
private void SetupBoneMatrices(AnimationFrame frame, AnimationFrame root) { AnimationMeshContainer mesh = (AnimationMeshContainer)frame.MeshContainer; if (mesh != null) { AnimationFrame[] boneFrames = null; PositionBlendWeightIndexedColored[] boneLines = null; if (mesh.RealBones > 0) { int numBones = mesh.BoneNames.Length; boneFrames = new AnimationFrame[numBones]; var boneDic = new Dictionary<string, int>(); int topBone = -1; int topLevel = 100; for (int i = 0; i < numBones; i++) { string boneName = mesh.BoneNames[i]; if (boneName != null) { AnimationFrame bone = (AnimationFrame)root.FindChild(boneName); boneFrames[i] = bone; boneDic.Add(boneName, i); if (i < mesh.RealBones) { int level = 0; while (bone != root) { bone = bone.Parent; level++; } if (level < topLevel) { topLevel = level; topBone = i; } } } } List<PositionBlendWeightIndexedColored> boneLineList = new List<PositionBlendWeightIndexedColored>(numBones * BoneObjSize); for (int i = 0; i < numBones; i++) { float boneWidth = 0.009f; AnimationFrame bone = boneFrames[i]; if (bone == null) { continue; } AnimationFrame parent = bone.Parent; if (parent == null) { continue; } Matrix boneMatrix = Matrix.Invert(mesh.BoneOffsets[i]); Vector3 bonePos = Vector3.TransformCoordinate(new Vector3(), boneMatrix); if (i >= mesh.RealBones && bonePos.X == 0 && bonePos.Y == 0 && bonePos.Z == 0) { continue; } int realParentId; Vector3 boneParentPos; if (i != topBone) { boneDic.TryGetValue(parent.Name, out realParentId); Matrix boneParentMatrix = Matrix.Invert(mesh.BoneOffsets[realParentId]); boneParentPos = Vector3.TransformCoordinate(new Vector3(), boneParentMatrix); if (i >= mesh.RealBones && boneParentPos.X == 0 && boneParentPos.Y == 0 && boneParentPos.Z == 0) { continue; } } else { realParentId = i; boneParentPos = bonePos; } float lenlen = (bonePos - boneParentPos).LengthSquared(); if (lenlen < 1E-12) { boneWidth /= 3f; int level = 0; while (parent != null) { level++; parent = parent.Parent; } if ((level % 2) == 0) { bonePos.Y -= boneWidth; boneParentPos.Y += boneWidth; } else { bonePos.Y += boneWidth; boneParentPos.Y -= boneWidth; } } else if (lenlen < 0.0001) { boneWidth /= 2f; } Vector3 direction = bonePos - boneParentPos; float scale = boneWidth * (1 + direction.Length() / 2); Vector3 perpendicular = direction.Perpendicular(); Vector3 cross = Vector3.Cross(direction, perpendicular); perpendicular = Vector3.Normalize(perpendicular) * scale; cross = Vector3.Normalize(cross) * scale; Vector3 bottomLeft = -perpendicular + -cross + boneParentPos; Vector3 bottomRight = -perpendicular + cross + boneParentPos; Vector3 topLeft = perpendicular + -cross + boneParentPos; Vector3 topRight = perpendicular + cross + boneParentPos; int boneColor = i < mesh.RealBones ? Color.CornflowerBlue.ToArgb() : Color.BlueViolet.ToArgb(); if (realParentId < 256 && i < 256) { byte boneParentId = (byte)realParentId; boneLineList.Add(new PositionBlendWeightIndexedColored(bottomLeft, boneParentId, boneColor)); boneLineList.Add(new PositionBlendWeightIndexedColored(bottomRight, boneParentId, boneColor)); boneLineList.Add(new PositionBlendWeightIndexedColored(bottomRight, boneParentId, boneColor)); boneLineList.Add(new PositionBlendWeightIndexedColored(topRight, boneParentId, boneColor)); boneLineList.Add(new PositionBlendWeightIndexedColored(topRight, boneParentId, boneColor)); boneLineList.Add(new PositionBlendWeightIndexedColored(topLeft, boneParentId, boneColor)); boneLineList.Add(new PositionBlendWeightIndexedColored(topLeft, boneParentId, boneColor)); boneLineList.Add(new PositionBlendWeightIndexedColored(bottomLeft, boneParentId, boneColor)); byte boneId = (byte)i; boneLineList.Add(new PositionBlendWeightIndexedColored(bottomLeft, boneParentId, boneColor)); boneLineList.Add(new PositionBlendWeightIndexedColored(bonePos, boneId, boneColor)); boneLineList.Add(new PositionBlendWeightIndexedColored(bottomRight, boneParentId, boneColor)); boneLineList.Add(new PositionBlendWeightIndexedColored(bonePos, boneId, boneColor)); boneLineList.Add(new PositionBlendWeightIndexedColored(topLeft, boneParentId, boneColor)); boneLineList.Add(new PositionBlendWeightIndexedColored(bonePos, boneId, boneColor)); boneLineList.Add(new PositionBlendWeightIndexedColored(topRight, boneParentId, boneColor)); boneLineList.Add(new PositionBlendWeightIndexedColored(bonePos, boneId, boneColor)); } else { for (int j = 0; j < BoneObjSize; j++) { boneLineList.Add(new PositionBlendWeightIndexedColored()); } } } boneLines = boneLineList.ToArray(); } while (mesh != null) { if (mesh.NextMeshContainer == null) { mesh.BoneLines = boneLines; } mesh.BoneFrames = boneFrames; mesh = (AnimationMeshContainer)mesh.NextMeshContainer; } } if (frame.Sibling != null) { SetupBoneMatrices(frame.Sibling as AnimationFrame, root); } if (frame.FirstChild != null) { SetupBoneMatrices(frame.FirstChild as AnimationFrame, root); } }
private AnimationFrame CreateFrame(xxFrame frame, xxParser parser, HashSet<string> extractFrames, HashSet<string> meshNames, Device device, Matrix combinedParent, List<AnimationFrame> meshFrames) { AnimationFrame animationFrame = new AnimationFrame(); animationFrame.Name = frame.Name; animationFrame.TransformationMatrix = frame.Matrix; animationFrame.OriginalTransform = animationFrame.TransformationMatrix; animationFrame.CombinedTransform = combinedParent * animationFrame.TransformationMatrix; xxMesh mesh = frame.Mesh; if (meshNames.Contains(frame.Name) && (mesh != null)) { List<xxBone> boneList = mesh.BoneList; string[] boneNames = new string[boneList.Count]; Matrix[] boneOffsets = new Matrix[boneList.Count]; for (int i = 0; i < boneList.Count; i++) { xxBone bone = boneList[i]; boneNames[i] = bone.Name; boneOffsets[i] = bone.Matrix; } AnimationMeshContainer[] meshContainers = new AnimationMeshContainer[mesh.SubmeshList.Count]; Vector3 min = new Vector3(Single.MaxValue); Vector3 max = new Vector3(Single.MinValue); for (int i = 0; i < mesh.SubmeshList.Count; i++) { xxSubmesh submesh = mesh.SubmeshList[i]; List<xxFace> faceList = submesh.FaceList; List<xxVertex> vertexList = submesh.VertexList; Mesh animationMesh = new Mesh(device, faceList.Count, vertexList.Count, MeshFlags.Managed, PositionBlendWeightsIndexedNormalTexturedColoured.Format); using (DataStream indexStream = animationMesh.LockIndexBuffer(LockFlags.None)) { for (int j = 0; j < faceList.Count; j++) { ushort[] indices = faceList[j].VertexIndices; indexStream.Write(indices[0]); indexStream.Write(indices[2]); indexStream.Write(indices[1]); } animationMesh.UnlockIndexBuffer(); } FillVertexBuffer(animationMesh, vertexList, -1); var normalLines = new PositionBlendWeightsIndexedColored[vertexList.Count * 2]; for (int j = 0; j < vertexList.Count; j++) { xxVertex vertex = vertexList[j]; normalLines[j * 2] = new PositionBlendWeightsIndexedColored(vertex.Position, vertex.Weights3, vertex.BoneIndices, Color.Yellow.ToArgb()); normalLines[(j * 2) + 1] = new PositionBlendWeightsIndexedColored(vertex.Position + (vertex.Normal / 16), vertex.Weights3, vertex.BoneIndices, Color.Yellow.ToArgb()); min = Vector3.Minimize(min, vertex.Position); max = Vector3.Maximize(max, vertex.Position); } AnimationMeshContainer meshContainer = new AnimationMeshContainer(); meshContainer.Name = animationFrame.Name; meshContainer.MeshData = new MeshData(animationMesh); meshContainer.NormalLines = normalLines; meshContainers[i] = meshContainer; int matIdx = submesh.MaterialIndex; if ((matIdx >= 0) && (matIdx < parser.MaterialList.Count)) { int texIdx; if (!MatTexIndices.TryGetValue(matIdx, out texIdx)) { texIdx = -1; xxMaterial mat = parser.MaterialList[matIdx]; Material materialD3D = new Material(); materialD3D.Ambient = mat.Ambient; materialD3D.Diffuse = mat.Diffuse; materialD3D.Emissive = mat.Emissive; materialD3D.Specular = mat.Specular; materialD3D.Power = mat.Power; Materials[matIdx] = materialD3D; xxMaterialTexture matTex = mat.Textures[0]; string matTexName = matTex.Name; if (matTexName != String.Empty) { for (int j = 0; j < parser.TextureList.Count; j++) { xxTexture tex = parser.TextureList[j]; if (tex.Name == matTexName) { texIdx = j; if (Textures[j] == null) { ImportedTexture importedTex = xx.ImportedTexture(tex); Textures[j] = Texture.FromMemory(device, importedTex.Data); } break; } } } MatTexIndices.Add(matIdx, texIdx); } meshContainer.MaterialIndex = matIdx; meshContainer.TextureIndex = texIdx; } } for (int i = 0; i < (meshContainers.Length - 1); i++) { meshContainers[i].NextMeshContainer = meshContainers[i + 1]; } for (int i = 0; i < meshContainers.Length; i++) { meshContainers[i].BoneNames = boneNames; meshContainers[i].BoneOffsets = boneOffsets; } min = Vector3.TransformCoordinate(min, animationFrame.CombinedTransform); max = Vector3.TransformCoordinate(max, animationFrame.CombinedTransform); animationFrame.Bounds = new BoundingBox(min, max); animationFrame.MeshContainer = meshContainers[0]; meshFrames.Add(animationFrame); } for (int i = 0; i < frame.Count; i++) { xxFrame child = frame[i]; if (extractFrames.Contains(child.Name)) { AnimationFrame childAnimationFrame = CreateFrame(child, parser, extractFrames, meshNames, device, animationFrame.CombinedTransform, meshFrames); childAnimationFrame.Parent = animationFrame; animationFrame.AppendChild(childAnimationFrame); } } numFrames++; return animationFrame; }
private void SetupBoneMatrices(AnimationFrame frame, AnimationFrame root) { for (AnimationMeshContainer mesh = (AnimationMeshContainer)frame.MeshContainer; mesh != null; mesh = (AnimationMeshContainer)mesh.NextMeshContainer) { int numBones = mesh.BoneNames.Length; if (numBones <= 0) continue; AnimationFrame[] boneFrames = new AnimationFrame[numBones]; for (int i = 0; i < numBones; i++) { AnimationFrame boneFrame = (AnimationFrame)root.FindChild(mesh.BoneNames[i]); boneFrames[i] = boneFrame; } mesh.BoneFrames = boneFrames; int boneObjSize = 16; float boneWidth = 0.1f; int boneColor = Color.CornflowerBlue.ToArgb(); PositionBlendWeightIndexedColored[] boneLines = new PositionBlendWeightIndexedColored[numBones * boneObjSize]; for (byte i = 0; i < numBones; i++) { AnimationFrame bone = boneFrames[i]; if (bone != null && bone.Parent != null) { byte parentBoneIdx = 0xFF; for (byte j = 0; j < mesh.BoneNames.Length; j++) { if (mesh.BoneNames[j] == bone.Parent.Name) { parentBoneIdx = j; break; } } if (parentBoneIdx == 0xFF) { continue; } Matrix boneMatrix = Matrix.Invert(mesh.BoneOffsets[i]); Matrix boneParentMatrix = Matrix.Invert(mesh.BoneOffsets[parentBoneIdx]); Vector3 bonePos = Vector3.TransformCoordinate(new Vector3(), boneMatrix); Vector3 boneParentPos = Vector3.TransformCoordinate(new Vector3(), boneParentMatrix); Vector3 direction = bonePos - boneParentPos; Vector3 perpendicular = direction.Perpendicular(); Vector3 cross = Vector3.Cross(direction, perpendicular); perpendicular = Vector3.Normalize(perpendicular) * boneWidth; cross = Vector3.Normalize(cross) * boneWidth; Vector3 bottomLeft = -perpendicular + -cross + boneParentPos; Vector3 bottomRight = -perpendicular + cross + boneParentPos; Vector3 topLeft = perpendicular + -cross + boneParentPos; Vector3 topRight = perpendicular + cross + boneParentPos; boneLines[i * boneObjSize] = new PositionBlendWeightIndexedColored(bottomLeft, parentBoneIdx, boneColor); boneLines[(i * boneObjSize) + 1] = new PositionBlendWeightIndexedColored(bottomRight, parentBoneIdx, boneColor); boneLines[(i * boneObjSize) + 2] = new PositionBlendWeightIndexedColored(bottomRight, parentBoneIdx, boneColor); boneLines[(i * boneObjSize) + 3] = new PositionBlendWeightIndexedColored(topRight, parentBoneIdx, boneColor); boneLines[(i * boneObjSize) + 4] = new PositionBlendWeightIndexedColored(topRight, parentBoneIdx, boneColor); boneLines[(i * boneObjSize) + 5] = new PositionBlendWeightIndexedColored(topLeft, parentBoneIdx, boneColor); boneLines[(i * boneObjSize) + 6] = new PositionBlendWeightIndexedColored(topLeft, parentBoneIdx, boneColor); boneLines[(i * boneObjSize) + 7] = new PositionBlendWeightIndexedColored(bottomLeft, parentBoneIdx, boneColor); boneLines[(i * boneObjSize) + 8] = new PositionBlendWeightIndexedColored(bottomLeft, parentBoneIdx, boneColor); boneLines[(i * boneObjSize) + 9] = new PositionBlendWeightIndexedColored(bonePos, i, boneColor); boneLines[(i * boneObjSize) + 10] = new PositionBlendWeightIndexedColored(bottomRight, parentBoneIdx, boneColor); boneLines[(i * boneObjSize) + 11] = new PositionBlendWeightIndexedColored(bonePos, i, boneColor); boneLines[(i * boneObjSize) + 12] = new PositionBlendWeightIndexedColored(topLeft, parentBoneIdx, boneColor); boneLines[(i * boneObjSize) + 13] = new PositionBlendWeightIndexedColored(bonePos, i, boneColor); boneLines[(i * boneObjSize) + 14] = new PositionBlendWeightIndexedColored(topRight, parentBoneIdx, boneColor); boneLines[(i * boneObjSize) + 15] = new PositionBlendWeightIndexedColored(bonePos, i, boneColor); } } mesh.BoneLines = boneLines; } if (frame.Sibling != null) { SetupBoneMatrices(frame.Sibling as AnimationFrame, root); } if (frame.FirstChild != null) { SetupBoneMatrices(frame.FirstChild as AnimationFrame, root); } }
private void DrawMeshFrame(AnimationFrame frame) { submeshNum = 0; for (AnimationMeshContainer meshContainer = (AnimationMeshContainer)frame.MeshContainer; meshContainer != null; meshContainer = (AnimationMeshContainer)meshContainer.NextMeshContainer, submeshNum++) { DrawMeshContainer(meshContainer, frame); } }
private void DrawMeshContainer(AnimationMeshContainer meshContainer, AnimationFrame frame) { device.SetRenderState(RenderState.ZEnable, ZBufferType.UseZBuffer); device.SetRenderState(RenderState.Lighting, true); #if !DONT_MIRROR Cull culling = (Gui.Renderer.Culling) ? Cull.Counterclockwise : Cull.None; #else Cull culling = (Gui.Renderer.Culling) ? Cull.Clockwise : Cull.None; #endif device.SetRenderState(RenderState.CullMode, culling); FillMode fill = (Gui.Renderer.Wireframe) ? FillMode.Wireframe : FillMode.Solid; device.SetRenderState(RenderState.FillMode, fill); if (meshContainer.BoneNames.Length > 0) { device.SetRenderState(RenderState.VertexBlend, VertexBlend.Weights3); device.SetRenderState(RenderState.IndexedVertexBlendEnable, true); // device.SetRenderState(RenderState.ColorVertex, true); device.SetRenderState(RenderState.DiffuseMaterialSource, ColorSource.Material); device.SetRenderState(RenderState.AmbientMaterialSource, ColorSource.Material); switch (Gui.Renderer.ShowBoneWeights) { case ShowBoneWeights.Weak: device.SetRenderState(RenderState.AmbientMaterialSource, ColorSource.Color1); break; case ShowBoneWeights.Strong: device.SetRenderState(RenderState.DiffuseMaterialSource, ColorSource.Color1); break; case ShowBoneWeights.Off: break; } for (int i = 0; i < meshContainer.BoneNames.Length; i++) { if (meshContainer.BoneFrames[i] != null) { device.SetTransform(i, meshContainer.BoneOffsets[i] * meshContainer.BoneFrames[i].CombinedTransform); } } } else { device.SetRenderState(RenderState.VertexBlend, VertexBlend.Disable); #if !DONT_MIRROR device.SetTransform(TransformState.World, Matrix.Scaling(1.0f, 1.0f, -1.0f) * frame.CombinedTransform); #else device.SetTransform(TransformState.World, frame.CombinedTransform); #endif } int matIdx = meshContainer.MaterialIndex; device.Material = ((matIdx >= 0) && (matIdx < Materials.Length)) ? Materials[matIdx] : nullMaterial; int texIdx = meshContainer.TextureIndex; Texture tex = ((texIdx >= 0) && (texIdx < Textures.Length)) ? Textures[texIdx] : null; device.SetTexture(0, tex); meshContainer.MeshData.Mesh.DrawSubset(0); if (HighlightSubmesh.Contains(submeshNum)) { device.SetRenderState(RenderState.ZEnable, ZBufferType.DontUseZBuffer); device.SetRenderState(RenderState.FillMode, FillMode.Wireframe); device.Material = highlightMaterial; device.SetTexture(0, null); meshContainer.MeshData.Mesh.DrawSubset(0); } if (Gui.Renderer.ShowNormals) { device.SetRenderState(RenderState.ZEnable, ZBufferType.UseZBuffer); device.SetRenderState(RenderState.Lighting, false); device.Material = nullMaterial; device.SetTexture(0, null); device.VertexFormat = PositionBlendWeightsIndexedColored.Format; device.DrawUserPrimitives(PrimitiveType.LineList, meshContainer.NormalLines.Length / 2, meshContainer.NormalLines); } if (Gui.Renderer.ShowBones && (meshContainer.BoneLines != null)) { device.SetRenderState(RenderState.ZEnable, ZBufferType.DontUseZBuffer); device.SetRenderState(RenderState.VertexBlend, VertexBlend.Weights1); device.SetRenderState(RenderState.IndexedVertexBlendEnable, true); device.SetRenderState(RenderState.Lighting, false); device.Material = nullMaterial; device.SetTexture(0, null); device.VertexFormat = PositionBlendWeightIndexedColored.Format; device.DrawUserPrimitives(PrimitiveType.LineList, meshContainer.BoneLines.Length / 2, meshContainer.BoneLines); } }
private AnimationFrame CreateFrame(odfFrame frame, odfParser parser, HashSet<int> extractFrames, HashSet<int> meshIDs, Device device, Matrix combinedParent, List<AnimationFrame> meshFrames) { AnimationFrame animationFrame = new AnimationFrame(); animationFrame.Name = frame.Name; animationFrame.TransformationMatrix = frame.Matrix; animationFrame.OriginalTransform = animationFrame.TransformationMatrix; animationFrame.CombinedTransform = combinedParent * animationFrame.TransformationMatrix; if ((int)frame.MeshId != 0 && meshIDs.Contains((int)frame.MeshId)) { odfMesh mesh = odf.FindMeshListSome(frame.MeshId, parser.MeshSection); ExtendedMaterial[] materials = new ExtendedMaterial[mesh.Count]; AnimationMeshContainer[] meshContainers = new AnimationMeshContainer[mesh.Count]; Vector3 min = new Vector3(Single.MaxValue); Vector3 max = new Vector3(Single.MinValue); for (int i = 0; i < mesh.Count; i++) { odfSubmesh submesh = mesh[i]; List<odfFace> faceList = submesh.FaceList; List<odfVertex> vertexList = submesh.VertexList; odfBoneList boneList = odf.FindBoneList(submesh.Id, parser.EnvelopeSection); bool skinned = boneList != null; int numBones = skinned ? boneList.Count : 0; string[] boneNames = new string[numBones]; Matrix[] boneOffsets = new Matrix[numBones]; for (int boneIdx = 0; boneIdx < numBones; boneIdx++) { odfBone bone = boneList[boneIdx]; boneNames[boneIdx] = odf.FindFrame(bone.FrameId, parser.FrameSection.RootFrame).Name; Matrix mirrored; if (!BoneMatrixDic.TryGetValue(boneNames[boneIdx], out mirrored)) { #if !DONT_MIRROR Vector3 translate, scale; Quaternion rotate; bone.Matrix.Decompose(out scale, out rotate, out translate); mirrored = Matrix.Scaling(scale.X, scale.Y, -scale.Z) * Matrix.RotationQuaternion(rotate) * Matrix.Translation(translate); #else mirrored = bone.Matrix; #endif BoneMatrixDic.Add(boneNames[boneIdx], mirrored); } boneOffsets[boneIdx] = mirrored; } Mesh animationMesh = new Mesh(device, faceList.Count, vertexList.Count, MeshFlags.Managed, PositionBlendWeightsIndexedNormalTexturedColoured.Format); using (DataStream indexStream = animationMesh.LockIndexBuffer(LockFlags.None)) { for (int j = 0; j < faceList.Count; j++) { ushort[] indices = faceList[j].VertexIndices; indexStream.Write(indices[0]); indexStream.Write(indices[1]); indexStream.Write(indices[2]); } animationMesh.UnlockIndexBuffer(); } float[][] vertexWeights = ConvertVertexWeights(vertexList, boneList); FillVertexBuffer(animationMesh, vertexList, vertexWeights, -1); var normalLines = new PositionBlendWeightsIndexedColored[vertexList.Count * 2]; for (int j = 0; j < vertexList.Count; j++) { odfVertex vertex = vertexList[j]; #if !DONT_MIRROR Vector3 position = new Vector3(vertex.Position.X, vertex.Position.Y, -vertex.Position.Z); Vector3 normal = new Vector3(vertex.Normal.X, vertex.Normal.Y, -vertex.Normal.Z); #else Vector3 position = vertex.Position; Vector3 normal = vertex.Normal; #endif float[] boneWeights = vertexWeights[j]; normalLines[j * 2] = new PositionBlendWeightsIndexedColored(position, boneWeights, vertex.BoneIndices, Color.Yellow.ToArgb()); normalLines[(j * 2) + 1] = new PositionBlendWeightsIndexedColored(position + (normal / 11), boneWeights, vertex.BoneIndices, Color.Blue.ToArgb()); min = Vector3.Minimize(min, position); max = Vector3.Maximize(max, position); } AnimationMeshContainer meshContainer = new AnimationMeshContainer(); meshContainer.Name = animationFrame.Name; meshContainer.MeshData = new MeshData(animationMesh); meshContainer.NormalLines = normalLines; meshContainer.BoneNames = boneNames; meshContainer.BoneOffsets = boneOffsets; meshContainers[i] = meshContainer; odfMaterial mat = odf.FindMaterialInfo(submesh.MaterialId, parser.MaterialSection); if (mat != null) { Material material3D = new Material(); material3D.Ambient = mat.Ambient; material3D.Diffuse = mat.Diffuse; material3D.Emissive = mat.Emissive; material3D.Specular = mat.Specular; material3D.Power = mat.SpecularPower; int matIdx = parser.MaterialSection.IndexOf(mat); Materials[matIdx] = material3D; meshContainer.MaterialIndex = matIdx; int texIdx = -1; if ((int)submesh.TextureIds[0] != 0 && !TextureDic.TryGetValue((int)submesh.TextureIds[0], out texIdx)) { odfTexture tex = odf.FindTextureInfo(submesh.TextureIds[0], parser.TextureSection); if (tex != null) { try { odfTextureFile texFile = new odfTextureFile(null, Path.GetDirectoryName(parser.ODFPath) + Path.DirectorySeparatorChar + tex.TextureFile); int fileSize = 0; ImportedTexture impTex = new ImportedTexture(texFile.DecryptFile(ref fileSize).BaseStream, tex.TextureFile); Texture memTex = impTex.ToTexture(device); texIdx = TextureDic.Count; TextureDic.Add((int)submesh.TextureIds[0], texIdx); Textures[texIdx] = memTex; } catch (SlimDXException ex) { Utility.ReportException(ex); Report.ReportLog("Please check " + tex.TextureFile + ". It may have an unsupported format."); } catch (Exception ex) { Utility.ReportException(ex); } } } meshContainer.TextureIndex = texIdx; } } for (int i = 0; i < (meshContainers.Length - 1); i++) { meshContainers[i].NextMeshContainer = meshContainers[i + 1]; } animationFrame.Bounds = new BoundingBox(min, max); animationFrame.MeshContainer = meshContainers[0]; meshFrames.Add(animationFrame); } for (int i = 0; i < frame.Count; i++) { odfFrame child = frame[i]; if (extractFrames.Contains((int)child.Id)) { AnimationFrame childAnimationFrame = CreateFrame(child, parser, extractFrames, meshIDs, device, animationFrame.CombinedTransform, meshFrames); childAnimationFrame.Parent = animationFrame; animationFrame.AppendChild(childAnimationFrame); } } numFrames++; return animationFrame; }
private void DrawMeshFrame(AnimationFrame frame) { if (frame.MeshContainer is AnimationMeshContainer) { AnimationMeshContainer animMeshContainer = (AnimationMeshContainer)frame.MeshContainer; if (animMeshContainer.BoneNames.Length > 0) { device.SetRenderState(RenderState.VertexBlend, VertexBlend.Weights3); device.SetRenderState(RenderState.IndexedVertexBlendEnable, true); // uncomment to emphazise bone weights and darken everything else // device.SetRenderState(RenderState.DiffuseMaterialSource, ColorSource.Color1); device.SetRenderState(RenderState.AmbientMaterialSource, ColorSource.Color1); for (int i = 0; i < animMeshContainer.BoneNames.Length; i++) { if (animMeshContainer.BoneFrames[i] != null) { device.SetTransform(i, animMeshContainer.BoneOffsets[i] * animMeshContainer.BoneFrames[i].CombinedTransform); } } } else { device.SetRenderState(RenderState.VertexBlend, VertexBlend.Disable); device.SetRenderState(RenderState.AmbientMaterialSource, ColorSource.Material); device.SetTransform(TransformState.World, frame.CombinedTransform); } submeshNum = 0; while (animMeshContainer != null) { DrawAnimationMeshContainer(animMeshContainer); animMeshContainer = (AnimationMeshContainer)animMeshContainer.NextMeshContainer; submeshNum++; } } else if (frame.MeshContainer is MorphMeshContainer) { MorphMeshContainer morphMeshContainer = (MorphMeshContainer)frame.MeshContainer; device.SetRenderState(RenderState.AmbientMaterialSource, ColorSource.Material); device.SetTransform(TransformState.World, frame.CombinedTransform); submeshNum = 0; DrawMorphMeshContainer(morphMeshContainer); } }
public void AppendChild(AnimationFrame child) { child.Parent = this; base.AppendChild(child); }