public BvhShapeDefinition(AssimpMesh mesh) { this.vertices = new Vector3[mesh.VerticesCount]; this.indices = mesh.Indices.ToArray(); Vector3* v = (Vector3*)mesh.Positions(); for (int i = 0; i < mesh.VerticesCount; i++) { this.vertices[i] = v[i]; } }
private void WriteMesh(AssimpMesh mesh, int slice) { this.position[slice].SliceCount = mesh.VerticesCount; fixed (Vector3* vptr = &this.position[slice].Stream.Buffer[0]) { memcpy(new IntPtr(vptr), mesh.PositionPointer, mesh.VerticesCount * 12); } if (mesh.HasNormals) { this.normals[slice].SliceCount = mesh.VerticesCount; fixed (Vector3* nptr = &this.normals[slice].Stream.Buffer[0]) { memcpy(new IntPtr(nptr), mesh.NormalsPointer, mesh.VerticesCount * 12); } } else { this.normals[slice].SliceCount = 0; } if (mesh.UvChannelCount > 0) { int chancnt = this.GetChannelCount(mesh, 0); this.uv1[slice].SliceCount = mesh.VerticesCount * chancnt; this.uvchancount[slice] = chancnt; fixed (float* uptr = &this.uv1[slice].Stream.Buffer[0]) { memcpy(new IntPtr(uptr), mesh.GetUvPointer(0), mesh.VerticesCount * 4 * chancnt); } } else { this.uv1[slice].SliceCount = 0; this.uvchancount[slice] = 0; } this.indices[slice].SliceCount = mesh.Indices.Count; var inds = mesh.Indices; var ibo = this.indices[slice].Stream.Buffer; for (int i = 0; i < mesh.Indices.Count; i++) { ibo[i] = inds[i]; } }
private int GetChannelCount(AssimpMesh mesh, int slot) { var fmt = mesh.GetInputElements().Where(ie => ie.SemanticName == "TEXCOORD" && ie.SemanticIndex == slot).First(); switch(fmt.Format) { case SlimDX.DXGI.Format.R32_Float: return 1; case SlimDX.DXGI.Format.R32G32_Float: return 2; case SlimDX.DXGI.Format.R32G32B32_Float: return 3; case SlimDX.DXGI.Format.R32G32B32A32_Float: return 4; default : return 0; } }
private void AppendMesh(AssimpNode node, AssimpMesh mesh) { List<int> inds = mesh.Indices; if (inds.Count > 0 && mesh.VerticesCount > 0) { for (int idx = 0; idx < inds.Count; idx++) { inds[idx] += vertexoffset; } indexbuffer.AddRange(inds); //vp.AddRange(mesh.v) vertexoffset += mesh.VerticesCount; this.currentid++; } }
public void Update(IPluginIO pin, DX11RenderContext context) { if (this.FInvalidate || this.FEmpty) { for (int i = 0; i < this.scenes.Count; i++) { if (scenes[i] != null) { AssimpScene scene = scenes[i]; for (int j = 0; j < scene.MeshCount; j++) { AssimpMesh assimpmesh = scene.Meshes[j]; List <int> inds = assimpmesh.Indices; if (inds.Count > 0 && assimpmesh.VerticesCount > 0) { var indexstream = new DataStream(inds.Count * 4, true, true); indexstream.WriteRange(inds.ToArray()); indexstream.Position = 0; DX11IndexOnlyGeometry geom = new DX11IndexOnlyGeometry(context); geom.IndexBuffer = new DX11IndexBuffer(context, indexstream, false, true); geom.InputLayout = assimpmesh.GetInputElements().ToArray(); geom.Topology = PrimitiveTopology.TriangleList; geom.HasBoundingBox = true; geom.BoundingBox = assimpmesh.BoundingBox; DX11DynamicStructuredBuffer <Vector3> p = new DX11DynamicStructuredBuffer <Vector3>(context, assimpmesh.PositionPointer, assimpmesh.VerticesCount); DX11DynamicStructuredBuffer <Vector3> n = new DX11DynamicStructuredBuffer <Vector3>(context, assimpmesh.NormalsPointer, assimpmesh.VerticesCount); if (assimpmesh.UvChannelCount > 0) { DX11DynamicStructuredBuffer <Vector3> u = new DX11DynamicStructuredBuffer <Vector3>(context, assimpmesh.GetUvPointer(0), assimpmesh.VerticesCount); this.FOutUvs[i][j][context] = u; } DX11RawBuffer rb = new DX11RawBuffer(context, geom.IndexBuffer.Buffer); this.FOutPosition[i][j][context] = p; this.FOutNormals[i][j][context] = n; this.FOutGeom[i][j][context] = geom; this.FOutIndices[i][j][context] = rb; } } } } this.FInvalidate = false; this.FEmpty = false; } }
private static void ReadMesh(string path, string filename, string texturepath) { string importingAssetsDir; if (File.Exists(path + "/" + filename)) { var flags = ( // Assimp.PostProcessSteps.MakeLeftHanded | Assimp.PostProcessSteps.Triangulate | Assimp.PostProcessSteps.CalculateTangentSpace | Assimp.PostProcessSteps.GenerateUVCoords | Assimp.PostProcessSteps.GenerateSmoothNormals | Assimp.PostProcessSteps.RemoveComponent | Assimp.PostProcessSteps.JoinIdenticalVertices ); var config = Assimp.aiCreatePropertyStore(); Assimp.aiSetImportPropertyFloat(config, Assimp.AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE, 60.0f); Assimp.aiSetImportPropertyInteger(config, Assimp.AI_CONFIG_PP_LBW_MAX_WEIGHTS, 4); // IntPtr scene = Assimp.aiImportFile(path + "/" + filename, (uint)flags); var scene = Assimp.aiImportFileWithProperties(path + "/" + filename, (uint)flags, config); Assimp.aiReleasePropertyStore(config); if (scene == null) { Debug.LogWarning("failed to read file: " + path + "/" + filename); return; } else { var nm = Path.GetFileNameWithoutExtension(filename); importingAssetsDir = "Assets/Prefabs/" + nm + "/"; if (_SaveAssets) { if (!Directory.Exists(importingAssetsDir)) { Directory.CreateDirectory(importingAssetsDir); } AssetDatabase.Refresh(); } var objectRoot = new GameObject(nm); var meshContainer = new GameObject(nm + "_Mesh"); meshContainer.transform.parent = objectRoot.transform; // List<CombineInstance> combineInstances = new List<CombineInstance>(); var materials = new List <Material>(); var meshList = new List <AssimpMesh>(); for (var i = 0; i < Assimp.aiScene_GetNumMaterials(scene); i++) { var matName = Assimp.aiMaterial_GetName(scene, i); matName = nm + "_mat" + i; // string fname = Path.GetFileNameWithoutExtension(Assimp.aiMaterial_GetTexture(scene, i, (int)Assimp.TextureType.Diffuse)); var fname = Path.GetFileName(Assimp.aiMaterial_GetTexture(scene, i, (int)Assimp.TextureType.Diffuse)); Debug.Log("texture " + fname + "Material :" + matName); var ambient = Assimp.aiMaterial_GetAmbient(scene, i); var diffuse = Assimp.aiMaterial_GetDiffuse(scene, i); var specular = Assimp.aiMaterial_GetSpecular(scene, i); var emissive = Assimp.aiMaterial_GetEmissive(scene, i); var mat = new Material(Shader.Find("Diffuse")); mat.name = matName; mat.color = diffuse; // Debug.Log(ambient.ToString()); // Debug.Log(diffuse.ToString()); // Debug.Log(specular.ToString()); // Debug.Log(emissive.ToString()); var texturename = path + "/" + fname; var tex = Utils.LoadTex(texturename); if (tex != null) { Debug.Log("LOAD (" + texturename + ") texture"); mat.SetTexture("_MainTex", tex); } else { Debug.LogError("Fail LOAD (" + texturename + ") error"); } if (_SaveAssets) { var materialAssetPath = AssetDatabase.GenerateUniqueAssetPath(importingAssetsDir + mat.name + ".asset"); AssetDatabase.CreateAsset(mat, materialAssetPath); } materials.Add(mat); } AssetDatabase.Refresh(); if (Assimp.aiScene_GetRootNode(scene) != null) { objectRoot.transform.position = Assimp.aiNode_GetPosition(Assimp.aiScene_GetRootNode(scene)); //assimp quaternion is w,x,y,z and unity x,y,z,w bu int this lib i fix this for unity var assQuad = Assimp.aiNode_GetRotation(Assimp.aiScene_GetRootNode(scene)); objectRoot.transform.rotation = assQuad; var skeleton = new GameObject("Skeleton"); skeleton.transform.parent = objectRoot.transform; ProcessNodes(scene, Assimp.aiScene_GetRootNode(scene), ref _list_joints); for (var i = 0; i < _list_joints.Count; i++) { var joint = _list_joints[i]; var bone = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform; // bone.transform.localScale.Set(2,2,2); // Transform bone = new GameObject(joint.Name).transform; // DebugBone debug = (DebugBone)bone.gameObject.AddComponent(typeof(DebugBone)); bone.name = joint._Name; bone.parent = skeleton.transform; if (GetBoneByName(joint._ParentName) != null) { var index = FindBoneByName(joint._ParentName); bone.parent = joint._Parent._Transform; } bone.localPosition = joint._Position; bone.localRotation = joint._Orientation; joint._Transform = bone; } } if (Assimp.aiScene_HasMeshes(scene)) { for (var i = 0; i < Assimp.aiScene_GetNumMeshes(scene); i++) { var name = "Mesh_"; name += i.ToString(); var hasNormals = Assimp.aiMesh_HasNormals(scene, i); var hasTexCoord = Assimp.aiMesh_HasTextureCoords(scene, i, 0); var hasFaces = Assimp.aiMesh_HasFaces(scene, i); var mesh = new AssimpMesh(meshContainer, objectRoot, name); mesh.Setmaterial(materials[Assimp.aiMesh_GetMaterialIndex(scene, i)]); meshList.Add(mesh); for (var v = 0; v < Assimp.aiMesh_GetNumVertices(scene, i); v++) { var vertex = Assimp.aiMesh_Vertex(scene, i, v); var n = Assimp.aiMesh_Normal(scene, i, v); var x = Assimp.aiMesh_TextureCoordX(scene, i, v, 0); var y = Assimp.aiMesh_TextureCoordY(scene, i, v, 0); var binormalf = Assimp.aiMesh_Bitangent(scene, i, v); var tangentf = Assimp.aiMesh_Tangent(scene, i, v); var outputTangent = new Vector4(tangentf.x, tangentf.y, tangentf.z, 0.0F); var dp = Vector3.Dot(Vector3.Cross(n, tangentf), binormalf); if (dp > 0.0F) { outputTangent.w = 1.0F; } else { outputTangent.w = -1.0F; } mesh.AddVertex(vertex, n, outputTangent, new Vector2(x, y)); } for (var f = 0; f < Assimp.aiMesh_GetNumFaces(scene, i); f++) { var a = Assimp.aiMesh_Indice(scene, i, f, 0); var b = Assimp.aiMesh_Indice(scene, i, f, 1); var c = Assimp.aiMesh_Indice(scene, i, f, 2); mesh.AddFace(a, b, c); } //**** var numBone = Assimp.aiMesh_GetNumBones(scene, i); for (var b = 0; b < numBone; b++) { var bname = Assimp.aiMesh_GetBoneName(scene, i, b); var joint = GetBoneByName(bname); var boneId = FindBoneByName(bname); var numWeights = Assimp.aiMesh_GetNumBoneWeights(scene, i, b); for (var w = 0; w < numWeights; w++) { var weight = Assimp.aiMesh_GetBoneWeight(scene, i, b, w); var vertexId = Assimp.aiMesh_GetBoneVertexId(scene, i, b, w); mesh.AddBone(vertexId, boneId, weight); } } for (var j = 0; j < _list_joints.Count; j++) { var joint = _list_joints[j]; mesh.AddJoint(joint); } //********** mesh.BuilSkin(); mesh.Build(); if (_SaveAssets) { var meshAssetPath = AssetDatabase.GenerateUniqueAssetPath(importingAssetsDir + mesh._Name + ".asset"); AssetDatabase.CreateAsset(mesh._Geometry, meshAssetPath); } mesh.Dispose(); } } //create key frames if (Assimp.aiScene_HasAnimation(scene)) { var anim = (Animation)objectRoot.AddComponent(typeof(Animation)); var numAnimation = Assimp.aiScene_GetNumAnimations(scene); Debug.Log("count animation :" + numAnimation); for (var a = 0; a < numAnimation; a++) { var clip = new AnimationClip(); var anima = Assimp.aiAnim_GetName(scene, a); clip.name = nm + "_" + anima + "_" + a; clip.legacy = true; clip.wrapMode = WrapMode.Loop; var tinks = (float)Assimp.aiAnim_GetTicksPerSecond(scene, a); if (tinks <= 1f) { tinks = 1f; } var fps = tinks; clip.frameRate = tinks; Debug.Log("animation fps :" + fps); var numchannels = Assimp.aiAnim_GetNumChannels(scene, a); for (var i = 0; i < numchannels; i++) { var name = Assimp.aiAnim_GetChannelName(scene, a, i); var joint = GetBoneByName(name); // Debug.Log(String.Format("anim channel {0} bone name {1} poskeys {2} rotkeys{2}", i, name, Assimp.aiAnim_GetNumPositionKeys(scene, 0, i), Assimp.aiAnim_GetNumRotationKeys(scene, 0, i))); //public static bool ignoreRotations = true; // public static bool ignorePositions = true; // public static bool ignoreScalling = true; if (!_IgnoreScalling) { if (Assimp.aiAnim_GetNumScalingKeys(scene, a, i) != 0) { var scaleXcurve = new AnimationCurve(); var scaleYcurve = new AnimationCurve(); var scaleZcurve = new AnimationCurve(); for (var j = 0; j < Assimp.aiAnim_GetNumScalingKeys(scene, a, i); j++) { var time = (float)Assimp.aiAnim_GetScalingFrame(scene, a, i, j);// / fps; var scale = Assimp.aiAnim_GetScalingKey(scene, a, i, j); scaleXcurve.AddKey(time, scale.x); scaleYcurve.AddKey(time, scale.y); scaleZcurve.AddKey(time, scale.z); } clip.SetCurve("Skeleton/" + joint._Path, typeof(Transform), "m_LocalScale.x", scaleXcurve); clip.SetCurve("Skeleton/" + joint._Path, typeof(Transform), "m_LocalScale.y", scaleYcurve); clip.SetCurve("Skeleton/" + joint._Path, typeof(Transform), "m_LocalScale.z", scaleZcurve); } } if (!_IgnorePositions) { if (Assimp.aiAnim_GetNumPositionKeys(scene, a, i) != 0) { var posXcurve = new AnimationCurve(); var posYcurve = new AnimationCurve(); var posZcurve = new AnimationCurve(); for (var j = 0; j < Assimp.aiAnim_GetNumPositionKeys(scene, a, i); j++) { var time = (float)Assimp.aiAnim_GetPositionFrame(scene, a, i, j);// / fps; var pos = Assimp.aiAnim_GetPositionKey(scene, a, i, j); posXcurve.AddKey(time, pos.x); posYcurve.AddKey(time, pos.y); posZcurve.AddKey(time, pos.z); } clip.SetCurve("Skeleton/" + joint._Path, typeof(Transform), "localPosition.x", posXcurve); clip.SetCurve("Skeleton/" + joint._Path, typeof(Transform), "localPosition.y", posYcurve); clip.SetCurve("Skeleton/" + joint._Path, typeof(Transform), "localPosition.z", posZcurve); } } if (!_IgnoreRotations) { if (Assimp.aiAnim_GetNumRotationKeys(scene, a, i) != 0) { var rotXcurve = new AnimationCurve(); var rotYcurve = new AnimationCurve(); var rotZcurve = new AnimationCurve(); var rotWcurve = new AnimationCurve(); for (var j = 0; j < Assimp.aiAnim_GetNumRotationKeys(scene, a, i); j++) { var time = (float)Assimp.aiAnim_GetRotationFrame(scene, a, i, j);// / fps; var rotation = Assimp.aiAnim_GetRotationKey(scene, a, i, j); rotXcurve.AddKey(time, rotation.x); rotYcurve.AddKey(time, rotation.y); rotZcurve.AddKey(time, rotation.z); rotWcurve.AddKey(time, rotation.w); } clip.SetCurve("Skeleton/" + joint._Path, typeof(Transform), "localRotation.x", rotXcurve); clip.SetCurve("Skeleton/" + joint._Path, typeof(Transform), "localRotation.y", rotYcurve); clip.SetCurve("Skeleton/" + joint._Path, typeof(Transform), "localRotation.z", rotZcurve); clip.SetCurve("Skeleton/" + joint._Path, typeof(Transform), "localRotation.w", rotWcurve); } } } clip.EnsureQuaternionContinuity(); anim.AddClip(clip, clip.name); anim.clip = clip; var clipAssetPath = AssetDatabase.GenerateUniqueAssetPath(importingAssetsDir + clip.name + ".asset"); AssetDatabase.CreateAsset(clip, clipAssetPath); // AssetDatabase.CreateAsset(clip, "Assets/Models/" + nm +"_"+a+ ".anim"); // AssetDatabase.SaveAssets(); } } if (_SaveAssets) { var prefabPath = AssetDatabase.GenerateUniqueAssetPath(importingAssetsDir + filename + ".prefab"); var prefab = PrefabUtility.CreateEmptyPrefab(prefabPath); PrefabUtility.ReplacePrefab(objectRoot, prefab, ReplacePrefabOptions.ConnectToPrefab); AssetDatabase.Refresh(); } meshList.Clear(); } _list_joints.Clear(); Assimp.aiReleaseImport(scene); Debug.LogWarning(path + "/" + filename + " Imported ;) "); } }
public void Update(DX11RenderContext context) { if (this.FInvalidate || !this.FOutGeom[0].Contains(context)) { int vertexoffset = 0; List <Pos3Norm3Tex2InstanceVertex> vertices = new List <Pos3Norm3Tex2InstanceVertex>(); List <int> indices = new List <int>(); List <Vector2> uvs = new List <Vector2>(); int cnt = this.FinUseName[0] ? idsort.Count : this.FInScene[0].MeshCount; for (int i = 0; i < cnt; i++) { AssimpMesh assimpmesh = this.FinUseName[0] == false ? this.FInScene[0].Meshes[i] : this.FInScene[0].Meshes[idsort[i]]; List <int> inds = assimpmesh.Indices; if (inds.Count > 0 && assimpmesh.VerticesCount > 0) { var texcd = assimpmesh.GetInputElements().Where(ie => ie.SemanticName == "TEXCOORD").FirstOrDefault(); bool zuv = false; if (texcd != null) { zuv = texcd.Format == SlimDX.DXGI.Format.R32G32B32_Float; } for (int j = 0; j < inds.Count; j++) { indices.Add(inds[j] + vertexoffset); } DataStream posbuffer = new DataStream(assimpmesh.PositionPointer, assimpmesh.VerticesCount * 12, true, true); DataStream normbuffer = new DataStream(assimpmesh.NormalsPointer, assimpmesh.VerticesCount * 12, true, true); DataStream uvbuffer = null; List <DataStream> uvbuffers = new List <DataStream>(); List <int> uvcounters = new List <int>(); for (int uvc = 0; uvc < assimpmesh.UvChannelCount; uvc++) { uvbuffers.Add(new DataStream(assimpmesh.GetUvPointer(uvc), assimpmesh.VerticesCount * 12, true, true)); uvcounters.Add(this.GetUVChannelCount(assimpmesh, uvc)); } if (assimpmesh.UvChannelCount > 0) { uvbuffer = new DataStream(assimpmesh.GetUvPointer(0), assimpmesh.VerticesCount * 12, true, true); } Vector3 *pos = (Vector3 *)posbuffer.DataPointer.ToPointer(); Vector3 accum = Vector3.Zero; for (int j = 0; j < assimpmesh.VerticesCount; j++) { accum += pos[j]; } Vector3 center = accum / assimpmesh.VerticesCount; for (int j = 0; j < assimpmesh.VerticesCount; j++) { Pos3Norm3Tex2InstanceVertex vert = new Pos3Norm3Tex2InstanceVertex() { InstanceID = i, Normals = normbuffer.Read <Vector3>(), Position = posbuffer.Read <Vector3>(), Center = center, TexCoords = uvbuffer != null?uvbuffer.Read <Vector2>() : Vector2.Zero }; vertices.Add(vert); for (int k = 0; k < assimpmesh.UvChannelCount; k++) { var b = uvbuffers[k]; uvs.Add(b.Read <Vector2>()); if (uvcounters[k] == 3) { b.Read <float>(); } } if (uvbuffer != null && zuv) { uvbuffer.Read <float>(); } } vertexoffset += assimpmesh.VerticesCount; } } DataStream vS = new DataStream(vertices.ToArray(), true, true); vS.Position = 0; DataStream iS = new DataStream(indices.ToArray(), true, true); iS.Position = 0; var vbuffer = new SlimDX.Direct3D11.Buffer(context.Device, vS, new BufferDescription() { BindFlags = BindFlags.VertexBuffer, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None, SizeInBytes = (int)vS.Length, Usage = ResourceUsage.Default }); DX11IndexedGeometry geom = new DX11IndexedGeometry(context); geom.VertexBuffer = vbuffer; geom.IndexBuffer = new DX11IndexBuffer(context, iS, true, false); geom.InputLayout = Pos3Norm3Tex2InstanceVertex.Layout; geom.Topology = PrimitiveTopology.TriangleList; geom.VerticesCount = vertices.Count; geom.VertexSize = Pos3Norm3Tex2InstanceVertex.VertexSize; geom.HasBoundingBox = false; vS.Position = 0; DataStream uvS = new DataStream(uvs.ToArray(), true, true); uvS.Position = 0; this.FOutGeom[0][context] = geom; this.FOutBuffer[0][context] = new DX11ImmutableStructuredBuffer(context.Device, geom.VerticesCount, geom.VertexSize, vS); this.FOutIndices[0][context] = new DX11RawBuffer(context, geom.IndexBuffer.Buffer); this.FOutUVBuffer[0][context] = new DX11ImmutableStructuredBuffer(context.Device, uvs.Count, 8, uvS); this.FInvalidate = false; } }
private int GetUVChannelCount(AssimpMesh assimpmesh, int slot) { var texcd = assimpmesh.GetInputElements().Where(ie => ie.SemanticName == "TEXCOORD" && ie.SemanticIndex == slot).FirstOrDefault(); int cnt = 2; if (texcd != null) { if (texcd.Format == SlimDX.DXGI.Format.R32G32B32_Float) { cnt = 3; } } return cnt; }