예제 #1
0
        public static Dictionary <int, Vector4> MaterialColorLookup(this VimScene scene)
        {
            var r = scene.Model.MaterialList.ToEnumerable().ToDictionary(m => m.Id, GetDiffuseColor);

            r.Add(-1, DefaultColor);
            return(r);
        }
예제 #2
0
 public VimSceneNode(VimScene scene, SerializableSceneNode source, int index, Matrix4x4 transform)
 {
     _Scene = scene;
     _Source = source;
     Id = index;
     Transform = transform;
     GeometryIndex = source.Geometry;
     geometry = scene.Geometries.ElementAtOrDefault(GeometryIndex);
 }
예제 #3
0
        private static void CollectVimSceneNodesFromLocalSpaceGeometry(
            VimScene scene,
            IReadOnlyList <Tree <SerializableSceneNode> > flattenedTreeNodes,
            IEnumerable <Tree <SerializableSceneNode> > treeNodesToProcess,
            Matrix4x4 parentBasis,
            List <VimSceneNode> result)
        {
            // For each instance, check if the source node has children. If so, expand those children locally.
            foreach (var treeNode in treeNodesToProcess)
            {
                var node = treeNode.Value;
                if (node.Instance >= 0)
                {
                    var sourceTreeNode = flattenedTreeNodes[node.Instance];
                    var sourceNode     = sourceTreeNode.Value;
                    var instanceBasis  = node.Transform * parentBasis;

                    // Add the source node world space info.
                    result.Add(new VimSceneNode(scene, node, result.Count, instanceBasis));

                    // Expand the source node's children (if any) into the local basis.
                    if (sourceTreeNode.Children.Count > 0)
                    {
                        var descendents = sourceTreeNode.AllNodes().Where(tn => tn != sourceTreeNode);

                        // Invert the source node's basis to transform that node hierarchy to the origin, then transform it to the instance basis.
                        if (Matrix4x4.Invert(sourceNode.Transform, out var sourceNodeInverse))
                        {
                            var instanceChildrenBasis = sourceNodeInverse * instanceBasis;
                            CollectVimSceneNodesFromLocalSpaceGeometry(scene, flattenedTreeNodes, descendents, instanceChildrenBasis, result);
                        }
                        else
                        {
                            Debug.WriteLine("Failed to invert node");
                        }
                    }
                }
                else
                {
                    result.Add(new VimSceneNode(scene, node, result.Count, node.Transform * parentBasis));
                }
            }
        }
예제 #4
0
        private static void CollectVimSceneNodesFromWorldSpaceGeometry(
            VimScene scene,
            IReadOnlyList <Tree <SerializableSceneNode> > flattenedTreeNodes,
            IEnumerable <Tree <SerializableSceneNode> > treeNodesToProcess,
            Matrix4x4 parentBasis,
            List <VimSceneNode> result)
        {
            // For each instance, check if the source node has children. If so, expand those children locally.
            foreach (var treeNode in treeNodesToProcess)
            {
                var node = treeNode.Value;
                if (node.Instance >= 0)
                {
                    var sourceTreeNode = flattenedTreeNodes[node.Instance];
                    var sourceNode     = sourceTreeNode.Value;

                    // Can't proceed unless the source node transform can be inverted.
                    if (!Matrix4x4.Invert(sourceNode.Transform, out var sourceNodeInverse))
                    {
                        continue;
                    }

                    var localBasis = sourceNodeInverse * node.Transform * parentBasis;

                    // Add the source node world space info.
                    result.Add(new VimSceneNode(scene, node, result.Count, localBasis));

                    // Expand the source node's children, if any.
                    if (sourceTreeNode.Children.Count > 0)
                    {
                        var descendents = sourceTreeNode.AllNodes().Where(tn => tn != sourceTreeNode);
                        CollectVimSceneNodesFromWorldSpaceGeometry(scene, flattenedTreeNodes, descendents, localBasis, result);
                    }
                }
                else
                {
                    // Non-instances are presumed to have their geometry baked in world space.
                    result.Add(new VimSceneNode(scene, node, result.Count, parentBasis));
                }
            }
        }
예제 #5
0
        // TODO: TECH DEBT - A DUPLICATE OF SerializableSceneNodeExtensions >> GetExpandedGeometryIdsAndTransforms
        public static List <VimSceneNode> GetExpandedVimSceneNodes(
            VimScene scene,
            IReadOnlyList <SerializableSceneNode> nodes,
            ExpansionMode expansionMode)
        {
            // Start with a flat collection of tree nodes.
            var treeNodes = nodes.Select(n => new Tree <SerializableSceneNode> {
                Value = n
            }).ToArray();

            // Establish the parent/child hierarchy.
            foreach (var treeNode in treeNodes)
            {
                var parentIndex = treeNode.Value.Parent;
                if (parentIndex < 0 || parentIndex >= treeNodes.Length)
                {
                    continue;
                }

                treeNodes[parentIndex].AddChild(treeNode);
            }

            var result = new List <VimSceneNode>();

            switch (expansionMode)
            {
            case ExpansionMode.WorldSpaceGeometry:
                // DEPRECATED: This is a legacy stopgap to allow support for objectmodel version 2.
                // objectmodel version 3 and onward expects local space geometry.
                CollectVimSceneNodesFromWorldSpaceGeometry(scene, treeNodes, treeNodes, Matrix4x4.Identity, result);
                break;

            case ExpansionMode.LocalGeometry:
                CollectVimSceneNodesFromLocalSpaceGeometry(scene, treeNodes, treeNodes, Matrix4x4.Identity, result);
                break;
            }

            return(result);
        }
예제 #6
0
 public static IArray <Vector4> CalculateVertexColors(this VimScene scene, IMesh m)
 => m.FaceDataToVertexData(scene.FaceColors(m));
예제 #7
0
        public static IArray <Vector4> FaceColors(this VimScene scene, IMesh m)
        {
            var colorLookup = scene.MaterialColorLookup();

            return(m.FaceMaterialIds.Select(mId => colorLookup.GetOrDefault(mId, DefaultColor)));
        }