public static Onyx3D.Mesh ToOnyx3D(this Assimp.Mesh mesh) { Onyx3D.Mesh newMesh = new Onyx3D.Mesh(); newMesh.Indices = mesh.GetIndices(); for (int vi = 0; vi < mesh.VertexCount; ++vi) { Vertex newVertex = new Vertex(); newVertex.Position = mesh.Vertices[vi].ToOnyx3D(); if (mesh.HasTextureCoords(0)) { Assimp.Vector3D texCoord = mesh.TextureCoordinateChannels[0][vi]; newVertex.TexCoord = texCoord.ToOnyx3D().Xy; } if (mesh.HasNormals) { newVertex.Normal = mesh.Normals[vi].ToOnyx3D().Normalized(); if (mesh.HasTangentBasis) { newVertex.Bitangent = mesh.BiTangents[vi].ToOnyx3D().Normalized(); newVertex.Tangent = mesh.Tangents[vi].ToOnyx3D().Normalized(); } } newMesh.Vertices.Add(newVertex); } newMesh.GenerateVAO(); return(newMesh); }
private static Vector3 toDX3(Assimp.Vector3D vValue) { //return new Vector3(vValue.X, vValue.Y, vValue.Z); float y = vValue.Y - 1.0f; return(new Vector3(vValue.X, y, -vValue.Z)); }
public static Vector3 ToVector3(this Assimp.Vector3D vec) { Vector3 v; v.X = vec.X; v.Y = vec.Y; v.Z = vec.Z; return(v); }
public static OpenToolkit.Mathematics.Vector3 ToOtk(this Assimp.Vector3D v) { var ret = new OpenToolkit.Mathematics.Vector3(); ret.X = v.X; ret.Y = v.Y; ret.Z = v.Z; return(ret); }
private Vector2[] ConvertVectors(Assimp.Vector3D[] vectors) { Vector2[] data = new Vector2[vectors.Length]; for (int i = 0; i < vectors.Length; i++) { Assimp.Vector3D vector = vectors[i]; data[i] = new Vector2(vector.X, 1 - vector.Y); } return(data); }
public static Assimp.Vector3D CalcInterpolatedScaling(float animationTime, Assimp.NodeAnimationChannel nodeAnim) { if (nodeAnim.ScalingKeyCount == 1) { return(nodeAnim.ScalingKeys[0].Value); } Assimp.Vector3D result; int index = FindScaling(animationTime, nodeAnim); int nextIndex = (index + 1); float deltaTime = (float)(nodeAnim.ScalingKeys[nextIndex].Time - nodeAnim.ScalingKeys[index].Time); float factor = (animationTime - (float)nodeAnim.ScalingKeys[index].Time) / deltaTime; Assimp.Vector3D start = nodeAnim.ScalingKeys[index].Value; Assimp.Vector3D end = nodeAnim.ScalingKeys[nextIndex].Value; Assimp.Vector3D delta = end - start; result = start + factor * delta; return(result); }
private static Assimp.Vector3D CalcInterpolatedPosition(float animationTime, Assimp.NodeAnimationChannel nodeAnim) { Assimp.Vector3D result; if (nodeAnim.PositionKeyCount == 1) { result = nodeAnim.PositionKeys[0].Value; return(result); } uint index = FindPosition(animationTime, nodeAnim); uint nextIndex = (index + 1); //assert(NextPositionIndex < nodeAnim->mNumPositionKeys); float deltaTime = (float)(nodeAnim.PositionKeys[nextIndex].Time - nodeAnim.PositionKeys[index].Time); float factor = (animationTime - (float)nodeAnim.PositionKeys[index].Time) / deltaTime; //assert(Factor >= 0.0f && Factor <= 1.0f); Assimp.Vector3D start = nodeAnim.PositionKeys[index].Value; Assimp.Vector3D end = nodeAnim.PositionKeys[nextIndex].Value; Assimp.Vector3D delta = end - start; result = start + factor * delta; return(result); }
private static Assimp.Vector3D CalcInterpolatedScaling(float animationTime, Assimp.NodeAnimationChannel nodeAnim) { Assimp.Vector3D Out; if (nodeAnim.ScalingKeyCount == 1) { Out = nodeAnim.ScalingKeys[0].Value; return(Out); } uint ScalingIndex = FindScaling(animationTime, nodeAnim); uint NextScalingIndex = (ScalingIndex + 1); //assert(NextScalingIndex < nodeAnim->mNumScalingKeys); float DeltaTime = (float)(nodeAnim.ScalingKeys[NextScalingIndex].Time - nodeAnim.ScalingKeys[ScalingIndex].Time); float Factor = (animationTime - (float)nodeAnim.ScalingKeys[ScalingIndex].Time) / DeltaTime; //assert(Factor >= 0.0f && Factor <= 1.0f); Assimp.Vector3D Start = nodeAnim.ScalingKeys[ScalingIndex].Value; Assimp.Vector3D End = nodeAnim.ScalingKeys[NextScalingIndex].Value; Assimp.Vector3D Delta = End - Start; Out = Start + Factor * Delta; return(Out); }
private static void ReadNodeHeirarchy(float animationTime, Assimp.Node node, Assimp.Animation animation, mat4 parentTransform, AllBoneInfos allBones) { string nodeName = node.Name; mat4 nodeTransform = node.Transform.ToMat4(); Assimp.NodeAnimationChannel nodeAnim = FineNodeAnim(animation, nodeName); if (nodeAnim != null) { mat4 mat = mat4.identity(); // Interpolate scaling and generate scaling transformation matrix Assimp.Vector3D Scaling = CalcInterpolatedScaling(animationTime, nodeAnim); mat4 ScalingM = glm.scale(mat, new vec3(Scaling.X, Scaling.Y, Scaling.Z)); // Interpolate rotation and generate rotation transformation matrix Assimp.Quaternion RotationQ = CalcInterpolatedRotation(animationTime, nodeAnim); mat4 RotationM = new Assimp.Matrix4x4(RotationQ.GetMatrix()).ToMat4(); // Interpolate translation and generate translation transformation matrix Assimp.Vector3D Translation = CalcInterpolatedPosition(animationTime, nodeAnim); mat4 TranslationM = glm.translate(mat4.identity(), new vec3(Translation.X, Translation.Y, Translation.Z)); // Combine the above transformations nodeTransform = TranslationM * RotationM * ScalingM; } mat4 transform = parentTransform * nodeTransform; if (allBones.nameIndexDict.ContainsKey(nodeName)) { uint BoneIndex = allBones.nameIndexDict[nodeName]; allBones.boneInfos[BoneIndex].finalTransformation = transform; } for (int i = 0; i < node.ChildCount; i++) { ReadNodeHeirarchy(animationTime, node.Children[i], animation, transform, allBones); } }
//--------------------------------------------------------------------------------------------------------- /// <summary> /// Конвертация объекта вектор в объект типа <see cref="Vector3D"/> /// </summary> /// <param name="value">Значение</param> /// <param name="target_type">Целевой тип</param> /// <param name="parameter">Дополнительный параметр</param> /// <param name="culture">Культура</param> /// <returns>Объект <see cref="Vector3D"/></returns> //--------------------------------------------------------------------------------------------------------- public Object Convert(Object value, Type target_type, Object parameter, CultureInfo culture) { if (value is Vector3D) { return(value); } if (value is System.Windows.Media.Media3D.Vector3D) { System.Windows.Media.Media3D.Vector3D v = (System.Windows.Media.Media3D.Vector3D)value; return(new Vector3D(v.X, v.Y, v.Z)); } if (value is System.Windows.Media.Media3D.Point3D) { System.Windows.Media.Media3D.Point3D v = (System.Windows.Media.Media3D.Point3D)value; return(new Vector3D(v.X, v.Y, v.Z)); } #if USE_ASSIMP if (value is Assimp.Vector3D) { Assimp.Vector3D v = (Assimp.Vector3D)value; return(new Vector3D(v.X, v.Y, v.Z)); } #endif #if USE_SHARPDX if (value is SharpDX.Vector3) { SharpDX.Vector3 v = (SharpDX.Vector3)value; return(new Vector3D(v.X, v.Y, v.Z)); } #endif return(Vector3D.Zero); }
public override Assimp.Node assimpExport(ref Assimp.Scene scn, ref Dictionary <int, int> meshImportStatus) { Assimp.Mesh amesh = new Assimp.Mesh(); Assimp.Node node; amesh.Name = name; int meshHash = meshVao.GetHashCode(); //TESTING if (scn.MeshCount > 20) { node = base.assimpExport(ref scn, ref meshImportStatus); return(node); } if (!meshImportStatus.ContainsKey(meshHash)) //if (false) { meshImportStatus[meshHash] = scn.MeshCount; int vertcount = metaData.vertrend_graphics - metaData.vertrstart_graphics + 1; MemoryStream vms = new MemoryStream(gobject.meshDataDict[metaData.Hash].vs_buffer); MemoryStream ims = new MemoryStream(gobject.meshDataDict[metaData.Hash].is_buffer); BinaryReader vbr = new BinaryReader(vms); BinaryReader ibr = new BinaryReader(ims); //Initialize Texture Component Channels if (gobject.bufInfo[1] != null) { List <Assimp.Vector3D> textureChannel = new List <Assimp.Vector3D>(); amesh.TextureCoordinateChannels.Append(textureChannel); amesh.UVComponentCount[0] = 2; } //Generate bones only for the joints related to the mesh Dictionary <int, Assimp.Bone> localJointDict = new Dictionary <int, Assimp.Bone>(); //Export Bone Structure if (Skinned) //if (false) { for (int i = 0; i < meshVao.BoneRemapIndicesCount; i++) { int joint_id = meshVao.BoneRemapIndices[i]; //Fetch name Joint relJoint = null; foreach (Joint jnt in parentScene.jointDict.Values) { if (jnt.jointIndex == joint_id) { relJoint = jnt; break; } } //Generate bone Assimp.Bone b = new Assimp.Bone(); if (relJoint != null) { b.Name = relJoint.name; b.OffsetMatrix = MathUtils.convertMatrix(relJoint.invBMat); } localJointDict[i] = b; amesh.Bones.Add(b); } } //Write geometry info vbr.BaseStream.Seek(0, SeekOrigin.Begin); for (int i = 0; i < vertcount; i++) { Assimp.Vector3D v, vN; for (int j = 0; j < gobject.bufInfo.Count; j++) { bufInfo buf = gobject.bufInfo[j]; if (buf is null) { continue; } switch (buf.semantic) { case 0: //vPosition { switch (buf.type) { case VertexAttribPointerType.HalfFloat: uint v1 = vbr.ReadUInt16(); uint v2 = vbr.ReadUInt16(); uint v3 = vbr.ReadUInt16(); uint v4 = vbr.ReadUInt16(); //Transform vector with worldMatrix v = new Assimp.Vector3D(Utils.Half.decompress(v1), Utils.Half.decompress(v2), Utils.Half.decompress(v3)); break; case VertexAttribPointerType.Float: //This is used in my custom vbos float f1 = vbr.ReadSingle(); float f2 = vbr.ReadSingle(); float f3 = vbr.ReadSingle(); //Transform vector with worldMatrix v = new Assimp.Vector3D(f1, f2, f3); break; default: throw new Exception("Unimplemented Vertex Type"); } amesh.Vertices.Add(v); break; } case 1: //uvPosition { Assimp.Vector3D uv; uint v1 = vbr.ReadUInt16(); uint v2 = vbr.ReadUInt16(); uint v3 = vbr.ReadUInt16(); uint v4 = vbr.ReadUInt16(); //uint v4 = Convert.ToUInt16(vbr.ReadUInt16()); uv = new Assimp.Vector3D(Utils.Half.decompress(v1), Utils.Half.decompress(v2), 0.0f); amesh.TextureCoordinateChannels[0].Add(uv); //Add directly to the first channel break; } case 2: //nPosition case 3: //tPosition { switch (buf.type) { case (VertexAttribPointerType.Float): float f1, f2, f3; f1 = vbr.ReadSingle(); f2 = vbr.ReadSingle(); f3 = vbr.ReadSingle(); vN = new Assimp.Vector3D(f1, f2, f3); break; case (VertexAttribPointerType.HalfFloat): uint v1, v2, v3; v1 = vbr.ReadUInt16(); v2 = vbr.ReadUInt16(); v3 = vbr.ReadUInt16(); vN = new Assimp.Vector3D(Utils.Half.decompress(v1), Utils.Half.decompress(v2), Utils.Half.decompress(v3)); break; case (VertexAttribPointerType.Int2101010Rev): int i1, i2, i3; uint value; byte[] a32 = new byte[4]; a32 = vbr.ReadBytes(4); value = BitConverter.ToUInt32(a32, 0); //Convert Values i1 = _2sComplement.toInt((value >> 00) & 0x3FF, 10); i2 = _2sComplement.toInt((value >> 10) & 0x3FF, 10); i3 = _2sComplement.toInt((value >> 20) & 0x3FF, 10); //int i4 = _2sComplement.toInt((value >> 30) & 0x003, 10); float norm = (float)Math.Sqrt(i1 * i1 + i2 * i2 + i3 * i3); vN = new Assimp.Vector3D(Convert.ToSingle(i1) / norm, Convert.ToSingle(i2) / norm, Convert.ToSingle(i3) / norm); //Debug.WriteLine(vN); break; default: throw new Exception("UNIMPLEMENTED NORMAL TYPE. PLEASE REPORT"); } if (j == 2) { amesh.Normals.Add(vN); } else if (j == 3) { amesh.Tangents.Add(vN); amesh.BiTangents.Add(new Assimp.Vector3D(0.0f, 0.0f, 1.0f)); } break; } case 4: //bPosition vbr.ReadBytes(4); // skip break; case 5: //BlendIndices + BlendWeights { int[] joint_ids = new int[4]; float[] weights = new float[4]; for (int k = 0; k < 4; k++) { joint_ids[k] = vbr.ReadByte(); } for (int k = 0; k < 4; k++) { weights[k] = Utils.Half.decompress(vbr.ReadUInt16()); } if (Skinned) //if (false) { for (int k = 0; k < 4; k++) { int joint_id = joint_ids[k]; Assimp.VertexWeight vw = new Assimp.VertexWeight(); vw.VertexID = i; vw.Weight = weights[k]; localJointDict[joint_id].VertexWeights.Add(vw); } } break; } case 6: break; //Handled by 5 default: { throw new Exception("UNIMPLEMENTED BUF Info. PLEASE REPORT"); break; } } } } //Export Faces //Get indices ibr.BaseStream.Seek(0, SeekOrigin.Begin); bool start = false; int fstart = 0; for (int i = 0; i < metaData.batchcount / 3; i++) { int f1, f2, f3; //NEXT models assume that all gstream meshes have uint16 indices f1 = ibr.ReadUInt16(); f2 = ibr.ReadUInt16(); f3 = ibr.ReadUInt16(); if (!start && this.type != TYPES.COLLISION) { fstart = f1; start = true; } else if (!start && this.type == TYPES.COLLISION) { fstart = 0; start = true; } int f11, f22, f33; f11 = f1 - fstart; f22 = f2 - fstart; f33 = f3 - fstart; Assimp.Face face = new Assimp.Face(); face.Indices.Add(f11); face.Indices.Add(f22); face.Indices.Add(f33); amesh.Faces.Add(face); } scn.Meshes.Add(amesh); } node = base.assimpExport(ref scn, ref meshImportStatus); node.MeshIndices.Add(meshImportStatus[meshHash]); return(node); }
public static Vector3 ToOnyx3D(this Assimp.Vector3D v) { return(new Vector3(v.X, v.Y, v.Z)); }
public static UnityEngine.Vector3 ToV3(this Assimp.Vector3D v3) { return(new UnityEngine.Vector3(v3.X, v3.Y, v3.Z)); }
private static Vector3 ToVector3(Assimp.Vector3D vector) { return(Unsafe.As <Assimp.Vector3D, Vector3>(ref vector)); }
public static Assimp.Vector2D XY(this Assimp.Vector3D v) { return(new Assimp.Vector2D(v.X, v.Y)); }
public static Vector3 TK(this Assimp.Vector3D assimp) { return(new Vector3(assimp.X, assimp.Y, assimp.Z)); }
internal static Mesh FromAssimp(Assimp.Mesh mesh) { Mesh newMesh = new Mesh(); newMesh.Indices = mesh.GetUnsignedIndices(); bool hasTexCoords = mesh.HasTextureCoords(0); List <Assimp.Vector3D> uvs = hasTexCoords ? mesh.TextureCoordinateChannels[0] : null; // bounding box values float min_x, max_x, min_y, max_y, min_z, max_z; min_x = max_x = mesh.Vertices[0].X; min_y = max_y = mesh.Vertices[0].Y; min_z = max_z = mesh.Vertices[0].Z; Vertex[] vertices = new Vertex[mesh.VertexCount]; for (int i = 0; i < vertices.Length; i++) { Vector3 vec = mesh.Vertices[i].ToNumeric(); Vector3 norm = mesh.Normals[i].ToNumeric(); if (hasTexCoords) { Assimp.Vector3D uv = uvs[i]; vertices[i] = new Vertex(vec, new Vector2(uv.X, 1.0f - uv.Y), norm); } else { vertices[i] = new Vertex(vec, Vector2.Zero, norm); } if (vec.X < min_x) { min_x = vec.X; } if (vec.X > max_x) { max_x = vec.X; } if (vec.Y < min_y) { min_y = vec.Y; } if (vec.Y > max_y) { max_y = vec.Y; } if (vec.Z < min_z) { min_z = vec.Z; } if (vec.Z > max_z) { max_z = vec.Z; } } newMesh.BoundingBox = new BoundingBox(new Vector3(min_x, min_y, min_z), new Vector3(max_x, max_y, max_z)); newMesh.Vertices = vertices; return(newMesh); }
public static Vector3 ToNumeric(this Assimp.Vector3D vector) => new Vector3(vector.X, vector.Y, vector.Z);
public static XNAV3 ToXna(this Assimp.Vector3D v) { return(new XNAV3(v.X, v.Y, v.Z)); }
public static Vector3 FromAssimp(Assimp.Vector3D value) { return(new Vector3(value.X, value.Y, value.Z)); }
private static Vector2 toDX2(Assimp.Vector3D vValue) { return(new Vector2(vValue.X, vValue.Y)); }
private static Vector3 toDX(Assimp.Vector3D vValue) { return(new Vector3(vValue.X, vValue.Y, vValue.Z)); }
public static Vector2 FromAssimpAsVector2(Assimp.Vector3D value) { return(new Vector2(value.X, value.Y)); }
public override ModelContent Process(Assimp.Scene scene, string filename, ContentProcessorContext context) { try { Assimp.AssimpContext c = new Assimp.AssimpContext(); Assimp.ExportFormatDescription des = c.GetSupportedExportFormats()[0]; //c.ExportFile(scene,Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),"test.dae"),des.FormatId); ModelContent content = new ModelContent(); content.Meshes = new MeshContent[scene.MeshCount]; for (int meshIndex = 0; meshIndex < scene.MeshCount; meshIndex++) { var sceneMesh = scene.Meshes[meshIndex]; var meshContent = new MeshContent(); meshContent.PrimitiveCount = sceneMesh.FaceCount; meshContent.Vertices = new VertexPositionNormalTexture[meshContent.PrimitiveCount * 3]; int vertex = 0; //TODO: indexing foreach (var f in sceneMesh.Faces) { foreach (var i in f.Indices) { var pos = sceneMesh.Vertices[i]; var norm = sceneMesh.Normals[i]; Assimp.Vector3D tex = new Assimp.Vector3D(); if (sceneMesh.TextureCoordinateChannels.Length > 0 && sceneMesh.TextureCoordinateChannels[0].Count > i) { tex = sceneMesh.TextureCoordinateChannels[0][i]; } var translated = new Vector3(pos.X, pos.Y, pos.Z) + settings.Translate; meshContent.Vertices[vertex++] = new VertexPositionNormalTexture( new Vector3(translated.X * settings.Scale.X, translated.Y * settings.Scale.Y, translated.Z * settings.Scale.Z), new Vector3(norm.X, norm.Y, norm.Z), new Vector2(tex.X, -tex.Y)); } } /*for (int i = 0; i < sceneMesh.VertexCount; i++) * { * * }*/ content.Meshes[meshIndex] = meshContent; } content.Nodes = new List <NodeContent>(); content.RootNode = ParseNode(content, scene.RootNode); foreach (var animation in scene.Animations) { var anim = new AnimationContent(); anim.Channels = new List <AnimationNodeContent>(); foreach (var channel in animation.NodeAnimationChannels) { AnimationNodeContent node = new AnimationNodeContent(); var curNode = content.Nodes.First(n => n.Name == channel.NodeName); node.Node = curNode; node.Frames = new List <AnimationFrame>(); int frameCount = Math.Max(Math.Max(channel.PositionKeyCount, channel.RotationKeyCount), channel.ScalingKeyCount); float diff = 0.0f, maxTime = 0;; for (int i = 0; i < frameCount; i++) { AnimationFrame frame = new AnimationFrame(); if (i < channel.PositionKeyCount) { frame.Frame = (float)channel.PositionKeys[i].Time; } else if (i < channel.RotationKeyCount) { frame.Frame = (float)channel.RotationKeys[i].Time; } else if (i < channel.ScalingKeyCount) { frame.Frame = (float)channel.ScalingKeys[i].Time; } if (i == 0) { diff = frame.Frame; } frame.Frame -= diff; frame.Frame = (float)(frame.Frame / animation.TicksPerSecond); maxTime = Math.Max(frame.Frame, maxTime); //TODO: interpolation var rot = channel.RotationKeyCount == 0 ? new Assimp.Quaternion(1, 0, 0, 0) : i >= channel.RotationKeyCount ? channel.RotationKeys.Last().Value : channel.RotationKeys[i].Value; var loc = channel.PositionKeyCount == 0 ? new Assimp.Vector3D() : i >= channel.PositionKeyCount ? channel.PositionKeys.Last().Value : channel.PositionKeys[i].Value; var sca = channel.ScalingKeyCount == 0 ? new Assimp.Vector3D(1, 1, 1) : i >= channel.ScalingKeyCount ? channel.ScalingKeys.Last().Value : channel.ScalingKeys[i].Value; rot.Normalize(); frame.Transform = new AnimationTransform(node.Node.Name, new Vector3((loc.X + settings.Translate.X), (loc.Y + settings.Translate.Y), (loc.Z + settings.Translate.Z)), new Vector3(sca.X * settings.Scale.X, sca.Y * settings.Scale.Y, sca.Z * settings.Scale.Z), new Quaternion(rot.X, rot.Y, rot.Z, rot.W)); node.Frames.Add(frame); } anim.MaxTime = maxTime; anim.Channels.Add(node); } content.Animations.Add(anim); } PostProcess(content, content.RootNode); return(content); } catch (Exception ex) { context.RaiseBuildMessage(filename, ex.Message, BuildMessageEventArgs.BuildMessageType.Error); } return(null); }
public IEnumerable <VertexBuffer> GetVertexAttribute(string bufferName) { if (strPosition == bufferName) { if (this.positionBuffer == null) { this.positionBuffer = this.mesh.Vertices.GenVertexBuffer(VBOConfig.Vec3, BufferUsage.StaticDraw); } yield return(this.positionBuffer); } else if (strNormal == bufferName) { if (this.normalBuffer == null) { this.normalBuffer = this.mesh.Normals.GenVertexBuffer(VBOConfig.Vec3, BufferUsage.StaticDraw); } yield return(this.normalBuffer); } else if (strTexCoord == bufferName) { if (this.texCoordBuffer == null) { Assimp.Vector3D[] texCoords = this.mesh.GetTextureCoords(0); if (texCoords == null) { texCoords = new Assimp.Vector3D[this.mesh.VertexCount]; for (int i = 0; i < texCoords.Length; i++) { texCoords[i] = new Assimp.Vector3D(-1, -1, -1); } } this.texCoordBuffer = texCoords.GenVertexBuffer(VBOConfig.Vec3, BufferUsage.StaticDraw); } yield return(this.texCoordBuffer); } else if (strBoneIDs == bufferName) { if (this.boneIDsBuffer == null) { this.boneIDsBuffer = this.boneIDs.GenVertexBuffer(VBOConfig.UVec4, BufferUsage.StaticDraw); } yield return(this.boneIDsBuffer); } else if (strWeights == bufferName) { if (this.weightsBuffer == null) { this.weightsBuffer = this.boneWeights.GenVertexBuffer(VBOConfig.Vec4, BufferUsage.StaticDraw); } yield return(this.weightsBuffer); } else { throw new ArgumentException(); } }
public static UnityEngine.Vector2 ToV2(this Assimp.Vector3D v3) { return(new UnityEngine.Vector2(v3.X, v3.Y)); }
public static JVector Jitter(this Assimp.Vector3D assimp) { return(new JVector(assimp.X, assimp.Y, assimp.Z)); }
public static System.Numerics.Vector3 ToSystemVec3(this Assimp.Vector3D v) { return(new System.Numerics.Vector3(v.X, v.Y, v.Z)); }
private static Vector2 Get2DCoord(Assimp.Vector3D vector3D) => new Vector2(vector3D.X, 1 - vector3D.Y);
public static Assimp.Scene ToAssimpScene(RwClumpNode clumpNode) { // Scene var aiScene = new Assimp.Scene(); // RootNode var rootFrame = clumpNode.FrameList[0]; var aiRootNode = new Assimp.Node("RootNode", null); aiRootNode.Transform = new Assimp.Matrix4x4(rootFrame.Transform.M11, rootFrame.Transform.M21, rootFrame.Transform.M31, rootFrame.Transform.M41, rootFrame.Transform.M12, rootFrame.Transform.M22, rootFrame.Transform.M32, rootFrame.Transform.M42, rootFrame.Transform.M13, rootFrame.Transform.M23, rootFrame.Transform.M33, rootFrame.Transform.M43, rootFrame.Transform.M14, rootFrame.Transform.M24, rootFrame.Transform.M34, rootFrame.Transform.M44); aiScene.RootNode = aiRootNode; for (int i = 1; i < clumpNode.FrameList.Count; i++) { var frame = clumpNode.FrameList[i]; var frameName = "_" + frame.HAnimFrameExtensionNode.NameId; Assimp.Node aiParentNode = null; if (frame.Parent != null) { string parentName = "RootNode"; if (frame.Parent.HasHAnimExtension) { parentName = "_" + frame.Parent.HAnimFrameExtensionNode.NameId; } aiParentNode = aiRootNode.FindNode(parentName); } var aiNode = new Assimp.Node(frameName, aiParentNode); aiNode.Transform = new Assimp.Matrix4x4(frame.Transform.M11, frame.Transform.M21, frame.Transform.M31, frame.Transform.M41, frame.Transform.M12, frame.Transform.M22, frame.Transform.M32, frame.Transform.M42, frame.Transform.M13, frame.Transform.M23, frame.Transform.M33, frame.Transform.M43, frame.Transform.M14, frame.Transform.M24, frame.Transform.M34, frame.Transform.M44); aiParentNode.Children.Add(aiNode); } // Meshes, Materials for (int atomicIndex = 0; atomicIndex < clumpNode.Atomics.Count; atomicIndex++) { var atomic = clumpNode.Atomics[atomicIndex]; var geometry = clumpNode.GeometryList[atomic.GeometryIndex]; var frame = clumpNode.FrameList[atomic.FrameIndex]; var aiNodeName = $"Atomic{atomicIndex}"; var aiNode = new Assimp.Node(aiNodeName, aiScene.RootNode); var frameWorldTransform = frame.WorldTransform; aiNode.Transform = new Assimp.Matrix4x4(frameWorldTransform.M11, frameWorldTransform.M21, frameWorldTransform.M31, frameWorldTransform.M41, frameWorldTransform.M12, frameWorldTransform.M22, frameWorldTransform.M32, frameWorldTransform.M42, frameWorldTransform.M13, frameWorldTransform.M23, frameWorldTransform.M33, frameWorldTransform.M43, frameWorldTransform.M14, frameWorldTransform.M24, frameWorldTransform.M34, frameWorldTransform.M44); aiScene.RootNode.Children.Add(aiNode); bool hasVertexWeights = geometry.SkinNode != null; for (int meshIndex = 0; meshIndex < geometry.MeshListNode.MaterialMeshes.Length; meshIndex++) { var mesh = geometry.MeshListNode.MaterialMeshes[meshIndex]; var aiMesh = new Assimp.Mesh($"Atomic{atomicIndex}_Geometry{atomic.GeometryIndex}_Mesh{meshIndex}", Assimp.PrimitiveType.Triangle); // get triangle list indices int[] indices; if (geometry.MeshListNode.PrimitiveType == RwPrimitiveType.TriangleList) { indices = mesh.Indices; } else { indices = MeshUtilities.ToTriangleList(mesh.Indices, false); } // Faces for (int i = 0; i < indices.Length; i += 3) { var faceIndices = new[] { i, i + 1, i + 2 }; var aiFace = new Assimp.Face(faceIndices); aiMesh.Faces.Add(aiFace); } // TextureCoordinateChannels, VertexColorChannels, Vertices, MaterialIndex, Normals for (int triIdx = 0; triIdx < indices.Length; triIdx += 3) { for (int triVertIdx = 0; triVertIdx < 3; triVertIdx++) { int vertexIndex = indices[triIdx + triVertIdx]; // TextureCoordinateChannels if (geometry.HasTextureCoordinates) { for (int channelIdx = 0; channelIdx < geometry.TextureCoordinateChannelCount; channelIdx++) { var textureCoordinate = geometry.TextureCoordinateChannels[channelIdx][vertexIndex]; var aiTextureCoordinate = new Assimp.Vector3D(textureCoordinate.X, textureCoordinate.Y, 0f); aiMesh.TextureCoordinateChannels[channelIdx].Add(aiTextureCoordinate); } } // VertexColorChannels if (geometry.HasColors) { var color = geometry.Colors[vertexIndex]; var aiColor = new Assimp.Color4D(color.R / 255f, color.G / 255f, color.B / 255f, color.A / 255f); aiMesh.VertexColorChannels[0].Add(aiColor); } // Vertices if (geometry.HasVertices) { var vertex = geometry.Vertices[vertexIndex]; var aiVertex = new Assimp.Vector3D(vertex.X, vertex.Y, vertex.Z); aiMesh.Vertices.Add(aiVertex); } // Normals if (geometry.HasNormals) { var normal = geometry.Normals[vertexIndex]; var aiNormal = new Assimp.Vector3D(normal.X, normal.Y, normal.Z); aiMesh.Normals.Add(aiNormal); } } } // Bones if (hasVertexWeights) { var skinNode = geometry.SkinNode; var aiBoneMap = new Dictionary <int, Assimp.Bone>(); for (int i = 0; i < indices.Length; i++) { var vertexIndex = indices[i]; int realVertexIndex = i; for (int j = 0; j < 4; j++) { var boneIndex = skinNode.VertexBoneIndices[vertexIndex][j]; var boneWeight = skinNode.VertexBoneWeights[vertexIndex][j]; if (boneWeight == 0.0f) { continue; } if (!aiBoneMap.Keys.Contains(boneIndex)) { var aiBone = new Assimp.Bone(); var boneFrame = clumpNode.FrameList.GetFrameByHierarchyIndex(boneIndex); aiBone.Name = boneFrame.HasHAnimExtension ? "_" + boneFrame.HAnimFrameExtensionNode.NameId : "RootNode"; aiBone.VertexWeights.Add(new Assimp.VertexWeight(realVertexIndex, boneWeight)); Matrix4x4.Invert(frame.WorldTransform, out Matrix4x4 invertedFrameWorldTransform); Matrix4x4.Invert(boneFrame.WorldTransform * invertedFrameWorldTransform, out Matrix4x4 offsetMatrix); aiBone.OffsetMatrix = new Assimp.Matrix4x4(offsetMatrix.M11, offsetMatrix.M21, offsetMatrix.M31, offsetMatrix.M41, offsetMatrix.M12, offsetMatrix.M22, offsetMatrix.M32, offsetMatrix.M42, offsetMatrix.M13, offsetMatrix.M23, offsetMatrix.M33, offsetMatrix.M43, offsetMatrix.M14, offsetMatrix.M24, offsetMatrix.M34, offsetMatrix.M44); aiBoneMap[boneIndex] = aiBone; } if (!aiBoneMap[boneIndex].VertexWeights.Any(x => x.VertexID == realVertexIndex)) { aiBoneMap[boneIndex].VertexWeights.Add(new Assimp.VertexWeight(realVertexIndex, boneWeight)); } } } aiMesh.Bones.AddRange(aiBoneMap.Values); } else { var aiBone = new Assimp.Bone(); // Name aiBone.Name = frame.HasHAnimExtension ? "_" + frame.HAnimFrameExtensionNode.NameId : "RootNode"; // VertexWeights for (int i = 0; i < aiMesh.Vertices.Count; i++) { var aiVertexWeight = new Assimp.VertexWeight(i, 1f); aiBone.VertexWeights.Add(aiVertexWeight); } // OffsetMatrix /* * Matrix4x4.Invert( frame.WorldTransform, out Matrix4x4 offsetMatrix ); * aiBone.OffsetMatrix = new Assimp.Matrix4x4( offsetMatrix.M11, offsetMatrix.M21, offsetMatrix.M31, offsetMatrix.M41, * offsetMatrix.M12, offsetMatrix.M22, offsetMatrix.M32, offsetMatrix.M42, * offsetMatrix.M13, offsetMatrix.M23, offsetMatrix.M33, offsetMatrix.M43, * offsetMatrix.M14, offsetMatrix.M24, offsetMatrix.M34, offsetMatrix.M44 ); */ aiBone.OffsetMatrix = Assimp.Matrix4x4.Identity; aiMesh.Bones.Add(aiBone); } var material = geometry.Materials[mesh.MaterialIndex]; var aiMaterial = new Assimp.Material(); if (material.IsTextured) { // TextureDiffuse var texture = material.TextureReferenceNode; aiMaterial.TextureDiffuse = new Assimp.TextureSlot( texture.Name + ".png", Assimp.TextureType.Diffuse, 0, Assimp.TextureMapping.FromUV, 0, 0, Assimp.TextureOperation.Add, Assimp.TextureWrapMode.Wrap, Assimp.TextureWrapMode.Wrap, 0); } // Name aiMaterial.Name = material.Name ?? $"Geometry{atomic.GeometryIndex}_Material{mesh.MaterialIndex}"; if (material.IsTextured && material.Name == null) { aiMaterial.Name = material.TextureReferenceNode.Name; } aiMaterial.ShadingMode = Assimp.ShadingMode.Phong; // Add mesh to meshes aiScene.Meshes.Add(aiMesh); // Add material to materials aiScene.Materials.Add(aiMaterial); // MaterialIndex aiMesh.MaterialIndex = aiScene.Materials.Count - 1; // Add mesh index to node aiNode.MeshIndices.Add(aiScene.Meshes.Count - 1); } } return(aiScene); }