public void addBoneAssignment(VertexBoneAssignment vertBoneAssign) { OgrePINVOKE.Mesh_addBoneAssignment(swigCPtr, VertexBoneAssignment.getCPtr(vertBoneAssign)); if (OgrePINVOKE.SWIGPendingException.Pending) { throw OgrePINVOKE.SWIGPendingException.Retrieve(); } }
/// <summary> /// Assigns a vertex to a bone with a given weight, for skeletal animation. /// </summary> /// <remarks> /// This method is only valid after setting the SkeletonName property. /// You should not need to modify bone assignments during rendering (only the positions of bones) /// and the engine reserves the right to do some internal data reformatting of this information, /// depending on render system requirements. /// </remarks> /// <param name="boneAssignment"></param> public void AddBoneAssignment(VertexBoneAssignment boneAssignment) { if (!this.boneAssignmentList.ContainsKey(boneAssignment.vertexIndex)) { this.boneAssignmentList[boneAssignment.vertexIndex] = new List <VertexBoneAssignment>(); } this.boneAssignmentList[boneAssignment.vertexIndex].Add(boneAssignment); this.boneAssignmentsOutOfDate = true; }
protected void ReadVertexBoneAssigment(XmlNode node, SubMesh subMesh) { VertexBoneAssignment assignment = new VertexBoneAssignment(); // read the data from the file assignment.vertexIndex = int.Parse(node.Attributes["vertexindex"].Value); assignment.boneIndex = ushort.Parse(node.Attributes["boneindex"].Value);; assignment.weight = float.Parse(node.Attributes["weight"].Value);; // add the assignment to the mesh subMesh.AddBoneAssignment(assignment); }
public void SetPoints(List <Vector3> points, List <ColorEx> colors, List <VertexBoneAssignment> boneHandles) { // Preprocess the list of bone assignments so we get a list of // bone assignments for each vertex. List <List <VertexBoneAssignment> > boneAssignments = null; if (boneHandles != null) { Dictionary <int, List <VertexBoneAssignment> > dict = new Dictionary <int, List <VertexBoneAssignment> >(); foreach (VertexBoneAssignment vba in boneHandles) { List <VertexBoneAssignment> vbaList; if (!dict.TryGetValue(vba.vertexIndex, out vbaList)) { vbaList = new List <VertexBoneAssignment>(); dict[vba.vertexIndex] = vbaList; } vbaList.Add(vba); } // Construct the list of bone assignments for each vertex boneAssignments = new List <List <VertexBoneAssignment> >(); for (int i = 0; i < points.Count; ++i) { List <VertexBoneAssignment> vbaList; if (!dict.TryGetValue(i, out vbaList)) { vbaList = new List <VertexBoneAssignment>(); } if (vbaList.Count > 4) { // only allowed to use 4 bone influences - trim the less important ones vbaList.Sort(new VertexBoneAssignmentWeightComparer()); vbaList.RemoveRange(4, vbaList.Count - 4); } else { while (vbaList.Count < 4) { // Pad it out to 4 influences VertexBoneAssignment vba = new VertexBoneAssignment(); vba.vertexIndex = i; vba.boneIndex = 0; vba.weight = 0; vbaList.Add(vba); } } boneAssignments.Add(vbaList); } } SetPointsImpl(points, colors, boneAssignments); }
public static void CopyBoneAssignments(SubMesh dst, SubMesh src, Dictionary<uint, uint> vertexIdMap) { foreach (KeyValuePair<uint, uint> vertexMapping in vertexIdMap) { if (!src.BoneAssignmentList.ContainsKey((int)vertexMapping.Key)) continue; List<VertexBoneAssignment> srcVbaList = src.BoneAssignmentList[(int)vertexMapping.Key]; foreach (VertexBoneAssignment srcVba in srcVbaList) { Debug.Assert(srcVba.vertexIndex == (int)vertexMapping.Key); VertexBoneAssignment dstVba = new VertexBoneAssignment(); dstVba.boneIndex = srcVba.boneIndex; dstVba.vertexIndex = (int)vertexMapping.Value; dstVba.weight = srcVba.weight; dst.AddBoneAssignment(dstVba); } } }
public static void CopyBoneAssignments(Mesh dst, Mesh src, Dictionary <uint, uint> vertexIdMap) { foreach (KeyValuePair <uint, uint> vertexMapping in vertexIdMap) { List <VertexBoneAssignment> srcVbaList = src.BoneAssignmentList[(int)vertexMapping.Key]; foreach (VertexBoneAssignment srcVba in srcVbaList) { Debug.Assert(srcVba.vertexIndex == (int)vertexMapping.Key); VertexBoneAssignment dstVba = new VertexBoneAssignment(); dstVba.boneIndex = srcVba.boneIndex; dstVba.vertexIndex = (int)vertexMapping.Value; dstVba.weight = srcVba.weight; dst.AddBoneAssignment(dstVba); } } }
internal void RigidBindToBone(SubMesh subMesh, Bone bone) { m_Log.InfoFormat("Creating rigid binding from {0} to {1}", Id, bone.Name); for (int i = 0; i < subMesh.vertexData.vertexCount; ++i) { VertexBoneAssignment vba = new VertexBoneAssignment(); vba.boneIndex = bone.Handle; vba.vertexIndex = i; vba.weight = 1.0f; subMesh.AddBoneAssignment(vba); } BoneAssignmentList = subMesh.BoneAssignmentList; }
protected XmlElement WriteVertexBoneAssignment(VertexBoneAssignment vba) { XmlElement node = document.CreateElement("vertexboneassignment"); XmlAttribute attr; attr = document.CreateAttribute("vertexindex"); attr.Value = vba.vertexIndex.ToString(); node.Attributes.Append(attr); attr = document.CreateAttribute("boneindex"); attr.Value = vba.boneIndex.ToString(); node.Attributes.Append(attr); attr = document.CreateAttribute("weight"); attr.Value = vba.weight.ToString(); node.Attributes.Append(attr); return(node); }
internal void WeightedBindToBones(SubMesh subMesh, List <VertexBoneAssignment> vbaList) { // Some of these vertices needed to be split into multiple vertices. // Rebuild the vertex bone assignment list, to have entries for our // new vertex ids instead. foreach (VertexBoneAssignment item in vbaList) { List <int> subMeshVertexIds = GetVertexIds(item.vertexIndex); if (null != subMeshVertexIds) { foreach (int subVertexId in subMeshVertexIds) { VertexBoneAssignment vba = new VertexBoneAssignment(item); vba.vertexIndex = subVertexId; subMesh.AddBoneAssignment(vba); } } } BoneAssignmentList = subMesh.BoneAssignmentList; }
/// <summary> /// Assigns a vertex to a bone with a given weight, for skeletal animation. /// </summary> /// <remarks> /// This method is only valid after setting the SkeletonName property. /// You should not need to modify bone assignments during rendering (only the positions of bones) /// and the engine reserves the right to do some internal data reformatting of this information, /// depending on render system requirements. /// </remarks> /// <param name="boneAssignment"></param> public void AddBoneAssignment( VertexBoneAssignment boneAssignment ) { if ( !this.boneAssignmentList.ContainsKey( boneAssignment.vertexIndex ) ) { this.boneAssignmentList[ boneAssignment.vertexIndex ] = new List<VertexBoneAssignment>(); } this.boneAssignmentList[ boneAssignment.vertexIndex ].Add( boneAssignment ); this.boneAssignmentsOutOfDate = true; }
protected void WriteMeshBoneAssignment( BinaryWriter writer, VertexBoneAssignment vba ) { var start_offset = writer.Seek( 0, SeekOrigin.Current ); WriteChunk( writer, MeshChunkID.MeshBoneAssignment, 0 ); WriteUInt( writer, (uint)vba.vertexIndex ); WriteUShort( writer, (ushort)vba.boneIndex ); WriteFloat( writer, vba.weight ); var end_offset = writer.Seek( 0, SeekOrigin.Current ); writer.Seek( (int)start_offset, SeekOrigin.Begin ); WriteChunk( writer, MeshChunkID.MeshBoneAssignment, (int)( end_offset - start_offset ) ); writer.Seek( (int)end_offset, SeekOrigin.Begin ); }
protected virtual void ReadSubMeshBoneAssignment( BinaryReader reader, SubMesh sub ) { var assignment = new VertexBoneAssignment(); // read the data from the file assignment.vertexIndex = ReadInt( reader ); assignment.boneIndex = ReadUShort( reader ); assignment.weight = ReadFloat( reader ); // add the assignment to the mesh sub.AddBoneAssignment( assignment ); }
private LineRenderable CreateBoneLines(Skeleton skeleton) { List<Vector3> points = new List<Vector3>(); List<ColorEx> colors = new List<ColorEx>(); List<VertexBoneAssignment> vbas = new List<VertexBoneAssignment>(); int vertexIndex = 0; VertexBoneAssignment vba; foreach (Bone bone in skeleton.Bones) { Matrix4 bindTransform = bone.BindDerivedInverseTransform.Inverse(); Vector3 bonePosition = bindTransform.Translation; Bone parentBone = null; if (bone.Parent != null) parentBone = bone.Parent as Bone; // If we have a parent bone, draw a line to the parent bone if (parentBone != null) { points.Add(parentBone.BindDerivedInverseTransform.Inverse().Translation); points.Add(bonePosition); colors.Add(ColorEx.Cyan); colors.Add(ColorEx.Cyan); // Set up the vba for the bone base vba = new VertexBoneAssignment(); vba.vertexIndex = vertexIndex++; vba.weight = 1.0f; vba.boneIndex = parentBone.Handle; vbas.Add(vba); // Set up the vba for the bone end vba = new VertexBoneAssignment(); vba.vertexIndex = vertexIndex++; vba.weight = 1.0f; vba.boneIndex = bone.Handle; vbas.Add(vba); } // Set up axis lines for this entry // X axis line points.Add(bonePosition); points.Add(bindTransform * (Vector3.UnitX * boneAxisLength)); colors.Add(ColorEx.Red); colors.Add(ColorEx.Red); vba = new VertexBoneAssignment(); vba.vertexIndex = vertexIndex++; vba.weight = 1.0f; vba.boneIndex = bone.Handle; vbas.Add(vba); vba = new VertexBoneAssignment(); vba.vertexIndex = vertexIndex++; vba.weight = 1.0f; vba.boneIndex = bone.Handle; vbas.Add(vba); // Y axis line points.Add(bonePosition); points.Add(bindTransform * (Vector3.UnitY * boneAxisLength)); colors.Add(ColorEx.Blue); colors.Add(ColorEx.Blue); vba = new VertexBoneAssignment(); vba.vertexIndex = vertexIndex++; vba.weight = 1.0f; vba.boneIndex = bone.Handle; vbas.Add(vba); vba = new VertexBoneAssignment(); vba.vertexIndex = vertexIndex++; vba.weight = 1.0f; vba.boneIndex = bone.Handle; vbas.Add(vba); // Z axis line points.Add(bonePosition); points.Add(bindTransform * (Vector3.UnitZ * boneAxisLength)); colors.Add(ColorEx.Lime); colors.Add(ColorEx.Lime); vba = new VertexBoneAssignment(); vba.vertexIndex = vertexIndex++; vba.weight = 1.0f; vba.boneIndex = bone.Handle; vbas.Add(vba); vba = new VertexBoneAssignment(); vba.vertexIndex = vertexIndex++; vba.weight = 1.0f; vba.boneIndex = bone.Handle; vbas.Add(vba); } LineRenderable lines = new LineRenderable(); lines.SetPoints(points, colors, vbas); lines.MaterialName = "MVSkinnedLines"; lines.Skeleton = skeleton; return lines; }
private void ExportMesh(xxFrame meshParent, int indent) { string meshSpaces = GetStringSpaces(indent); xxMesh mesh = meshParent.Mesh; List<xxBone> boneList = mesh.BoneList; bool skinned = (boneList.Count > 0); for (int i = 0; i < mesh.SubmeshList.Count; i++) { List<VertexBoneAssignment>[] boneAssignments = null; if (skinned) { boneAssignments = new List<VertexBoneAssignment>[256]; for (int j = 0; j < boneAssignments.Length; j++) { boneAssignments[j] = new List<VertexBoneAssignment>(); } } writer.WriteLine(meshSpaces + "Mesh " + meshParent.Name + i + " {"); xxSubmesh submesh = mesh.SubmeshList[i]; List<xxFace> faceList = submesh.FaceList; List<xxVertex> vertexList = submesh.VertexList; writer.WriteLine(meshSpaces + " " + vertexList.Count + ";"); for (int j = 0; j < vertexList.Count; j++) { string s = meshSpaces + " "; xxVertex vertex = vertexList[j]; Vector3 coords = vertex.Position; coords[2] = -coords[2]; for (int k = 0; k < 3; k++) { s += coords[k].ToFloat6String() + ";"; } if (j < (vertexList.Count - 1)) { s += ","; } else { s += ";"; } writer.WriteLine(s); if (skinned) { float[] weights4 = vertex.Weights4(skinned); byte[] boneIndices = vertex.BoneIndices; for (int k = 0; k < boneIndices.Length; k++) { if ((boneIndices[k] != 0xFF) && (weights4[k] > 0)) { VertexBoneAssignment vba = new VertexBoneAssignment(); vba.vertexIndex = j; vba.weight = weights4[k]; boneAssignments[boneIndices[k]].Add(vba); } } } } writer.WriteLine(meshSpaces + " " + faceList.Count + ";"); for (int j = 0; j < faceList.Count; j++) { string s = meshSpaces + " 3;"; xxFace face = faceList[j]; s += face.VertexIndices[0].ToString() + ","; s += face.VertexIndices[2].ToString() + ","; s += face.VertexIndices[1].ToString() + ";"; if (j < (faceList.Count - 1)) { s += ","; } else { s += ";"; } writer.WriteLine(s); } writer.WriteLine(); writer.WriteLine(meshSpaces + " MeshNormals {"); writer.WriteLine(meshSpaces + " " + vertexList.Count + ";"); for (int j = 0; j < vertexList.Count; j++) { xxVertex vertex = vertexList[j]; Vector3 normal = vertex.Normal; writer.Write(meshSpaces + " " + normal[0].ToFloat6String() + ";" + normal[1].ToFloat6String() + ";" + (-normal[2]).ToFloat6String() + ";"); if (j < (vertexList.Count - 1)) { writer.WriteLine(","); } else { writer.WriteLine(";"); } } writer.WriteLine(meshSpaces + " " + faceList.Count + ";"); for (int j = 0; j < faceList.Count; j++) { xxFace face = faceList[j]; writer.Write(meshSpaces + " 3;" + face.VertexIndices[0] + "," + face.VertexIndices[2] + "," + face.VertexIndices[1] + ";"); if (j < (faceList.Count - 1)) { writer.WriteLine(","); } else { writer.WriteLine(";"); } } writer.WriteLine(meshSpaces + " }"); writer.WriteLine(); writer.WriteLine(meshSpaces + " MeshTextureCoords {"); writer.WriteLine(meshSpaces + " " + vertexList.Count + ";"); for (int j = 0; j < vertexList.Count; j++) { xxVertex vertex = vertexList[j]; float[] uv = vertex.UV; writer.Write(meshSpaces + " " + uv[0].ToFloat6String() + ";" + uv[1].ToFloat6String() + ";"); if (j < (vertexList.Count - 1)) { writer.WriteLine(","); } else { writer.WriteLine(";"); } } writer.WriteLine(meshSpaces + " }"); writer.WriteLine(); int materialIdx = submesh.MaterialIndex; if ((materialIdx >= 0) && (materialIdx < xxParser.MaterialList.Count)) { writer.WriteLine(meshSpaces + " MeshMaterialList {"); writer.WriteLine(meshSpaces + " 1;"); writer.WriteLine(meshSpaces + " " + faceList.Count + ";"); for (int j = 0; j < faceList.Count; j++) { writer.Write(meshSpaces + " 0"); if (j < (faceList.Count - 1)) { writer.WriteLine(","); } else { writer.WriteLine(";"); } } xxMaterial mat = xxParser.MaterialList[materialIdx]; Color4 ambient = mat.Ambient; Color4 specular = mat.Specular; Color4 emissive = mat.Emissive; writer.WriteLine(); writer.WriteLine(meshSpaces + " Material " + mat.Name + " {"); writer.WriteLine(meshSpaces + " " + ambient.Red.ToFloat6String() + ";" + ambient.Green.ToFloat6String() + ";" + ambient.Blue.ToFloat6String() + ";" + ambient.Alpha.ToFloat6String() + ";;"); writer.WriteLine(meshSpaces + " " + mat.Power.ToFloat6String() + ";"); writer.WriteLine(meshSpaces + " " + specular.Red.ToFloat6String() + ";" + specular.Green.ToFloat6String() + ";" + specular.Blue.ToFloat6String() + ";;"); writer.WriteLine(meshSpaces + " " + emissive.Red.ToFloat6String() + ";" + emissive.Green.ToFloat6String() + ";" + emissive.Blue.ToFloat6String() + ";;"); xxMaterialTexture matTex = mat.Textures[0]; if (matTex.Name != String.Empty) { writer.WriteLine(); writer.WriteLine(meshSpaces + " TextureFilename {"); writer.WriteLine(meshSpaces + " \"" + matTex.Name + "\";"); writer.WriteLine(meshSpaces + " }"); for (int j = 0; j < xxParser.TextureList.Count; j++) { xxTexture tex = xxParser.TextureList[j]; if (matTex.Name == tex.Name) { if (!usedTextures.ContainsKey(tex.Name)) { usedTextures.Add(tex.Name, tex); } break; } } } writer.WriteLine(meshSpaces + " }"); writer.WriteLine(meshSpaces + " }" + Environment.NewLine); } else { Report.ReportLog("Warning: mesh " + meshParent.Name + " object " + i + " uses non-existant material index " + materialIdx); } if (skinned) { int numUsedBones = 0; for (int j = 0; j < boneList.Count; j++) { xxBone bone = boneList[j]; if (boneAssignments[bone.Index].Count > 0) { numUsedBones++; } } writer.WriteLine(meshSpaces + " XSkinMeshHeader {"); writer.WriteLine(meshSpaces + " 4;"); writer.WriteLine(meshSpaces + " 12;"); writer.WriteLine(meshSpaces + " " + numUsedBones + ";"); writer.WriteLine(meshSpaces + " }"); writer.WriteLine(); for (int j = 0; j < boneList.Count; j++) { xxBone bone = boneList[j]; List<VertexBoneAssignment> boneAssignmentList = boneAssignments[bone.Index]; if (boneAssignmentList.Count <= 0) { continue; } writer.WriteLine(meshSpaces + " SkinWeights {"); writer.WriteLine(meshSpaces + " \"" + bone.Name + "\";"); writer.WriteLine(meshSpaces + " " + boneAssignmentList.Count + ";"); string vertexString = String.Empty; string weightString = String.Empty; for (int k = 0; k < boneAssignmentList.Count; k++) { vertexString += meshSpaces + " " + boneAssignmentList[k].vertexIndex; weightString += meshSpaces + " " + boneAssignmentList[k].weight.ToFloat6String(); if (k < (boneAssignmentList.Count - 1)) { vertexString += "," + Environment.NewLine; weightString += "," + Environment.NewLine; } else { vertexString += ";" + Environment.NewLine; weightString += ";" + Environment.NewLine; } } Matrix matrix = RHToLHMatrix(bone.Matrix); writer.Write(vertexString); writer.Write(weightString); writer.WriteLine(meshSpaces + " " + GetStringMatrix(matrix) + ";;"); writer.WriteLine(meshSpaces + " }"); writer.WriteLine(); } } writer.WriteLine(meshSpaces + "}"); writer.WriteLine(); } }
public void SetPoints(List<Vector3> points, List<ColorEx> colors, List<VertexBoneAssignment> boneHandles) { // Preprocess the list of bone assignments so we get a list of // bone assignments for each vertex. List<List<VertexBoneAssignment>> boneAssignments = null; if (boneHandles != null) { Dictionary<int, List<VertexBoneAssignment>> dict = new Dictionary<int, List<VertexBoneAssignment>>(); foreach (VertexBoneAssignment vba in boneHandles) { List<VertexBoneAssignment> vbaList; if (!dict.TryGetValue(vba.vertexIndex, out vbaList)) { vbaList = new List<VertexBoneAssignment>(); dict[vba.vertexIndex] = vbaList; } vbaList.Add(vba); } // Construct the list of bone assignments for each vertex boneAssignments = new List<List<VertexBoneAssignment>>(); for (int i = 0; i < points.Count; ++i) { List<VertexBoneAssignment> vbaList; if (!dict.TryGetValue(i, out vbaList)) vbaList = new List<VertexBoneAssignment>(); if (vbaList.Count > 4) { // only allowed to use 4 bone influences - trim the less important ones vbaList.Sort(new VertexBoneAssignmentWeightComparer()); vbaList.RemoveRange(4, vbaList.Count - 4); } else { while (vbaList.Count < 4) { // Pad it out to 4 influences VertexBoneAssignment vba = new VertexBoneAssignment(); vba.vertexIndex = i; vba.boneIndex = 0; vba.weight = 0; vbaList.Add(vba); } } boneAssignments.Add(vbaList); } } SetPointsImpl(points, colors, boneAssignments); }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(VertexBoneAssignment obj) { return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr); }
protected XmlElement WriteVertexBoneAssignment(VertexBoneAssignment vba) { XmlElement node = document.CreateElement("vertexboneassignment"); XmlAttribute attr; attr = document.CreateAttribute("vertexindex"); attr.Value = vba.vertexIndex.ToString(); node.Attributes.Append(attr); attr = document.CreateAttribute("boneindex"); attr.Value = vba.boneIndex.ToString(); node.Attributes.Append(attr); attr = document.CreateAttribute("weight"); attr.Value = vba.weight.ToString(); node.Attributes.Append(attr); return node; }
protected void ReadVertexBoneAssigment(XmlNode node, SubMesh subMesh) { VertexBoneAssignment assignment = new VertexBoneAssignment(); // read the data from the file assignment.vertexIndex = int.Parse(node.Attributes["vertexindex"].Value); assignment.boneIndex = ushort.Parse(node.Attributes["boneindex"].Value); ; assignment.weight = float.Parse(node.Attributes["weight"].Value); ; // add the assignment to the mesh subMesh.AddBoneAssignment(assignment); }