Пример #1
0
        // TODO: could probably figure out "inverse" from direction of topY compared to bottomY
        public static Vector3[] GetConeFrustumVertices(CSGCircleDefinition definition, float topHeight, float rotation, int segments, ref Vector3[] vertices, bool inverse = false)
        {
            var rotate      = Quaternion.AngleAxis(rotation, Vector3.up);
            var bottomAxisX = rotate * Vector3.right * definition.diameterX * 0.5f;
            var bottomAxisZ = rotate * Vector3.forward * definition.diameterZ * 0.5f;
            var topY        = Vector3.up * topHeight;
            var bottomY     = Vector3.up * definition.height;

            if (vertices == null ||
                vertices.Length != segments + 1)
            {
                vertices = new Vector3[segments + 1];
            }

            float angleOffset = ((segments & 1) == 1) ? 0.0f : ((360.0f / segments) * 0.5f);

            vertices[0] = topY;
            for (int v = 0; v < segments; v++)
            {
                var r = (((v * 360.0f) / (float)segments) + angleOffset) * Mathf.Deg2Rad;
                var s = Mathf.Sin(r);
                var c = Mathf.Cos(r);

                var bottomVertex = (bottomAxisX * c) + (bottomAxisZ * s);
                bottomVertex += bottomY;
                var vi = inverse ? (segments - v) : (v + 1);
                vertices[vi] = bottomVertex;
            }

            return(vertices);
        }
Пример #2
0
        public static bool GenerateCylinderSubMesh(CSGBrushSubMesh subMesh, CSGCircleDefinition bottom, float topHeight, float rotation, int sides, CSGSurfaceAsset[] surfaceAssets, SurfaceDescription[] surfaceDescriptions)
        {
            CSGCircleDefinition top;

            top.diameterX = bottom.diameterX;
            top.diameterZ = bottom.diameterZ;
            top.height    = topHeight;
            return(GenerateConicalFrustumSubMesh(subMesh, bottom, top, rotation, sides, surfaceAssets, surfaceDescriptions));
        }
Пример #3
0
        public static bool GenerateConeAsset(CSGBrushMeshAsset brushMeshAsset, CSGCircleDefinition bottom, float topHeight, float rotation, int sides, CSGSurfaceAsset[] surfaceAssets, SurfaceDescription[] surfaceDescriptions)
        {
            CSGCircleDefinition top;

            top.diameterX = 0;
            top.diameterZ = 0;
            top.height    = topHeight;
            return(GenerateConicalFrustumAsset(brushMeshAsset, bottom, top, rotation, sides, surfaceAssets, surfaceDescriptions));
        }
Пример #4
0
        public static bool GenerateConicalFrustumSubMesh(CSGBrushSubMesh subMesh, CSGCircleDefinition bottom, CSGCircleDefinition top, float rotation, int segments, CSGSurfaceAsset[] surfaceAssets, SurfaceDescription[] surfaceDescriptions)
        {
            if (segments < 3 || (top.height - bottom.height) == 0 || (bottom.diameterX == 0 && top.diameterX == 0) || (bottom.diameterZ == 0 && top.diameterZ == 0))
            {
                subMesh.Clear();
                return(false);
            }

            if (surfaceAssets.Length < 3 ||
                surfaceDescriptions.Length < segments + 2)
            {
                subMesh.Clear();
                return(false);
            }
            // TODO: handle situation where diameterX & diameterZ are 0 (only create one vertex)

            if (top.diameterX == 0)
            {
                var vertices = new Vector3[segments + 1];
                GetConeFrustumVertices(bottom, top.height, rotation, segments, ref vertices, inverse: false);

                // TODO: the polygon/half-edge part would be the same for any extruded shape and should be re-used
                CreateConeSubMesh(subMesh, segments, null, vertices, surfaceAssets, surfaceDescriptions);
            }
            else
            if (bottom.diameterX == 0)
            {
                var vertices = new Vector3[segments + 1];
                GetConeFrustumVertices(top, bottom.height, rotation, segments, ref vertices, inverse: true);

                // TODO: the polygon/half-edge part would be the same for any extruded shape and should be re-used
                CreateConeSubMesh(subMesh, segments, null, vertices, surfaceAssets, surfaceDescriptions);
            }
            else
            {
                if (top.height > bottom.height)
                {
                    var temp = top; top = bottom; bottom = temp;
                }

                var vertices = new Vector3[segments * 2];
                GetConicalFrustumVertices(bottom, top, rotation, segments, ref vertices);

                // TODO: the polygon/half-edge part would be the same for any extruded shape and should be re-used
                CreateExtrudedSubMesh(subMesh, segments, null, 0, 1, vertices, surfaceAssets, surfaceDescriptions);
            }

            return(true);
        }
Пример #5
0
        public static Vector3[] GetConicalFrustumVertices(CSGCircleDefinition bottom, CSGCircleDefinition top, float rotation, int segments, ref Vector3[] vertices)
        {
            if (top.height > bottom.height)
            {
                var temp = top; top = bottom; bottom = temp;
            }

            var rotate      = Quaternion.AngleAxis(rotation, Vector3.up);
            var topAxisX    = rotate * Vector3.right * top.diameterX * 0.5f;
            var topAxisZ    = rotate * Vector3.forward * top.diameterZ * 0.5f;
            var bottomAxisX = rotate * Vector3.right * bottom.diameterX * 0.5f;
            var bottomAxisZ = rotate * Vector3.forward * bottom.diameterZ * 0.5f;
            var topY        = Vector3.up * top.height;
            var bottomY     = Vector3.up * bottom.height;

            // TODO: handle situation where diameterX & diameterZ are 0 (only create one vertex)

            if (vertices == null ||
                vertices.Length != segments * 2)
            {
                vertices = new Vector3[segments * 2];
            }

            float angleOffset = ((segments & 1) == 1) ? 0.0f : ((360.0f / segments) * 0.5f);

            for (int v = 0; v < segments; v++)
            {
                var r = (((v * 360.0f) / (float)segments) + angleOffset) * Mathf.Deg2Rad;
                var s = Mathf.Sin(r);
                var c = Mathf.Cos(r);

                var topVertex    = (topAxisX * c) + (topAxisZ * s);
                var bottomVertex = (bottomAxisX * c) + (bottomAxisZ * s);
                topVertex             += topY;
                bottomVertex          += bottomY;
                vertices[v]            = topVertex;
                vertices[v + segments] = bottomVertex;
            }

            return(vertices);
        }
Пример #6
0
        public static bool GenerateConicalFrustumAsset(CSGBrushMeshAsset brushMeshAsset, CSGCircleDefinition bottom, CSGCircleDefinition top, float rotation, int segments, CSGSurfaceAsset[] surfaceAssets, SurfaceDescription[] surfaceDescriptions)
        {
            if (segments < 3 || (top.height - bottom.height) == 0 || (bottom.diameterX == 0 && top.diameterX == 0) || (bottom.diameterZ == 0 && top.diameterZ == 0))
            {
                brushMeshAsset.Clear();
                return(false);
            }

            if (surfaceAssets.Length != 3 ||
                surfaceDescriptions.Length != segments + 2)
            {
                brushMeshAsset.Clear();
                return(false);
            }

            var subMesh = new CSGBrushSubMesh();

            if (!GenerateConicalFrustumSubMesh(subMesh, bottom, top, rotation, segments, surfaceAssets, surfaceDescriptions))
            {
                brushMeshAsset.Clear();
                return(false);
            }

            brushMeshAsset.SubMeshes = new CSGBrushSubMesh[] { subMesh };
            brushMeshAsset.CalculatePlanes();
            brushMeshAsset.SetDirty();
            return(true);
        }