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);
            }
        }
Exemple #2
0
        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);
            }
        }