private void Export(DirectoryInfo dir, xxFrame meshFrame) { try { xaMorphSection morphSection = xaParser.MorphSection; xaMorphIndexSet indexSet = xa.FindMorphIndexSet(clip.Name, morphSection); ushort[] meshIndices = indexSet.MeshIndices; ushort[] morphIndices = indexSet.MorphIndices; xxMesh meshList = meshFrame.Mesh; int meshObjIdx = xa.MorphMeshObjIdx(meshIndices, meshList); if (meshObjIdx < 0) { throw new Exception("no valid mesh object was found for the morph"); } xxSubmesh meshObjBase = meshList.SubmeshList[meshObjIdx]; colorVertex = new bool[meshObjBase.VertexList.Count]; for (int i = 0; i < meshIndices.Length; i++) { colorVertex[meshIndices[i]] = true; } string dest = Utility.GetDestFile(dir, meshFrame.Name + "-" + clip.Name + "-", ".morph.mqo"); List <xaMorphKeyframeRef> refList = clip.KeyframeRefList; morphNames = new List <string>(refList.Count); vertLists = new List <List <ImportedVertex> >(refList.Count); for (int i = 0; i < refList.Count; i++) { if (!morphNames.Contains(refList[i].Name)) { List <ImportedVertex> vertList = xx.ImportedVertexList(meshObjBase.VertexList, xx.IsSkinned(meshList)); vertLists.Add(vertList); xaMorphKeyframe keyframe = xa.FindMorphKeyFrame(refList[i].Name, morphSection); for (int j = 0; j < meshIndices.Length; j++) { ImportedVertex vert = vertList[meshIndices[j]]; vert.Position = keyframe.PositionList[morphIndices[j]]; } morphNames.Add(keyframe.Name); } } faceList = xx.ImportedFaceList(meshObjBase.FaceList); Export(dest, meshObjBase.MaterialIndex); foreach (xxTexture tex in usedTextures) { xx.ExportTexture(tex, dir.FullName + @"\" + Path.GetFileName(tex.Name)); } Report.ReportLog("Finished exporting morph to " + dest); } catch (Exception ex) { Report.ReportLog("Error exporting morph: " + ex.Message); } }
public void SetMorphClipName(int position, string newName) { string oldName = Parser.MorphSection.ClipList[position].Name; xaMorphIndexSet set = xa.FindMorphIndexSet(oldName, Parser.MorphSection); set.Name = newName; Parser.MorphSection.ClipList[position].Name = newName; Changed = true; }
public static void CalculateNormals(xaParser parser, xxFrame meshFrame, string morphClip, string keyframe, float threshold) { HashSet <Tuple <xaMorphClip, xaMorphKeyframe> > keyframes = new HashSet <Tuple <xaMorphClip, xaMorphKeyframe> >(); foreach (xaMorphClip clip in parser.MorphSection.ClipList) { if (morphClip != null && clip.Name != morphClip) { continue; } if (keyframe != null) { xaMorphKeyframe xaKeyframe = FindMorphKeyFrame(keyframe, parser.MorphSection); if (xaKeyframe == null) { throw new Exception("keyframe " + keyframe + " not found in morph clip " + morphClip); } keyframes.Add(new Tuple <xaMorphClip, xaMorphKeyframe>(clip, xaKeyframe)); break; } else { foreach (xaMorphKeyframeRef morphRef in clip.KeyframeRefList) { xaMorphKeyframe xaKeyframe = FindMorphKeyFrame(morphRef.Name, parser.MorphSection); keyframes.Add(new Tuple <xaMorphClip, xaMorphKeyframe>(clip, xaKeyframe)); } } } if (keyframes.Count == 0) { Report.ReportLog("No keyframe for mesh " + meshFrame.Name + " to calculate normals for found."); return; } foreach (var tup in keyframes) { xaMorphIndexSet set = FindMorphIndexSet(tup.Item1.Name, parser.MorphSection); CalculateNormals(parser, meshFrame, tup.Item2, set, threshold); } }
private VertexBuffer CreateMorphVertexBuffer(xaMorphIndexSet idxSet, xaMorphKeyframe keyframe, List <xxVertex> vertexList) { int vertBufferSize = keyframe.PositionList.Count * Marshal.SizeOf(typeof(TweeningMeshesVertexBufferFormat.Stream0)); VertexBuffer vertBuffer = new VertexBuffer(device, vertBufferSize, Usage.WriteOnly, VertexFormat.Position | VertexFormat.Normal, Pool.Managed); Vector3[] positions = new Vector3[vertexList.Count]; Vector3[] normals = new Vector3[vertexList.Count]; for (int i = 0; i < positions.Length; i++) { positions[i] = vertexList[i].Position; normals[i] = vertexList[i].Normal; } ushort[] meshIndices = idxSet.MeshIndices; ushort[] morphIndices = idxSet.MorphIndices; List <Vector3> keyframePositions = keyframe.PositionList; List <Vector3> keyframeNormals = keyframe.NormalList; for (int i = 0; i < meshIndices.Length; i++) { positions[meshIndices[i]] = keyframePositions[morphIndices[i]]; normals[meshIndices[i]] = keyframeNormals[morphIndices[i]]; } using (DataStream vertexStream = vertBuffer.Lock(0, vertBufferSize, LockFlags.None)) { for (int i = 0; i < positions.Length; i++) { Vector3 pos = positions[i]; vertexStream.Write(pos.X); vertexStream.Write(pos.Y); vertexStream.Write(pos.Z); Vector3 normal = normals[i]; vertexStream.Write(normal.X); vertexStream.Write(normal.Y); vertexStream.Write(normal.Z); } vertBuffer.Unlock(); } return(vertBuffer); }
public void SetTweenFactor(xxFrame meshFrame, xaMorphIndexSet idxSet, float tweenFactor) { foreach (AnimationFrame frame in meshFrames) { if (frame.Name == meshFrame.Name) { xxMesh xxMesh = meshFrame.Mesh; int meshObjIdx = xa.MorphMeshObjIdx(idxSet.MeshIndices, xxMesh); if (meshObjIdx < 0) { Report.ReportLog("no valid mesh object was found for the morph"); return; } MeshContainer animMesh = frame.MeshContainer; for (int i = 1; i < meshObjIdx; i++) { animMesh = animMesh.NextMeshContainer; if (animMesh == null) { break; } } if (animMesh == null) { Report.ReportLog("Bad submesh specified."); return; } MorphMeshContainer morphMesh = (MorphMeshContainer)animMesh; morphMesh.TweenFactor = tweenFactor; return; } } Report.ReportLog("Mesh frame " + meshFrame + " not displayed."); return; }
public float UnsetMorphKeyframe(xxFrame meshFrame, xaMorphIndexSet idxSet, bool asStart) { foreach (AnimationFrame frame in meshFrames) { if (frame.Name == meshFrame.Name) { xxMesh xxMesh = meshFrame.Mesh; int meshObjIdx = xa.MorphMeshObjIdx(idxSet.MeshIndices, xxMesh); if (meshObjIdx < 0) { Report.ReportLog("no valid mesh object was found for the morph"); return(-1f); } MeshContainer animMesh = frame.MeshContainer; for (int i = 1; i < meshObjIdx; i++) { animMesh = animMesh.NextMeshContainer; if (animMesh == null) { break; } } if (animMesh == null) { Report.ReportLog("Bad submesh specified."); return(-1f); } MorphMeshContainer morphMesh = (MorphMeshContainer)animMesh; if (asStart) { if (morphMesh.StartBuffer != morphMesh.EndBuffer) { morphMesh.StartBuffer.Dispose(); morphMesh.StartBuffer = morphMesh.EndBuffer; } else { frame.MeshContainer = morphMesh.NextMeshContainer; } morphMesh.TweenFactor = 1.0f; } else { if (morphMesh.StartBuffer != morphMesh.EndBuffer) { morphMesh.EndBuffer.Dispose(); morphMesh.EndBuffer = morphMesh.StartBuffer; } else { frame.MeshContainer = morphMesh.NextMeshContainer; } morphMesh.TweenFactor = 0.0f; } return(morphMesh.TweenFactor); } } Report.ReportLog("Mesh frame " + meshFrame + " not displayed."); return(-1f); }
public float SetMorphKeyframe(xxFrame meshFrame, xaMorphIndexSet idxSet, xaMorphKeyframe keyframe, bool asStart) { foreach (AnimationFrame frame in meshFrames) { if (frame.Name == meshFrame.Name) { xxMesh xxMesh = meshFrame.Mesh; int meshObjIdx = xa.MorphMeshObjIdx(idxSet.MeshIndices, xxMesh); if (meshObjIdx < 0) { Report.ReportLog("no valid mesh object was found for the morph"); return(-1f); } MorphMeshContainer morphMesh = null; AnimationMeshContainer animMesh = frame.MeshContainer as AnimationMeshContainer; if (animMesh != null) { for (int i = 1; i < meshObjIdx; i++) { animMesh = (AnimationMeshContainer)animMesh.NextMeshContainer; if (animMesh == null) { break; } } if (animMesh == null) { Report.ReportLog("Bad submesh specified."); return(-1f); } morphMesh = new MorphMeshContainer(); morphMesh.FaceCount = xxMesh.SubmeshList[meshObjIdx].FaceList.Count; morphMesh.IndexBuffer = animMesh.MeshData.Mesh.IndexBuffer; morphMesh.VertexCount = xxMesh.SubmeshList[meshObjIdx].VertexList.Count; List <xxVertex> vertexList = xxMesh.SubmeshList[meshObjIdx].VertexList; VertexBuffer vertBuffer = CreateMorphVertexBuffer(idxSet, keyframe, vertexList); morphMesh.StartBuffer = morphMesh.EndBuffer = vertBuffer; int vertBufferSize = morphMesh.VertexCount * Marshal.SizeOf(typeof(TweeningMeshesVertexBufferFormat.Stream2)); vertBuffer = new VertexBuffer(device, vertBufferSize, Usage.WriteOnly, VertexFormat.Texture1, Pool.Managed); using (DataStream vertexStream = vertBuffer.Lock(0, vertBufferSize, LockFlags.None)) { for (int i = 0; i < vertexList.Count; i++) { xxVertex vertex = vertexList[i]; vertexStream.Write(vertex.UV[0]); vertexStream.Write(vertex.UV[1]); } vertBuffer.Unlock(); } morphMesh.CommonBuffer = vertBuffer; morphMesh.MaterialIndex = animMesh.MaterialIndex; morphMesh.TextureIndex = animMesh.TextureIndex; morphMesh.NextMeshContainer = animMesh; frame.MeshContainer = morphMesh; morphMesh.TweenFactor = 0.0f; } else { morphMesh = frame.MeshContainer as MorphMeshContainer; List <xxVertex> vertexList = xxMesh.SubmeshList[meshObjIdx].VertexList; VertexBuffer vertBuffer = CreateMorphVertexBuffer(idxSet, keyframe, vertexList); if (asStart) { if (morphMesh.StartBuffer != morphMesh.EndBuffer) { morphMesh.StartBuffer.Dispose(); } morphMesh.StartBuffer = vertBuffer; morphMesh.TweenFactor = 0.0f; } else { if (morphMesh.StartBuffer != morphMesh.EndBuffer) { morphMesh.EndBuffer.Dispose(); } morphMesh.EndBuffer = vertBuffer; morphMesh.TweenFactor = 1.0f; } } return(morphMesh.TweenFactor); } } Report.ReportLog("Mesh frame " + meshFrame + " not displayed."); return(-1f); }
protected xaMorphSection ParseMorphSection() { if (reader.ReadByte() == 0) { return(null); } xaMorphSection section = new xaMorphSection(); int numIndexSets = reader.ReadInt32(); section.IndexSetList = new List <xaMorphIndexSet>(numIndexSets); for (int i = 0; i < numIndexSets; i++) { xaMorphIndexSet indexSet = new xaMorphIndexSet(); section.IndexSetList.Add(indexSet); indexSet.Unknown1 = reader.ReadBytes(1); int numVertices = reader.ReadInt32(); indexSet.MeshIndices = reader.ReadUInt16Array(numVertices); indexSet.MorphIndices = reader.ReadUInt16Array(numVertices); indexSet.Name = reader.ReadName(); } int numKeyframes = reader.ReadInt32(); section.KeyframeList = new List <xaMorphKeyframe>(numKeyframes); for (int i = 0; i < numKeyframes; i++) { xaMorphKeyframe keyframe = new xaMorphKeyframe(); section.KeyframeList.Add(keyframe); int numVertices = reader.ReadInt32(); keyframe.PositionList = new List <Vector3>(numVertices); keyframe.NormalList = new List <Vector3>(numVertices); for (int j = 0; j < numVertices; j++) { keyframe.PositionList.Add(reader.ReadVector3()); } for (int j = 0; j < numVertices; j++) { keyframe.NormalList.Add(reader.ReadVector3()); } keyframe.Name = reader.ReadName(); } int numClips = reader.ReadInt32(); section.ClipList = new List <xaMorphClip>(numClips); for (int i = 0; i < numClips; i++) { xaMorphClip clip = new xaMorphClip(); section.ClipList.Add(clip); clip.MeshName = reader.ReadName(); clip.Name = reader.ReadName(); int numKeyframeRefs = reader.ReadInt32(); clip.KeyframeRefList = new List <xaMorphKeyframeRef>(numKeyframeRefs); for (int j = 0; j < numKeyframeRefs; j++) { xaMorphKeyframeRef keyframeRef = new xaMorphKeyframeRef(); clip.KeyframeRefList.Add(keyframeRef); keyframeRef.Unknown1 = reader.ReadBytes(1); keyframeRef.Index = reader.ReadInt32(); keyframeRef.Unknown2 = reader.ReadBytes(1); keyframeRef.Name = reader.ReadName(); } clip.Unknown1 = reader.ReadBytes(4); } return(section); }
private static void CalculateNormals(xaParser parser, xxFrame meshFrame, xaMorphKeyframe keyframe, xaMorphIndexSet set, float threshold) { xxMesh mesh = meshFrame.Mesh; ushort[] meshIndices = set.MeshIndices; ushort[] morphIndices = set.MorphIndices; int morphSubmeshIdx = MorphMeshObjIdx(meshIndices, mesh); if (morphSubmeshIdx < 0) { throw new Exception("no valid mesh object was found for the morph " + set.Name); } xxSubmesh submesh = mesh.SubmeshList[morphSubmeshIdx]; List <xxVertex> morphedVertices = new List <xxVertex>(submesh.VertexList.Count); for (ushort i = 0; i < submesh.VertexList.Count; i++) { xxVertex vert = new xxVertexUShort(); vert.Index = i; vert.Position = submesh.VertexList[i].Position; vert.Normal = submesh.VertexList[i].Normal; morphedVertices.Add(vert); } for (int i = 0; i < meshIndices.Length; i++) { morphedVertices[meshIndices[i]].Position = keyframe.PositionList[morphIndices[i]]; } var pairList = new List <Tuple <List <xxFace>, List <xxVertex> > >(1); pairList.Add(new Tuple <List <xxFace>, List <xxVertex> >(submesh.FaceList, morphedVertices)); xx.CalculateNormals(pairList, threshold); for (int i = 0; i < meshIndices.Length; i++) { keyframe.NormalList[morphIndices[i]] = morphedVertices[meshIndices[i]].Normal; } }
public static void ReplaceMorph(string destMorphName, xaParser parser, WorkspaceMorph wsMorphList, string newMorphName, bool replaceMorphMask, bool replaceNormals, float minSquaredDistance, bool minKeyframes) { if (parser.MorphSection == null) { Report.ReportLog("The .xa file doesn't have a morph section. Skipping these morphs"); return; } xaMorphSection morphSection = parser.MorphSection; xaMorphIndexSet indices = FindMorphIndexSet(destMorphName, morphSection); if (indices == null) { Report.ReportLog("Couldn't find morph clip " + destMorphName + ". Skipping these morphs"); return; } if (replaceMorphMask && wsMorphList.MorphedVertexIndices != null) { int index = morphSection.IndexSetList.IndexOf(indices); xaMorphIndexSet newIndices = new xaMorphIndexSet(); newIndices.Name = indices.Name; int numMorphedVertices = wsMorphList.MorphedVertexIndices.Count; newIndices.MeshIndices = new ushort[numMorphedVertices]; wsMorphList.MorphedVertexIndices.CopyTo(newIndices.MeshIndices); newIndices.MorphIndices = new ushort[numMorphedVertices]; if (minKeyframes) { for (ushort i = 0; i < numMorphedVertices; i++) { newIndices.MorphIndices[i] = i; } } else { wsMorphList.MorphedVertexIndices.CopyTo(newIndices.MorphIndices); } newIndices.Unknown1 = indices.Unknown1; morphSection.IndexSetList.RemoveAt(index); morphSection.IndexSetList.Insert(index, newIndices); indices = newIndices; } Report.ReportLog("Replacing morphs ..."); try { ushort[] meshIndices = indices.MeshIndices; ushort[] morphIndices = indices.MorphIndices; foreach (ImportedMorphKeyframe wsMorph in wsMorphList.KeyframeList) { if (!wsMorphList.isMorphKeyframeEnabled(wsMorph)) { continue; } List <ImportedVertex> vertList = wsMorph.VertexList; xaMorphKeyframe keyframe = FindMorphKeyFrame(wsMorph.Name, morphSection); if (keyframe == null) { Report.ReportLog("Adding new Keyframe " + wsMorph.Name); keyframe = new xaMorphKeyframe(); keyframe.Name = wsMorph.Name; int numVertices = minKeyframes ? meshIndices.Length : wsMorph.VertexList.Count; keyframe.PositionList = new List <Vector3>(new Vector3[numVertices]); keyframe.NormalList = new List <Vector3>(new Vector3[numVertices]); for (int i = 0; i < meshIndices.Length; i++) { keyframe.PositionList[morphIndices[i]] = vertList[meshIndices[i]].Position; keyframe.NormalList[morphIndices[i]] = vertList[meshIndices[i]].Normal; } morphSection.KeyframeList.Add(keyframe); } else { if (!minKeyframes && keyframe.PositionList.Count != vertList.Count || minKeyframes && keyframe.PositionList.Count != meshIndices.Length) { Report.ReportLog("Adapting Keyframe " + wsMorph.Name + " to new length."); int length = minKeyframes ? meshIndices.Length : vertList.Count; Vector3[] newPositions = new Vector3[length]; Vector3[] newNormals = new Vector3[length]; if (!minKeyframes) { for (int i = 0; i < vertList.Count; i++) { newPositions[i] = vertList[i].Position; newNormals[i] = vertList[i].Normal; } } for (int i = 0; i < meshIndices.Length; i++) { newPositions[morphIndices[i]] = vertList[meshIndices[i]].Position; newNormals[morphIndices[i]] = vertList[meshIndices[i]].Normal; } keyframe.PositionList.Clear(); keyframe.NormalList.Clear(); keyframe.PositionList.AddRange(newPositions); keyframe.NormalList.AddRange(newNormals); } else { Report.ReportLog("Replacing Keyframe " + wsMorph.Name); for (int i = 0; i < meshIndices.Length; i++) { Vector3 orgPos = new Vector3(keyframe.PositionList[morphIndices[i]].X, keyframe.PositionList[morphIndices[i]].Y, keyframe.PositionList[morphIndices[i]].Z), newPos = new Vector3(vertList[meshIndices[i]].Position.X, vertList[meshIndices[i]].Position.Y, vertList[meshIndices[i]].Position.Z); if ((orgPos - newPos).LengthSquared() >= minSquaredDistance) { keyframe.PositionList[morphIndices[i]] = vertList[meshIndices[i]].Position; if (replaceNormals) { keyframe.NormalList[morphIndices[i]] = vertList[meshIndices[i]].Normal; } } } } } string morphNewName = wsMorphList.getMorphKeyframeNewName(wsMorph); if (morphNewName != String.Empty) { for (int i = 0; i < morphSection.ClipList.Count; i++) { xaMorphClip clip = morphSection.ClipList[i]; for (int j = 0; j < clip.KeyframeRefList.Count; j++) { xaMorphKeyframeRef keyframeRef = clip.KeyframeRefList[j]; if (keyframeRef.Name == wsMorph.Name) { keyframeRef.Name = morphNewName; } } } keyframe.Name = morphNewName; } } if (newMorphName != String.Empty) { for (int i = 0; i < morphSection.ClipList.Count; i++) { xaMorphClip clip = morphSection.ClipList[i]; if (clip.Name == destMorphName) { clip.Name = newMorphName; break; } } indices.Name = newMorphName; } } catch (Exception ex) { Report.ReportLog("Error replacing morphs: " + ex.Message); } }
public static void ReplaceMorph(string destMorphName, xaParser parser, WorkspaceMorph wsMorphList, string newMorphName, bool replaceNormals, float minSquaredDistance) { if (parser.MorphSection == null) { Report.ReportLog("The .xa file doesn't have a morph section. Skipping these morphs"); return; } xaMorphSection morphSection = parser.MorphSection; xaMorphIndexSet indices = FindMorphIndexSet(destMorphName, morphSection); if (indices == null) { Report.ReportLog("Couldn't find morph clip " + destMorphName + ". Skipping these morphs"); return; } Report.ReportLog("Replacing morphs ..."); try { ushort[] meshIndices = indices.MeshIndices; ushort[] morphIndices = indices.MorphIndices; foreach (ImportedMorphKeyframe wsMorph in wsMorphList.KeyframeList) { if (!wsMorphList.isMorphKeyframeEnabled(wsMorph)) { continue; } List <ImportedVertex> vertList = wsMorph.VertexList; xaMorphKeyframe keyframe = FindMorphKeyFrame(wsMorph.Name, morphSection); if (keyframe == null) { keyframe = new xaMorphKeyframe(); keyframe.Name = wsMorph.Name; keyframe.PositionList = new List <Vector3>(new Vector3[wsMorph.VertexList.Count]); keyframe.NormalList = new List <Vector3>(new Vector3[wsMorph.VertexList.Count]); for (int i = 0; i < meshIndices.Length; i++) { keyframe.PositionList[morphIndices[i]] = vertList[meshIndices[i]].Position; keyframe.NormalList[morphIndices[i]] = vertList[meshIndices[i]].Normal; } morphSection.KeyframeList.Add(keyframe); } else { for (int i = 0; i < meshIndices.Length; i++) { Vector3 orgPos = new Vector3(keyframe.PositionList[morphIndices[i]].X, keyframe.PositionList[morphIndices[i]].Y, keyframe.PositionList[morphIndices[i]].Z), newPos = new Vector3(vertList[meshIndices[i]].Position.X, vertList[meshIndices[i]].Position.Y, vertList[meshIndices[i]].Position.Z); if ((orgPos - newPos).LengthSquared() >= minSquaredDistance) { keyframe.PositionList[morphIndices[i]] = vertList[meshIndices[i]].Position; if (replaceNormals) { keyframe.NormalList[morphIndices[i]] = vertList[meshIndices[i]].Normal; } } } } string morphNewName = wsMorphList.getMorphKeyframeNewName(wsMorph); if (morphNewName != String.Empty) { for (int i = 0; i < morphSection.ClipList.Count; i++) { xaMorphClip clip = morphSection.ClipList[i]; for (int j = 0; j < clip.KeyframeRefList.Count; j++) { xaMorphKeyframeRef keyframeRef = clip.KeyframeRefList[j]; if (keyframeRef.Name == wsMorph.Name) { keyframeRef.Name = morphNewName; } } } keyframe.Name = morphNewName; } } if (newMorphName != String.Empty) { for (int i = 0; i < morphSection.ClipList.Count; i++) { xaMorphClip clip = morphSection.ClipList[i]; if (clip.Name == destMorphName) { clip.Name = newMorphName; break; } } indices.Name = newMorphName; } } catch (Exception ex) { Report.ReportLog("Error replacing morphs: " + ex.Message); } }