public override void Draw(RenderContext context) { // Clear previous model groups foreach (var modelGroup in ModelGroups) { modelGroup.Clear(); } ModelGroups.Clear(); var groupMaskUsed = EntityGroupMask.None; // Collect models for this frame, and dispatch them to list of group foreach (var matchingEntity in enabledEntities) { var item = matchingEntity.Value; var renderModel = item.RenderModel; // Skip disabled model components, or model components without a proper model set if (!renderModel.Update()) { continue; } // Add the render model to the specified collection group var groupIndex = (int)matchingEntity.Key.Group; groupMaskUsed |= (EntityGroupMask)(1 << groupIndex); var modelCollection = allModelGroups[groupIndex]; modelCollection.Add(renderModel); Vector3 scale, translation; Matrix rotation; bool isScalingNegative = false; if (item.TransformComponent.WorldMatrix.Decompose(out scale, out rotation, out translation)) { isScalingNegative = scale.X * scale.Y * scale.Z < 0.0f; } item.ModelComponent.Update(ref item.TransformComponent.WorldMatrix, isScalingNegative); if (item.Links != null) { var modelViewHierarchy = item.ModelComponent.ModelViewHierarchy; // Update links: transfer node/bone transformation to a specific entity transformation // Then update this entity transformation tree // TODO: Ideally, we should order update (matchingEntities?) to avoid updating a ModelViewHierarchy before its transformation is updated. foreach (var link in item.Links) { var linkTransformation = link.Entity.Transform; Matrix linkedLocalMatrix; TransformComponent.CreateMatrixTRS(ref linkTransformation.Position, ref linkTransformation.Rotation, ref linkTransformation.Scale, out linkedLocalMatrix); Matrix.Multiply(ref linkedLocalMatrix, ref modelViewHierarchy.NodeTransformations[link.NodeIndex].WorldMatrix, out linkTransformation.LocalMatrix); linkTransformationToUpdate.Clear(); linkTransformationToUpdate.Add(linkTransformation); TransformProcessor.UpdateTransformations(linkTransformationToUpdate, false); } } } // Collect model groups for (int groupIndex = 0, groupMask = (int)groupMaskUsed; groupMask != 0; groupMask = groupMask >> 1, groupIndex++) { if ((groupMask & 1) == 0) { continue; } var modelGroup = allModelGroups[groupIndex]; ModelGroups.Add(modelGroup); } }
public override void Draw(RenderContext context) { // Clear previous model groups foreach (var modelGroup in ModelGroups) { modelGroup.Clear(); } ModelGroups.Clear(); var groupMaskUsed = EntityGroupMask.None; // Collect models for this frame, and dispatch them to list of group foreach (var matchingEntity in enabledEntities) { var renderModel = matchingEntity.Value; // Skip disabled model components, or model components without a proper model set if (!renderModel.ModelComponent.Enabled || renderModel.ModelComponent.ModelViewHierarchy == null || renderModel.ModelComponent.Model == null) { continue; } // Update the group in case it changed renderModel.Update(); // Add the render model to the specified collection group var groupIndex = (int)renderModel.Group; groupMaskUsed |= (EntityGroupMask)(1 << groupIndex); var modelCollection = allModelGroups[groupIndex]; modelCollection.Add(renderModel); var modelComponent = renderModel.ModelComponent; var modelViewHierarchy = renderModel.ModelComponent.ModelViewHierarchy; var transformationComponent = renderModel.TransformComponent; var links = renderModel.Links; modelComponent.Update(ref transformationComponent.WorldMatrix); if (links != null) { // Update links: transfer node/bone transformation to a specific entity transformation // Then update this entity transformation tree // TODO: Ideally, we should order update (matchingEntities?) to avoid updating a ModelViewHierarchy before its transformation is updated. foreach (var link in renderModel.Links) { var linkTransformation = link.Entity.Transform; Matrix linkedLocalMatrix; TransformComponent.CreateMatrixTRS(ref linkTransformation.Position, ref linkTransformation.Rotation, ref linkTransformation.Scale, out linkedLocalMatrix); Matrix.Multiply(ref linkedLocalMatrix, ref modelViewHierarchy.NodeTransformations[link.NodeIndex].WorldMatrix, out linkTransformation.LocalMatrix); linkTransformationToUpdate.Clear(); linkTransformationToUpdate.Add(linkTransformation); TransformProcessor.UpdateTransformations(linkTransformationToUpdate, false); } } // TODO: World update and skinning is now perform at ModelComponentRenderer time. Check if we can find a better place to do this. //// Upload matrices to TransformationKeys.World //modelViewHierarchy.UpdateToRenderModel(renderModel); //// Upload skinning blend matrices //MeshSkinningUpdater.Update(modelViewHierarchy, renderModel); } // Collect model groups for (int groupIndex = 0, groupMask = (int)groupMaskUsed; groupMask != 0; groupMask = groupMask >> 1, groupIndex++) { if ((groupMask & 1) == 0) { continue; } var modelGroup = allModelGroups[groupIndex]; ModelGroups.Add(modelGroup); } }