void RekursiveDraw(Assimp.Node node, OpenGlDevice Device) { if ((node.HasMeshes)) { foreach (var index in node.MeshIndices) { D3DMesh mesh = (Meshes[index] as D3DMesh); xyzf b = new xyzf(0, 0, 0); CpuSkinningEvaluator.CachedMeshData MD = SkinninEvaluator.GetEntry(mesh); SkinninEvaluator.GetTransformedVertexPosition(node, mesh, 0, out b); if (mesh.Material.Translucent < 1) { TransparentMeshes.Add(new TransParencyItem(mesh, MD._cachedPositions, MD._cachedNormals)); continue; } xyzf[] SavePos = mesh.Position; xyzf[] SaveNormals = mesh.Normals; mesh.Position = MD._cachedPositions; mesh.Normals = MD._cachedNormals; mesh.Paint(Device); mesh.Position = SavePos; mesh.Normals = SaveNormals; } } for (int i = 0; i < node.Children.Count; i++) { RekursiveDraw(node.Children[i], Device); } }
Box RekursiveGetBox(Assimp.Node node, Box BoxMin) { Box _Box = BoxMin; if ((node.HasMeshes)) { foreach (var index in node.MeshIndices) { D3DMesh mesh = (Meshes[index] as D3DMesh); xyzf b = new xyzf(0, 0, 0); CpuSkinningEvaluator.CachedMeshData MD = SkinninEvaluator.GetEntry(mesh); SkinninEvaluator.GetTransformedVertexPosition(node, mesh, 0, out b); xyzf[] P = new xyzf[MD._cachedPositions.Length]; for (int i = 0; i < P.Length; i++) { P[i] = mesh.Transformation * MD._cachedPositions[i]; } _Box = Box.GetEnvBox(P, _Box); } } for (int i = 0; i < node.Children.Count; i++) { _Box = RekursiveGetBox(node.Children[i], _Box); } return(_Box); }
public CachedMeshData(Scene scene, D3DMesh source) { _scene = scene; _source = source; _cachedPositions = new xyzf[source.Position.Length]; _cachedNormals = new xyzf[source.Position.Length]; _boneMap = new BoneByVertexMap(source); }
/// <summary> /// Get the cache entry corresponding to a mesh. /// /// Creates an entry if it does not exist yet. /// </summary> /// <param name="mesh"></param> /// <returns></returns> public CachedMeshData GetEntry(D3DMesh mesh) { CachedMeshData entry; if (_cache.TryGetValue(mesh, out entry) && entry.CompatibleWith(mesh)) { return(entry); } return(_cache[mesh] = new CachedMeshData(_owner, mesh)); }
/// <summary> /// Constructs a CpuSkinningEvaluator for a given scene. /// </summary> /// <param name="owner"></param> public CpuSkinningEvaluator(Scene owner) { _owner = owner; _cache = new Dictionary <D3DMesh, CachedMeshData>(); // for (var i = 0; i < owner.Raw.Meshes.Count; ++i) for (var i = 0; i < owner.Children.Count; ++i) { D3DMesh mesh = owner.Children[i] as D3DMesh; if (!mesh.HasBones) { continue; } _cache[mesh] = new CachedMeshData(owner, mesh); } }
/// <summary> /// Obtain the bone matrices for a given node mesh index at the /// current time. Calling this is costly, redundant invocations /// should thus be avoided. /// </summary> /// <param name="node">Node for which to query bone matrices</param> /// <param name="mesh">Mesh for which to query bone matrices. Must be /// one of the meshes attached to the node.</param> /// <returns>For each bone of the mesh the bone transformation /// matrix. The returned array is only valid for the rest of /// the frame or till the next call to GetBoneMatricesForMesh(). /// It may contain more entries than the mesh has bones, the extra entries /// should be ignored in this case.</returns> public Matrix[] GetBoneMatricesForMesh(Node node, D3DMesh mesh) { // calculate the mesh's inverse global transform Matrix globalInverseMeshTransform; GetGlobalTransform(node, out globalInverseMeshTransform); globalInverseMeshTransform = globalInverseMeshTransform.invert(); // Bone matrices transform from mesh coordinates in bind pose to mesh coordinates in skinned pose // Therefore the formula is offsetMatrix * currentGlobalTransform * inverseCurrentMeshTransform for (int a = 0; a < mesh.Bones.Count; ++a) { var bone = mesh.Bones[a]; Matrix currentGlobalTransform; GetGlobalTransform(bone.Name, out currentGlobalTransform); _boneMatrices[a] = globalInverseMeshTransform * currentGlobalTransform * bone.OffsetMatrix; // TODO for some reason, all OpenTk matrices need a ^T - clarify our conventions somewhere // _boneMatrices[a].Transpose(); } return(_boneMatrices); }
internal BoneByVertexMap(D3DMesh mesh) { Debug.Assert(mesh != null); _mesh = mesh; _offsets = new uint[mesh.Position.Length]; _countBones = new uint[mesh.Position.Length]; if (_mesh.Bones.Count == 0) { _bonesByVertex = new IndexWeightTuple[0]; return; } // get per-vertex bone influence counts var countWeights = 0; for (var i = 0; i < mesh.Bones.Count; ++i) { var bone = mesh.Bones[i]; countWeights += bone.VertexWeightCount; for (int j = 0; j < bone.VertexWeightCount; ++j) { var weight = bone.VertexWeights[j]; ++_countBones[weight.VertexID]; } } _bonesByVertex = new IndexWeightTuple[countWeights]; // generate offset table uint sum = 0; for (var i = 0; i < _mesh.Position.Length; ++i) { _offsets[i] = sum; sum += _countBones[i]; } // populate vertex-to-bone table, using the offset table // to keep track of how many bones have already been // written for a vertex. for (var i = 0; i < mesh.Bones.Count; ++i) { var bone = mesh.Bones[i]; countWeights += bone.VertexWeightCount; for (int j = 0; j < bone.VertexWeightCount; ++j) { var weight = bone.VertexWeights[j]; BonesByVertex[_offsets[weight.VertexID]++] = new IndexWeightTuple(i, weight.Weight); } } // undo previous changes to the offset table for (var i = 0; i < _mesh.Position.Length; ++i) { _offsets[i] -= _countBones[i]; } Debug.Assert(_offsets[0] == 0); }
public TransParencyItem(D3DMesh Mesh, xyzf[] Position, xyzf[] Normals) { this.Mesh = Mesh; this.Position = Position; this.Normals = Normals; }
/// <summary> /// Get a transformed vertex normal for a given mesh + vertex index. The /// results of this method are cached between calls in the same frame. /// </summary> /// <param name="node">Node that holds the mesh</param> /// <param name="meshIndex"></param> /// <param name="vertexIndex"></param> /// <param name="nor"></param> public void GetTransformedVertexNormal(Node node, D3DMesh mesh, uint vertexIndex, out xyzf nor) { GetEntry(mesh).GetTransformedVertexNormal(node, vertexIndex, out nor); }
/// <summary> /// Get a transformed vertex position for a given mesh + vertex index. The /// results of this method are cached between calls in the same frame. /// </summary> /// <param name="node">Node that holds the mesh</param> /// <param name="meshIndex"></param> /// <param name="vertexIndex"></param> /// <param name="pos"></param> public void GetTransformedVertexPosition(Node node, D3DMesh mesh, uint vertexIndex, out xyzf pos) { GetEntry(mesh).GetTransformedVertexPosition(node, vertexIndex, out pos); }
/// <summary> /// internal. /// </summary> internal static Scene ConvertFromAssimp(Assimp.Scene _Scene) { Scene Result = new Scene(); LoadTextures(_Scene); Result.CompileEnable = false; for (int i = 0; i < _Scene.Meshes.Count; i++) { D3DMesh _M = new D3DMesh(); _M.CompileEnable = false; Assimp.Mesh M = _Scene.Meshes[i]; List <int> _Indices = new List <int>(M.Faces.Count * 4); if (M.Faces.Count > 0) { for (int j = 0; j < M.Faces.Count; j++) { if (M.Faces[j].Indices.Count > 4) { _Indices.Add(M.Faces[j].Indices[0]); _Indices.Add(M.Faces[j].Indices[1]); _Indices.Add(M.Faces[j].Indices[4]); _Indices.Add(M.Faces[j].Indices[4]); _Indices.Add(M.Faces[j].Indices[1]); _Indices.Add(M.Faces[j].Indices[2]); _Indices.Add(M.Faces[j].Indices[4]); _Indices.Add(M.Faces[j].Indices[2]); _Indices.Add(M.Faces[j].Indices[3]); } else if (M.Faces[j].Indices.Count > 3) { _Indices.Add(M.Faces[j].Indices[0]); _Indices.Add(M.Faces[j].Indices[1]); _Indices.Add(M.Faces[j].Indices[3]); _Indices.Add(M.Faces[j].Indices[3]); _Indices.Add(M.Faces[j].Indices[1]); _Indices.Add(M.Faces[j].Indices[2]); } else { _Indices.Add(M.Faces[j].Indices[0]); _Indices.Add(M.Faces[j].Indices[1]); _Indices.Add(M.Faces[j].Indices[2]); } } _M.Indices = _Indices.ToArray(); } Result.Meshes.Add(_M); //----------------Indices-------------------- int[] Indices = M.GetIndices(); _M.Material = AssimpConv.ConvertMaterial(_Scene.Materials[M.MaterialIndex]); _M.Texture = LoadTexture(_Scene.Materials[M.MaterialIndex]); List <Vector3D> Vertices = M.Vertices; _M.Position = new xyzf[Vertices.Count]; for (int j = 0; j < Vertices.Count; j++) { Vector3D V = Vertices[j]; _M.Position[j] = new xyzf(V.X, V.Y, V.Z); } List <Vector3D> Normals = M.Normals; _M.Normals = new xyzf[Normals.Count]; for (int j = 0; j < Normals.Count; j++) { Vector3D V = Normals[j]; _M.Normals[j] = new xyzf(V.X, V.Y, V.Z).normalized(); } if (M.TextureCoordinateChannelCount > 0) { _M.TextureCoords = new xyf[M.TextureCoordinateChannels[0].Count]; for (int j = 0; j < M.TextureCoordinateChannels[0].Count; j++) { Vector3D V = M.TextureCoordinateChannels[0][j]; _M.TextureCoords[j] = new xyf(V.X, V.Y); } } _M.Bones = new List <Bone>(); for (int k = 0; k < M.BoneCount; k++) { Assimp.Bone B = M.Bones[k]; VertexWeight[] VW = new VertexWeight[B.VertexWeights.Count]; for (int g = 0; g < VW.Length; g++) { VW[g] = new VertexWeight(B.VertexWeights[g].VertexID, B.VertexWeights[g].Weight); } Bone _B = new Bone(B.Name, AssimpConv.ConvertTransform(B.OffsetMatrix), VW); _M.Bones.Add(_B); } } LoadNode(_Scene, Result); MoveTranslucentAtEnd(Result); Result._Scene = _Scene; Result.SceneAnimator = new SceneAnimator(Result); return(Result); }