public void ExportModel(string fileName, DAE.ExportSettings settings) { List <STGenericMaterial> Materials = new List <STGenericMaterial>(); foreach (var mesh in Renderer.Meshes) { if (mesh.GetMaterial() != null) { Materials.Add(mesh.GetMaterial()); } } var textures = new List <STGenericTexture>(); foreach (var tex in PluginRuntime.stikersTextures) { textures.Add(tex); } var model = new STGenericModel(); model.Materials = Materials; model.Objects = Renderer.Meshes; STSkeleton skeleton = null; if (DrawableContainer.Drawables.Count > 1) { skeleton = (STSkeleton)DrawableContainer.Drawables[1]; } DAE.Export(fileName, settings, model, textures, skeleton); }
public void Export(STAnimation animation, STSkeleton skeleton, string filePath) { if (skeleton == null) { return; } using (StreamWriter writer = new StreamWriter(new FileStream(filePath, FileMode.Create))) { writer.WriteLine("version 1"); writer.WriteLine("nodes"); foreach (STBone bone in skeleton.Bones) { writer.WriteLine($" {skeleton.Bones.IndexOf(bone)} \"{bone.Name}\" {bone.ParentIndex}"); } writer.WriteLine("end"); writer.WriteLine("skeleton"); animation.Frame = 0; for (int i = 0; i < animation.FrameCount; i++) { animation.UpdateFrame(i); writer.WriteLine($"time {animation.StartFrame + i}"); foreach (STBone bone in skeleton.Bones) { var controller = bone.AnimationController; writer.WriteLine($" {skeleton.Bones.IndexOf(bone)}" + $"{controller.Position.X} {controller.Position.Y} {controller.Position.Z} " + $"{controller.EulerRotation.X} {controller.EulerRotation.Y} {controller.EulerRotation.Z}"); } } writer.WriteLine("end"); } }
public void Load(Skeleton skeleton, BCRES bcres) { Renderable = new STSkeleton(); BcresParent = bcres; Skeleton = skeleton; Text = "Skeleton"; Checked = true; foreach (var bone in skeleton.Bones.Values) { var boneWrapper = new CRESBoneWrapper(); boneWrapper.skeletonParent = Renderable; boneWrapper.Load(bone, bcres); Renderable.bones.Add(boneWrapper); } Nodes.Clear(); foreach (var bone in Renderable.bones) { if (bone.Parent == null) { Nodes.Add(bone); } } Renderable.update(); Renderable.reset(); }
public void Export(STAnimation animation, STSkeleton skeleton, string filePath) { if (skeleton == null) { return; } using (StreamWriter file = new StreamWriter(filePath)) { file.WriteLine("animVersion " + header.animVersion + ";"); file.WriteLine("mayaVersion " + header.mayaVersion + ";"); file.WriteLine("timeUnit " + header.timeUnit + ";"); file.WriteLine("linearUnit " + header.linearUnit + ";"); file.WriteLine("angularUnit " + header.angularUnit + ";"); file.WriteLine("startTime " + 1 + ";"); file.WriteLine("endTime " + header.endTime + ";"); foreach (var group in animation.AnimGroups) { var bone = skeleton.SearchBone(group.Name); if (bone == null) { continue; } file.WriteLine(""); } } }
/// <summary> /// A helper method to set a common skeleton bone block layout. /// Note not all games use the same skeleton bone block data! /// </summary> public virtual void SetBoneMatrixBlock(STSkeleton skeleton, bool useInverse, UniformBlock block, int maxTransforms = 170) { block.Buffer.Clear(); //Fixed buffer of max amount of transform values for (int i = 0; i < maxTransforms; i++) { Matrix4 value = Matrix4.Zero; //Set the inverse matrix and load the matrix data into 3 vec4s if (i < skeleton.Bones.Count) { //Check if the bone is smooth skinning aswell for accuracy purposes. if (useInverse || ((BfresBone)skeleton.Bones[i]).UseSmoothMatrix) //Use inverse transforms for smooth skinning { value = skeleton.Bones[i].Inverse * skeleton.Bones[i].Transform; } else { value = skeleton.Bones[i].Transform; } } block.Add(value.Column0); block.Add(value.Column1); block.Add(value.Column2); } }
public void FillSkeleton(SuperBMDLib.BMD.INF1 INF1, STSkeleton skeleton, List <SuperBMDLib.Rigging.Bone> flatSkeleton) { for (int i = 1; i < INF1.FlatNodes.Count; i++) { SuperBMDLib.Scenegraph.SceneNode curNode = INF1.FlatNodes[i]; if (curNode.Type == SuperBMDLib.Scenegraph.Enums.NodeType.Joint) { var Bone = flatSkeleton[curNode.Index]; var stBone = new STBone(skeleton); stBone.Text = Bone.Name; stBone.FromTransform(Bone.TransformationMatrix); if (Bone.Parent != null) { stBone.parentIndex = flatSkeleton.IndexOf(Bone.Parent); } else { stBone.parentIndex = -1; } skeleton.bones.Add(stBone); } } }
public void SetBoneMatrixBlock(STSkeleton skeleton, bool useInverse, UniformBlock block, int maxTransforms = 64) { block.Buffer.Clear(); //Fixed buffer of max amount of transform values for (int i = 0; i < maxTransforms; i++) { Matrix4 value = Matrix4.Zero; //Set the inverse matrix and load the matrix data into 3 vec4s if (i < skeleton.Bones.Count) { if (useInverse) //Use inverse transforms for smooth skinning { value = skeleton.Bones[i].Inverse * skeleton.Bones[i].Transform; } else { value = skeleton.Bones[i].Transform; } } block.Add(value.Column0); block.Add(value.Column1); block.Add(value.Column2); } }
public void Load(H3DModel model, BCH bch) { Renderable = new STSkeleton(); bch.DrawableContainer.Drawables.Add(Renderable); BcresParent = bch; ModelParent = model; Text = "Skeleton"; Checked = true; foreach (var bone in model.Skeleton) { Renderable.bones.Add(new H3DBoneWrapper(Renderable, bone, bch)); } Nodes.Clear(); foreach (var bone in Renderable.bones) { if (bone.Parent == null) { Nodes.Add(bone); } } Renderable.update(); Renderable.reset(); }
public void DrawModel(GLControl control, STSkeleton Skeleton, STGenericMaterial Material, STGenericObject m, ShaderProgram shader) { if (m.PolygonGroups.Count > 0) { foreach (var group in m.PolygonGroups) { if (group.faces.Count <= 3) { return; } SetRenderData(Material, shader, m); SetUniforms(Material, shader, m); SetUniformBlocks(Material, shader, m); SetBoneUniforms(control, shader, Skeleton, m); SetVertexAttributes(m, shader); SetTextureUniforms(Material, m, shader); if (m.IsSelected || m.GetMaterial().IsSelected) { DrawModelSelection(group, shader); } else { if (Runtime.RenderModels) { GL.DrawElements(PrimitiveType.Triangles, group.displayFaceSize, DrawElementsType.UnsignedInt, group.Offset); } } } } else { if (m.lodMeshes.Count <= 0 || m.lodMeshes[m.DisplayLODIndex].faces.Count <= 3) { return; } SetUniforms(Material, shader, m); SetUniformBlocks(Material, shader, m); SetBoneUniforms(control, shader, Skeleton, m); SetVertexAttributes(m, shader); SetTextureUniforms(Material, m, shader); if (m.IsSelected) { DrawModelSelection(m, shader); } else { if (Runtime.RenderModels) { GL.DrawElements(PrimitiveType.Triangles, m.lodMeshes[m.DisplayLODIndex].displayFaceSize, DrawElementsType.UnsignedInt, m.Offset); } } } }
public virtual void SetBoneUniforms(GLControl control, ShaderProgram shader, STSkeleton Skeleton, STGenericObject mesh) { int i = 0; foreach (var bone in Skeleton.bones) { Matrix4 transform = bone.invert * bone.Transform; GL.UniformMatrix4(GL.GetUniformLocation(shader.programs[control], String.Format("bones[{0}]", i++)), false, ref transform); } }
private void SetBoneUniforms(ShaderProgram shader, STSkeleton Skeleton) { int i = 0; foreach (var bone in Skeleton.Bones) { Matrix4 transform = bone.Inverse * bone.Transform; GL.UniformMatrix4(GL.GetUniformLocation(shader.program, String.Format("bones[{0}]", i++)), false, ref transform); } }
public void Load(System.IO.Stream stream) { Header = new HsfFile(stream); Skeleton = new STSkeleton(); this.Label = FileInfo.FileName; this.Tag = this; LoadSkeleton(); LoadMeshes(); LoadTextures(); LoadAnimations(); HSFRenderer = new HSF_Renderer(this, ToGeneric()); }
private void SetModelMatrix(int programID, STSkeleton skeleton, bool useInverse = true) { GL.Uniform1(GL.GetUniformLocation(programID, "UseSkinning"), 1); for (int i = 0; i < skeleton.Bones.Count; i++) { Matrix4 transform = skeleton.Bones[i].Transform; //Check if the bone is smooth skinning aswell for accuracy purposes. if (useInverse || ((BfresBone)skeleton.Bones[i]).UseSmoothMatrix) { transform = skeleton.Bones[i].Inverse * skeleton.Bones[i].Transform; } GL.UniformMatrix4(GL.GetUniformLocation(programID, String.Format("bones[{0}]", i)), false, ref transform); } }
public void Load(System.IO.Stream stream) { Text = FileName; //Set renderer Renderer = new BMD_Renderer(); Skeleton = new STSkeleton(); DrawableContainer.Name = FileName; DrawableContainer.Drawables.Add(Renderer); DrawableContainer.Drawables.Add(Skeleton); BMDFile = Model.Load(stream); LoadBMD(BMDFile); }
private void TraverseNodeGraph(STSkeleton skeleton, int index, int parentIndex = -1) { Node node = Header.Nodes[index]; skeleton.Bones[index].ParentIndex = parentIndex; if (node.ChildIndex > 0) //Advanced to next node { TraverseNodeGraph(skeleton, index + node.ChildIndex, index); } if (node.SiblingIndex > 0) //Connect a sibling from the current index { TraverseNodeGraph(skeleton, index + node.SiblingIndex, parentIndex); } }
public void BatchExportCombined(object sender, EventArgs args) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Multiselect = true; ofd.Filter = "Supported Formats|*.bin"; if (ofd.ShowDialog() != DialogResult.OK) { return; } SaveFileDialog sfd = new SaveFileDialog(); sfd.Filter = "Supported Formats|*.dae"; if (sfd.ShowDialog() == DialogResult.OK) { List <STGenericObject> Objects = new List <STGenericObject>(); STSkeleton Skeleton = new STSkeleton(); List <STGenericMaterial> Materials = new List <STGenericMaterial>(); int MatIndex = 0; foreach (var file in ofd.FileNames) { LM2_ARCADE_Model model = new LM2_ARCADE_Model(); var stream = File.Open(file, FileMode.Open); model.Load(stream); stream.Dispose(); foreach (STGenericMaterial mat in model.Nodes[0].Nodes) { mat.Text = $"Material {MatIndex++}"; Materials.Add(mat); } Skeleton.bones.AddRange(((STSkeleton)model.DrawableContainer.Drawables[0]).bones); Objects.AddRange(((GenericModelRenderer)model.DrawableContainer.Drawables[1]).Meshes); model.Unload(); } ExportModelSettings settings = new ExportModelSettings(); if (settings.ShowDialog() == DialogResult.OK) { DAE.Export(sfd.FileName, settings.Settings, Objects, Materials, new List <STGenericTexture>(), Skeleton); } } }
/// <summary> /// Generates a baked skeleton based on the first frame of the animation. /// </summary> /// <returns></returns> public STSkeleton CreateBakedSkeleton(int skeletonIndex) { var skel = Skeletons.FirstOrDefault(); if (skeletonIndex < Skeletons.Count) { skel = Skeletons[skeletonIndex]; } if (skel == null) { return(new STSkeleton()); } var target = Animations[0]; STSkeleton skeleton = new STSkeleton(); for (int i = 0; i < skel.GlobalIndexList.Count; i++) { var boneAnim = target.BoneGroups[i]; float posX = boneAnim.TranslateX.GetBaseValue(); float posY = boneAnim.TranslateY.GetBaseValue(); float posZ = boneAnim.TranslateZ.GetBaseValue(); float rotX = boneAnim.RotateX.GetBaseValue(); float rotY = boneAnim.RotateY.GetBaseValue(); float rotZ = boneAnim.RotateZ.GetBaseValue(); float scaleX = boneAnim.ScaleX.GetBaseValue(true); float scaleY = boneAnim.ScaleY.GetBaseValue(true); float scaleZ = boneAnim.ScaleZ.GetBaseValue(true); STBone bone = new STBone(skeleton); bone.ParentIndex = skel.GlobalIndexList[i].ParentIndex; bone.Name = $"Bone{i}"; //Multiply by 1024 (hardcoded scale value) bone.Position = new Vector3(posX, posY, posZ) * 1024.0f; bone.EulerRotation = new Vector3(rotX, rotY, rotZ); bone.Scale = new Vector3(scaleX, scaleY, scaleZ); skeleton.Bones.Add(bone); } skeleton.Reset(); skeleton.Update(); return(skeleton); }
public Matrix4 CalculateMatrix(Vector3 Rotation, Vector3 Position, float twist) { if (settings.HasFlag(Settings.EulerZXY)) { return(Matrix4.CreateFromQuaternion(STSkeleton.FromEulerAngles(Rotation.Z, Rotation.Y, Rotation.X))); } else { float rad2deg = (float)(180.0 / Math.PI); var c = Matrix4.CreateRotationZ(twist); var rotation = LookAtAngles(Position) * rad2deg; return(Matrix4.CreateFromQuaternion(STSkeleton.FromEulerAngles(rotation.Z, rotation.Y, rotation.X)) * c); } }
public static void Save(STSkeletonAnimation anim, String Fname) { System.Globalization.CultureInfo customCulture = (System.Globalization.CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone(); customCulture.NumberFormat.NumberDecimalSeparator = "."; STSkeleton Skeleton = anim.GetActiveSkeleton(); using (System.IO.StreamWriter file = new System.IO.StreamWriter(@Fname)) { file.WriteLine("version 1"); file.WriteLine("nodes"); foreach (STBone b in Skeleton.bones) { file.WriteLine(Skeleton.bones.IndexOf(b) + " \"" + b.Text + "\" " + b.parentIndex); } file.WriteLine("end"); file.WriteLine("skeleton"); anim.SetFrame(0); for (int i = 0; i <= anim.FrameCount; i++) { anim.SetFrame(i); anim.NextFrame(); file.WriteLine($"time {i}"); foreach (var sb in anim.AnimGroups) { STBone b = Skeleton.GetBone(sb.Name); if (b == null) { continue; } Vector3 eul = STMath.ToEulerAngles(b.rot); Vector3 scale = b.GetScale(); Vector3 translate = b.GetPosition(); file.WriteLine($"{ Skeleton.bones.IndexOf(b)} {translate.X} {translate.Y} {translate.Z} {eul.X} {eul.Y} {eul.Z}"); } } file.WriteLine("end"); file.Close(); } }
public static void Save(Animation anim, STSkeleton Skeleton, String Fname) { System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; using (System.IO.StreamWriter file = new System.IO.StreamWriter(@Fname)) { file.WriteLine("version 1"); file.WriteLine("nodes"); foreach (STBone b in Skeleton.bones) { file.WriteLine(Skeleton.bones.IndexOf(b) + " \"" + b.Text + "\" " + b.parentIndex); } file.WriteLine("end"); file.WriteLine("skeleton"); anim.SetFrame(0); for (int i = 0; i <= anim.FrameCount; i++) { anim.NextFrame(Skeleton, false, true); file.WriteLine($"time {i}"); foreach (Animation.KeyNode sb in anim.Bones) { STBone b = Skeleton.GetBone(sb.Text); if (b == null) { continue; } Vector3 eul = STMath.ToEulerAngles(b.rot); Vector3 scale = b.GetScale(); Vector3 translate = b.GetPosition(); file.WriteLine($"{ Skeleton.bones.IndexOf(b)} {translate.X} {translate.Y} {translate.Z} {eul.X} {eul.Y} {eul.Z}"); } } file.WriteLine("end"); file.Close(); } }
public static void SaveAnimation(string FileName, Animation anim, STSkeleton skeleton) { anim.SetFrame(anim.FrameCount - 1); //from last frame for (int f = 0; f < anim.FrameCount; ++f) //go through each frame with nextFrame { anim.NextFrame(skeleton); } anim.NextFrame(skeleton); //go on first frame SEAnim seAnim = new SEAnim(); seAnim.Looping = anim.CanLoop; seAnim.AnimType = AnimationType.Absolute; //Reset active animation to 0 anim.SetFrame(0); for (int frame = 0; frame < anim.FrameCount; frame++) { anim.NextFrame(skeleton, false, true); foreach (Animation.KeyNode boneAnim in anim.Bones) { if (boneAnim.HasKeyedFrames(frame)) { STBone bone = skeleton.GetBone(boneAnim.Text); if (bone == null) { continue; } Vector3 position = bone.GetPosition(); Quaternion rotation = bone.GetRotation(); Vector3 scale = bone.GetScale(); seAnim.AddTranslationKey(boneAnim.Text, frame, position.X, position.Y, position.Z); seAnim.AddRotationKey(boneAnim.Text, frame, rotation.X, rotation.Y, rotation.Z, rotation.W); seAnim.AddScaleKey(boneAnim.Text, frame, scale.X, scale.Y, scale.Z); } } } seAnim.Write(FileName); }
public GenericSkeletonRenderer(STSkeleton skeleton) : base(Color.Yellow, Color.Yellow, Color.Yellow) { Skeleton = skeleton; var points = new RenderablePathPoint[skeleton.Bones.Count]; for (int i = 0; i < skeleton.Bones.Count; i++) { STBone bone = skeleton.Bones[i]; points[i] = FromBone(bone); } for (int i = 0; i < skeleton.Bones.Count; i++) { if (skeleton.Bones[i].ParentIndex != -1) { points[skeleton.Bones[i].ParentIndex].AddChild(points[i]); } } PathPoints = points.ToList(); }
public static void SaveAnimation(string FileName, Animation anim, STSkeleton skeleton) { SEAnim seAnim = new SEAnim(); //Reset active animation to 0 anim.SetFrame(0); for (int frame = 0; frame < anim.FrameCount; frame++) { anim.NextFrame(skeleton); //Reset it when it reaches the total frame count if (anim.Frame >= anim.FrameCount) { anim.Frame = 0; } foreach (Animation.KeyNode boneAnim in anim.Bones) { STBone bone = skeleton.GetBone(boneAnim.Text); if (bone == null) { continue; } Vector3 position = bone.GetPosition(); Quaternion rotation = bone.GetRotation(); Vector3 scale = bone.GetScale(); seAnim.AddTranslationKey(boneAnim.Text, frame, position.X, position.Y, position.Z); seAnim.AddRotationKey(boneAnim.Text, frame, rotation.X, rotation.Y, rotation.Z, rotation.W); seAnim.AddScaleKey(boneAnim.Text, frame, scale.X, scale.Y, scale.Z); } //Add frames to the playing animation anim.Frame += 1f; } seAnim.Write(FileName); }
public static void Save(STSkeletonAnimation anim, string FileName) { STSkeleton skeleton = anim.GetActiveSkeleton(); SEAnim seAnim = new SEAnim(); seAnim.Looping = anim.Loop; seAnim.AnimType = AnimationType.Absolute; anim.SetFrame(0); for (int frame = 0; frame < anim.FrameCount; frame++) { anim.SetFrame(frame); anim.NextFrame(); foreach (STAnimGroup boneAnim in anim.AnimGroups) { if (boneAnim.GetTracks().Any(x => x.HasKeys)) { STBone bone = skeleton.GetBone(boneAnim.Name); if (bone == null) { continue; } Vector3 position = bone.GetPosition(); Quaternion rotation = bone.GetRotation(); Vector3 scale = bone.GetScale(); seAnim.AddTranslationKey(boneAnim.Name, frame, position.X, position.Y, position.Z); seAnim.AddRotationKey(boneAnim.Name, frame, rotation.X, rotation.Y, rotation.Z, rotation.W); seAnim.AddScaleKey(boneAnim.Name, frame, scale.X, scale.Y, scale.Z); } } } seAnim.Write(FileName); }
private static void SetBoneUniforms(GLControl control, ShaderProgram shader, STSkeleton Skeleton, STGenericObject mesh) { int i = 0; foreach (var bone in Skeleton.bones) { Matrix4 transform = bone.invert * bone.Transform; GL.UniformMatrix4(GL.GetUniformLocation(shader.programs[control], String.Format("bones[{0}]", i++)), false, ref transform); } /* foreach (var FaceGroup in fshp.Shape.FaceGroups) * { * if (FaceGroup.BoneIndexList == null) * continue; * * for (int i = 0; i < FaceGroup.BoneIndexList.Length; i++) * { * GL.Uniform1(GL.GetUniformLocation(shader.programs[control], String.Format("boneIds[{0}]", i)), FaceGroup.BoneIndexList[i]); * * Matrix4 transform = fmdl.Skeleton.Renderable.bones[(int)FaceGroup.BoneIndexList[i]].invert * fmdl.Skeleton.Renderable.bones[(int)FaceGroup.BoneIndexList[i]].Transform; * GL.UniformMatrix4(GL.GetUniformLocation(shader.programs[control], String.Format("bones[{0}]", i)), false, ref transform); * } * }*/ }
public SkeletonRenderer(STSkeleton skeleton) { Skeleton = skeleton; }
private void PlaySkeletalAnim(HSFMotionAnimation anim) { STSkeleton skeleton = Renderer.Scene.Models[0].Skeleton; foreach (var container in Runtime.ModelContainers) { var skel = container.SearchActiveSkeleton(); if (skel != null) { skeleton = skel; } } Console.WriteLine($"skeleton {skeleton != null}"); if (skeleton == null) { return; } if (anim.Frame == 0) { skeleton.Reset(); } bool Updated = false; // no need to update skeleton of animations that didn't change foreach (AnimationNode node in anim.AnimGroups) { var b = skeleton.SearchBone(node.Name); if (b == null) { continue; } Updated = true; Vector3 position = b.Position; Vector3 scale = b.Scale; Quaternion rotation = b.Rotation; if (node.TranslateX.HasKeys) { position.X = node.TranslateX.GetFrameValue(anim.Frame) * HSF_Renderer.PreviewScale; } if (node.TranslateY.HasKeys) { position.Y = node.TranslateY.GetFrameValue(anim.Frame) * HSF_Renderer.PreviewScale; } if (node.TranslateZ.HasKeys) { position.Z = node.TranslateZ.GetFrameValue(anim.Frame) * HSF_Renderer.PreviewScale; } if (node.ScaleX.HasKeys) { scale.X = node.ScaleX.GetFrameValue(anim.Frame); } if (node.ScaleY.HasKeys) { scale.Y = node.ScaleY.GetFrameValue(anim.Frame); } if (node.ScaleZ.HasKeys) { scale.Z = node.ScaleZ.GetFrameValue(anim.Frame); } if (node.RotationX.HasKeys || node.RotationY.HasKeys || node.RotationZ.HasKeys) { float x = node.RotationX.HasKeys ? MathHelper.DegreesToRadians(node.RotationX.GetFrameValue(anim.Frame)) : b.EulerRotation.X; float y = node.RotationY.HasKeys ? MathHelper.DegreesToRadians(node.RotationY.GetFrameValue(anim.Frame)) : b.EulerRotation.Y; float z = node.RotationZ.HasKeys ? MathHelper.DegreesToRadians(node.RotationZ.GetFrameValue(anim.Frame)) : b.EulerRotation.Z; rotation = STMath.FromEulerAngles(new Vector3(x, y, z)); } b.AnimationController.Position = position; b.AnimationController.Scale = scale; b.AnimationController.Rotation = rotation; } if (Updated) { skeleton.Update(); } }
public STVertex ToGenericVertex(Mesh mesh, VertexGroup group, STSkeleton skeleton) { List <int> boneIndices = new List <int>(); List <float> boneWeights = new List <float>(); Vector3 position = Vector3.Zero; Vector3 normal = Vector3.Zero; Vector2 uv0 = Vector2.Zero; Vector4 color = Vector4.One; if (mesh.Positions.Count > group.PositionIndex) { position = mesh.Positions[group.PositionIndex]; } if (mesh.Normals.Count > group.NormalIndex && group.NormalIndex != -1) { normal = mesh.Normals[group.NormalIndex]; } if (mesh.TexCoords.Count > group.UVIndex && group.UVIndex != -1) { uv0 = mesh.TexCoords[group.UVIndex]; } if (mesh.Colors.Count > group.ColorIndex && group.ColorIndex != -1) { color = mesh.Colors[group.ColorIndex]; } foreach (var msh in Header.ObjectData.Meshes) { if (msh.ObjectParent == mesh.ObjectData) { if (msh.Positions.Count > group.PositionIndex) { position = msh.Positions[group.PositionIndex]; } if (msh.Normals.Count > group.NormalIndex) { normal = msh.Normals[group.NormalIndex]; } } } position *= HSF_Renderer.PreviewScale; int nodeIndex = Header.ObjectData.Objects.IndexOf(mesh.ObjectData); if (nodeIndex != -1) { boneIndices.Clear(); boneWeights.Clear(); boneIndices.Add(nodeIndex); boneWeights.Add(1); position = Vector3.TransformPosition(position, skeleton.Bones[nodeIndex].Transform); } if (mesh.HasRigging) { foreach (var singleBind in mesh.RiggingInfo.SingleBinds) { if (group.PositionIndex >= singleBind.PositionIndex && group.PositionIndex < singleBind.PositionIndex + singleBind.PositionCount) { boneIndices.Clear(); boneWeights.Clear(); boneIndices.Add(singleBind.BoneIndex); boneWeights.Add(1); break; } } int mbOffset = 0; foreach (var multiBind in mesh.RiggingInfo.DoubleBinds) { for (int i = mbOffset; i < mbOffset + multiBind.Count; i++) { var w = mesh.RiggingInfo.DoubleWeights[i]; if (group.PositionIndex >= w.PositionIndex && group.PositionIndex < w.PositionIndex + w.PositionCount) { boneIndices.Clear(); boneWeights.Clear(); boneIndices.Add(multiBind.Bone1); boneIndices.Add(multiBind.Bone2); boneWeights.Add(w.Weight); boneWeights.Add(1 - w.Weight); break; } } mbOffset += multiBind.Count; } mbOffset = 0; foreach (var multiBind in mesh.RiggingInfo.MultiBinds) { if (group.PositionIndex >= multiBind.PositionIndex && group.PositionIndex < multiBind.PositionIndex + multiBind.PositionCount) { boneIndices.Clear(); boneWeights.Clear(); Vector4 indices = new Vector4(0); Vector4 weight = new Vector4(0); for (int i = mbOffset; i < mbOffset + multiBind.Count; i++) { indices[i - mbOffset] = mesh.RiggingInfo.MultiWeights[i].BoneIndex; weight[i - mbOffset] = mesh.RiggingInfo.MultiWeights[i].Weight; } if (weight.X != 0) { boneIndices.Add((int)indices.X); boneWeights.Add(weight.X); } if (weight.Y != 0) { boneIndices.Add((int)indices.Y); boneWeights.Add(weight.Y); } if (weight.Z != 0) { boneIndices.Add((int)indices.Z); boneWeights.Add(weight.Z); } if (weight.W != 0) { boneIndices.Add((int)indices.W); boneWeights.Add(weight.W); } break; } mbOffset += multiBind.Count; } } return(new STVertex() { Position = position, Colors = new Vector4[] { color }, Normal = normal, BoneIndices = boneIndices, BoneWeights = boneWeights, TexCoords = new Vector2[] { uv0 }, }); }
public BfresBone(STSkeleton skeleton) { skeletonParent = skeleton; }
public HSFBoneWrapper(ObjectData obj, STSkeleton skeleton) : base(skeleton) { ObjectData = obj; }