コード例 #1
0
        internal static void GenerateSurfaceRenderBuffers(int brushNodeID, LoopList loopList)
        {
            var output        = CSGManager.GetBrushOutput(brushNodeID);
            var brushInstance = CSGManager.GetBrushMeshID(brushNodeID);
            var mesh          = BrushMeshManager.GetBrushMesh(brushInstance);
            var meshPolygons  = mesh.polygons;
            var meshSurfaces  = mesh.surfaces;

            Matrix4x4 worldToLocal = Matrix4x4.identity;

            CSGManager.GetTreeToNodeSpaceMatrix(brushNodeID, out worldToLocal);

            var outputSurfaces     = new CSGSurfaceRenderBuffer[loopList.loops.Count]; // TODO: should be same size as brush.surfaces.Length
            int outputSurfaceCount = 0;

            foreach (var loop in loopList.loops)
            {
                var polygonIndex = loop.basePlaneIndex;       // TODO: fix this
                var meshPolygon  = meshPolygons[polygonIndex];

                var surfaceIndex = meshPolygon.surfaceID;       // TODO: fix this

                var localSpaceToPlaneSpace = MathExtensions.GenerateLocalToPlaneSpaceMatrix(meshSurfaces[surfaceIndex].plane);
                var uv0Matrix = meshPolygon.description.UV0.ToMatrix() * (localSpaceToPlaneSpace * worldToLocal);

                // TODO: all separate loops on same surface should be put in same OutputSurfaceMesh
                if (!loop.Triangulate(uv0Matrix, ref outputSurfaces[outputSurfaceCount]))
                {
                    continue;
                }

                // TODO: make this work
//				outputSurfaces[outputSurfaceCount].meshQuery		= loop.layers; //???
//				outputSurfaces[outputSurfaceCount].surfaceParameter = loop.surfaceParameter; //???
                outputSurfaces[outputSurfaceCount].surfaceIndex = surfaceIndex;
                outputSurfaceCount++;
            }
            if (outputSurfaceCount != loopList.loops.Count)
            {
                Array.Resize(ref outputSurfaces, outputSurfaceCount);
            }
            output.renderBuffers.surfaceRenderBuffers.AddRange(outputSurfaces);
        }
コード例 #2
0
        // TODO: not really CSG yet .. just a hack
        // TODO: move somewhere else
        internal static LoopList PerformCSG(int brushNodeID, bool mode)
        {
            var brushNodeIndex = brushNodeID - 1;
            var output         = CSGManager.GetBrushOutput(brushNodeID);
            var outputLoops    = output.brushOutputLoops;
            var brushInstance  = CSGManager.GetBrushMeshID(brushNodeID);
            var surfaceLoops   = (outputLoops.intersectionLoops == null || outputLoops.intersectionLoops.Count == 0) ? null : outputLoops.intersectionLoops.Values.First();  // temp. Hack

            // TODO: get rid of needing mesh here
            var mesh         = BrushMeshManager.GetBrushMesh(brushInstance);
            var meshPolygons = mesh.polygons;
            var meshSurfaces = mesh.surfaces;


            var loopList = new LoopList(); // TODO: get rid of this somehow

            // TODO: separate base loops with holes
            //          need a seperate set of holes per intersecting brush
            for (int p = 0; p < meshPolygons.Length; p++)
            {
                // TODO: get rid of needing mesh here
                var meshPolygon  = meshPolygons[p];
                var surfaceIndex = meshPolygon.surfaceID;


                // Add all holes that share the same plane to the polygon
                var holeLoops = (surfaceLoops == null) ? (List <Loop>)null : surfaceLoops.surfaces[surfaceIndex];
                // Add all holes that share the same plane to the polygon
                if (mode)
                {
                    var loop = outputLoops.basePolygons[p]; // TODO: need to copy this
                    loopList.loops.Add(loop);
                    if (holeLoops != null)
                    {
                        for (int l = holeLoops.Count - 1; l >= 0; l--)
                        {
                            //if (holeLoops[l].basePlaneIndex != loop.basePlaneIndex)
                            //	continue;

                            // Cut polygons with its holes if they overlap
                            if (loopList.RemoveFrom(loop, holeLoops[l]))
                            {
                                holeLoops.RemoveAt(l);
                                //	lookHierarchies.Add(holeLoops[l]);
                                continue;
                            }
                            //loop.holes.Add(holeLoops[l]);
                        }
                        loop.holes.AddRange(holeLoops);
                    }
                }
                else
                {
                    if (holeLoops != null)
                    {
                        foreach (var hole in holeLoops)
                        {
                            hole.interiorCategory = Category.ReverseAligned;
                            loopList.loops.Add(hole);
                        }
                    }
                }
            }
            return(loopList);
        }
コード例 #3
0
        internal static bool UpdateTreeMesh(int treeNodeID)
        {
            if (!IsValidNodeID(treeNodeID) || !AssertNodeType(treeNodeID, CSGNodeType.Tree))
            {
                return(false);
            }

            // TODO: optimize, only do this when necessary
            for (int i = 0; i < brushes.Count; i++)
            {
                var brushNodeID                  = brushes[i];
                var brushNodeIndex               = brushNodeID - 1;
                var parentNodeID                 = nodeHierarchies[brushNodeIndex].parentNodeID;
                var parentNodeIndex              = parentNodeID - 1;
                var parentLocalTransformation    = (parentNodeIndex < 0) ? Matrix4x4.identity : nodeLocalTransforms[parentNodeIndex].localTransformation;
                var parentLocalInvTransformation = (parentNodeIndex < 0) ? Matrix4x4.identity : nodeLocalTransforms[parentNodeIndex].invLocalTransformation;

                // TODO: should be transformations the way up to the tree, not just tree vs brush
                var brushLocalTransformation    = nodeLocalTransforms[brushNodeIndex].localTransformation;
                var brushLocalInvTransformation = nodeLocalTransforms[brushNodeIndex].invLocalTransformation;

                var nodeTransform = nodeTransforms[brushNodeIndex];
                nodeTransform.nodeToTree       = brushLocalTransformation * parentLocalInvTransformation;
                nodeTransform.treeToNode       = parentLocalTransformation * brushLocalInvTransformation;
                nodeTransforms[brushNodeIndex] = nodeTransform;
            }

            // TODO: find intersecting brushes

            // TODO: build categorization tree



            // check if we even have a valid brushMesh

            // TODO: update all renderbuffers for all brushes

            /*
             * var brushMesh = BrushMeshManager.GetBrushMesh(brushOutput.brushMeshInstanceID);
             * if (brushMesh == null)
             *  continue;
             * {
             *  renderBuffers = new CSGBrushRenderBuffer();
             *  if (!brushOutput.triangleMesh.UpdateRenderBuffer(nodeIndex,
             *                                               brushMesh,
             *                                               renderBuffers,
             *                                               meshQueries.Length, meshQueries, vertexChannelMask))
             *      continue;
             *  brushOutput.renderBuffers = renderBuffers;
             * }
             */

            // FIXME: surfaceIndex == planeIndex == polygonIndex

            for (int b = 0; b < CSGManager.brushes.Count; b++)
            {
                var brushNodeID = CSGManager.brushes[b];
                var output      = CSGManager.GetBrushOutput(brushNodeID);
                var outputLoops = output.brushOutputLoops;
                outputLoops.brush = new CSGTreeBrush()
                {
                    brushNodeID = brushNodeID
                };
                outputLoops.GenerateBasePolygons();
            }

            for (int b0 = 0; b0 < CSGManager.brushes.Count; b0++)
            {
                var brush0NodeID = CSGManager.brushes[b0];
                var output       = CSGManager.GetBrushOutput(brush0NodeID);
                var outputLoops  = output.brushOutputLoops;

                // FIXME: for now assume that all brushes touch all brushes, fix this
                for (int b1 = 0; b1 < CSGManager.brushes.Count; b1++)
                {
                    if (b0 == b1)
                    {
                        continue;
                    }

                    var brush1NodeID = CSGManager.brushes[b1];
                    // TODO: only when they actually touch & need updating
                    // TODO: ensure intersections between brushes are the same on all intersecting brushes
                    outputLoops.GenerateIntersectionLoops(new CSGTreeBrush()
                    {
                        brushNodeID = brush1NodeID
                    });
                }
            }

            // TODO: Cache the output surface meshes, only update when necessary
            for (int b = 0; b < CSGManager.brushes.Count; b++)
            {
                // TODO: Be able to perform actual csg on brushes
                var brushNodeID = CSGManager.brushes[b];
                var loopList    = PerformCSG(brushNodeID, (b & 1) == 0);
                GenerateSurfaceRenderBuffers(brushNodeID, loopList);
            }
            return(true);
        }