private static void BoundingBoxIgnoreWorld(InstancingData instancingData, IInstancing instancing, ModelComponent.MeshInfo meshInfo, Mesh mesh) { // We need to remove the world transformation component if (instancingData.ModelComponent.Skeleton != null) { var ibb = instancing.BoundingBox; var mbb = new BoundingBoxExt(meshInfo.BoundingBox); Matrix.Invert(ref instancingData.ModelComponent.Skeleton.NodeTransformations[0].LocalMatrix, out var invWorld);
/// <summary> /// Draws all the dwarves /// </summary> /// <param name="view"></param> /// <param name="projection"></param> public void Draw(Matrix view, Matrix projection) { this.RefreshMeshCounts(new BoundingFrustum(view * projection)); this.visibleInstances = 0; // Reset the current index of each instance, so we know where to put instance data for (int i = 0; i < this.meshInstances.Count; i++) { this.meshInstances[i].currentIndex = 0; } for (int i = 0; i < this.numInstances; i++) { Dwarf dwarf = dwarves[i]; if (dwarf.IsVisible) { this.visibleInstances++; // Get the current index each part is at int currentBodyIndex = this.meshInstances[dwarf.BodyPart].currentIndex; this.meshInstances[dwarf.BodyPart].currentIndex++; int currentHeadIndex = this.meshInstances[dwarf.HeadPart].currentIndex; this.meshInstances[dwarf.HeadPart].currentIndex++; int currentLegIndex = this.meshInstances[dwarf.LegPart].currentIndex; this.meshInstances[dwarf.LegPart].currentIndex++; // Assign transform data this.meshInstances[dwarf.BodyPart].transforms[currentBodyIndex] = dwarf.Transform; this.meshInstances[dwarf.HeadPart].transforms[currentHeadIndex] = dwarf.Transform; this.meshInstances[dwarf.LegPart].transforms[currentLegIndex] = dwarf.Transform; // Assign animation data this.meshInstances[dwarf.BodyPart].animations[currentBodyIndex] = dwarf.AnimationFrame; this.meshInstances[dwarf.HeadPart].animations[currentHeadIndex] = dwarf.AnimationFrame; this.meshInstances[dwarf.LegPart].animations[currentLegIndex] = dwarf.AnimationFrame; } } // Now that we have our data, do the actual drawing! for (int i = 0; i < this.meshInstances.Count; i++) { InstancingData instance = this.meshInstances[i]; if (instance.currentIndex > 0) { this.dwarfModel.Meshes[i].Draw(instance.transforms, instance.animations, view, projection); } } }
private void UpdateInstancing(InstancingComponent instancingComponent, InstancingData instancingData) { if (instancingComponent.Enabled && instancingComponent.Type != null) { var instancing = instancingComponent.Type; // Calculate inverse world and bounding box instancing.Update(); if (instancingData.ModelComponent != null && instancing.InstanceCount > 0) { // Bounding box var meshCount = instancingData.ModelComponent.MeshInfos.Count; for (int i = 0; i < meshCount; i++) { var mesh = instancingData.ModelComponent.Model.Meshes[i]; var meshInfo = instancingData.ModelComponent.MeshInfos[i]; // This must reflect the transformations in the shaders // This is currently not entirely correct, it ignores cases with extreme scalings switch (instancing.ModelTransformUsage) { case ModelTransformUsage.Ignore: BoundingBoxIgnoreWorld(instancingData, instancing, meshInfo, mesh); break; case ModelTransformUsage.PreMultiply: BoundingBoxPreMultiplyWorld(instancingData, instancing, meshInfo, mesh); break; case ModelTransformUsage.PostMultiply: BoundingBoxPostMultiplyWorld(instancingData, instancing, meshInfo, mesh); break; default: break; } } } } }