示例#1
0
文件: Cone.cs 项目: jfeng94/Thesis
        /// <summary>
        /// re/generate mesh geometry based on parameters
        /// </summary>
        /// <param name="radius0">fist radius of cone</param>
        /// <param name="radius1">second radius of cone</param>
        /// <param name="height">height of cone</param>
        /// <param name="sides">number of triangle segments in radius</param>
        /// <param name="heightSegments">number of triangle segments in height</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        /// <returns>Cone class with Cone game object</returns>
        public void GenerateGeometry(float radius0, float radius1, float thickness, float height, int sides, int heightSegments, NormalsType normalsType, PivotPosition pivotPosition)
        {
            // generate new mesh and clear old one
            var meshFilter = GetComponent<MeshFilter>();

            if (meshFilter.sharedMesh == null)
            {
                meshFilter.sharedMesh = new Mesh();
            }

            var mesh = meshFilter.sharedMesh;

            // generate geometry
            if (thickness >= 0)
            {
                GenerationTimeMS = Primitives.HollowConePrimitive.GenerateGeometry(mesh, radius0, radius1, thickness, height, sides, heightSegments, normalsType, pivotPosition);
            }
            else
            {
                GenerationTimeMS = Primitives.ConePrimitive.GenerateGeometry(mesh, radius0, radius1, height, sides, heightSegments, normalsType, pivotPosition);
            }

            this.radius0 = radius0;
            this.radius1 = radius1;
            this.height = height;
            this.thickness = thickness;
            this.sides = sides;
            this.heightSegments = heightSegments;
            this.normalsType = normalsType;
            this.flipNormals = false;
            this.pivotPosition = pivotPosition;
        }
示例#2
0
        /// <summary>
        /// re/generate mesh geometry based on parameters
        /// </summary>
        /// <param name="radius0">fist radius of tube</param>
        /// <param name="radius1">second radius of tube</param>
        /// <param name="torusSegments">number of triangle of torusKnot</param>
        /// <param name="coneSegments">number of triangle of torusKnot cone</param>
        /// <param name="P">knot parameter</param>
        /// <param name="Q">knot parameter</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public void GenerateGeometry(float radius0, float radius1, int torusSegments, int coneSegments, int P, int Q, NormalsType normalsType, PivotPosition pivotPosition)
        {
            // generate new mesh and clear old one
            var meshFilter = GetComponent<MeshFilter>();

            if (meshFilter.sharedMesh == null)
            {
                meshFilter.sharedMesh = new Mesh();
            }

            var mesh = meshFilter.sharedMesh;

            // generate geometry
            GenerationTimeMS = Primitives.TorusKnotPrimitive.GenerateGeometry(mesh, radius0, radius1, torusSegments, coneSegments, P, Q, normalsType, pivotPosition);

            this.radius0 = radius0;
            this.radius1 = radius1;
            this.torusSegments = torusSegments;
            this.coneSegments = coneSegments;
            this.P = P;
            this.Q = Q;
            this.normalsType = normalsType;
            this.flipNormals = false;
            this.pivotPosition = pivotPosition;
        }
示例#3
0
        /// <summary>
        /// craete combo box with normals type values
        /// </summary>
        /// <param name="value">value of normals type</param>
        /// <returns>true if value has been changed</returns>
        public static bool NormalsType(ref NormalsType value)
        {
            var oldNormalsType = value;

            EditorGUILayout.BeginHorizontal();
            value = (NormalsType)EditorGUILayout.EnumPopup("Normals type", value);
            EditorGUILayout.EndHorizontal();
            return(oldNormalsType != value);
        }
示例#4
0
    /// <summary>
    /// Creates the geometry.
    /// </summary>
    protected void CreateGeometry(float radius0, float radius1, float thickness, float height, int sides, 
	                              int heightSegments, NormalsType normalsType, PivotPosition pivotPosition)
    {
        // Clear the old mesh and generate a new one.
        var meshFilter = GetComponent<MeshFilter>();
        if (meshFilter.sharedMesh == null)
        {
            meshFilter.sharedMesh = new Mesh();
        }
        var mesh = meshFilter.sharedMesh;
        _meshGenerationTime = ShapesFactory.CreateDiamond(mesh, radius0, radius1, height, sides, heightSegments, normalsType, pivotPosition);
    }
示例#5
0
        /// <summary>
        /// create TorusKnot game object
        /// </summary>
        /// <param name="radius0">first radius of tube</param>
        /// <param name="radius1">second radius of tube</param>
        /// <param name="torusSegments">number of triangle segments of torusKnot</param>
        /// <param name="coneSegments">number of triangle segments or torusKnot cone</param>
        /// <returns>TorusKnot class with TorusKnot game object</returns>
        /// <param name="P">knot parameter</param>
        /// <param name="Q">knot parameter</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public static TorusKnot Create(float radius0, float radius1, int torusSegments, int coneSegments, int P, int Q, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var cylinderObject = new GameObject("TorusKnotPro");

            cylinderObject.AddComponent<MeshFilter>();
            var renderer = cylinderObject.AddComponent<MeshRenderer>();

            renderer.sharedMaterial = new Material(Shader.Find("Diffuse"));

            var torusKnot = cylinderObject.AddComponent<TorusKnot>();
            torusKnot.GenerateGeometry(radius0, radius1, torusSegments, coneSegments, P, Q, normalsType, pivotPosition);

            return torusKnot;
        }
示例#6
0
        /// <summary>
        /// create RoundedCube game object
        /// </summary>
        /// <param name="width">width of the cube</param>
        /// <param name="height">height of the cube</param>
        /// <param name="length">length of the cube</param>
        /// <param name="segments">number of segments</param>
        /// <param name="roundness">roudness coefficient</param>
        /// <param name="normals">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        /// <returns>RoundedCube class with RoundedCube game object</returns>
        public static RoundedCube Create(float width, float height, float length, int segments, float roundness, NormalsType normals, PivotPosition pivotPosition)
        {
            var sphereObject = new GameObject("RoundedCubePro");

            sphereObject.AddComponent<MeshFilter>();
            var renderer = sphereObject.AddComponent<MeshRenderer>();

            renderer.sharedMaterial = new Material(Shader.Find("Diffuse"));

            var superellipsoid = sphereObject.AddComponent<RoundedCube>();
            superellipsoid.GenerateGeometry(width, height, length, segments, roundness, normals, pivotPosition);

            return superellipsoid;
        }
示例#7
0
文件: Tube.cs 项目: pisipo/CTB
        /// <summary>
        /// create Tube game object
        /// </summary>
        /// <param name="radius0">first radius of tube</param>
        /// <param name="radius1">second radius of tube</param>
        /// <param name="height">height of tube</param>
        /// <param name="sides">number of triangle segments in radius direction</param>
        /// <param name="heightSegments">number of triangle segments in height direction</param>
        /// <returns>Tube class with Tube game object</returns>
        /// <param name="slice">slicing parameter</param>
        /// <param name="radialMapping">using radial uv mapping on the top/bottom of the tube</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public static Tube Create(float radius0, float radius1, float height, int sides, int heightSegments, float slice, bool radialMapping, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var cylinderObject = new GameObject("TubePro");

            cylinderObject.AddComponent<MeshFilter>();
            var renderer = cylinderObject.AddComponent<MeshRenderer>();

            renderer.sharedMaterial = new Material(Shader.Find("Diffuse"));

            var tube = cylinderObject.AddComponent<Tube>();
            tube.GenerateGeometry(radius0, radius1, height, sides, heightSegments, slice, radialMapping, normalsType, pivotPosition);

            return tube;
        }
示例#8
0
        /// <summary>
        /// create GeoSphere game object
        /// </summary>
        /// <param name="radius">radius of sphere</param>
        /// <param name="subdivision">number of subdivision</param>
        /// <param name="baseType">type of generation primitive</param>
        /// <param name="normals">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        /// <returns>GeoSphere class with GeoSphere game object</returns>
        public static GeoSphere Create(float radius, int subdivision, Primitives.GeoSpherePrimitive.BaseType baseType, NormalsType normals, PivotPosition pivotPosition)
        {
            var sphereObject = new GameObject("GeoSpherePro");

            sphereObject.AddComponent<MeshFilter>();
            var renderer = sphereObject.AddComponent<MeshRenderer>();

            renderer.sharedMaterial = new Material(Shader.Find("Diffuse"));

            var sphere = sphereObject.AddComponent<GeoSphere>();
            sphere.GenerateGeometry(radius, subdivision, baseType, normals, pivotPosition);

            return sphere;
        }
示例#9
0
文件: Sphere.cs 项目: jaroosh/Habitat
        /// <summary>
        /// create Sphere game object
        /// </summary>
        /// <param name="radius">radius of sphere</param>
        /// <param name="segments">number of segments</param>
        /// <param name="hemisphere">hemisphere, 0 ... complete sphere, 0.5 ... half-sphere</param>
        /// <param name="normals">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        /// <param name="innerRadius">radius of the inner sphere</param>
        /// <param name="slice">vertical slice parameter</param>
        /// <returns>Sphere class with Sphere game object</returns>
        public static Sphere Create(float radius, int segments, float hemisphere, float innerRadius, float slice, NormalsType normals, PivotPosition pivotPosition)
        {
            var sphereObject = new GameObject("SpherePro");

            sphereObject.AddComponent<MeshFilter>();
            var renderer = sphereObject.AddComponent<MeshRenderer>();

            renderer.sharedMaterial = new Material(Shader.Find("Diffuse"));

            var sphere = sphereObject.AddComponent<Sphere>();
            sphere.GenerateGeometry(radius, segments, hemisphere, innerRadius, slice, normals, pivotPosition);

            return sphere;
        }
示例#10
0
        /// <summary>
        /// create SuperEllipsoid game object
        /// </summary>
        /// <param name="width">width of the cube</param>
        /// <param name="height">height of the cube</param>
        /// <param name="length">length of the cube</param>
        /// <param name="segments">number of segments</param>
        /// <param name="normals">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        /// <param name="n1">first parameter</param>
        /// <param name="n2">second parameter</param>
        /// <returns>SuperEllipsoid class with SuperEllipsoid game object</returns>
        public static SuperEllipsoid Create(float width, float height, float length, int segments, float n1, float n2, NormalsType normals, PivotPosition pivotPosition)
        {
            var sphereObject = new GameObject("SuperEllipsoidPro");

            sphereObject.AddComponent<MeshFilter>();
            var renderer = sphereObject.AddComponent<MeshRenderer>();

            renderer.sharedMaterial = new Material(Shader.Find("Diffuse"));

            var roundedCube = sphereObject.AddComponent<SuperEllipsoid>();
            roundedCube.GenerateGeometry(width, height, length, segments, n1, n2, normals, pivotPosition);

            return roundedCube;
        }
示例#11
0
文件: Cone.cs 项目: jfeng94/Thesis
        /// <summary>
        /// create Cone game object
        /// </summary>
        /// <param name="radius0">first radius of cone</param>
        /// <param name="radius1">second radius of cone</param>
        /// <param name="thickness">thickness</param>
        /// <param name="height">height of cone</param>
        /// <param name="sides">number of triangle segments in radius direction</param>
        /// <param name="heightSegments">number of triangle segments in height direction</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        /// <returns>Cone class with Cone game object</returns>
        public static Cone Create(float radius0, float radius1, float thickness, float height, int sides, int heightSegments, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var cylinderObject = new GameObject("ConePro");

            cylinderObject.AddComponent<MeshFilter>();
            var renderer = cylinderObject.AddComponent<MeshRenderer>();

            renderer.sharedMaterial = new Material(Shader.Find("Diffuse"));

            var cone = cylinderObject.AddComponent<Cone>();
            cone.GenerateGeometry(radius0, radius1, thickness, height, sides, heightSegments, normalsType, pivotPosition);

            return cone;
        }
示例#12
0
        /// <summary>
        /// create Capsule game object
        /// </summary>
        /// <param name="radius">radius of capsule</param>
        /// <param name="sides">number of segments</param>
        /// <param name="heightSegments">number of segments of central cylinder</param>
        /// <param name="normals">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        /// <returns>Capsule class with Capsule game object</returns>
        public static Capsule Create(float radius, float height, int sides, int heightSegments, bool preserveHeight, NormalsType normals, PivotPosition pivotPosition)
        {
            var capsuleObject = new GameObject("CapsulePro");

            capsuleObject.AddComponent<MeshFilter>();
            var renderer = capsuleObject.AddComponent<MeshRenderer>();

            renderer.sharedMaterial = new Material(Shader.Find("Diffuse"));

            var capsule = capsuleObject.AddComponent<Capsule>();
            capsule.GenerateGeometry(radius, height, sides, heightSegments, preserveHeight, normals, pivotPosition);

            return capsule;
        }
示例#13
0
文件: Cylinder.cs 项目: pisipo/CTB
        /// <summary>
        /// create Cylinder game object
        /// </summary>
        /// <param name="radius">radius of cylinder</param>
        /// <param name="height">height of cylinder</param>
        /// <param name="sides">number of triangle segments in radius direction</param>
        /// <param name="heightSegments">number of triangle segments in height direction</param>
        /// <returns>Cylinder class with Cylinder game object</returns>
        /// <param name="pivotPosition">position of the model pivot</param>
        /// <param name="normals">type of normals to be generated</param>
        public static Cylinder Create(float radius, float height, int sides, int heightSegments, NormalsType normals, PivotPosition pivotPosition)
        {
            var cylinderObject = new GameObject("CylinderPro");

            cylinderObject.AddComponent<MeshFilter>();
            var renderer = cylinderObject.AddComponent<MeshRenderer>();

            renderer.sharedMaterial = new Material(Shader.Find("Diffuse"));

            var cylinder = cylinderObject.AddComponent<Cylinder>();
            cylinder.GenerateGeometry(radius, height, sides, heightSegments, normals, pivotPosition);

            return cylinder;
        }
示例#14
0
        // Token: 0x06004254 RID: 16980 RVA: 0x001510E0 File Offset: 0x0014F4E0
        public void GenerateGeometry(float radius, int segments, float coneAngle, NormalsType normalsType, PivotPosition pivotPosition)
        {
            MeshFilter component = base.GetComponent <MeshFilter>();

            if (component.sharedMesh == null)
            {
                component.sharedMesh = new Mesh();
            }
            Mesh sharedMesh = component.sharedMesh;

            base.GenerationTimeMS = SphericalConePrimitive.GenerateGeometry(sharedMesh, radius, segments, coneAngle, normalsType, pivotPosition);
            this.radius           = radius;
            this.segments         = segments;
            this.coneAngle        = coneAngle;
            this.normalsType      = normalsType;
            this.flipNormals      = false;
            this.pivotPosition    = pivotPosition;
        }
示例#15
0
        /// <summary>
        /// create SphericalCone game object
        /// </summary>
        /// <param name="radius">radius of sphere</param>
        /// <param name="segments">number of segments</param>
        /// <param name="coneAngle">angle of conus in DEG, 360 ... complete sphere, 180 ... half-sphere</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public void GenerateGeometry(float radius, int segments, float coneAngle, NormalsType normalsType, PivotPosition pivotPosition)
        {
            // generate new mesh and clear old one
            var meshFilter = GetComponent <MeshFilter>();

            if (meshFilter.sharedMesh == null)
            {
                meshFilter.sharedMesh = new Mesh();
            }

            var mesh = meshFilter.sharedMesh;

            // generate geometry
            GenerationTimeMS = Primitives.SphericalConePrimitive.GenerateGeometry(mesh, radius, segments, coneAngle, normalsType, pivotPosition);

            this.radius        = radius;
            this.segments      = segments;
            this.coneAngle     = coneAngle;
            this.normalsType   = normalsType;
            this.flipNormals   = false;
            this.pivotPosition = pivotPosition;
        }
示例#16
0
        /// <summary>
        /// create GeoSphere game object
        /// </summary>
        /// <param name="radius">radius of sphere</param>
        /// <param name="subdivision">number of subdivision</param>
        /// <param name="baseType">type of generation primitive</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public void GenerateGeometry(float radius, int subdivision, Primitives.GeoSpherePrimitive.BaseType baseType, NormalsType normalsType, PivotPosition pivotPosition)
        {
            // generate new mesh and clear old one
            var meshFilter = GetComponent<MeshFilter>();

            if (meshFilter.sharedMesh == null)
            {
                meshFilter.sharedMesh = new Mesh();
            }

            var mesh = meshFilter.sharedMesh;

            // geneate geometry
            GenerationTimeMS = Primitives.GeoSpherePrimitive.GenerateGeometry(mesh, radius, subdivision, baseType, normalsType, pivotPosition);

            this.radius = radius;
            this.subdivision = subdivision;
            this.baseType = baseType;
            this.normalsType = normalsType;
            this.flipNormals = false;
            this.pivotPosition = pivotPosition;
        }
示例#17
0
        /// <summary>
        /// create SphericalCone game object
        /// </summary>
        /// <param name="radius">radius of sphere</param>
        /// <param name="segments">number of segments</param>
        /// <param name="coneAngle">angle of conus in DEG, 360 ... complete sphere, 180 ... half-sphere</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public void GenerateGeometry(float radius, int segments, float coneAngle, NormalsType normalsType, PivotPosition pivotPosition)
        {
            // generate new mesh and clear old one
            var meshFilter = GetComponent<MeshFilter>();

            if (meshFilter.sharedMesh == null)
            {
                meshFilter.sharedMesh = new Mesh();
            }

            var mesh = meshFilter.sharedMesh;

            // generate geometry
            GenerationTimeMS = Primitives.SphericalConePrimitive.GenerateGeometry(mesh, radius, segments, coneAngle, normalsType, pivotPosition);

            this.radius = radius;
            this.segments = segments;
            this.coneAngle = coneAngle;
            this.normalsType = normalsType;
            this.flipNormals = false;
            this.pivotPosition = pivotPosition;
        }
示例#18
0
        /// <summary>
        /// create Ellipsoid game object
        /// </summary>
        /// <param name="width">width of ellipsoid</param>
        /// <param name="height">height of ellipsoid</param>
        /// <param name="length">length of ellipsoid</param>
        /// <param name="segments">number of segments</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public void GenerateGeometry(float width, float height, float length, int segments, NormalsType normalsType, PivotPosition pivotPosition)
        {
            // generate new mesh and clear old one
            var meshFilter = GetComponent<MeshFilter>();

            if (meshFilter.sharedMesh == null)
            {
                meshFilter.sharedMesh = new Mesh();
            }

            var mesh = meshFilter.sharedMesh;

            // generate geometry
            GenerationTimeMS = Primitives.EllipsoidPrimitive.GenerateGeometry(mesh, width, height, length, segments, normalsType, pivotPosition);

            this.width = width;
            this.height = height;
            this.length = length;
            this.segments = segments;
            this.normalsType = normalsType;
            this.flipNormals = false;
            this.pivotPosition = pivotPosition;
        }
示例#19
0
        /// <summary>
        /// re/generate mesh geometry based on parameters
        /// </summary>
        /// <param name="radius">radius of cylinder</param>
        /// <param name="height">height of cylinder</param>
        /// <param name="sides">number of triangle segments in radius</param>
        /// <param name="heightSegments">number of triangle segments in height</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        /// <param name="normalsType">type of normals to be generated</param>
        public void GenerateGeometry(float radius, float height, int sides, int heightSegments, NormalsType normalsType, PivotPosition pivotPosition)
        {
            // generate new mesh and clear old one
            var meshFilter = GetComponent<MeshFilter>();

            if (meshFilter.sharedMesh == null)
            {
                meshFilter.sharedMesh = new Mesh();
            }

            var mesh = meshFilter.sharedMesh;

            // generate cone with same radiuses
            GenerationTimeMS = Primitives.ConePrimitive.GenerateGeometry(mesh, radius, radius, height, sides, heightSegments, normalsType, pivotPosition);

            this.radius = radius;
            this.height = height;
            this.sides = sides;
            this.heightSegments = heightSegments;
            this.normalsType = normalsType;
            this.flipNormals = false;
            this.pivotPosition = pivotPosition;
        }
示例#20
0
文件: Sphere.cs 项目: jfeng94/Thesis
        /// <summary>
        /// create Sphere game object
        /// </summary>
        /// <param name="radius">radius of sphere</param>
        /// <param name="segments">number of segments</param>
        /// <param name="hemisphere">hemisphere, 0 ... complete sphere, 0.5 ... half-sphere</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="innerRadius">radius of the inner sphere</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        /// <param name="slice">vertical slice parameter</param>
        public void GenerateGeometry(float radius, int segments, float hemisphere, float innerRadius, float slice, NormalsType normalsType, PivotPosition pivotPosition)
        {
            // generate new mesh and clear old one
            var meshFilter = GetComponent<MeshFilter>();

            if (meshFilter.sharedMesh == null)
            {
                meshFilter.sharedMesh = new Mesh();
            }

            var mesh = meshFilter.sharedMesh;

            // generate geometry
            GenerationTimeMS = Primitives.SpherePrimitive.GenerateGeometry(mesh, radius, segments, hemisphere, innerRadius, slice, normalsType, pivotPosition);

            this.radius = radius;
            this.segments = segments;
            this.hemisphere = hemisphere;
            this.normalsType = normalsType;
            this.flipNormals = false;
            this.innerRadius = innerRadius;
            this.slice = slice;
            this.pivotPosition = pivotPosition;
        }
示例#21
0
        /// <summary>
        /// create GeoSphere game object
        /// </summary>
        /// <param name="radius">radius of sphere</param>
        /// <param name="subdivision">number of subdivision</param>
        /// <param name="baseType">type of generation primitive</param>
        /// <param name="normals">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        /// <returns>GeoSphere class with GeoSphere game object</returns>
        public static GeoSphere Create(float radius, int subdivision, Primitives.GeoSpherePrimitive.BaseType baseType, NormalsType normals, PivotPosition pivotPosition)
        {
            var sphereObject = new GameObject("GeoSpherePro");

            sphereObject.AddComponent <MeshFilter>();
            var renderer = sphereObject.AddComponent <MeshRenderer>();

            renderer.sharedMaterial = new Material(Shader.Find("Diffuse"));

            var sphere = sphereObject.AddComponent <GeoSphere>();

            sphere.GenerateGeometry(radius, subdivision, baseType, normals, pivotPosition);

            return(sphere);
        }
示例#22
0
        /// <summary>
        /// create Helix game object
        /// </summary>
        /// <param name="radius0">first radius of tube</param>
        /// <param name="radius1">second radius of tube</param>
        /// <param name="height">height of tube</param>
        /// <param name="sides">number of triangle segments in radius direction</param>
        /// <param name="heightSegments">number of triangle segments in height direction</param>
        /// <returns>Helix class with Helix game object</returns>
        /// <param name="slice">slicing parameter</param>
        /// <param name="radialMapping">using radial uv mapping on the top/bottom of the tube</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public static Helix Create(float radius0, float radius1, float height, int sides, int heightSegments, float slice, float angleRatio, bool radialMapping, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var cylinderObject = new GameObject("HelixPro");

            cylinderObject.AddComponent <MeshFilter>();
            var renderer = cylinderObject.AddComponent <MeshRenderer>();

            renderer.sharedMaterial = new Material(Shader.Find("Diffuse"));

            var tube = cylinderObject.AddComponent <Helix>();

            tube.GenerateGeometry(radius0, radius1, height, sides, heightSegments, slice, angleRatio, radialMapping, normalsType, pivotPosition);

            return(tube);
        }
        /// <summary>
        /// generate mesh geometry for SuperEllipsoid
        /// </summary>
        /// <param name="mesh">mesh to be generated</param>
        /// <param name="width">width of roundedCube</param>
        /// <param name="height">height of roundedCube</param>
        /// <param name="length">length of roundedCube</param>
        /// <param name="segments">number of segments</param>
        /// <param name="n2">second parameter of superellipsoid</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        /// <param name="n1">second parameter of superellipsoid</param>
        public static float GenerateGeometry(Mesh mesh, float width, float height, float length, int segments, float n1, float n2, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var stopWatch = new Stopwatch();
            stopWatch.Start();

            width = Mathf.Clamp(width, 0, 100);
            length = Mathf.Clamp(length, 0, 100);
            height = Mathf.Clamp(height, 0, 100);
            segments = Mathf.Clamp(segments, 1, 100);
            n1 = Mathf.Clamp(n1, 0.01f, 5.0f);
            n2 = Mathf.Clamp(n2, 0.01f, 5.0f);

            mesh.Clear();

            // to fix spherical uv generation use only segments % 3
            segments = segments*4 - 1;

            segments += 5;

            var numVertices = (segments + 1)*(segments/2 + 1);
            var numTriangles = segments*(segments / 2) * 6;

            if (normalsType == NormalsType.Face)
            {
                numVertices = numTriangles;
            }

            if (numVertices > 60000)
            {
                UnityEngine.Debug.LogError("Too much vertices!");
                return 0.0f;
            }

            var vertices = new Vector3[numVertices];
            var uvs = new Vector2[numVertices];
            var triangles = new int[numTriangles];

            var pivotOffset = Vector3.zero;
            switch (pivotPosition)
            {
                case PivotPosition.Botttom: pivotOffset = new Vector3(0.0f, height, 0.0f);
                    break;
                case PivotPosition.Top: pivotOffset = new Vector3(0.0f, -height, 0.0f);
                    break;
            }

            var vertIndex = 0;

            for (int j = 0; j <= segments / 2; j++)
            {
                for (int i = 0; i <= segments; i++)
                {
                    var index = j * (segments + 1) + i;
                    var theta = i * 2.0f * Mathf.PI / segments;
                    var phi = -0.5f * Mathf.PI + Mathf.PI * j / (segments / 2.0f);

                    // make unit sphere, power determines roundness
                    vertices[index].x = RPower(Mathf.Cos(phi), n1) * RPower(Mathf.Cos(theta), n2) * width;
                    vertices[index].z = RPower(Mathf.Cos(phi), n1) * RPower(Mathf.Sin(theta), n2) * length;
                    vertices[index].y = RPower(Mathf.Sin(phi), n1) * height;

                    // compute uv spherical mapping
                    uvs[index].x = Mathf.Atan2(vertices[index].z, vertices[index].x) / (2.0f * Mathf.PI);

                    if (uvs[index].x < 0)
                    {
                        uvs[index].x = 1 + uvs[index].x;
                    }

                    uvs[index].y = 0.5f + Mathf.Atan2(vertices[index].y, Mathf.Sqrt(vertices[index].x * vertices[index].x + vertices[index].z * vertices[index].z)) / Mathf.PI;

                    // fix seams
                    if (j == 0)
                    {
                        vertices[index].x = 0;
                        vertices[index].y = -height;
                        vertices[index].z = 0;
                        uvs[index].y = 0.0f;
                        uvs[index].x = 0;
                    }

                    if (j == segments / 2)
                    {
                        vertices[index].x = 0;
                        vertices[index].y = height;
                        vertices[index].z = 0;
                        uvs[index].y = 1.0f;
                        uvs[index].x = uvs[(j-1) * (segments + 1) + i].x;
                    }

                    if (i == segments)
                    {
                        vertices[index].x = vertices[j * (segments + 1)].x;
                        vertices[index].z = vertices[j * (segments + 1)].z;
                        uvs[index].x = 1.0f;
                    }

                    vertices[index] += pivotOffset;

                    if (vertIndex < index)
                    {
                        vertIndex = index;
                    }
                }
            }

            // fix uv seam
            for (int i=0; i<=segments; i++)
            {
                var indexNext = (segments + 1) + i;
                uvs[i].x = uvs[indexNext].x;
            }

            var triIndex = 0;
            for (int j=0;j<segments/2;j++)
            {
                for (int i = 0; i < segments; i++)
                {
                    var i1 = j*(segments + 1) + i;
                    var i2 = j*(segments + 1) + (i + 1);
                    var i3 = (j + 1)*(segments + 1) + (i + 1);
                    var i4 = (j + 1)*(segments + 1) + i;

                    triangles[triIndex + 0] = i3;
                    triangles[triIndex + 1] = i2;
                    triangles[triIndex + 2] = i1;
                    triangles[triIndex + 3] = i4;
                    triangles[triIndex + 4] = i3;
                    triangles[triIndex + 5] = i1;

                    triIndex += 6;
                }
            }

            if (normalsType == NormalsType.Face)
            {
                MeshUtils.DuplicateSharedVertices(ref vertices, ref uvs, triangles, -1);
            }

            mesh.vertices = vertices;
            mesh.uv = uvs;
            mesh.triangles = triangles;

            if (normalsType == NormalsType.Vertex)
            {
                Vector3[] normals = null;
                MeshUtils.ComputeVertexNormals(vertices, triangles, out normals);

                // fix normals seam
                for (int j = 0; j < segments / 2; j++)
                {
                    var index0 = j * (segments + 1);
                    var index = j * (segments + 1) + segments;
                    normals[index] = normals[index0];
                }

                mesh.normals = normals;
            }
            else
            {
                mesh.RecalculateNormals();
            }

            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            mesh.Optimize();

            stopWatch.Stop();
            return stopWatch.ElapsedMilliseconds;
        }
示例#24
0
        /// <summary>
        /// generate geometry for capsule
        /// </summary>
        /// <param name="mesh">mesh to be generated</param>
        /// <param name="radius">radius of capsule</param>
        /// <param name="sides">number of segments</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="heightSegments">number of segments of central cylinder</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public static float GenerateGeometry(Mesh mesh, float radius, float height, int sides, int heightSegments, bool preserveHeight, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var stopWatch = new Stopwatch();
            stopWatch.Start();

            radius = Mathf.Clamp(radius, 0, 100);
            height = Mathf.Clamp(height, 0, 100);
            heightSegments = Mathf.Clamp(heightSegments, 1, 250);
            sides = Mathf.Clamp(sides, 4, 250);

            mesh.Clear();

            if (preserveHeight)
            {
                height = height - radius * 2;
                if (height < 0)
                {
                    height = 0;
                }
            }

            int rings = sides;
            int sectors = sides+1;

            if ((rings&1) == 0)
            {
                rings += 1;
                sectors = sides+1;
            }

            float R = 1 / (float)(rings - 1);
            float S = 1 / (float)(sectors - 1);
            var midRing = rings/2 + 1;

            int verticesNum = 0;
            var trianglesNum = (rings - 1) * (sectors - 1) * 6;
            var verticesCylinder = (sides + 1) * (heightSegments + 1);
            var trianglesCylinder = sides * 6 * heightSegments;

            if (normalsType == NormalsType.Vertex)
            {
                verticesNum = rings*sectors +sectors;
            }
            else
            {
                verticesNum = (midRing - 1)*(sectors - 1)*4 + ((rings - 1) - (midRing - 1))*(sectors - 1)*4;
                verticesCylinder = sides * (4 + (heightSegments - 1) * 2);
            }

            if (verticesNum + verticesCylinder > 60000)
            {
                UnityEngine.Debug.LogError("Too much vertices!");
                return 0.0f;
            }

            var vertices = new Vector3[verticesNum + verticesCylinder];
            var normals = new Vector3[verticesNum + verticesCylinder];
            var uvs = new Vector2[verticesNum + verticesCylinder];
            var triangles = new int[trianglesNum + trianglesCylinder];

            var capsuleRadius = radius + height/2;

            var pivotOffset = Vector3.zero;
            switch (pivotPosition)
            {
                case PivotPosition.Botttom: pivotOffset = new Vector3(0.0f, capsuleRadius, 0.0f);
                    break;
                case PivotPosition.Top: pivotOffset = new Vector3(0.0f, -capsuleRadius, 0.0f);
                    break;
            }

            var vertIndex = 0;
            var triIndex = 0;

            var vertIndexCyl = 0;
            var triIndexCyl = 0;

            // calculate capsule with vertex normals
            if (normalsType == NormalsType.Vertex)
            {
                // generate upper hemisphere
                for (int r = 0; r < midRing; r++)
                {
                    var y = Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * r * R);
                    var sinR = Mathf.Sin(Mathf.PI * r * R);

                    for (int s = 0; s < sectors; s++)
                    {
                        float x = Mathf.Sin(2*Mathf.PI*s*S)*sinR;
                        float z = Mathf.Cos(2 * Mathf.PI * s * S) * sinR;

                        vertices[vertIndex + 0] = new Vector3(x, y, z) * radius + pivotOffset;
                        normals[vertIndex + 0] = new Vector3(x, y, z);

                        vertices[vertIndex + 0].y += height / 2;

                        var uv = GetSphericalUV(vertices[vertIndex + 0] - pivotOffset);
                        //uvs[vertIndex + 0] = new Vector2(s * S, 1.0f - (r * R));
                        uvs[vertIndex + 0] = new Vector2(1.0f - s * S, uv.y);

                        if (r < midRing-1 && s < sectors - 1)
                        {
                            triangles[triIndex + 0] = (r + 1) * sectors + (s);
                            triangles[triIndex + 1] = r * sectors + (s + 1);
                            triangles[triIndex + 2] = r * sectors + s;

                            triangles[triIndex + 3] = (r + 1) * sectors + (s + 1);
                            triangles[triIndex + 4] = r * sectors + (s + 1);
                            triangles[triIndex + 5] = (r + 1) * sectors + (s);

                            triIndex += 6;
                        }

                        vertIndex += 1;
                    }
                }

                // generate central cylinder
                if (height > 0)
                {
                    vertIndexCyl = verticesNum;
                    triIndexCyl = trianglesNum;
                    var triVertCyl = verticesNum;
                    var heightRatio = height/heightSegments;
                    var bottomCenter = new Vector3(0.0f, -height/2, 0.0f);

                    var sinR = Mathf.Sin(Mathf.PI * (midRing-1) * R);

                    for (int s = 0; s <= sides; s++)
                    {
                        float x = Mathf.Sin(2 * Mathf.PI * s * S) * sinR;
                        float z = Mathf.Cos(2 * Mathf.PI * s * S) * sinR;

                        var v0 = new Vector3(x, 0.0f, z);
            //                        var texV = (midRing - 1) * R;

                        var currHeight = 0.0f;

                        for (int j = 0; j <= heightSegments; j++)
                        {
                            // generate vertices
                            vertices[vertIndexCyl + 0] = bottomCenter + v0 * radius + new Vector3(0.0f, currHeight, 0.0f) + pivotOffset;
                            normals[vertIndexCyl + 0] = v0;
            //                            uvs[vertIndexCyl + 0] = new Vector2(s * S, texV/2);
            //
            //                            texV += 1.0f/heightSegments;

                            var uv = GetSphericalUV(vertices[vertIndexCyl + 0] - pivotOffset);
            //                        uvs[vertIndex + 0] = new Vector2(s * S, 1.0f - (r * R));
                            uvs[vertIndexCyl + 0] = new Vector2(1.0f - s * S, uv.y);

                            vertIndexCyl += 1;
                            currHeight += heightRatio;
                        }
                    }

                    for (int i = 0; i < sides; i++)
                    {
                        var triVertNext = verticesNum + (i + 1)*(heightSegments + 1);

                        for (int j = 0; j < heightSegments; j++)
                        {
                            triangles[triIndexCyl + 0] = triVertNext + 0;
                            triangles[triIndexCyl + 1] = triVertNext + 1;
                            triangles[triIndexCyl + 2] = triVertCyl + 0;

                            triangles[triIndexCyl + 3] = triVertNext + 1;
                            triangles[triIndexCyl + 4] = triVertCyl + 1;
                            triangles[triIndexCyl + 5] = triVertCyl + 0;

                            triIndexCyl += 6;
                            triVertCyl += 1;
                            triVertNext += 1;
                        }

                        triVertCyl += 1;
                    }
                }

                // generate bottom hemisphere
                for (int r = midRing-1; r < rings; r++)
                {
                    var y = Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * r * R);
                    var sinR = Mathf.Sin(Mathf.PI * r * R);

                    for (int s = 0; s < sectors; s++)
                    {
                        float x = Mathf.Sin(2 * Mathf.PI * s * S) * sinR;
                        float z = Mathf.Cos(2 * Mathf.PI * s * S) * sinR;

                        vertices[vertIndex + 0] = new Vector3(x, y, z) * radius;
                        normals[vertIndex + 0] = new Vector3(x, y, z);

                        vertices[vertIndex] += pivotOffset;

                        vertices[vertIndex + 0].y -= height/2;

                        var uv = GetSphericalUV(vertices[vertIndex + 0] - pivotOffset);
            //                        uvs[vertIndex + 0] = new Vector2(s * S, 1.0f - (r * R));
                        uvs[vertIndex + 0] = new Vector2(1.0f - s * S, uv.y);

                        if (r < rings-1 && s < sectors - 1)
                        {
                            triangles[triIndex + 0] = ((r+1) + 1) * sectors + (s);
                            triangles[triIndex + 1] = (r+1) * sectors + (s + 1);
                            triangles[triIndex + 2] = (r+1) * sectors + s;

                            triangles[triIndex + 3] = ((r+1) + 1) * sectors + (s + 1);
                            triangles[triIndex + 4] = (r+1) * sectors + (s + 1);
                            triangles[triIndex + 5] = ((r+1) + 1) * sectors + (s);

                            triIndex += 6;
                        }

                        vertIndex += 1;
                    }
                }
            }
            else
            {
                // generate upper hemisphere
                for (int r = 0; r < midRing-1; r++)
                {
                    var y = Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * r * R);
                    var yNext = Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * (r+1) * R);

                    var sinR = Mathf.Sin(Mathf.PI * r * R);
                    var sinR1 = Mathf.Sin(Mathf.PI * (r + 1) * R);

                    for (int s = 0; s < sectors-1; s++)
                    {
                        var sinS = Mathf.Sin(2*Mathf.PI*s*S);
                        var sinS1 = Mathf.Sin(2*Mathf.PI*(s + 1)*S);
                        var cosS = Mathf.Cos(2*Mathf.PI*(s)*S);
                        var cosS1 = Mathf.Cos(2*Mathf.PI*(s + 1)*S);

                        var x = sinS*sinR;
                        var xNext = sinS1*sinR;
                        var xNextR = sinS*sinR1;
                        var xNextRS = sinS1*sinR1;
                        var z = Mathf.Cos(2*Mathf.PI*s*S)*sinR;
                        var zNext = cosS1*sinR;
                        var zNextR = cosS*sinR1;
                        var zNextRS = cosS1*sinR1;

                        // r, s
                        vertices[vertIndex + 0] = new Vector3(x, y, z) * radius + pivotOffset;
            //                        uvs[vertIndex + 0] = new Vector2(s * S, 1.0f - r * R);
                        vertices[vertIndex + 0].y += height/2;

                        var uv = GetSphericalUV(vertices[vertIndex + 0] - pivotOffset);
                        uvs[vertIndex + 0] = new Vector2(1.0f - s * S, uv.y);

                        // r+1, s
                        vertices[vertIndex + 1] = new Vector3(xNextR, yNext, zNextR) * radius + pivotOffset;
            //                        uvs[vertIndex + 1] = new Vector2(s * S, 1.0f - (r+1) * R);
                        vertices[vertIndex + 1].y += height / 2;
                        uv = GetSphericalUV(vertices[vertIndex + 1] - pivotOffset);
                        uvs[vertIndex + 1] = new Vector2(1.0f - s * S, uv.y);

                        // r, s+1
                        vertices[vertIndex + 2] = new Vector3(xNext, y, zNext) * radius + pivotOffset;
            //                        uvs[vertIndex + 2] = new Vector2((s+1) * S, 1.0f - (r) * R);
                        vertices[vertIndex + 2].y += height / 2;
                        uv = GetSphericalUV(vertices[vertIndex + 2] - pivotOffset);
                        uvs[vertIndex + 2] = new Vector2(1.0f - (s+1) * S, uv.y);

                        // r+1, s+1
                        vertices[vertIndex + 3] = new Vector3(xNextRS, yNext, zNextRS) * radius + pivotOffset;
            //                        uvs[vertIndex + 3] = new Vector2((s+1) * S, 1.0f - (r+1) * R);
                        vertices[vertIndex + 3].y += height / 2;
                        uv = GetSphericalUV(vertices[vertIndex + 3] - pivotOffset);
                        uvs[vertIndex + 3] = new Vector2(1.0f - (s+1) * S, uv.y);

                        triangles[triIndex + 0] = vertIndex + 1;
                        triangles[triIndex + 1] = vertIndex + 2;
                        triangles[triIndex + 2] = vertIndex + 0;

                        triangles[triIndex + 3] = vertIndex + 3;
                        triangles[triIndex + 4] = vertIndex + 2;
                        triangles[triIndex + 5] = vertIndex + 1;

                        triIndex += 6;

                        vertIndex += 4;
                    }
                }

                // generate central cylinder
                if (height > 0)
                {
                    vertIndexCyl = verticesNum;
                    triIndexCyl = trianglesNum;
                    var heightRatio = height / heightSegments;
                    var bottomCenter = new Vector3(0.0f, -height / 2, 0.0f);

                    var sinR = Mathf.Sin(Mathf.PI * (midRing - 1) * R);

                    for (int s = 0; s < sides; s++)
                    {
                        var v0 = new Vector3(Mathf.Sin(2 * Mathf.PI * s * S) * sinR, 0.0f, Mathf.Cos(2 * Mathf.PI * s * S) * sinR);
                        var v1 = new Vector3(Mathf.Sin(2 * Mathf.PI * (s+1) * S) * sinR, 0.0f, Mathf.Cos(2 * Mathf.PI * (s+1) * S) * sinR);

            //                        var texV = (midRing - 1) * R;
                        var currHeight = 0.0f;

                        var triVertCyl = vertIndexCyl;

                        var normal = (v0 + v1).normalized;

                        for (int j = 0; j <= heightSegments; j++)
                        {
                            // generate vertices
                            vertices[vertIndexCyl + 0] = bottomCenter + v0 * radius + new Vector3(0.0f, currHeight, 0.0f) + pivotOffset;
                            vertices[vertIndexCyl + 1] = bottomCenter + v1 * radius + new Vector3(0.0f, currHeight, 0.0f) + pivotOffset;

                            normals[vertIndexCyl + 0] = normal;
                            normals[vertIndexCyl + 1] = normal;

            //                            uvs[vertIndexCyl + 0] = new Vector2(s * S, texV/2);
            //                            uvs[vertIndexCyl + 1] = new Vector2((s + 1) * S, texV/2);
            //                            texV += 1.0f/heightSegments;

                            var uv = GetSphericalUV(vertices[vertIndexCyl + 0] - pivotOffset);
                            uvs[vertIndexCyl + 0] = new Vector2(1.0f - s * S, uv.y);
                            uvs[vertIndexCyl + 1] = new Vector2(1.0f - (s+1) * S, uv.y);

                            vertIndexCyl += 2;

                            currHeight += heightRatio;
                        }

                        for (int j = 0; j < heightSegments; j++)
                        {
                            triangles[triIndexCyl + 0] = triVertCyl + 0;
                            triangles[triIndexCyl + 1] = triVertCyl + 1;
                            triangles[triIndexCyl + 2] = triVertCyl + 3;

                            triangles[triIndexCyl + 3] = triVertCyl + 3;
                            triangles[triIndexCyl + 4] = triVertCyl + 2;
                            triangles[triIndexCyl + 5] = triVertCyl + 0;

                            triIndexCyl += 6;
                            triVertCyl += 2;
                        }
                    }
                }

                // generate bottom hemisphere
                for (int r = midRing-1; r < rings - 1; r++)
                {
                    var y = Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * r * R);
                    var yNext = Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * (r + 1) * R);

                    var sinR = Mathf.Sin(Mathf.PI * r * R);
                    var sinR1 = Mathf.Sin(Mathf.PI * (r + 1) * R);

                    for (int s = 0; s < sectors - 1; s++)
                    {
                        var sinS = Mathf.Sin(2 * Mathf.PI * s * S);
                        var sinS1 = Mathf.Sin(2 * Mathf.PI * (s + 1) * S);
                        var cosS = Mathf.Cos(2 * Mathf.PI * (s) * S);
                        var cosS1 = Mathf.Cos(2 * Mathf.PI * (s + 1) * S);

                        var x = sinS * sinR;
                        var xNext = sinS1 * sinR;
                        var xNextR = sinS * sinR1;
                        var xNextRS = sinS1 * sinR1;
                        var z = Mathf.Cos(2 * Mathf.PI * s * S) * sinR;
                        var zNext = cosS1 * sinR;
                        var zNextR = cosS * sinR1;
                        var zNextRS = cosS1 * sinR1;

                        // r, s
                        vertices[vertIndex + 0] = new Vector3(x, y, z) * radius + pivotOffset;
            //                        uvs[vertIndex + 0] = new Vector2(s * S, 1.0f - r * R);
                        vertices[vertIndex + 0].y -= height / 2;
                        var uv = GetSphericalUV(vertices[vertIndex + 0] - pivotOffset);
                        uvs[vertIndex + 0] = new Vector2(1.0f - s * S, uv.y);

                        // r+1, s
                        vertices[vertIndex + 1] = new Vector3(xNextR, yNext, zNextR) * radius + pivotOffset;
            //                        uvs[vertIndex + 1] = new Vector2(s * S, 1.0f - (r + 1) * R);
                        vertices[vertIndex + 1].y -= height / 2;
                        uv = GetSphericalUV(vertices[vertIndex + 1] - pivotOffset);
                        uvs[vertIndex + 1] = new Vector2(1.0f - s * S, uv.y);

                        // r, s+1
                        vertices[vertIndex + 2] = new Vector3(xNext, y, zNext) * radius + pivotOffset;
            //                        uvs[vertIndex + 2] = new Vector2((s + 1) * S, 1.0f - (r) * R);
                        vertices[vertIndex + 2].y -= height / 2;
                        uv = GetSphericalUV(vertices[vertIndex + 2] - pivotOffset);
                        uvs[vertIndex + 2] = new Vector2(1.0f - (s+1) * S, uv.y);

                        // r+1, s+1
                        vertices[vertIndex + 3] = new Vector3(xNextRS, yNext, zNextRS) * radius + pivotOffset;
            //                        uvs[vertIndex + 3] = new Vector2((s + 1) * S, 1.0f - (r + 1) * R);
                        vertices[vertIndex + 3].y -= height / 2;
                        uv = GetSphericalUV(vertices[vertIndex + 3] - pivotOffset);
                        uvs[vertIndex + 3] = new Vector2(1.0f - (s + 1) * S, uv.y);

                        triangles[triIndex + 0] = vertIndex + 1;
                        triangles[triIndex + 1] = vertIndex + 2;
                        triangles[triIndex + 2] = vertIndex + 0;

                        triangles[triIndex + 3] = vertIndex + 3;
                        triangles[triIndex + 4] = vertIndex + 2;
                        triangles[triIndex + 5] = vertIndex + 1;

                        triIndex += 6;

                        vertIndex += 4;
                    }
                }
            }

            mesh.vertices = vertices;
            mesh.normals = normals;
            mesh.uv = uvs;
            mesh.triangles = triangles;

            // generate normals by unity in face case
            if (normalsType == NormalsType.Face)
            {
                mesh.RecalculateNormals();
            }

            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            mesh.Optimize();

            stopWatch.Stop();
            return stopWatch.ElapsedMilliseconds;
        }
示例#25
0
        // Token: 0x0600425D RID: 16989 RVA: 0x0015134C File Offset: 0x0014F74C
        public void GenerateGeometry(float width, float height, float length, int segments, float n1, float n2, NormalsType normalsType, PivotPosition pivotPosition)
        {
            MeshFilter component = base.GetComponent <MeshFilter>();

            if (component.sharedMesh == null)
            {
                component.sharedMesh = new Mesh();
            }
            Mesh sharedMesh = component.sharedMesh;

            base.GenerationTimeMS = SuperEllipsoidPrimitive.GenerateGeometry(sharedMesh, width, height, length, segments, n1, n2, normalsType, pivotPosition);
            this.width            = width;
            this.height           = height;
            this.length           = length;
            this.segments         = segments;
            this.n1            = n1;
            this.n2            = n2;
            this.normalsType   = normalsType;
            this.flipNormals   = false;
            this.pivotPosition = pivotPosition;
        }
        /// <summary>
        /// create SuperEllipsoid game object
        /// </summary>
        /// <param name="width">width of the cube</param>
        /// <param name="height">height of the cube</param>
        /// <param name="length">length of the cube</param>
        /// <param name="segments">number of segments</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public void GenerateGeometry(float width, float height, float length, int segments, float n1, float n2, NormalsType normalsType, PivotPosition pivotPosition)
        {
            // generate new mesh and clear old one
            var meshFilter = GetComponent <MeshFilter>();

            if (meshFilter.sharedMesh == null)
            {
                meshFilter.sharedMesh = new Mesh();
            }

            var mesh = meshFilter.sharedMesh;

            // generate geometry
            GenerationTimeMS = Primitives.SuperEllipsoidPrimitive.GenerateGeometry(mesh, width, height, length, segments, n1, n2, normalsType, pivotPosition);

            this.width         = width;
            this.height        = height;
            this.length        = length;
            this.segments      = segments;
            this.n1            = n1;
            this.n2            = n2;
            this.normalsType   = normalsType;
            this.flipNormals   = false;
            this.pivotPosition = pivotPosition;
        }
        /// <summary>
        /// generate mesh geometry for Spherical cone
        ///
        /// references:
        /// http://mathworld.wolfram.com/SphericalCone.html
        /// http://en.wikipedia.org/wiki/Spherical_sector
        ///
        /// </summary>
        /// <param name="mesh">mesh to be generated</param>
        /// <param name="radius">radius of sphere</param>
        /// <param name="segments">number of segments</param>
        /// <param name="coneAngle">angle of conus in DEG, 360 ... complete sphere, 180 ... half-sphere</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public static float GenerateGeometry(Mesh mesh, float radius, int segments, float coneAngle, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var stopWatch = new Stopwatch();

            stopWatch.Start();

            radius    = Mathf.Clamp(radius, 0, 100);
            segments  = Mathf.Clamp(segments, 4, 100);
            coneAngle = Mathf.Clamp(coneAngle, 0, 360);
            var hemisphere = 1.0f - (coneAngle / 360.0f);

            mesh.Clear();

            int rings   = segments - 1;
            int sectors = segments;

            var hemisphereCapY    = -1 + hemisphere * 2;
            int hemisphereCapRing = rings;
//            var hemisphereYpos = -radius;

            float R = 1 / (float)(rings - 1);
            float S = 1 / (float)(sectors - 1);

            // calculate hemisphere parameters
//            var lastY = 0.0f;
            for (int r = 0; r < rings; r++)
            {
                var y = Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * r * R);

                if (y < hemisphereCapY)
                {
                    hemisphereCapRing = r;
//                    hemisphereYpos = lastY * radius;
                    break;
                }

//                lastY = y;
            }

            int verticesNum            = 0;
            var trianglesNum           = (hemisphereCapRing) * (sectors) * 6;
            var verticesHemisphereNum  = segments + 1;
            var trianglesHemisphereNum = segments * 3;

            if (hemisphereCapRing == rings)
            {
                trianglesNum -= sectors * 3;
            }

            if (normalsType == NormalsType.Vertex)
            {
                verticesNum = (hemisphereCapRing + 1) * (sectors + 1);
            }
            else
            {
                verticesNum = trianglesNum;
            }

            if (hemisphereCapRing == rings)
            {
                verticesNum -= sectors + 1;
            }

            var pivotOffset = Vector3.zero;

            switch (pivotPosition)
            {
            case PivotPosition.Botttom: pivotOffset = new Vector3(0.0f, radius, 0.0f);
                break;

            case PivotPosition.Top: pivotOffset = new Vector3(0.0f, -radius, 0.0f);
                break;

            case PivotPosition.Center: pivotOffset = Vector3.zero;
                break;
            }

            if (verticesNum + verticesHemisphereNum > 60000)
            {
                UnityEngine.Debug.LogError("Too much vertices!");
                return(0.0f);
            }

            var vertices  = new Vector3[verticesNum + verticesHemisphereNum];
            var normals   = new Vector3[verticesNum + verticesHemisphereNum];
            var uvs       = new Vector2[verticesNum + verticesHemisphereNum];
            var triangles = new int[trianglesNum + trianglesHemisphereNum];

            var vertIndex = 0;
            var triIndex  = 0;

            for (int r = 0; r < hemisphereCapRing; r++)
            {
                var y    = -Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * r * R);
                var sinR = Mathf.Sin(Mathf.PI * r * R);

                for (int s = 0; s < sectors; s++)
                {
                    float x = Mathf.Sin(2 * Mathf.PI * s * S) * sinR;
                    float z = Mathf.Cos(2 * Mathf.PI * s * S) * sinR;

                    vertices[vertIndex + 0] = new Vector3(x, y, z) * radius + pivotOffset;
                    normals[vertIndex + 0]  = new Vector3(x, y, z);
                    uvs[vertIndex + 0]      = new Vector2(1.0f - (s * S), (r * R));

                    if (r < hemisphereCapRing - 1 && s < sectors - 1)
                    {
                        //543
                        triangles[triIndex + 5] = (r + 1) * sectors + (s);
                        triangles[triIndex + 4] = r * sectors + (s + 1);
                        triangles[triIndex + 3] = r * sectors + s;
                        //210
                        triangles[triIndex + 2] = (r + 1) * sectors + (s + 1);
                        triangles[triIndex + 1] = r * sectors + (s + 1);
                        triangles[triIndex + 0] = (r + 1) * sectors + (s);

                        triIndex += 6;
                    }

                    vertIndex += 1;
                }
            }

            var hemisphereVertOffset = vertIndex;

            // calculate hemisphere plane
            if (hemisphereCapRing < rings)
            {
                // duplicate triangles in face case
                if (normalsType == NormalsType.Face)
                {
                    MeshUtils.DuplicateSharedVertices(ref vertices, ref uvs, triangles, triIndex);
                    hemisphereVertOffset = triIndex;
                }

                var triVert = hemisphereVertOffset;
                vertIndex = hemisphereVertOffset;

                var y    = -Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * (hemisphereCapRing - 1) * R);
                var sinR = Mathf.Sin(Mathf.PI * (hemisphereCapRing - 1) * R);

                var zeroIndex = 0;

                for (int i = 0; i < sectors; i++)
                {
                    var x = Mathf.Sin(2 * Mathf.PI * i * S) * sinR;
                    var z = Mathf.Cos(2 * Mathf.PI * i * S) * sinR;
                    var v = new Vector3(x, y, z);

                    vertices[vertIndex + 0] = v * radius + pivotOffset;
//                    normals[vertIndex + 0] = new Vector3(0.0f, 1.0f, 0.0f);

                    if (i > 0)
                    {
                        normals[vertIndex + 0] = -MeshUtils.ComputePolygonNormal(pivotOffset, vertices[vertIndex], vertices[vertIndex - 1]);

                        if (i == sectors - 1)
                        {
                            normals[zeroIndex] = MeshUtils.ComputePolygonNormal(pivotOffset, vertices[zeroIndex], vertices[zeroIndex + 1]);
                        }
                    }
                    else
                    {
                        zeroIndex = vertIndex;
                    }

                    // make planar uv mapping for hemisphere plane
                    var uvV      = new Vector2(v.x * 0.5f, v.z * .5f);
                    var uvCenter = new Vector2(0.5f, 0.5f);

                    uvs[vertIndex + 0] = uvCenter + uvV;

                    vertIndex += 1;
                }

                vertices[vertIndex + 0] = pivotOffset;
                normals[vertIndex + 0]  = new Vector3(0, 1, 0);
                uvs[vertIndex + 0]      = new Vector2(0.5f, 0.5f);

                vertIndex += 1;

                for (int i = 0; i < rings; i++)
                {
                    triangles[triIndex + 2] = triVert + 0;
                    triangles[triIndex + 1] = vertIndex - 1;

                    if (i == rings - 1)
                    {
                        triangles[triIndex + 0] = hemisphereVertOffset;
                    }
                    else
                    {
                        triangles[triIndex + 0] = triVert + 1;
                    }

                    triIndex += 3;
                    triVert  += 1;
                }
            }

            mesh.vertices  = vertices;
            mesh.uv        = uvs;
            mesh.triangles = triangles;

            // generate normals by unity in face case
            if (normalsType == NormalsType.Face)
            {
                mesh.RecalculateNormals();
            }
            else
            {
                mesh.normals = normals;
            }

            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            ;

            stopWatch.Stop();
            return(stopWatch.ElapsedMilliseconds);
        }
示例#28
0
        // Token: 0x06004201 RID: 16897 RVA: 0x0014F99C File Offset: 0x0014DD9C
        public static Cylinder Create(float radius, float height, int sides, int heightSegments, NormalsType normals, PivotPosition pivotPosition)
        {
            GameObject gameObject = new GameObject("CylinderPro");

            gameObject.AddComponent <MeshFilter>();
            MeshRenderer meshRenderer = gameObject.AddComponent <MeshRenderer>();

            meshRenderer.sharedMaterial = new Material(Shader.Find("Diffuse"));
            Cylinder cylinder = gameObject.AddComponent <Cylinder>();

            cylinder.GenerateGeometry(radius, height, sides, heightSegments, normals, pivotPosition);
            return(cylinder);
        }
示例#29
0
        // Token: 0x060042F2 RID: 17138 RVA: 0x001593B8 File Offset: 0x001577B8
        public static float GenerateGeometry(Mesh mesh, float radius0, float radius1, float height, int sides, int heightSegments, NormalsType normalsType, PivotPosition pivotPosition)
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            mesh.Clear();
            radius0        = Mathf.Clamp(radius0, 0f, 100f);
            radius1        = Mathf.Clamp(radius1, 0f, 100f);
            height         = Mathf.Clamp(height, 0f, 100f);
            sides          = Mathf.Clamp(sides, 3, 100);
            heightSegments = Mathf.Clamp(heightSegments, 1, 100);
            int num  = sides * 6 * heightSegments;
            int num2 = 2 * (sides + 1);
            int num3 = 2 * (3 * sides);
            int num4;

            if (normalsType == NormalsType.Face)
            {
                num4 = sides * (4 + (heightSegments - 1) * 2);
            }
            else
            {
                num4 = (sides + 1) * (heightSegments + 1);
            }
            if (num4 + num2 > 60000)
            {
                UnityEngine.Debug.LogError("Too much vertices!");
                return(0f);
            }
            Vector3[] array     = new Vector3[num4 + num2];
            Vector3[] array2    = new Vector3[num4 + num2];
            Vector2[] array3    = new Vector2[num4 + num2];
            int[]     array4    = new int[num + num3];
            Vector3   zero      = Vector3.zero;
            float     magnitude = (new Vector3(zero.x + radius0, zero.y, zero.z) - new Vector3(zero.x + radius1, zero.y + height, zero.z)).magnitude;
            Vector3   zero2     = Vector3.zero;

            if (pivotPosition != PivotPosition.Center)
            {
                if (pivotPosition == PivotPosition.Top)
                {
                    zero2 = new Vector3(0f, -height, 0f);
                }
            }
            else
            {
                zero2 = new Vector3(0f, -height / 2f, 0f);
            }
            if (normalsType == NormalsType.Face)
            {
                int   num5 = 0;
                int   num6 = 0;
                float num7 = magnitude / (float)heightSegments;
                for (int i = 0; i < sides; i++)
                {
                    float   f           = (float)i / (float)sides * 3.14159274f * 2f;
                    Vector3 vector      = new Vector3(Mathf.Cos(f), 0f, Mathf.Sin(f));
                    Vector3 normalized  = vector.normalized;
                    float   f2          = (float)(i + 1) / (float)sides * 3.14159274f * 2f;
                    Vector3 vector2     = new Vector3(Mathf.Cos(f2), 0f, Mathf.Sin(f2));
                    Vector3 normalized2 = vector2.normalized;
                    float   num8        = 0f;
                    int     num9        = num5;
                    Vector3 a           = zero + new Vector3(0f, height, 0f) + normalized * radius1 - (zero + normalized * radius0);
                    Vector3 a2          = zero + new Vector3(0f, height, 0f) + normalized2 * radius1 - (zero + normalized2 * radius0);
                    a.Normalize();
                    a2.Normalize();
                    Vector3 normalized3 = (normalized + normalized2).normalized;
                    for (int j = 0; j <= heightSegments; j++)
                    {
                        array[num5]      = zero + normalized * radius0 + a * num8 + zero2;
                        array[num5 + 1]  = zero + normalized2 * radius0 + a2 * num8 + zero2;
                        array2[num5]     = normalized3;
                        array2[num5 + 1] = normalized3;
                        array3[num5]     = new Vector2((float)i / (float)sides, (float)j / (float)heightSegments);
                        array3[num5 + 1] = new Vector2((float)(i + 1) / (float)sides, (float)j / (float)heightSegments);
                        num5            += 2;
                        num8            += num7;
                    }
                    for (int k = 0; k < heightSegments; k++)
                    {
                        array4[num6]     = num9;
                        array4[num6 + 1] = num9 + 2;
                        array4[num6 + 2] = num9 + 1;
                        array4[num6 + 3] = num9 + 2;
                        array4[num6 + 4] = num9 + 3;
                        array4[num6 + 5] = num9 + 1;
                        num6            += 6;
                        num9            += 2;
                    }
                }
            }
            else
            {
                int   num10 = 0;
                int   num11 = 0;
                int   num12 = 0;
                float num13 = magnitude / (float)heightSegments;
                for (int l = 0; l <= sides; l++)
                {
                    float   f3          = (float)l / (float)sides * 3.14159274f * 2f;
                    Vector3 vector3     = new Vector3(Mathf.Cos(f3), 0f, Mathf.Sin(f3));
                    Vector3 normalized4 = vector3.normalized;
                    Vector3 a3          = zero + new Vector3(0f, height, 0f) + normalized4 * radius1 - (zero + normalized4 * radius0);
                    a3.Normalize();
                    float num14 = 0f;
                    for (int m = 0; m <= heightSegments; m++)
                    {
                        array[num10]  = zero + normalized4 * radius0 + a3 * num14 + zero2;
                        array2[num10] = normalized4;
                        array3[num10] = new Vector2((float)l / (float)sides, (float)m / (float)heightSegments);
                        num10++;
                        num14 += num13;
                    }
                }
                for (int n = 0; n < sides; n++)
                {
                    int num15 = (n + 1) * (heightSegments + 1);
                    for (int num16 = 0; num16 < heightSegments; num16++)
                    {
                        array4[num11]     = num12;
                        array4[num11 + 1] = num12 + 1;
                        array4[num11 + 2] = num15;
                        array4[num11 + 3] = num15;
                        array4[num11 + 4] = num12 + 1;
                        array4[num11 + 5] = num15 + 1;
                        num11            += 6;
                        num12++;
                        num15++;
                    }
                    num12++;
                }
            }
            int num17 = num4;
            int num18 = num;
            int num19 = num17;

            for (int num20 = 0; num20 < sides; num20++)
            {
                float   f4          = (float)num20 / (float)sides * 3.14159274f * 2f;
                Vector3 vector4     = new Vector3(Mathf.Cos(f4), 0f, Mathf.Sin(f4));
                Vector3 normalized5 = vector4.normalized;
                array[num17]      = zero + normalized5 * radius0 + zero2;
                array2[num17]     = new Vector3(0f, -1f, 0f);
                array[num17 + 1]  = zero + normalized5 * radius1 + new Vector3(0f, height, 0f) + zero2;
                array2[num17 + 1] = new Vector3(0f, 1f, 0f);
                Vector2 b  = new Vector2(normalized5.x * 0.5f, normalized5.z * 0.5f);
                Vector2 a4 = new Vector2(0.5f, 0.5f);
                array3[num17]     = a4 + b;
                array3[num17 + 1] = a4 + b;
                num17            += 2;
            }
            array[num17]      = new Vector3(0f, 0f, 0f) + zero2;
            array[num17 + 1]  = new Vector3(0f, height, 0f) + zero2;
            array2[num17]     = new Vector3(0f, -1f, 0f);
            array2[num17 + 1] = new Vector3(0f, 1f, 0f);
            array3[num17]     = new Vector2(0.5f, 0.5f);
            array3[num17 + 1] = new Vector2(0.5f, 0.5f);
            num17            += 2;
            for (int num21 = 0; num21 < sides; num21++)
            {
                array4[num18]     = num19;
                array4[num18 + 2] = num17 - 2;
                array4[num18 + 3] = num19 + 1;
                array4[num18 + 4] = num17 - 1;
                if (num21 == sides - 1)
                {
                    array4[num18 + 1] = num4;
                    array4[num18 + 5] = num4 + 1;
                }
                else
                {
                    array4[num18 + 1] = num19 + 2;
                    array4[num18 + 5] = num19 + 3;
                }
                num18 += 6;
                num19 += 2;
            }
            mesh.vertices  = array;
            mesh.normals   = array2;
            mesh.uv        = array3;
            mesh.triangles = array4;
            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            stopwatch.Stop();
            return((float)stopwatch.ElapsedMilliseconds);
        }
示例#30
0
        /// <summary>
        /// generate mesh geometry for Tube
        /// </summary>
        /// <param name="mesh">mesh to be generated</param>
        /// <param name="radius0">fist radius of tube</param>
        /// <param name="radius1">second radius of tube</param>
        /// <param name="height">height of tube</param>
        /// <param name="sides">number of triangle segments in radius</param>
        /// <param name="heightSegments">number of triangle segments in height</param>
        /// <param name="slice">slicing parameter</param>
        /// <param name="radialMapping">uv radial mapping for top/down of the Tube</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public static float GenerateGeometry(Mesh mesh, float radius0, float radius1, float height, int sides, int heightSegments, float slice, bool radialMapping, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var stopWatch = new Stopwatch();
            stopWatch.Start();

            radius0 = Mathf.Clamp(radius0, 0, 100);
            radius1 = Mathf.Clamp(radius1, 0, 100);
            height = Mathf.Clamp(height, 0, 100);
            sides = Mathf.Clamp(sides, 3, 100);
            heightSegments = Mathf.Clamp(heightSegments, 1, 100);
            slice = Mathf.Clamp(slice, 0, 360);

            // normalize slice
            slice = slice/360.0f;

            mesh.Clear();

            heightSegments = Mathf.Clamp(heightSegments, 1, 250);
            sides = Mathf.Clamp(sides, 3, 250);

            int sidesPipe = (int)(sides * (1.0f - slice));
            float pipeAngle = (1.0f-slice)*2.0f*Mathf.PI;

            if (sidesPipe == 0)
            {
                sidesPipe = 1;
            }

            int numVertices = 0;
            int numTriangles = sidesPipe * 6 * heightSegments * 2;
            int numVerticesCaps = ((sidesPipe+1) * 2 * 2);
            int numTrianglesCaps = (sidesPipe) * 6 * 2;
            int numTrianglesPipeCaps = 0;
            int numVerticesPipeCaps = 0;

            if (sidesPipe < sides)
            {
                numTrianglesPipeCaps = 12;
                numVerticesPipeCaps = 8;
            }

            if (normalsType == NormalsType.Face)
            {
                numVertices = sidesPipe * (4 + (heightSegments - 1) * 2) * 2;
            }
            else
            {
                numVertices = (sidesPipe + 1) * (heightSegments + 1) * 2;
            }

            if (numVertices + numVerticesCaps > 60000)
            {
                UnityEngine.Debug.LogError("Too much vertices!");
                return 0.0f;
            }

            var vertices = new Vector3[numVertices + numVerticesCaps + numVerticesPipeCaps];
            var normals = new Vector3[numVertices + numVerticesCaps + numVerticesPipeCaps];
            var uvs = new Vector2[numVertices + numVerticesCaps + numVerticesPipeCaps];
            var triangles = new int[numTriangles + numTrianglesCaps + numTrianglesPipeCaps];

            var bottomCenter = Vector3.zero;
            var innerVertOffset = numVertices / 2;
            var innerTriOffset = numTriangles / 2;

            var pivotOffset = Vector3.zero;
            switch (pivotPosition)
            {
                case PivotPosition.Center: pivotOffset = new Vector3(0.0f, -height/2, 0.0f);
                    break;
                case PivotPosition.Top: pivotOffset = new Vector3(0.0f, -height, 0.0f);
                    break;
            }

            if (normalsType == NormalsType.Face)
            {
                var vertIndex = 0;
                var triIndex = 0;
                var heightRatio = height/heightSegments;

                for (int i = 0; i < sidesPipe; i++)
                {
                    float angle0 = ((float)i / sides) * Mathf.PI * 2.0f;
                    var v0 = new Vector3(Mathf.Cos(angle0), 0.0f, Mathf.Sin(angle0)).normalized;

                    float angle1 = ((float)(i+1) / sides) * Mathf.PI * 2.0f;

                    if (i+1 == sidesPipe)
                    {
                        angle1 = pipeAngle;
                    }

                    var v1 = new Vector3(Mathf.Cos(angle1), 0.0f, Mathf.Sin(angle1)).normalized;

                    var currHeight = 0.0f;
                    var triVert = vertIndex;

                    var normal = (v0 + v1).normalized;

                    for (int j = 0; j <= heightSegments; j++)
                    {
                        // generate vertices for outer side
                        vertices[vertIndex + 0] = bottomCenter + v0*radius1 + new Vector3(0, currHeight, 0) + pivotOffset;
                        vertices[vertIndex + 1] = bottomCenter + v1 * radius1 + new Vector3(0, currHeight, 0) + pivotOffset;

                        normals[vertIndex + 0] = normal;
                        normals[vertIndex + 1] = normal;

                        uvs[vertIndex + 0] = new Vector2((float)i / sides, (float)j/heightSegments);
                        uvs[vertIndex + 1] = new Vector2((float)(i + 1) / sides, (float)j/heightSegments);

                        // generate vertices for inner side
                        vertices[vertIndex + innerVertOffset + 0] = bottomCenter + v0 * radius0 + new Vector3(0, currHeight, 0) + pivotOffset;
                        vertices[vertIndex + innerVertOffset + 1] = bottomCenter + v1 * radius0 + new Vector3(0, currHeight, 0) + pivotOffset;

                        normals[vertIndex + innerVertOffset + 0] = -normal;
                        normals[vertIndex + innerVertOffset + 1] = -normal;

                        uvs[vertIndex + innerVertOffset + 0] = new Vector2((float)i / sides, (float)j / heightSegments);
                        uvs[vertIndex + innerVertOffset + 1] = new Vector2((float)(i + 1) / sides, (float)j / heightSegments);

                        vertIndex += 2;

                        currHeight += heightRatio;
                    }

                    for (int j = 0; j < heightSegments; j++)
                    {
                        // generate triangles for outer side
                        triangles[triIndex + 0] = triVert + 0;
                        triangles[triIndex + 1] = triVert + 2;
                        triangles[triIndex + 2] = triVert + 1;

                        triangles[triIndex + 3] = triVert + 2;
                        triangles[triIndex + 4] = triVert + 3;
                        triangles[triIndex + 5] = triVert + 1;

                        // generate triangles for inner side
                        triangles[triIndex + innerTriOffset + 0] = triVert + innerVertOffset + 1;
                        triangles[triIndex + innerTriOffset + 1] = triVert + innerVertOffset + 2;
                        triangles[triIndex + innerTriOffset + 2] = triVert + innerVertOffset + 0;

                        triangles[triIndex + innerTriOffset + 3] = triVert + innerVertOffset + 1;
                        triangles[triIndex + innerTriOffset + 4] = triVert + innerVertOffset + 3;
                        triangles[triIndex + innerTriOffset + 5] = triVert + innerVertOffset + 2;

                        triIndex += 6;
                        triVert += 2;
                    }
                }
            }
            else
            {
                var vertIndex = 0;
                var triIndex = 0;
                var triVert = 0;
                var heightRatio = height / heightSegments;

                for (int i = 0; i <= sidesPipe; i++)
                {
                    float angle0 = ((float)i / sides) * Mathf.PI * 2.0f;

                    if (i == sidesPipe)
                    {
                        angle0 = pipeAngle;
                    }

                    var v0 = new Vector3(Mathf.Cos(angle0), 0.0f, Mathf.Sin(angle0)).normalized;

                    var currHeight = 0.0f;

                    for (int j = 0; j <= heightSegments; j++)
                    {
                        // generate vertices for outer side
                        vertices[vertIndex + 0] = bottomCenter + v0 * radius1 + new Vector3(0, currHeight, 0) + pivotOffset;
                        normals[vertIndex + 0] = v0;
                        uvs[vertIndex + 0] = new Vector2((float)i / sides, (float)j / heightSegments);

                        // generate vertices for inner side
                        vertices[vertIndex + innerVertOffset + 0] = bottomCenter + v0 * radius0 + new Vector3(0, currHeight, 0) + pivotOffset;
                        normals[vertIndex + innerVertOffset + 0] = -v0;
                        uvs[vertIndex + innerVertOffset + 0] = new Vector2((float)i / sides, (float)j / heightSegments);

                        vertIndex += 1;
                        currHeight += heightRatio;
                    }
                }

                for (int i=0; i<sidesPipe; i++)
                {
                    var triVertNext = (i+1)*(heightSegments+1);

                    for (int j=0; j<heightSegments; j++)
                    {
                        triangles[triIndex + 0] = triVert + 0;
                        triangles[triIndex + 1] = triVert + 1;
                        triangles[triIndex + 2] = triVertNext + 0;

                        triangles[triIndex + 3] = triVertNext + 0;
                        triangles[triIndex + 4] = triVert + 1;
                        triangles[triIndex + 5] = triVertNext + 1;

                        triangles[triIndex + innerTriOffset + 0] = triVertNext + innerVertOffset + 0;
                        triangles[triIndex + innerTriOffset + 1] = triVert + innerVertOffset + 1;
                        triangles[triIndex + innerTriOffset + 2] = triVert + innerVertOffset + 0;

                        triangles[triIndex + innerTriOffset + 3] = triVertNext + innerVertOffset + 1;
                        triangles[triIndex + innerTriOffset + 4] = triVert + innerVertOffset + 1;
                        triangles[triIndex + innerTriOffset + 5] = triVertNext + innerVertOffset + 0;

                        triIndex += 6;
                        triVert += 1;
                        triVertNext += 1;
                    }

                    triVert += 1;
                }
            }

            // generate caps
            {
                var vertIndex = numVertices;
                var triIndex = numTriangles;
                var triVert = vertIndex;
                var downVertOffset = numVerticesCaps/2;
                var downTriOffset = numTrianglesCaps/2;
                var downUVRatio = 0.5f*(radius0/radius1);

                for (int i = 0; i <=sidesPipe; i++)
                {
                    float angle0 = ((float)i / sides) * Mathf.PI * 2.0f;

                    if (i == sidesPipe)
                    {
                        angle0 = pipeAngle;
                    }

                    var v0 = new Vector3(Mathf.Cos(angle0), 0.0f, Mathf.Sin(angle0)).normalized;

                    // generate top caps
                    vertices[vertIndex + 0] = bottomCenter + v0 * radius0 + new Vector3(0, height, 0) + pivotOffset;
                    normals[vertIndex + 0] = new Vector3(0, 1, 0);
                    vertices[vertIndex + 1] = bottomCenter + v0 * radius1 + new Vector3(0, height, 0) + pivotOffset;
                    normals[vertIndex + 1] = new Vector3(0, 1, 0);

                    var uvV = new Vector2(v0.x*0.5f, v0.z*.5f);
                    var uvVInner = new Vector2(v0.x * downUVRatio, v0.z * downUVRatio);
                    var uvCenter = new Vector2(0.5f, 0.5f);

                    var ratio = (float)i / sides;

                    if (radialMapping)
                    {
                        uvs[vertIndex + 0] = new Vector2(ratio, 1.0f);
                        uvs[vertIndex + 1] = new Vector2(ratio, 0.0f);
                    }
                    else
                    {
                        uvs[vertIndex + 0] = uvCenter + uvVInner;
                        uvs[vertIndex + 1] = uvCenter + uvV;
                    }

                    // generate down caps
                    vertices[vertIndex + downVertOffset + 0] = bottomCenter + v0 * radius0 + pivotOffset;
                    normals[vertIndex + downVertOffset + 0] = new Vector3(0, -1, 0);
                    vertices[vertIndex + downVertOffset + 1] = bottomCenter + v0 * radius1 + pivotOffset;
                    normals[vertIndex + downVertOffset + 1] = new Vector3(0, -1, 0);

                    if (radialMapping)
                    {
                        uvs[vertIndex + downVertOffset + 0] = new Vector2(ratio, 1.0f);
                        uvs[vertIndex + downVertOffset + 1] = new Vector2(ratio, 0.0f);
                    }
                    else
                    {
                        uvs[vertIndex + downVertOffset + 0] = uvCenter + uvVInner;
                        uvs[vertIndex + downVertOffset + 1] = uvCenter + uvV;
                    }

                    vertIndex += 2;
                }

                for (int i=0; i<sidesPipe; i++)
                {
                    var triVertNext = numVertices + (i + 1) * 2;
                    var triVertNextDown = numVertices + downVertOffset + (i + 1) * 2;

                    triangles[triIndex + 0] = triVertNext + 0;
                    triangles[triIndex + 1] = triVert + 1;
                    triangles[triIndex + 2] = triVert + 0;

                    triangles[triIndex + 3] = triVertNext + 1;
                    triangles[triIndex + 4] = triVert + 1;
                    triangles[triIndex + 5] = triVertNext + 0;

                    triangles[triIndex + downTriOffset + 0] = triVert + downVertOffset + 0;
                    triangles[triIndex + downTriOffset + 1] = triVert + downVertOffset + 1;
                    triangles[triIndex + downTriOffset + 2] = triVertNextDown + 0;

                    triangles[triIndex + downTriOffset + 3] = triVertNextDown + 0;
                    triangles[triIndex + downTriOffset + 4] = triVert + downVertOffset + 1;
                    triangles[triIndex + downTriOffset + 5] = triVertNextDown + 1;

                    triIndex += 6;
                    triVert += 2;
                }
            }

            // generate pipe caps
            if (sidesPipe < sides)
            {
                var triIndex = numTriangles + numTrianglesCaps;
                var vertIndex = numVertices + numVerticesCaps;

                // vertices
                if (normalsType == NormalsType.Vertex)
                {
                    vertices[vertIndex + 0] = vertices[0];
                    vertices[vertIndex + 1] = vertices[innerVertOffset];
                    vertices[vertIndex + 2] = vertices[heightSegments];
                    vertices[vertIndex + 3] = vertices[innerVertOffset + heightSegments];

                    vertices[vertIndex + 4] = vertices[(sidesPipe) * (heightSegments + 1) + heightSegments];
                    vertices[vertIndex + 5] = vertices[(sidesPipe) * (heightSegments+1) + innerVertOffset];
                    vertices[vertIndex + 6] = vertices[(sidesPipe) * (heightSegments + 1)];
                    vertices[vertIndex + 7] = vertices[(sidesPipe) * (heightSegments+1) + innerVertOffset + heightSegments];
                }
                else
                {
                    vertices[vertIndex + 0] = vertices[0];
                    vertices[vertIndex + 1] = vertices[innerVertOffset];
                    vertices[vertIndex + 2] = vertices[heightSegments * 2];
                    vertices[vertIndex + 3] = vertices[innerVertOffset + heightSegments * 2];

                    vertices[vertIndex + 4] = vertices[(sidesPipe - 1) * ((heightSegments + 1) * 2) + (heightSegments) * 2 + 1];
                    vertices[vertIndex + 5] = vertices[(sidesPipe - 1) * ((heightSegments + 1) * 2) + innerVertOffset + 1];
                    vertices[vertIndex + 6] = vertices[(sidesPipe - 1) * ((heightSegments + 1) * 2) + 1];
                    vertices[vertIndex + 7] = vertices[(sidesPipe - 1) * ((heightSegments + 1) * 2) + innerVertOffset + (heightSegments) * 2 + 1];
                }

                // triangles
                triangles[triIndex + 0] = vertIndex + 0;
                triangles[triIndex + 1] = vertIndex + 1;
                triangles[triIndex + 2] = vertIndex + 2;
                triangles[triIndex + 3] = vertIndex + 3;
                triangles[triIndex + 4] = vertIndex + 2;
                triangles[triIndex + 5] = vertIndex + 1;

                triangles[triIndex + 6] = vertIndex + 4;
                triangles[triIndex + 7] = vertIndex + 5;
                triangles[triIndex + 8] = vertIndex + 6;
                triangles[triIndex + 9] = vertIndex + 7;
                triangles[triIndex + 10] = vertIndex + 5;
                triangles[triIndex + 11] = vertIndex + 4;

                // normals
                var normal0 = Vector3.Cross(vertices[vertIndex + 1] - vertices[vertIndex + 0], vertices[vertIndex + 2] - vertices[vertIndex + 0]);
                normals[vertIndex + 0] = normal0;
                normals[vertIndex + 1] = normal0;
                normals[vertIndex + 2] = normal0;
                normals[vertIndex + 3] = normal0;

                var normal1 = Vector3.Cross(vertices[vertIndex + 5] - vertices[vertIndex + 4], vertices[vertIndex + 6] - vertices[vertIndex + 4]);
                normals[vertIndex + 4] = normal1;
                normals[vertIndex + 5] = normal1;
                normals[vertIndex + 6] = normal1;
                normals[vertIndex + 7] = normal1;

                // uvs
            //                var uvInnerRatio = radius0/radius1;
            //                uvs[vertIndex + 0] = new Vector2(0.0f, uvInnerRatio);
            //                uvs[vertIndex + 1] = new Vector2(0.0f, 1.0f);
            //                uvs[vertIndex + 2] = new Vector2(1.0f, uvInnerRatio);
            //                uvs[vertIndex + 3] = new Vector2(1.0f, 1.0f);
            //
            //                uvs[vertIndex + 4] = new Vector2(0.0f, 0.0f);
            //                uvs[vertIndex + 5] = new Vector2(1.0f, 1.0f-uvInnerRatio);
            //                uvs[vertIndex + 6] = new Vector2(1.0f, 0.0f);
            //                uvs[vertIndex + 7] = new Vector2(0.0f, 1.0f-uvInnerRatio);

                // this code is responsible for uv mapping of the inside of tube slice cap
                // VERTICAL MAPPING FIX:
                uvs[vertIndex + 0] = new Vector2(1.0f, 1.0f);
                uvs[vertIndex + 1] = new Vector2(0.0f, 1.0f);
                uvs[vertIndex + 2] = new Vector2(1.0f, 0.0f);
                uvs[vertIndex + 3] = new Vector2(0.0f, 0.0f);

                uvs[vertIndex + 4] = new Vector2(1.0f, 1.0f);
                uvs[vertIndex + 5] = new Vector2(0.0f, 0.0f);
                uvs[vertIndex + 6] = new Vector2(1.0f, 0.0f);
                uvs[vertIndex + 7] = new Vector2(0.0f, 1.0f);
            }

            mesh.vertices = vertices;
            mesh.normals = normals;
            mesh.uv = uvs;
            mesh.triangles = triangles;
            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            mesh.Optimize();

            stopWatch.Stop();
            return stopWatch.ElapsedMilliseconds;
        }
示例#31
0
        // Token: 0x06004202 RID: 16898 RVA: 0x0014F9F0 File Offset: 0x0014DDF0
        public void GenerateGeometry(float radius, float height, int sides, int heightSegments, NormalsType normalsType, PivotPosition pivotPosition)
        {
            MeshFilter component = base.GetComponent <MeshFilter>();

            if (component.sharedMesh == null)
            {
                component.sharedMesh = new Mesh();
            }
            Mesh sharedMesh = component.sharedMesh;

            base.GenerationTimeMS = ConePrimitive.GenerateGeometry(sharedMesh, radius, radius, height, sides, heightSegments, normalsType, pivotPosition);
            this.radius           = radius;
            this.height           = height;
            this.sides            = sides;
            this.heightSegments   = heightSegments;
            this.normalsType      = normalsType;
            this.flipNormals      = false;
            this.pivotPosition    = pivotPosition;
        }
示例#32
0
        /// <summary>
        /// generate mesh geometry for cone
        /// </summary>
        /// <param name="mesh">mesh to be generated</param>
        /// <param name="radius0">fist radius of cone</param>
        /// <param name="radius1">second radius of cone</param>
        /// <param name="height">height of cone</param>
        /// <param name="sides">number of triangle segments in radius</param>
        /// <param name="heightSegments">number of triangle segments in height</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public static float GenerateGeometry(Mesh mesh, float radius0, float radius1, float height, int sides, int heightSegments, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var stopWatch = new Stopwatch();

            stopWatch.Start();
            mesh.Clear();

            radius0        = Mathf.Clamp(radius0, 0, 100);
            radius1        = Mathf.Clamp(radius1, 0, 100);
            height         = Mathf.Clamp(height, 0, 100);
            sides          = Mathf.Clamp(sides, 3, 100);
            heightSegments = Mathf.Clamp(heightSegments, 1, 100);

            int numVertices      = 0;
            int numTriangles     = sides * 6 * heightSegments;
            int numVerticesCaps  = 2 * (sides + 1);
            int numTrianglesCaps = 2 * (3 * sides);

            if (normalsType == NormalsType.Face)
            {
                numVertices = sides * (4 + (heightSegments - 1) * 2);
            }
            else
            {
                numVertices = (sides + 1) * (heightSegments + 1);
            }

            if (numVertices + numVerticesCaps > 60000)
            {
                UnityEngine.Debug.LogError("Too much vertices!");
                return(0.0f);
            }

            var vertices  = new Vector3[numVertices + numVerticesCaps];
            var normals   = new Vector3[numVertices + numVerticesCaps];
            var uvs       = new Vector2[numVertices + numVerticesCaps];
            var triangles = new int[numTriangles + numTrianglesCaps];

            var bottomCenter = Vector3.zero;
            var coneHeight   = (new Vector3(bottomCenter.x + radius0, bottomCenter.y, bottomCenter.z) -
                                new Vector3(bottomCenter.x + radius1, bottomCenter.y + height, bottomCenter.z)).magnitude;

            var pivotOffset = Vector3.zero;

            switch (pivotPosition)
            {
            case PivotPosition.Center: pivotOffset = new Vector3(0.0f, -height / 2, 0.0f);
                break;

            case PivotPosition.Top: pivotOffset = new Vector3(0.0f, -height, 0.0f);
                break;
            }

            if (normalsType == NormalsType.Face)
            {
                var vertIndex   = 0;
                var triIndex    = 0;
                var heightRatio = coneHeight / heightSegments;

                for (int i = 0; i < sides; i++)
                {
                    float angle0 = ((float)i / sides) * Mathf.PI * 2.0f;
                    var   v0     = new Vector3(Mathf.Cos(angle0), 0.0f, Mathf.Sin(angle0)).normalized;

                    float angle1 = ((float)(i + 1) / sides) * Mathf.PI * 2.0f;
                    var   v1     = new Vector3(Mathf.Cos(angle1), 0.0f, Mathf.Sin(angle1)).normalized;

                    var currHeight = 0.0f;
                    var triVert    = vertIndex;

                    var upVector0 = ((bottomCenter + new Vector3(0, height, 0)) + v0 * radius1) - (bottomCenter + v0 * radius0);
                    var upVector1 = ((bottomCenter + new Vector3(0, height, 0)) + v1 * radius1) - (bottomCenter + v1 * radius0);

                    upVector0.Normalize();
                    upVector1.Normalize();

                    var normal = (v0 + v1).normalized;

                    for (int j = 0; j <= heightSegments; j++)
                    {
                        // generate vertices
                        vertices[vertIndex + 0] = bottomCenter + v0 * radius0 + upVector0 * currHeight + pivotOffset;
                        vertices[vertIndex + 1] = bottomCenter + v1 * radius0 + upVector1 * currHeight + pivotOffset;

                        normals[vertIndex + 0] = normal;
                        normals[vertIndex + 1] = normal;

                        uvs[vertIndex + 0] = new Vector2((float)i / sides, (float)j / heightSegments);
                        uvs[vertIndex + 1] = new Vector2((float)(i + 1) / sides, (float)j / heightSegments);

                        vertIndex += 2;

                        currHeight += heightRatio;
                    }

                    for (int j = 0; j < heightSegments; j++)
                    {
                        triangles[triIndex + 0] = triVert + 0;
                        triangles[triIndex + 1] = triVert + 2;
                        triangles[triIndex + 2] = triVert + 1;

                        triangles[triIndex + 3] = triVert + 2;
                        triangles[triIndex + 4] = triVert + 3;
                        triangles[triIndex + 5] = triVert + 1;

                        triIndex += 6;
                        triVert  += 2;
                    }
                }
            }
            else
            {
                var vertIndex   = 0;
                var triIndex    = 0;
                var triVert     = 0;
                var heightRatio = coneHeight / heightSegments;

                for (int i = 0; i <= sides; i++)
                {
                    float angle0 = ((float)i / sides) * Mathf.PI * 2.0f;
                    var   v0     = new Vector3(Mathf.Cos(angle0), 0.0f, Mathf.Sin(angle0)).normalized;

                    var upVector = ((bottomCenter + new Vector3(0, height, 0)) + v0 * radius1) - (bottomCenter + v0 * radius0);
                    upVector.Normalize();

                    var currHeight = 0.0f;

                    for (int j = 0; j <= heightSegments; j++)
                    {
                        // generate vertices
                        vertices[vertIndex + 0] = bottomCenter + v0 * radius0 + upVector * currHeight + pivotOffset;
                        normals[vertIndex + 0]  = v0;
                        uvs[vertIndex + 0]      = new Vector2((float)i / sides, (float)j / heightSegments);

                        vertIndex  += 1;
                        currHeight += heightRatio;
                    }
                }

                for (int i = 0; i < sides; i++)
                {
                    var triVertNext = (i + 1) * (heightSegments + 1);

                    for (int j = 0; j < heightSegments; j++)
                    {
                        triangles[triIndex + 0] = triVert + 0;
                        triangles[triIndex + 1] = triVert + 1;
                        triangles[triIndex + 2] = triVertNext + 0;

                        triangles[triIndex + 3] = triVertNext + 0;
                        triangles[triIndex + 4] = triVert + 1;
                        triangles[triIndex + 5] = triVertNext + 1;

                        triIndex    += 6;
                        triVert     += 1;
                        triVertNext += 1;
                    }

                    triVert += 1;
                }
            }

            // generate caps
            {
                var vertIndex = numVertices;
                var triIndex  = numTriangles;
                var triVert   = vertIndex;

                for (int i = 0; i < sides; i++)
                {
                    float angle0 = ((float)i / sides) * Mathf.PI * 2.0f;
                    var   v0     = new Vector3(Mathf.Cos(angle0), 0.0f, Mathf.Sin(angle0)).normalized;

                    vertices[vertIndex + 0] = bottomCenter + v0 * radius0 + pivotOffset;
                    normals[vertIndex + 0]  = new Vector3(0, -1, 0);
                    vertices[vertIndex + 1] = bottomCenter + v0 * radius1 + new Vector3(0, height, 0) + pivotOffset;
                    normals[vertIndex + 1]  = new Vector3(0, 1, 0);

                    var uvV      = new Vector2(v0.x * 0.5f, v0.z * .5f);
                    var uvCenter = new Vector2(0.5f, 0.5f);
                    uvs[vertIndex + 0] = uvCenter + uvV;
                    uvs[vertIndex + 1] = uvCenter + uvV;

                    vertIndex += 2;
                }

                vertices[vertIndex + 0] = new Vector3(0, 0, 0) + pivotOffset;
                vertices[vertIndex + 1] = new Vector3(0, height, 0) + pivotOffset;
                normals[vertIndex + 0]  = new Vector3(0, -1, 0);
                normals[vertIndex + 1]  = new Vector3(0, 1, 0);
                uvs[vertIndex + 0]      = new Vector2(0.5f, 0.5f);
                uvs[vertIndex + 1]      = new Vector2(0.5f, 0.5f);

                vertIndex += 2;

                for (int i = 0; i < sides; i++)
                {
                    triangles[triIndex + 0] = triVert + 0;
                    triangles[triIndex + 2] = vertIndex - 2;
                    triangles[triIndex + 3] = triVert + 1;
                    triangles[triIndex + 4] = vertIndex - 1;

                    if (i == sides - 1)
                    {
                        triangles[triIndex + 1] = numVertices;
                        triangles[triIndex + 5] = numVertices + 1;
                    }
                    else
                    {
                        triangles[triIndex + 1] = triVert + 2;
                        triangles[triIndex + 5] = triVert + 3;
                    }

                    triIndex += 6;
                    triVert  += 2;
                }
            }

            mesh.vertices  = vertices;
            mesh.normals   = normals;
            mesh.uv        = uvs;
            mesh.triangles = triangles;
            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            mesh.Optimize();

            stopWatch.Stop();
            return(stopWatch.ElapsedMilliseconds);
        }
示例#33
0
        /// <summary>
        /// generate mesh geometry for Tube
        /// </summary>
        /// <param name="mesh">mesh to be generated</param>
        /// <param name="radius0">fist radius of tube</param>
        /// <param name="radius1">second radius of tube</param>
        /// <param name="height">height of tube</param>
        /// <param name="sides">number of triangle segments in radius</param>
        /// <param name="heightSegments">number of triangle segments in height</param>
        /// <param name="slice">slicing parameter</param>
        /// <param name="radialMapping">uv radial mapping for top/down of the Tube</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public static float GenerateGeometry(Mesh mesh, float radius0, float radius1, float height, int sides, int heightSegments, float slice, bool radialMapping, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var stopWatch = new Stopwatch();

            stopWatch.Start();

            radius0        = Mathf.Clamp(radius0, 0, 100);
            radius1        = Mathf.Clamp(radius1, 0, 100);
            height         = Mathf.Clamp(height, 0, 1000);
            sides          = Mathf.Clamp(sides, 3, 100);
            heightSegments = Mathf.Clamp(heightSegments, 1, 100);
            slice          = Mathf.Clamp(slice, 0, 360);

            // normalize slice
            slice = slice / 360.0f;

            mesh.Clear();

            heightSegments = Mathf.Clamp(heightSegments, 1, 250);
            sides          = Mathf.Clamp(sides, 3, 250);

            var sidesPipe = (int)(sides * (1.0f - slice));
            var pipeAngle = (1.0f - slice) * 2.0f * Mathf.PI;

            if (sidesPipe == 0)
            {
                sidesPipe = 1;
            }

            var numVertices          = 0;
            var numTriangles         = sidesPipe * 6 * heightSegments * 2;
            var numVerticesCaps      = ((sidesPipe + 1) * 2 * 2);
            var numTrianglesCaps     = (sidesPipe) * 6 * 2;
            var numTrianglesPipeCaps = 0;
            var numVerticesPipeCaps  = 0;

            if (sidesPipe < sides)
            {
                numTrianglesPipeCaps = 12;
                numVerticesPipeCaps  = 8;
            }

            if (normalsType == NormalsType.Face)
            {
                numVertices = sidesPipe * (4 + (heightSegments - 1) * 2) * 2;
            }
            else
            {
                numVertices = (sidesPipe + 1) * (heightSegments + 1) * 2;
            }

            if (numVertices + numVerticesCaps > 60000)
            {
                UnityEngine.Debug.LogError("Too much vertices!");
                return(0.0f);
            }

            var vertices  = new Vector3[numVertices + numVerticesCaps + numVerticesPipeCaps];
            var normals   = new Vector3[numVertices + numVerticesCaps + numVerticesPipeCaps];
            var uvs       = new Vector2[numVertices + numVerticesCaps + numVerticesPipeCaps];
            var triangles = new int[numTriangles + numTrianglesCaps + numTrianglesPipeCaps];

            var bottomCenter    = Vector3.zero;
            var innerVertOffset = numVertices / 2;
            var innerTriOffset  = numTriangles / 2;

            var pivotOffset = Vector3.zero;

            switch (pivotPosition)
            {
            case PivotPosition.Center: pivotOffset = new Vector3(0.0f, -height / 2, 0.0f);
                break;

            case PivotPosition.Top: pivotOffset = new Vector3(0.0f, -height, 0.0f);
                break;
            }

            if (normalsType == NormalsType.Face)
            {
                var vertIndex   = 0;
                var triIndex    = 0;
                var heightRatio = height / heightSegments;

                for (var i = 0; i < sidesPipe; i++)
                {
                    var angle0 = ((float)i / sides) * Mathf.PI * 2.0f;
                    var v0     = new Vector3(Mathf.Cos(angle0), 0.0f, Mathf.Sin(angle0)).normalized;

                    var angle1 = ((float)(i + 1) / sides) * Mathf.PI * 2.0f;

                    if (i + 1 == sidesPipe)
                    {
                        angle1 = pipeAngle;
                    }

                    var v1 = new Vector3(Mathf.Cos(angle1), 0.0f, Mathf.Sin(angle1)).normalized;

                    var currHeight = 0.0f;
                    var triVert    = vertIndex;

                    var normal = (v0 + v1).normalized;

                    for (var j = 0; j <= heightSegments; j++)
                    {
                        // generate vertices for outer side
                        vertices[vertIndex + 0] = bottomCenter + v0 * radius1 + new Vector3(0, currHeight, 0) + pivotOffset;
                        vertices[vertIndex + 1] = bottomCenter + v1 * radius1 + new Vector3(0, currHeight, 0) + pivotOffset;

                        normals[vertIndex + 0] = normal;
                        normals[vertIndex + 1] = normal;

                        uvs[vertIndex + 0] = new Vector2((float)i / sides, (float)j / heightSegments);
                        uvs[vertIndex + 1] = new Vector2((float)(i + 1) / sides, (float)j / heightSegments);

                        // generate vertices for inner side
                        vertices[vertIndex + innerVertOffset + 0] = bottomCenter + v0 * radius0 + new Vector3(0, currHeight, 0) + pivotOffset;
                        vertices[vertIndex + innerVertOffset + 1] = bottomCenter + v1 * radius0 + new Vector3(0, currHeight, 0) + pivotOffset;

                        normals[vertIndex + innerVertOffset + 0] = -normal;
                        normals[vertIndex + innerVertOffset + 1] = -normal;

                        uvs[vertIndex + innerVertOffset + 0] = new Vector2((float)i / sides, (float)j / heightSegments);
                        uvs[vertIndex + innerVertOffset + 1] = new Vector2((float)(i + 1) / sides, (float)j / heightSegments);

                        vertIndex += 2;

                        currHeight += heightRatio;
                    }

                    for (var j = 0; j < heightSegments; j++)
                    {
                        // generate triangles for outer side
                        triangles[triIndex + 0] = triVert + 0;
                        triangles[triIndex + 1] = triVert + 2;
                        triangles[triIndex + 2] = triVert + 1;

                        triangles[triIndex + 3] = triVert + 2;
                        triangles[triIndex + 4] = triVert + 3;
                        triangles[triIndex + 5] = triVert + 1;

                        // generate triangles for inner side
                        triangles[triIndex + innerTriOffset + 0] = triVert + innerVertOffset + 1;
                        triangles[triIndex + innerTriOffset + 1] = triVert + innerVertOffset + 2;
                        triangles[triIndex + innerTriOffset + 2] = triVert + innerVertOffset + 0;

                        triangles[triIndex + innerTriOffset + 3] = triVert + innerVertOffset + 1;
                        triangles[triIndex + innerTriOffset + 4] = triVert + innerVertOffset + 3;
                        triangles[triIndex + innerTriOffset + 5] = triVert + innerVertOffset + 2;

                        triIndex += 6;
                        triVert  += 2;
                    }
                }
            }
            else
            {
                var vertIndex   = 0;
                var triIndex    = 0;
                var triVert     = 0;
                var heightRatio = height / heightSegments;

                for (var i = 0; i <= sidesPipe; i++)
                {
                    var angle0 = ((float)i / sides) * Mathf.PI * 2.0f;

                    if (i == sidesPipe)
                    {
                        angle0 = pipeAngle;
                    }

                    var v0 = new Vector3(Mathf.Cos(angle0), 0.0f, Mathf.Sin(angle0)).normalized;

                    var currHeight = 0.0f;

                    for (var j = 0; j <= heightSegments; j++)
                    {
                        // generate vertices for outer side
                        vertices[vertIndex + 0] = bottomCenter + v0 * radius1 + new Vector3(0, currHeight, 0) + pivotOffset;
                        normals[vertIndex + 0]  = v0;
                        uvs[vertIndex + 0]      = new Vector2((float)i / sides, (float)j / heightSegments);

                        // generate vertices for inner side
                        vertices[vertIndex + innerVertOffset + 0] = bottomCenter + v0 * radius0 + new Vector3(0, currHeight, 0) + pivotOffset;
                        normals[vertIndex + innerVertOffset + 0]  = -v0;
                        uvs[vertIndex + innerVertOffset + 0]      = new Vector2((float)i / sides, (float)j / heightSegments);

                        vertIndex  += 1;
                        currHeight += heightRatio;
                    }
                }

                for (var i = 0; i < sidesPipe; i++)
                {
                    var triVertNext = (i + 1) * (heightSegments + 1);

                    for (var j = 0; j < heightSegments; j++)
                    {
                        triangles[triIndex + 0] = triVert + 0;
                        triangles[triIndex + 1] = triVert + 1;
                        triangles[triIndex + 2] = triVertNext + 0;

                        triangles[triIndex + 3] = triVertNext + 0;
                        triangles[triIndex + 4] = triVert + 1;
                        triangles[triIndex + 5] = triVertNext + 1;

                        triangles[triIndex + innerTriOffset + 0] = triVertNext + innerVertOffset + 0;
                        triangles[triIndex + innerTriOffset + 1] = triVert + innerVertOffset + 1;
                        triangles[triIndex + innerTriOffset + 2] = triVert + innerVertOffset + 0;

                        triangles[triIndex + innerTriOffset + 3] = triVertNext + innerVertOffset + 1;
                        triangles[triIndex + innerTriOffset + 4] = triVert + innerVertOffset + 1;
                        triangles[triIndex + innerTriOffset + 5] = triVertNext + innerVertOffset + 0;

                        triIndex    += 6;
                        triVert     += 1;
                        triVertNext += 1;
                    }

                    triVert += 1;
                }
            }

            // generate caps
            {
                var vertIndex      = numVertices;
                var triIndex       = numTriangles;
                var triVert        = vertIndex;
                var downVertOffset = numVerticesCaps / 2;
                var downTriOffset  = numTrianglesCaps / 2;
                var downUVRatio    = 0.5f * (radius0 / radius1);

                for (var i = 0; i <= sidesPipe; i++)
                {
                    var angle0 = ((float)i / sides) * Mathf.PI * 2.0f;

                    if (i == sidesPipe)
                    {
                        angle0 = pipeAngle;
                    }

                    var v0 = new Vector3(Mathf.Cos(angle0), 0.0f, Mathf.Sin(angle0)).normalized;

                    // generate top caps
                    vertices[vertIndex + 0] = bottomCenter + v0 * radius0 + new Vector3(0, height, 0) + pivotOffset;
                    normals[vertIndex + 0]  = new Vector3(0, 1, 0);
                    vertices[vertIndex + 1] = bottomCenter + v0 * radius1 + new Vector3(0, height, 0) + pivotOffset;
                    normals[vertIndex + 1]  = new Vector3(0, 1, 0);

                    var uvV      = new Vector2(v0.x * 0.5f, v0.z * .5f);
                    var uvVInner = new Vector2(v0.x * downUVRatio, v0.z * downUVRatio);
                    var uvCenter = new Vector2(0.5f, 0.5f);

                    var ratio = (float)i / sides;

                    if (radialMapping)
                    {
                        uvs[vertIndex + 0] = new Vector2(ratio, 1.0f);
                        uvs[vertIndex + 1] = new Vector2(ratio, 0.0f);
                    }
                    else
                    {
                        uvs[vertIndex + 0] = uvCenter + uvVInner;
                        uvs[vertIndex + 1] = uvCenter + uvV;
                    }

                    // generate down caps
                    vertices[vertIndex + downVertOffset + 0] = bottomCenter + v0 * radius0 + pivotOffset;
                    normals[vertIndex + downVertOffset + 0]  = new Vector3(0, -1, 0);
                    vertices[vertIndex + downVertOffset + 1] = bottomCenter + v0 * radius1 + pivotOffset;
                    normals[vertIndex + downVertOffset + 1]  = new Vector3(0, -1, 0);

                    if (radialMapping)
                    {
                        uvs[vertIndex + downVertOffset + 0] = new Vector2(ratio, 1.0f);
                        uvs[vertIndex + downVertOffset + 1] = new Vector2(ratio, 0.0f);
                    }
                    else
                    {
                        uvs[vertIndex + downVertOffset + 0] = uvCenter + uvVInner;
                        uvs[vertIndex + downVertOffset + 1] = uvCenter + uvV;
                    }

                    vertIndex += 2;
                }

                for (var i = 0; i < sidesPipe; i++)
                {
                    var triVertNext     = numVertices + (i + 1) * 2;
                    var triVertNextDown = numVertices + downVertOffset + (i + 1) * 2;

                    triangles[triIndex + 0] = triVertNext + 0;
                    triangles[triIndex + 1] = triVert + 1;
                    triangles[triIndex + 2] = triVert + 0;

                    triangles[triIndex + 3] = triVertNext + 1;
                    triangles[triIndex + 4] = triVert + 1;
                    triangles[triIndex + 5] = triVertNext + 0;

                    triangles[triIndex + downTriOffset + 0] = triVert + downVertOffset + 0;
                    triangles[triIndex + downTriOffset + 1] = triVert + downVertOffset + 1;
                    triangles[triIndex + downTriOffset + 2] = triVertNextDown + 0;

                    triangles[triIndex + downTriOffset + 3] = triVertNextDown + 0;
                    triangles[triIndex + downTriOffset + 4] = triVert + downVertOffset + 1;
                    triangles[triIndex + downTriOffset + 5] = triVertNextDown + 1;

                    triIndex += 6;
                    triVert  += 2;
                }
            }

            // generate pipe caps
            if (sidesPipe < sides)
            {
                var triIndex  = numTriangles + numTrianglesCaps;
                var vertIndex = numVertices + numVerticesCaps;

                // vertices
                if (normalsType == NormalsType.Vertex)
                {
                    vertices[vertIndex + 0] = vertices[0];
                    vertices[vertIndex + 1] = vertices[innerVertOffset];
                    vertices[vertIndex + 2] = vertices[heightSegments];
                    vertices[vertIndex + 3] = vertices[innerVertOffset + heightSegments];

                    vertices[vertIndex + 4] = vertices[(sidesPipe) * (heightSegments + 1) + heightSegments];
                    vertices[vertIndex + 5] = vertices[(sidesPipe) * (heightSegments + 1) + innerVertOffset];
                    vertices[vertIndex + 6] = vertices[(sidesPipe) * (heightSegments + 1)];
                    vertices[vertIndex + 7] = vertices[(sidesPipe) * (heightSegments + 1) + innerVertOffset + heightSegments];
                }
                else
                {
                    vertices[vertIndex + 0] = vertices[0];
                    vertices[vertIndex + 1] = vertices[innerVertOffset];
                    vertices[vertIndex + 2] = vertices[heightSegments * 2];
                    vertices[vertIndex + 3] = vertices[innerVertOffset + heightSegments * 2];

                    vertices[vertIndex + 4] = vertices[(sidesPipe - 1) * ((heightSegments + 1) * 2) + (heightSegments) * 2 + 1];
                    vertices[vertIndex + 5] = vertices[(sidesPipe - 1) * ((heightSegments + 1) * 2) + innerVertOffset + 1];
                    vertices[vertIndex + 6] = vertices[(sidesPipe - 1) * ((heightSegments + 1) * 2) + 1];
                    vertices[vertIndex + 7] = vertices[(sidesPipe - 1) * ((heightSegments + 1) * 2) + innerVertOffset + (heightSegments) * 2 + 1];
                }

                // triangles
                triangles[triIndex + 0] = vertIndex + 0;
                triangles[triIndex + 1] = vertIndex + 1;
                triangles[triIndex + 2] = vertIndex + 2;
                triangles[triIndex + 3] = vertIndex + 3;
                triangles[triIndex + 4] = vertIndex + 2;
                triangles[triIndex + 5] = vertIndex + 1;

                triangles[triIndex + 6]  = vertIndex + 4;
                triangles[triIndex + 7]  = vertIndex + 5;
                triangles[triIndex + 8]  = vertIndex + 6;
                triangles[triIndex + 9]  = vertIndex + 7;
                triangles[triIndex + 10] = vertIndex + 5;
                triangles[triIndex + 11] = vertIndex + 4;

                // normals
                var normal0 = Vector3.Cross(vertices[vertIndex + 1] - vertices[vertIndex + 0], vertices[vertIndex + 2] - vertices[vertIndex + 0]);
                normals[vertIndex + 0] = normal0;
                normals[vertIndex + 1] = normal0;
                normals[vertIndex + 2] = normal0;
                normals[vertIndex + 3] = normal0;

                var normal1 = Vector3.Cross(vertices[vertIndex + 5] - vertices[vertIndex + 4], vertices[vertIndex + 6] - vertices[vertIndex + 4]);
                normals[vertIndex + 4] = normal1;
                normals[vertIndex + 5] = normal1;
                normals[vertIndex + 6] = normal1;
                normals[vertIndex + 7] = normal1;

                // uvs
//                var uvInnerRatio = radius0/radius1;
//                uvs[vertIndex + 0] = new Vector2(0.0f, uvInnerRatio);
//                uvs[vertIndex + 1] = new Vector2(0.0f, 1.0f);
//                uvs[vertIndex + 2] = new Vector2(1.0f, uvInnerRatio);
//                uvs[vertIndex + 3] = new Vector2(1.0f, 1.0f);
//
//                uvs[vertIndex + 4] = new Vector2(0.0f, 0.0f);
//                uvs[vertIndex + 5] = new Vector2(1.0f, 1.0f-uvInnerRatio);
//                uvs[vertIndex + 6] = new Vector2(1.0f, 0.0f);
//                uvs[vertIndex + 7] = new Vector2(0.0f, 1.0f-uvInnerRatio);

                // this code is responsible for uv mapping of the inside of tube slice cap
                // VERTICAL MAPPING FIX:
                uvs[vertIndex + 0] = new Vector2(1.0f, 1.0f);
                uvs[vertIndex + 1] = new Vector2(0.0f, 1.0f);
                uvs[vertIndex + 2] = new Vector2(1.0f, 0.0f);
                uvs[vertIndex + 3] = new Vector2(0.0f, 0.0f);

                uvs[vertIndex + 4] = new Vector2(1.0f, 1.0f);
                uvs[vertIndex + 5] = new Vector2(0.0f, 0.0f);
                uvs[vertIndex + 6] = new Vector2(1.0f, 0.0f);
                uvs[vertIndex + 7] = new Vector2(0.0f, 1.0f);
            }

            mesh.vertices  = vertices;
            mesh.normals   = normals;
            mesh.uv        = uvs;
            mesh.triangles = triangles;
            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            ;

            stopWatch.Stop();
            return(stopWatch.ElapsedMilliseconds);
        }
        /// <summary>
        /// generate mesh geometry for Ellipsoid
        /// </summary>
        /// <param name="mesh">mesh to be generated</param>
        /// <param name="width">width of ellipsoid</param>
        /// <param name="height">height of ellipsoid</param>
        /// <param name="length">length of ellipsoid</param>
        /// <param name="segments">number of segments</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public static float GenerateGeometry(Mesh mesh, float width, float height, float length, int segments, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var stopWatch = new Stopwatch();

            stopWatch.Start();

            width    = Mathf.Clamp(width, 0, 100);
            height   = Mathf.Clamp(height, 0, 100);
            length   = Mathf.Clamp(length, 0, 100);
            segments = Mathf.Clamp(segments, 4, 100);

            mesh.Clear();

            var rings   = segments - 1;
            var sectors = segments;

            var R = 1 / (float)(rings - 1);
            var S = 1 / (float)(sectors - 1);

            var verticesNum  = rings * sectors;
            var trianglesNum = (rings - 1) * (sectors - 1) * 6;

            if (normalsType == NormalsType.Face)
            {
                verticesNum = trianglesNum;
            }

            var pivotOffset = Vector3.zero;

            switch (pivotPosition)
            {
            case PivotPosition.Botttom: pivotOffset = new Vector3(0.0f, height, 0.0f);
                break;

            case PivotPosition.Top: pivotOffset = new Vector3(0.0f, -height, 0.0f);
                break;
            }

            if (verticesNum > 60000)
            {
                UnityEngine.Debug.LogError("Too much vertices!");
                return(0.0f);
            }

            var vertices  = new Vector3[verticesNum];
            var normals   = new Vector3[verticesNum];
            var uvs       = new Vector2[verticesNum];
            var triangles = new int[trianglesNum];

            var vertIndex = 0;
            var triIndex  = 0;

            for (var r = 0; r < rings; r++)
            {
                var y    = Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * r * R);
                var sinR = Mathf.Sin(Mathf.PI * r * R);

                for (var s = 0; s < sectors; s++)
                {
                    var x = Mathf.Sin(2 * Mathf.PI * s * S) * sinR;
                    var z = Mathf.Cos(2 * Mathf.PI * s * S) * sinR;

                    vertices[vertIndex + 0] = new Vector3(x * width, y * height, z * length) + pivotOffset;
                    normals[vertIndex + 0]  = new Vector3(x, y, z);
                    uvs[vertIndex + 0]      = new Vector2(1.0f - (s * S), 1.0f - (r * R));

                    if (r < rings - 1 && s < sectors - 1)
                    {
                        triangles[triIndex + 0] = (r + 1) * sectors + (s);
                        triangles[triIndex + 1] = r * sectors + (s + 1);
                        triangles[triIndex + 2] = r * sectors + s;

                        triangles[triIndex + 3] = (r + 1) * sectors + (s + 1);
                        triangles[triIndex + 4] = r * sectors + (s + 1);
                        triangles[triIndex + 5] = (r + 1) * sectors + (s);

                        triIndex += 6;
                    }

                    vertIndex += 1;
                }
            }

            // duplicate triangles in face case
            if (normalsType == NormalsType.Face)
            {
                MeshUtils.DuplicateSharedVertices(ref vertices, ref uvs, triangles, -1);
            }

            mesh.vertices  = vertices;
            mesh.uv        = uvs;
            mesh.triangles = triangles;

            // generate normals by unity in face case
            if (normalsType == NormalsType.Face)
            {
                mesh.RecalculateNormals();
            }
            else
            {
                mesh.normals = normals;
            }

            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            ;

            stopWatch.Stop();
            return(stopWatch.ElapsedMilliseconds);
        }
示例#35
0
文件: Cone.cs 项目: Smoothstep/VRChat
        // Token: 0x060041F1 RID: 16881 RVA: 0x0014F40C File Offset: 0x0014D80C
        public void GenerateGeometry(float radius0, float radius1, float thickness, float height, int sides, int heightSegments, NormalsType normalsType, PivotPosition pivotPosition)
        {
            MeshFilter component = base.GetComponent <MeshFilter>();

            if (component.sharedMesh == null)
            {
                component.sharedMesh = new Mesh();
            }
            Mesh sharedMesh = component.sharedMesh;

            if (thickness >= 0f)
            {
                base.GenerationTimeMS = HollowConePrimitive.GenerateGeometry(sharedMesh, radius0, radius1, thickness, height, sides, heightSegments, normalsType, pivotPosition);
            }
            else
            {
                base.GenerationTimeMS = ConePrimitive.GenerateGeometry(sharedMesh, radius0, radius1, height, sides, heightSegments, normalsType, pivotPosition);
            }
            this.radius0        = radius0;
            this.radius1        = radius1;
            this.height         = height;
            this.thickness      = thickness;
            this.sides          = sides;
            this.heightSegments = heightSegments;
            this.normalsType    = normalsType;
            this.flipNormals    = false;
            this.pivotPosition  = pivotPosition;
        }
示例#36
0
        // Token: 0x060042F8 RID: 17144 RVA: 0x0015A1FC File Offset: 0x001585FC
        public static float GenerateGeometry(Mesh mesh, float radius, int subdivision, GeoSpherePrimitive.BaseType baseType, NormalsType normalsType, PivotPosition pivotPosition)
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            radius      = Mathf.Clamp(radius, 0f, 100f);
            subdivision = Mathf.Clamp(subdivision, 0, 6);
            mesh.Clear();
            bool sharedVertices = normalsType == NormalsType.Vertex;
            int  i        = GeoSpherePrimitive.GetVertCount(baseType, subdivision, sharedVertices);
            int  triCount = GeoSpherePrimitive.GetTriCount(baseType, subdivision);

            while (i > 60000)
            {
                subdivision--;
                i        = GeoSpherePrimitive.GetVertCount(baseType, subdivision, sharedVertices);
                triCount = GeoSpherePrimitive.GetTriCount(baseType, subdivision);
            }
            Vector3 zero = Vector3.zero;

            if (pivotPosition != PivotPosition.Botttom)
            {
                if (pivotPosition == PivotPosition.Top)
                {
                    zero = new Vector3(0f, -radius, 0f);
                }
            }
            else
            {
                zero = new Vector3(0f, radius, 0f);
            }
            int[]     array   = new int[triCount * 3];
            int[]     array2  = new int[triCount * 3];
            Vector3[] array3  = new Vector3[i];
            Vector2[] array4  = new Vector2[i];
            Vector3[] normals = null;
            GeoSpherePrimitive.InitBasePrimitive(radius, baseType, array3, array4, array);
            Dictionary <int, int> indexLookup = new Dictionary <int, int>();
            int vertCount = GeoSpherePrimitive.GetVertCount(baseType, 0, sharedVertices);

            for (int j = 0; j < subdivision; j++)
            {
                int num  = 0;
                int num2 = GeoSpherePrimitive.GetTriCount(baseType, j) * 3;
                for (int k = 0; k < num2; k += 3)
                {
                    int num3 = array[k];
                    int num4 = array[k + 1];
                    int num5 = array[k + 2];
                    int num6 = GeoSpherePrimitive.AddMidPoint(array3, radius, vertCount++, num3, num4, indexLookup);
                    int num7 = GeoSpherePrimitive.AddMidPoint(array3, radius, vertCount++, num4, num5, indexLookup);
                    int num8 = GeoSpherePrimitive.AddMidPoint(array3, radius, vertCount++, num5, num3, indexLookup);
                    array2[num]      = num3;
                    array2[num + 1]  = num6;
                    array2[num + 2]  = num8;
                    array2[num + 3]  = num4;
                    array2[num + 4]  = num7;
                    array2[num + 5]  = num6;
                    array2[num + 6]  = num5;
                    array2[num + 7]  = num8;
                    array2[num + 8]  = num7;
                    array2[num + 9]  = num6;
                    array2[num + 10] = num7;
                    array2[num + 11] = num8;
                    num += 12;
                }
                int[] array5 = array2;
                array2 = array;
                array  = array5;
            }
            if (normalsType == NormalsType.Face)
            {
                MeshUtils.DuplicateSharedVertices(ref array3, ref array4, array, -1);
            }
            for (int l = 0; l < i; l++)
            {
                array4[l] = GeoSpherePrimitive.GetSphericalUV(ref array3[l]);
            }
            List <Vector3> list  = new List <Vector3>(array3);
            List <Vector2> list2 = new List <Vector2>(array4);
            List <int>     list3 = new List <int>(array);

            GeoSpherePrimitive.CorrectSeam(list, list2, list3);
            GeoSpherePrimitive.CorrectPoles(list, list2, ref list3, radius);
            array3 = list.ToArray();
            array  = list3.ToArray();
            if (normalsType == NormalsType.Vertex)
            {
                GeoSpherePrimitive.CalculateNormals(array3, out normals);
            }
            else
            {
                MeshUtils.ComputeVertexNormals(array3, array, out normals);
            }
            GeoSpherePrimitive.CorrectPivot(list, pivotPosition, ref zero);
            if (list.Count > 60000)
            {
                UnityEngine.Debug.LogError("Too much vertices!");
                return(0f);
            }
            mesh.vertices  = list.ToArray();
            mesh.uv        = list2.ToArray();
            mesh.triangles = list3.ToArray();
            mesh.normals   = normals;
            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            stopwatch.Stop();
            return((float)stopwatch.ElapsedMilliseconds);
        }
示例#37
0
	/// <summary>
	/// Creates a diamond shape.
	/// </summary>
	/// <returns>The diamond.</returns>
	/// <param name="mesh">Mesh.</param>
	/// <param name="radius0">Radius0.</param>
	/// <param name="radius1">Radius1.</param>
	/// <param name="height">Height.</param>
	/// <param name="sides">Sides.</param>
	/// <param name="heightSegments">Height segments.</param>
	/// <param name="normalsType">Normals type.</param>
	/// <param name="pivotPosition">Pivot position.</param>
	public static float CreateDiamond(Mesh mesh, float radius0, float radius1, float height, int sides, int heightSegments, NormalsType normalsType, PivotPosition pivotPosition)
	{
		Debug.Log ("DIAMOND CREATED");
		return 0;
	}
        /// <summary>
        /// create SuperEllipsoid game object
        /// </summary>
        /// <param name="width">width of the cube</param>
        /// <param name="height">height of the cube</param>
        /// <param name="length">length of the cube</param>
        /// <param name="segments">number of segments</param>
        /// <param name="normals">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        /// <param name="n1">first parameter</param>
        /// <param name="n2">second parameter</param>
        /// <returns>SuperEllipsoid class with SuperEllipsoid game object</returns>
        public static SuperEllipsoid Create(float width, float height, float length, int segments, float n1, float n2, NormalsType normals, PivotPosition pivotPosition)
        {
            var sphereObject = new GameObject("SuperEllipsoidPro");

            sphereObject.AddComponent <MeshFilter>();
            var renderer = sphereObject.AddComponent <MeshRenderer>();

            renderer.sharedMaterial = new Material(Shader.Find("Diffuse"));

            var roundedCube = sphereObject.AddComponent <SuperEllipsoid>();

            roundedCube.GenerateGeometry(width, height, length, segments, n1, n2, normals, pivotPosition);

            return(roundedCube);
        }
示例#39
0
        /// <summary>
        /// generate mesh geometry for Torus
        /// </summary>
        /// <param name="mesh">mesh to be generated</param>
        /// <param name="torusRadius">radius of torus</param>
        /// <param name="coneRadius">radius of cone</param>
        /// <param name="torusSegments">number of triangle of torus</param>
        /// <param name="coneSegments">number of triangle of torus cone</param>
        /// <param name="slice">slice</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public static float GenerateGeometry(Mesh mesh, float torusRadius, float coneRadius, int torusSegments, int coneSegments, float slice, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var stopWatch = new Stopwatch();
            stopWatch.Start();

            torusRadius = Mathf.Clamp(torusRadius, 0, 100);
            coneRadius = Mathf.Clamp(coneRadius, 0, 100);
            torusSegments = Mathf.Clamp(torusSegments, 3, 250);
            coneSegments = Mathf.Clamp(coneSegments, 3, 100);
            slice = Mathf.Clamp(slice, 0.0f, 360.0f);

            mesh.Clear();

            // normalize slice
            slice = slice / 360.0f;
            int sidesSlice = (int)(torusSegments * (1.0f - slice));
            //            float pipeAngle = (1.0f - slice) * 2.0f * Mathf.PI;

            if (sidesSlice == 0)
            {
                sidesSlice = 1;
            }

            int numTriangles = 2 * (coneSegments) * (sidesSlice);
            int numVertices = 0;

            if (normalsType == NormalsType.Vertex)
            {
                numVertices = (sidesSlice + 1)*(coneSegments + 1);
            }
            else
            {
                numVertices = numTriangles*3;
            }

            int numTrianglesCaps = 0;
            int numVerticesCaps = 0;

            if (sidesSlice < torusSegments)
            {
                numTrianglesCaps = (coneSegments + 1)*2;
                numVerticesCaps = (coneSegments + 2)*2;
            }

            if (numVertices > 60000)
            {
                UnityEngine.Debug.LogError("Too much vertices!");
                return 0.0f;
            }

            var vertices = new Vector3[numVertices + numVerticesCaps];
            var normals = new Vector3[numVertices + numVerticesCaps];
            var uvs = new Vector2[numVertices + numVerticesCaps];
            var triangles = new int[numTriangles * 3 + numTrianglesCaps * 3];

            var theta = 0.0f;
            float step = 2.0f*Mathf.PI/torusSegments;
            var p = new Vector3();
            var pNext = new Vector3();
            var vertIndex = 0;
            var triIndex = 0;
            var triCapIndex = numTriangles*3;
            var vertCapIndex = numVertices+1;
            var lastTri = vertices.Length-1;

            var pivotOffset = Vector3.zero;
            switch (pivotPosition)
            {
                case PivotPosition.Botttom: pivotOffset = new Vector3(0.0f, coneRadius, 0.0f);
                    break;
                case PivotPosition.Top: pivotOffset = new Vector3(0.0f, -coneRadius, 0.0f);
                    break;
            }

            for (int i = 0; i <= sidesSlice+1; i++)
            {
                theta += step;

            //                if (i == sidesSlice)
            //                {
            //                    theta = pipeAngle;
            //                }

                p = pNext;

                // compute point on torus
                pNext = new Vector3(torusRadius * Mathf.Cos(theta), 0.0f, torusRadius * Mathf.Sin(theta));

                if (i > 0)
                {
                    var T = pNext - p;
                    var N = pNext + p;

                    // find vectors B and N perpendicular to tangent point at torus circle point p
                    var B = Vector3.Cross(T, N);
                    N = Vector3.Cross(B, T);

                    N.Normalize();
                    B.Normalize();

                    var theta2 = 0.0f;
                    var step2 = 2.0f*Mathf.PI/coneSegments;

                    for (int j=0; j<=coneSegments; j++)
                    {
                        theta2 += step2;

                        var s = coneRadius*Mathf.Sin(theta2);
                        var t = coneRadius*Mathf.Cos(theta2);

                        // find point u on cone radius
                        var u = (N*s) + (B*t);

                        vertices[vertIndex + 0] = pNext + u + pivotOffset;
                        normals[vertIndex + 0] = u.normalized;
                        uvs[vertIndex + 0] = new Vector2(1.0f - (float)(i-1) / torusSegments, (float)j / coneSegments);

                        vertIndex += 1;

                        // generate caps
                        if (sidesSlice < torusSegments)
                        {
                            if (i == sidesSlice + 1)
                            {
                                vertices[numVertices] = pNext + pivotOffset;
                                uvs[numVertices] = new Vector2(0.5f, 0.5f);
                                normals[numVertices] = T.normalized;

                                vertices[vertCapIndex + 0] = pNext + u + pivotOffset;
                                normals[vertCapIndex + 0] = T.normalized;
                                uvs[vertCapIndex + 0] = new Vector2(0.5f, 0.5f) + new Vector2(u.x * 0.5f, u.y * 0.5f);

                                if (j < coneSegments)
                                {
                                    triangles[triCapIndex + 0] = vertCapIndex + 1;
                                    triangles[triCapIndex + 1] = vertCapIndex + 0;
                                    triangles[triCapIndex + 2] = numVertices;
                                    triCapIndex += 3;
                                }

                                vertCapIndex += 1;
                            }
                            else if (i == 1)
                            {
                                var c1 = pNext;

                                vertices[lastTri] = c1 + pivotOffset;
                                uvs[lastTri] = new Vector2(0.5f, 0.5f);
                                normals[lastTri] = -T.normalized;

                                vertices[vertCapIndex + 0] = c1 + u + pivotOffset;
                                normals[vertCapIndex + 0] = -T.normalized;
                                uvs[vertCapIndex + 0] = new Vector2(0.5f, 0.5f) + new Vector2(u.x * 0.5f, u.y * 0.5f);

                                if (j < coneSegments)
                                {
                                    triangles[triCapIndex + 0] = lastTri;
                                    triangles[triCapIndex + 1] = vertCapIndex + 0;
                                    triangles[triCapIndex + 2] = vertCapIndex + 1;
                                    triCapIndex += 3;
                                }

                                vertCapIndex += 1;
                            }
                        }
                    }

                    if (i <= sidesSlice)
                    {
                        var torSeg = (i - 1) * (coneSegments + 1);
                        var nextTorSeg = (i) * (coneSegments + 1);
                        var trivert = 0;

                        for (int j = 0; j < coneSegments; j++)
                        {
                            triangles[triIndex + 0] = nextTorSeg + 0 + trivert;
                            triangles[triIndex + 1] = torSeg + 1 + trivert;
                            triangles[triIndex + 2] = torSeg + 0 + trivert;

                            triangles[triIndex + 3] = nextTorSeg + 1 + trivert;
                            triangles[triIndex + 4] = torSeg + 1 + trivert;
                            triangles[triIndex + 5] = nextTorSeg + 0 + trivert;

                            triIndex += 6;
                            trivert += 1;
                        }
                    }
                }
            }

            // duplicate shared vertices for face vertices
            if (normalsType == NormalsType.Face)
            {
                MeshUtils.DuplicateSharedVertices(ref vertices, ref uvs, triangles, -1);
            }

            mesh.vertices = vertices;
            mesh.triangles = triangles;

            if (normalsType == NormalsType.Vertex)
            {
                mesh.normals = normals;
            }
            else
            {
                mesh.RecalculateNormals();
            }

            mesh.uv = uvs;
            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            mesh.Optimize();

            stopWatch.Stop();
            return stopWatch.ElapsedMilliseconds;
        }
示例#40
0
        /// <summary>
        /// generate mesh geometry for TorusKnot
        /// </summary>
        /// <param name="mesh">mesh to be generated</param>
        /// <param name="torusRadius">radius of torus</param>
        /// <param name="coneRadius">radius of cone</param>
        /// <param name="torusSegments">number of triangle of torus</param>
        /// <param name="coneSegments">number of triangle of torus cone</param>
        /// <param name="P">Knot parameter</param>
        /// <param name="Q">Knot parameter</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public static float GenerateGeometry(Mesh mesh, float torusRadius, float coneRadius, int torusSegments, int coneSegments, int P, int Q, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var stopWatch = new Stopwatch();

            stopWatch.Start();

            torusRadius   = Mathf.Clamp(torusRadius, 0, 100);
            coneRadius    = Mathf.Clamp(coneRadius, 0, 100);
            torusSegments = Mathf.Clamp(torusSegments, 3, 250);
            coneSegments  = Mathf.Clamp(coneSegments, 3, 100);
            P             = Mathf.Clamp(P, 1, 20);
            Q             = Mathf.Clamp(Q, 1, 20);

            mesh.Clear();

            int numTriangles = 2 * (coneSegments) * (torusSegments);
            int numVertices  = 0;

            if (normalsType == NormalsType.Vertex)
            {
                numVertices = (torusSegments + 1) * (coneSegments + 1);
            }
            else
            {
                numVertices = numTriangles * 3;
            }

            if (numVertices > 60000)
            {
                UnityEngine.Debug.LogError("Too much vertices!");
                return(0.0f);
            }

            var vertices  = new Vector3[numVertices];
            var normals   = new Vector3[numVertices];
            var uvs       = new Vector2[numVertices];
            var triangles = new int[numTriangles * 3];

            var   theta     = 0.0f;
            float step      = 2.0f * Mathf.PI / torusSegments;
            var   p         = new Vector3();
            var   pNext     = new Vector3();
            var   vertIndex = 0;
            var   triIndex  = 0;

            var minY = float.MaxValue;
            var maxY = float.MinValue;

            for (int i = 0; i <= torusSegments + 1; i++)
            {
                theta += step;

                var r = torusRadius * 0.5f * (2.0f + Mathf.Sin(Q * theta));
                p = pNext;

                // compute point on torus
                pNext = new Vector3(r * Mathf.Cos(P * theta), r * Mathf.Cos(Q * theta), r * Mathf.Sin(P * theta));

                if (i > 0)
                {
                    var T = pNext - p;
                    var N = pNext + p;

                    // find vectors B and N perpendicular to tangent point at torus circle point p
                    var B = Vector3.Cross(T, N);
                    N = Vector3.Cross(B, T);

                    N.Normalize();
                    B.Normalize();

                    var theta2 = 0.0f;
                    var step2  = 2.0f * Mathf.PI / coneSegments;

                    for (int j = 0; j <= coneSegments; j++)
                    {
                        theta2 += step2;

                        var s = coneRadius * Mathf.Sin(theta2);
                        var t = coneRadius * Mathf.Cos(theta2);

                        // find point u on cone radius
                        var u = (N * s) + (B * t);

                        vertices[vertIndex + 0] = pNext + u;
                        normals[vertIndex + 0]  = u.normalized;
                        uvs[vertIndex + 0]      = new Vector2((float)(i - 1) / torusSegments, (float)j / coneSegments);

                        if (vertices[vertIndex].y < minY)
                        {
                            minY = vertices[vertIndex].y;
                        }
                        if (vertices[vertIndex].y > maxY)
                        {
                            maxY = vertices[vertIndex].y;
                        }

                        vertIndex += 1;
                    }

                    if (i <= torusSegments)
                    {
                        var torSeg     = (i - 1) * (coneSegments + 1);
                        var nextTorSeg = (i) * (coneSegments + 1);
                        var trivert    = 0;

                        for (int j = 0; j < coneSegments; j++)
                        {
                            triangles[triIndex + 0] = nextTorSeg + 0 + trivert;
                            triangles[triIndex + 1] = torSeg + 1 + trivert;
                            triangles[triIndex + 2] = torSeg + 0 + trivert;

                            triangles[triIndex + 3] = nextTorSeg + 1 + trivert;
                            triangles[triIndex + 4] = torSeg + 1 + trivert;
                            triangles[triIndex + 5] = nextTorSeg + 0 + trivert;

                            triIndex += 6;
                            trivert  += 1;
                        }
                    }
                }
            }

            // adjust pivot position
            if (pivotPosition != PivotPosition.Center)
            {
                var pivotOffset = pivotPosition == PivotPosition.Botttom ? -minY : -maxY;

                for (int i = 0; i < vertices.Length; i++)
                {
                    vertices[i].y += pivotOffset;
                }
            }

            // duplicate shared vertices for face vertices
            if (normalsType == NormalsType.Face)
            {
                MeshUtils.DuplicateSharedVertices(ref vertices, ref uvs, triangles, -1);
            }

            mesh.vertices  = vertices;
            mesh.triangles = triangles;

            if (normalsType == NormalsType.Vertex)
            {
                mesh.normals = normals;
            }
            else
            {
                mesh.RecalculateNormals();
            }

            mesh.uv = uvs;
            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            mesh.Optimize();

            stopWatch.Stop();
            return(stopWatch.ElapsedMilliseconds);
        }
示例#41
0
        /// <summary>
        /// generate geometry for GeoSphere
        /// </summary>
        /// <param name="mesh">mesh to be generated</param>
        /// <param name="radius">radius of sphere</param>
        /// <param name="subdivision">number of subdivision</param>
        /// <param name="baseType">type of generation primitive</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public static float GenerateGeometry(Mesh mesh, float radius, int subdivision, BaseType baseType, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var stopWatch = new Stopwatch();

            stopWatch.Start();

            radius      = Mathf.Clamp(radius, 0, 100);
            subdivision = Mathf.Clamp(subdivision, 0, 6);

            mesh.Clear();

            var sharedVertices = normalsType == NormalsType.Vertex;

            var verticesNum  = GetVertCount(baseType, subdivision, sharedVertices);
            var trianglesNum = GetTriCount(baseType, subdivision);

            // fix for too much vertices
            while (verticesNum > 60000)
            {
                subdivision -= 1;

                verticesNum  = GetVertCount(baseType, subdivision, sharedVertices);
                trianglesNum = GetTriCount(baseType, subdivision);
            }

            var pivotOffset = Vector3.zero;

            switch (pivotPosition)
            {
            case PivotPosition.Botttom: pivotOffset = new Vector3(0.0f, radius, 0.0f);
                break;

            case PivotPosition.Top: pivotOffset = new Vector3(0.0f, -radius, 0.0f);
                break;
            }

            var triangles    = new int[trianglesNum * 3];
            var trianglesTmp = new int[trianglesNum * 3];
            var vertices     = new Vector3[verticesNum];
            var uvs          = new Vector2[verticesNum];

            Vector3[] normals = null;

            // initialize basic primitive
            InitBasePrimitive(radius, baseType, vertices, uvs, triangles);

            var indexLookup = new Dictionary <int, int>();

            var vertIndex = GetVertCount(baseType, 0, sharedVertices);

            for (int i = 0; i < subdivision; i++)
            {
                var newTriIdx = 0;
                var triCount  = GetTriCount(baseType, i) * 3;

                for (int triIdx = 0; triIdx < triCount; triIdx += 3)
                {
                    // get triangle
                    var v1 = triangles[triIdx + 0];
                    var v2 = triangles[triIdx + 1];
                    var v3 = triangles[triIdx + 2];

                    // split each edge in half
                    var va = AddMidPoint(vertices, radius, vertIndex++, v1, v2, indexLookup);
                    var vb = AddMidPoint(vertices, radius, vertIndex++, v2, v3, indexLookup);
                    var vc = AddMidPoint(vertices, radius, vertIndex++, v3, v1, indexLookup);

                    // create 4 new triangles
                    trianglesTmp[newTriIdx + 0] = v1;
                    trianglesTmp[newTriIdx + 1] = va;
                    trianglesTmp[newTriIdx + 2] = vc;

                    trianglesTmp[newTriIdx + 3] = v2;
                    trianglesTmp[newTriIdx + 4] = vb;
                    trianglesTmp[newTriIdx + 5] = va;

                    trianglesTmp[newTriIdx + 6] = v3;
                    trianglesTmp[newTriIdx + 7] = vc;
                    trianglesTmp[newTriIdx + 8] = vb;

                    trianglesTmp[newTriIdx + 9]  = va;
                    trianglesTmp[newTriIdx + 10] = vb;
                    trianglesTmp[newTriIdx + 11] = vc;

                    newTriIdx += 12;
                }

                var swapTmp = trianglesTmp;
                trianglesTmp = triangles;
                triangles    = swapTmp;
            }

            // duplicate shared vertices if we are dealing with faces normals
            if (normalsType == NormalsType.Face)
            {
                MeshUtils.DuplicateSharedVertices(ref vertices, ref uvs, triangles, -1);
            }

            // generate spherical uv mapping
            for (int i = 0; i < verticesNum; i++)
            {
                uvs[i] = GetSphericalUV(ref vertices[i]);
            }

            var verticesList = new List <Vector3>(vertices);
            var uvList       = new List <Vector2>(uvs);
            var triangleList = new List <int>(triangles);

            CorrectSeam(verticesList, uvList, triangleList);
            CorrectPoles(verticesList, uvList, ref triangleList, radius);

            vertices  = verticesList.ToArray();
            triangles = triangleList.ToArray();

            if (normalsType == NormalsType.Vertex)
            {
                CalculateNormals(vertices, out normals);
            }
            else
            {
                MeshUtils.ComputeVertexNormals(vertices, triangles, out normals);
            }

            CorrectPivot(verticesList, pivotPosition, ref pivotOffset);

            trianglesTmp = null;

            if (verticesList.Count > 60000)
            {
                Debug.LogError("Too much vertices!");
                return(0.0f);
            }

            mesh.vertices  = verticesList.ToArray();
            mesh.uv        = uvList.ToArray();
            mesh.triangles = triangleList.ToArray();
            mesh.normals   = normals;

            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            mesh.Optimize();

            stopWatch.Stop();
            return(stopWatch.ElapsedMilliseconds);
        }
示例#42
0
        // Token: 0x06004313 RID: 17171 RVA: 0x0015E534 File Offset: 0x0015C934
        public static float GenerateGeometry(Mesh mesh, float width, float height, float length, int segments, float n1, float n2, NormalsType normalsType, PivotPosition pivotPosition)
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            width    = Mathf.Clamp(width, 0f, 100f);
            length   = Mathf.Clamp(length, 0f, 100f);
            height   = Mathf.Clamp(height, 0f, 100f);
            segments = Mathf.Clamp(segments, 1, 100);
            n1       = Mathf.Clamp(n1, 0.01f, 5f);
            n2       = Mathf.Clamp(n2, 0.01f, 5f);
            mesh.Clear();
            segments  = segments * 4 - 1;
            segments += 5;
            int num  = (segments + 1) * (segments / 2 + 1);
            int num2 = segments * (segments / 2) * 6;

            if (normalsType == NormalsType.Face)
            {
                num = num2;
            }
            if (num > 60000)
            {
                UnityEngine.Debug.LogError("Too much vertices!");
                return(0f);
            }
            Vector3[] array  = new Vector3[num];
            Vector2[] array2 = new Vector2[num];
            int[]     array3 = new int[num2];
            Vector3   zero   = Vector3.zero;

            if (pivotPosition != PivotPosition.Botttom)
            {
                if (pivotPosition == PivotPosition.Top)
                {
                    zero = new Vector3(0f, -height, 0f);
                }
            }
            else
            {
                zero = new Vector3(0f, height, 0f);
            }
            int num3 = 0;

            for (int i = 0; i <= segments / 2; i++)
            {
                for (int j = 0; j <= segments; j++)
                {
                    int   num4 = i * (segments + 1) + j;
                    float f    = (float)j * 2f * 3.14159274f / (float)segments;
                    float f2   = -1.57079637f + 3.14159274f * (float)i / ((float)segments / 2f);
                    array[num4].x  = SuperEllipsoidPrimitive.RPower(Mathf.Cos(f2), n1) * SuperEllipsoidPrimitive.RPower(Mathf.Cos(f), n2) * width;
                    array[num4].z  = SuperEllipsoidPrimitive.RPower(Mathf.Cos(f2), n1) * SuperEllipsoidPrimitive.RPower(Mathf.Sin(f), n2) * length;
                    array[num4].y  = SuperEllipsoidPrimitive.RPower(Mathf.Sin(f2), n1) * height;
                    array2[num4].x = Mathf.Atan2(array[num4].z, array[num4].x) / 6.28318548f;
                    if (array2[num4].x < 0f)
                    {
                        array2[num4].x = 1f + array2[num4].x;
                    }
                    array2[num4].y = 0.5f + Mathf.Atan2(array[num4].y, Mathf.Sqrt(array[num4].x * array[num4].x + array[num4].z * array[num4].z)) / 3.14159274f;
                    if (i == 0)
                    {
                        array[num4].x  = 0f;
                        array[num4].y  = -height;
                        array[num4].z  = 0f;
                        array2[num4].y = 0f;
                        array2[num4].x = 0f;
                    }
                    if (i == segments / 2)
                    {
                        array[num4].x  = 0f;
                        array[num4].y  = height;
                        array[num4].z  = 0f;
                        array2[num4].y = 1f;
                        array2[num4].x = array2[(i - 1) * (segments + 1) + j].x;
                    }
                    if (j == segments)
                    {
                        array[num4].x  = array[i * (segments + 1)].x;
                        array[num4].z  = array[i * (segments + 1)].z;
                        array2[num4].x = 1f;
                    }
                    array[num4] += zero;
                    if (num3 < num4)
                    {
                        num3 = num4;
                    }
                }
            }
            for (int k = 0; k <= segments; k++)
            {
                int num5 = segments + 1 + k;
                array2[k].x = array2[num5].x;
            }
            int num6 = 0;

            for (int l = 0; l < segments / 2; l++)
            {
                for (int m = 0; m < segments; m++)
                {
                    int num7  = l * (segments + 1) + m;
                    int num8  = l * (segments + 1) + (m + 1);
                    int num9  = (l + 1) * (segments + 1) + (m + 1);
                    int num10 = (l + 1) * (segments + 1) + m;
                    array3[num6]     = num9;
                    array3[num6 + 1] = num8;
                    array3[num6 + 2] = num7;
                    array3[num6 + 3] = num10;
                    array3[num6 + 4] = num9;
                    array3[num6 + 5] = num7;
                    num6            += 6;
                }
            }
            if (normalsType == NormalsType.Face)
            {
                MeshUtils.DuplicateSharedVertices(ref array, ref array2, array3, -1);
            }
            mesh.vertices  = array;
            mesh.uv        = array2;
            mesh.triangles = array3;
            if (normalsType == NormalsType.Vertex)
            {
                Vector3[] array4 = null;
                MeshUtils.ComputeVertexNormals(array, array3, out array4);
                for (int num11 = 0; num11 < segments / 2; num11++)
                {
                    int num12 = num11 * (segments + 1);
                    int num13 = num11 * (segments + 1) + segments;
                    array4[num13] = array4[num12];
                }
                mesh.normals = array4;
            }
            else
            {
                mesh.RecalculateNormals();
            }
            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            stopwatch.Stop();
            return((float)stopwatch.ElapsedMilliseconds);
        }
示例#43
0
        /// <summary>
        /// re/generate mesh geometry based on parameters
        /// </summary>
        /// <param name="radius0">fist radius of cone</param>
        /// <param name="radius1">second radius of cone</param>
        /// <param name="height">height of cone</param>
        /// <param name="sides">number of triangle segments in radius</param>
        /// <param name="heightSegments">number of triangle segments in height</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        /// <returns>Cone class with Cone game object</returns>
        public void GenerateGeometry(float radius0, float radius1, float thickness, float height, int sides, int heightSegments, NormalsType normalsType, PivotPosition pivotPosition)
        {
            // generate new mesh and clear old one
            var meshFilter = GetComponent <MeshFilter>();

            if (meshFilter.sharedMesh == null)
            {
                meshFilter.sharedMesh = new Mesh();
            }

            var mesh = meshFilter.sharedMesh;

            // generate geometry
            if (thickness >= 0)
            {
                GenerationTimeMS = Primitives.HollowConePrimitive.GenerateGeometry(mesh, radius0, radius1, thickness, height, sides, heightSegments, normalsType, pivotPosition);
            }
            else
            {
                GenerationTimeMS = Primitives.ConePrimitive.GenerateGeometry(mesh, radius0, radius1, height, sides, heightSegments, normalsType, pivotPosition);
            }

            this.radius0        = radius0;
            this.radius1        = radius1;
            this.height         = height;
            this.thickness      = thickness;
            this.sides          = sides;
            this.heightSegments = heightSegments;
            this.normalsType    = normalsType;
            this.flipNormals    = false;
            this.pivotPosition  = pivotPosition;
        }
示例#44
0
文件: Tube.cs 项目: pisipo/CTB
        /// <summary>
        /// re/generate mesh geometry based on parameters
        /// </summary>
        /// <param name="radius0">fist radius of tube</param>
        /// <param name="radius1">second radius of tube</param>
        /// <param name="height">height of tube</param>
        /// <param name="sides">number of triangle segments in radius</param>
        /// <param name="heightSegments">number of triangle segments in height</param>
        /// <param name="slice">slicing parameter</param>
        /// <param name="radialMapping">using radial uv mapping on the top/bottom of the tube</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public void GenerateGeometry(float radius0, float radius1, float height, int sides, int heightSegments, float slice, bool radialMapping, NormalsType normalsType, PivotPosition pivotPosition)
        {
            // generate new mesh and clear old one
            var meshFilter = GetComponent<MeshFilter>();

            if (meshFilter.sharedMesh == null)
            {
                meshFilter.sharedMesh = new Mesh();
            }

            var mesh = meshFilter.sharedMesh;

            // generate geometry
            GenerationTimeMS = Primitives.TubePrimitive.GenerateGeometry(mesh, radius0, radius1, height, sides, heightSegments, slice, radialMapping, normalsType, pivotPosition);

            this.radius0 = radius0;
            this.radius1 = radius1;
            this.height = height;
            this.sides = sides;
            this.heightSegments = heightSegments;
            this.slice = slice;
            this.radialMapping = radialMapping;
            this.normalsType = normalsType;
            this.flipNormals = false;
        }
示例#45
0
        /// <summary>
        /// generate mesh geometry for TorusKnot
        /// </summary>
        /// <param name="mesh">mesh to be generated</param>
        /// <param name="torusRadius">radius of torus</param>
        /// <param name="coneRadius">radius of cone</param>
        /// <param name="torusSegments">number of triangle of torus</param>
        /// <param name="coneSegments">number of triangle of torus cone</param>
        /// <param name="P">Knot parameter</param>
        /// <param name="Q">Knot parameter</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public static float GenerateGeometry(Mesh mesh, float torusRadius, float coneRadius, int torusSegments, int coneSegments, int P, int Q, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var stopWatch = new Stopwatch();
            stopWatch.Start();

            torusRadius = Mathf.Clamp(torusRadius, 0, 100);
            coneRadius = Mathf.Clamp(coneRadius, 0, 100);
            torusSegments = Mathf.Clamp(torusSegments, 3, 250);
            coneSegments = Mathf.Clamp(coneSegments, 3, 100);
            P = Mathf.Clamp(P, 1, 20);
            Q = Mathf.Clamp(Q, 1, 20);

            mesh.Clear();

            int numTriangles = 2 * (coneSegments) * (torusSegments);
            int numVertices = 0;

            if (normalsType == NormalsType.Vertex)
            {
                numVertices = (torusSegments + 1)*(coneSegments + 1);
            }
            else
            {
                numVertices = numTriangles * 3;
            }

            if (numVertices > 60000)
            {
                UnityEngine.Debug.LogError("Too much vertices!");
                return 0.0f;
            }

            var vertices = new Vector3[numVertices];
            var normals = new Vector3[numVertices];
            var uvs = new Vector2[numVertices];
            var triangles = new int[numTriangles * 3];

            var theta = 0.0f;
            float step = 2.0f*Mathf.PI/torusSegments;
            var p = new Vector3();
            var pNext = new Vector3();
            var vertIndex = 0;
            var triIndex = 0;

            var minY = float.MaxValue;
            var maxY = float.MinValue;

            for (int i = 0; i <= torusSegments+1; i++)
            {
                theta += step;

                var r = torusRadius*0.5f*(2.0f + Mathf.Sin(Q*theta));
                p = pNext;

                // compute point on torus
                pNext = new Vector3(r * Mathf.Cos(P * theta), r * Mathf.Cos(Q * theta), r * Mathf.Sin(P * theta));

                if (i > 0)
                {
                    var T = pNext - p;
                    var N = pNext + p;

                    // find vectors B and N perpendicular to tangent point at torus circle point p
                    var B = Vector3.Cross(T, N);
                    N = Vector3.Cross(B, T);

                    N.Normalize();
                    B.Normalize();

                    var theta2 = 0.0f;
                    var step2 = 2.0f*Mathf.PI/coneSegments;

                    for (int j=0; j<=coneSegments; j++)
                    {
                        theta2 += step2;

                        var s = coneRadius*Mathf.Sin(theta2);
                        var t = coneRadius*Mathf.Cos(theta2);

                        // find point u on cone radius
                        var u = (N*s) + (B*t);

                        vertices[vertIndex + 0] = pNext + u;
                        normals[vertIndex + 0] = u.normalized;
                        uvs[vertIndex + 0] = new Vector2((float)(i-1) / torusSegments, (float)j / coneSegments);

                        if (vertices[vertIndex].y < minY)
                        {
                            minY = vertices[vertIndex].y;
                        }
                        if (vertices[vertIndex].y > maxY)
                        {
                            maxY = vertices[vertIndex].y;
                        }

                        vertIndex += 1;
                    }

                    if (i <= torusSegments)
                    {
                        var torSeg = (i - 1) * (coneSegments + 1);
                        var nextTorSeg = (i) * (coneSegments + 1);
                        var trivert = 0;

                        for (int j = 0; j < coneSegments; j++)
                        {
                            triangles[triIndex + 0] = nextTorSeg + 0 + trivert;
                            triangles[triIndex + 1] = torSeg + 1 + trivert;
                            triangles[triIndex + 2] = torSeg + 0 + trivert;

                            triangles[triIndex + 3] = nextTorSeg + 1 + trivert;
                            triangles[triIndex + 4] = torSeg + 1 + trivert;
                            triangles[triIndex + 5] = nextTorSeg + 0 + trivert;

                            triIndex += 6;
                            trivert += 1;
                        }
                    }
                }
            }

            // adjust pivot position
            if (pivotPosition != PivotPosition.Center)
            {
                var pivotOffset = pivotPosition == PivotPosition.Botttom ? -minY : -maxY;

                for (int i=0; i<vertices.Length; i++)
                {
                    vertices[i].y += pivotOffset;
                }
            }

            // duplicate shared vertices for face vertices
            if (normalsType == NormalsType.Face)
            {
                MeshUtils.DuplicateSharedVertices(ref vertices, ref uvs, triangles, -1);
            }

            mesh.vertices = vertices;
            mesh.triangles = triangles;

            if (normalsType == NormalsType.Vertex)
            {
                mesh.normals = normals;
            }
            else
            {
                mesh.RecalculateNormals();
            }

            mesh.uv = uvs;
            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            mesh.Optimize();

            stopWatch.Stop();
            return stopWatch.ElapsedMilliseconds;
        }
示例#46
0
        /// <summary>
        /// create GeoSphere game object
        /// </summary>
        /// <param name="radius">radius of sphere</param>
        /// <param name="subdivision">number of subdivision</param>
        /// <param name="baseType">type of generation primitive</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public void GenerateGeometry(float radius, int subdivision, Primitives.GeoSpherePrimitive.BaseType baseType, NormalsType normalsType, PivotPosition pivotPosition)
        {
            // generate new mesh and clear old one
            var meshFilter = GetComponent <MeshFilter>();

            if (meshFilter.sharedMesh == null)
            {
                meshFilter.sharedMesh = new Mesh();
            }

            var mesh = meshFilter.sharedMesh;

            // geneate geometry
            GenerationTimeMS = Primitives.GeoSpherePrimitive.GenerateGeometry(mesh, radius, subdivision, baseType, normalsType, pivotPosition);

            this.radius        = radius;
            this.subdivision   = subdivision;
            this.baseType      = baseType;
            this.normalsType   = normalsType;
            this.flipNormals   = false;
            this.pivotPosition = pivotPosition;
        }
示例#47
0
        /// <summary>
        /// create RoundedCube game object
        /// </summary>
        /// <param name="width">width of the cube</param>
        /// <param name="height">height of the cube</param>
        /// <param name="length">length of the cube</param>
        /// <param name="segments">number of segments</param>
        /// <param name="roundness">roudness coefficient</param>
        /// <param name="normals">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        /// <returns>RoundedCube class with RoundedCube game object</returns>
        public static RoundedCube Create(float width, float height, float length, int segments, float roundness, NormalsType normals, PivotPosition pivotPosition)
        {
            var sphereObject = new GameObject("RoundedCubePro");

            sphereObject.AddComponent <MeshFilter>();
            var renderer = sphereObject.AddComponent <MeshRenderer>();

            renderer.sharedMaterial = new Material(Shader.Find("Diffuse"));

            var superellipsoid = sphereObject.AddComponent <RoundedCube>();

            superellipsoid.GenerateGeometry(width, height, length, segments, roundness, normals, pivotPosition);

            return(superellipsoid);
        }
示例#48
0
        /// <summary>
        /// re/generate mesh geometry based on parameters
        /// </summary>
        /// <param name="radius0">fist radius of tube</param>
        /// <param name="radius1">second radius of tube</param>
        /// <param name="height">height of tube</param>
        /// <param name="sides">number of triangle segments in radius</param>
        /// <param name="heightSegments">number of triangle segments in height</param>
        /// <param name="slice">slicing parameter</param>
        /// <param name="radialMapping">using radial uv mapping on the top/bottom of the tube</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public void GenerateGeometry(float radius0, float radius1, float height, int sides, int heightSegments, float slice, float angleRatio, bool radialMapping, NormalsType normalsType, PivotPosition pivotPosition)
        {
            // generate new mesh and clear old one
            var meshFilter = GetComponent <MeshFilter>();

            if (meshFilter.sharedMesh == null)
            {
                meshFilter.sharedMesh = new Mesh();
            }

            var mesh = meshFilter.sharedMesh;

            // generate geometry
            GenerationTimeMS = Primitives.HelixPrimitive.GenerateGeometry(mesh, radius0, radius1, height, sides, heightSegments, slice, angleRatio, radialMapping, normalsType, pivotPosition);

            this.radius0        = radius0;
            this.radius1        = radius1;
            this.height         = height;
            this.sides          = sides;
            this.heightSegments = heightSegments;
            this.slice          = slice;
            this.angleRatio     = angleRatio;
            this.radialMapping  = radialMapping;
            this.normalsType    = normalsType;
            this.flipNormals    = false;
        }
示例#49
0
        // Token: 0x0600421D RID: 16925 RVA: 0x00150108 File Offset: 0x0014E508
        public void GenerateGeometry(float radius, int subdivision, GeoSpherePrimitive.BaseType baseType, NormalsType normalsType, PivotPosition pivotPosition)
        {
            MeshFilter component = base.GetComponent <MeshFilter>();

            if (component.sharedMesh == null)
            {
                component.sharedMesh = new Mesh();
            }
            Mesh sharedMesh = component.sharedMesh;

            base.GenerationTimeMS = GeoSpherePrimitive.GenerateGeometry(sharedMesh, radius, subdivision, baseType, normalsType, pivotPosition);
            this.radius           = radius;
            this.subdivision      = subdivision;
            this.baseType         = baseType;
            this.normalsType      = normalsType;
            this.flipNormals      = false;
            this.pivotPosition    = pivotPosition;
        }
示例#50
0
        /// <summary>
        /// generate mesh geometry for Sphere
        /// </summary>
        /// <param name="mesh">mesh to be generated</param>
        /// <param name="radius">radius of sphere</param>
        /// <param name="segments">number of segments</param>
        /// <param name="hemisphere">hemisphere, 0 ... complete sphere, 0.5 ... half-sphere</param>
        /// <param name="innerRadius">radius of the inner sphere</param>
        /// <param name="slice">vertical slice parameter</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public static float GenerateGeometry(Mesh mesh, float radius, int segments, float hemisphere, float innerRadius, float slice, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var stopWatch = new Stopwatch();

            stopWatch.Start();

            radius      = Mathf.Clamp(radius, 0, 100);
            segments    = Mathf.Clamp(segments, 4, 100);
            hemisphere  = Mathf.Clamp(hemisphere, 0.0f, 1.0f);
            innerRadius = Mathf.Clamp01(innerRadius) * radius;
            slice       = Mathf.Clamp(slice, 0.0f, 360.0f);

            mesh.Clear();

            int rings   = segments - 1;
            int sectors = segments;

            slice = slice / 360.0f;
            int sidesSlice = (int)(sectors * (1.0f - slice));

            if (sidesSlice == 0)
            {
                sidesSlice = 1;
            }

            var hemisphereCapY    = -1 + hemisphere * 2;
            int hemisphereCapRing = rings;
            var hemisphereYpos    = -radius;

            float R = 1 / (float)(rings - 1);
            float S = 1 / (float)(sectors - 1);

            // calculate hemisphere parameters
            var lastY = 0.0f;

            for (int r = 0; r < rings; r++)
            {
                var y = Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * r * R);

                if (y < hemisphereCapY)
                {
                    hemisphereCapRing = r;
                    hemisphereYpos    = lastY * radius;
                    break;
                }

                lastY = y;
            }

            int verticesNum            = 0;
            var trianglesNum           = (hemisphereCapRing /* - 1*/) * (sectors /* - 1*/) * 6;
            var verticesHemisphereNum  = segments + 1;
            var trianglesHemisphereNum = segments * 3;

            if (hemisphereCapRing == rings)
            {
                trianglesNum -= sectors * 3;
            }

            if (normalsType == NormalsType.Vertex)
            {
                verticesNum = (hemisphereCapRing + 1) * (sectors + 1);
            }
            else
            {
                verticesNum = trianglesNum;
            }

            if (hemisphereCapRing == rings)
            {
                verticesNum -= sectors + 1;
            }

            if (innerRadius > 0 && hemisphereCapRing < rings)
            {
                verticesNum  *= 2;
                trianglesNum *= 2;

                verticesNum  += sectors * 2;
                trianglesNum += sectors * 3;
            }

            var pivotOffset = Vector3.zero;
            var height      = radius - hemisphereYpos;

            switch (pivotPosition)
            {
            case PivotPosition.Botttom: pivotOffset = new Vector3(0.0f, radius, 0.0f);
                break;

            case PivotPosition.Top: pivotOffset = new Vector3(0.0f, hemisphereYpos, 0.0f);
                break;

            case PivotPosition.Center: pivotOffset = new Vector3(0.0f, (hemisphereYpos + height / 2), 0.0f);
                break;
            }

            if (verticesNum + verticesHemisphereNum > 60000)
            {
                UnityEngine.Debug.LogError("Too much vertices!");
                return(0.0f);
            }

            var vertices  = new Vector3[verticesNum + verticesHemisphereNum];
            var normals   = new Vector3[verticesNum + verticesHemisphereNum];
            var uvs       = new Vector2[verticesNum + verticesHemisphereNum];
            var triangles = new int[trianglesNum + trianglesHemisphereNum];

            var vertIndex = 0;
            var triIndex  = 0;

//            MeshUtils.Log(sectors);

            for (int r = 0; r < hemisphereCapRing; r++)
            {
                var y    = -Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * r * R);
                var sinR = Mathf.Sin(Mathf.PI * r * R);

                for (int s = 0; s < sectors; s++)
                {
                    float x = Mathf.Sin(2 * Mathf.PI * s * S) * sinR;
                    float z = Mathf.Cos(2 * Mathf.PI * s * S) * sinR;

//                    if (s < sidesSlice)
//                    {
//                        continue;
//                    }

                    vertices[vertIndex + 0] = new Vector3(x, y, z) * radius + pivotOffset;
                    normals[vertIndex + 0]  = new Vector3(x, y, z);
                    uvs[vertIndex + 0]      = new Vector2(1.0f - (s * S), (r * R));

                    if (r < hemisphereCapRing - 1 && s < sectors - 1)
                    {
                        //543
                        triangles[triIndex + 5] = (r + 1) * sectors + (s);
                        triangles[triIndex + 4] = r * sectors + (s + 1);
                        triangles[triIndex + 3] = r * sectors + s;
                        //210
                        triangles[triIndex + 2] = (r + 1) * sectors + (s + 1);
                        triangles[triIndex + 1] = r * sectors + (s + 1);
                        triangles[triIndex + 0] = (r + 1) * sectors + (s);

                        triIndex += 6;
                    }

                    vertIndex += 1;
                }
            }

            var hemisphereVertOffset = vertIndex;

            // calculate hemisphere plane
            if (hemisphereCapRing < rings)
            {
                // generate inner sphere
                if (innerRadius > 0)
                {
                    var vertOffset = hemisphereVertOffset;
                    var outerY     = -Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * (hemisphereCapRing - 1) * R) * radius;
                    var innertY    = -Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * (hemisphereCapRing - 1) * R) * innerRadius;
                    var diff       = new Vector3(0, outerY - innertY, 0);

                    for (int r = 0; r < hemisphereCapRing; r++)
                    {
                        var y    = -Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * r * R);
                        var sinR = Mathf.Sin(Mathf.PI * r * R);

                        for (int s = 0; s < sectors; s++)
                        {
                            float x = Mathf.Sin(2 * Mathf.PI * s * S) * sinR;
                            float z = Mathf.Cos(2 * Mathf.PI * s * S) * sinR;

                            vertices[vertIndex + 0] = new Vector3(x, y, z) * innerRadius + pivotOffset + diff;
                            normals[vertIndex + 0]  = -new Vector3(x, y, z);
                            uvs[vertIndex + 0]      = new Vector2(1.0f - (s * S), (r * R));

                            if (r < hemisphereCapRing - 1 && s < sectors - 1)
                            {
                                triangles[triIndex + 0] = vertOffset + (r + 1) * sectors + (s);
                                triangles[triIndex + 1] = vertOffset + r * sectors + (s + 1);
                                triangles[triIndex + 2] = vertOffset + r * sectors + s;

                                triangles[triIndex + 3] = vertOffset + (r + 1) * sectors + (s + 1);
                                triangles[triIndex + 4] = vertOffset + r * sectors + (s + 1);
                                triangles[triIndex + 5] = vertOffset + (r + 1) * sectors + (s);

                                triIndex += 6;
                            }

                            vertIndex += 1;
                        }
                    }

                    hemisphereVertOffset = vertIndex;

                    // duplicate triangles in face case
                    if (normalsType == NormalsType.Face)
                    {
                        MeshUtils.DuplicateSharedVertices(ref vertices, ref uvs, triangles, triIndex);
                        hemisphereVertOffset = triIndex;
                    }

                    // connect two hemi-spheres
                    {
                        var y    = -Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * (hemisphereCapRing - 1) * R);
                        var sinR = Mathf.Sin(Mathf.PI * (hemisphereCapRing - 1) * R);

                        var triVert = hemisphereVertOffset;
                        vertIndex = triVert;

                        for (int i = 0; i < sectors; i++)
                        {
                            var x = Mathf.Sin(2 * Mathf.PI * i * S) * sinR;
                            var z = Mathf.Cos(2 * Mathf.PI * i * S) * sinR;
                            var v = new Vector3(x, y, z);

                            v.Normalize();

                            vertices[vertIndex + 0] = v * radius + pivotOffset;
                            vertices[vertIndex + 1] = v * innerRadius + pivotOffset + diff;
                            normals[vertIndex + 0]  = new Vector3(0.0f, 1.0f, 0.0f);
                            normals[vertIndex + 1]  = new Vector3(0.0f, 1.0f, 0.0f);

                            // make planar uv mapping for hemisphere plane
                            var uvV      = new Vector2(v.x * 0.5f, v.z * .5f);
                            var uvCenter = new Vector2(0.5f, 0.5f);
                            var uvV2     = new Vector2(v.x * innerRadius / radius * 0.5f, v.z * innerRadius / radius * 0.5f);

                            uvs[vertIndex + 0] = uvCenter + uvV;
                            uvs[vertIndex + 1] = uvCenter + uvV2;

                            vertIndex += 2;
                        }

                        for (int i = 0; i < rings; i++)
                        {
                            triangles[triIndex + 2] = triVert + 1;
                            triangles[triIndex + 1] = triVert + 2;
                            triangles[triIndex + 0] = triVert + 0;

                            triangles[triIndex + 4] = triVert + 3;
                            triangles[triIndex + 5] = triVert + 1;
                            triangles[triIndex + 3] = triVert + 2;

                            triIndex += 6;
                            triVert  += 2;
                        }
                    }
                }
                else
                {
                    // duplicate triangles in face case
                    if (normalsType == NormalsType.Face)
                    {
                        MeshUtils.DuplicateSharedVertices(ref vertices, ref uvs, triangles, triIndex);
                        hemisphereVertOffset = triIndex;
                    }

                    var triVert = hemisphereVertOffset;
                    vertIndex = hemisphereVertOffset;

                    var y    = -Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * (hemisphereCapRing - 1) * R);
                    var sinR = Mathf.Sin(Mathf.PI * (hemisphereCapRing - 1) * R);

                    for (int i = 0; i < sectors; i++)
                    {
                        var x = Mathf.Sin(2 * Mathf.PI * i * S) * sinR;
                        var z = Mathf.Cos(2 * Mathf.PI * i * S) * sinR;
                        var v = new Vector3(x, y, z);

                        vertices[vertIndex + 0] = v * radius + pivotOffset;
                        normals[vertIndex + 0]  = new Vector3(0.0f, 1.0f, 0.0f);

                        // make planar uv mapping for hemisphere plane
                        var uvV      = new Vector2(v.x * 0.5f, v.z * .5f);
                        var uvCenter = new Vector2(0.5f, 0.5f);

                        uvs[vertIndex + 0] = uvCenter + uvV;

                        vertIndex += 1;
                    }

                    vertices[vertIndex + 0] = new Vector3(0, -hemisphereYpos, 0) + pivotOffset;
                    normals[vertIndex + 0]  = new Vector3(0, 1, 0);
                    uvs[vertIndex + 0]      = new Vector2(0.5f, 0.5f);

                    vertIndex += 1;

                    for (int i = 0; i < rings; i++)
                    {
                        triangles[triIndex + 2] = triVert + 0;
                        triangles[triIndex + 1] = vertIndex - 1;

                        if (i == rings - 1)
                        {
                            triangles[triIndex + 0] = hemisphereVertOffset;
                        }
                        else
                        {
                            triangles[triIndex + 0] = triVert + 1;
                        }

                        triIndex += 3;
                        triVert  += 1;
                    }
                }
            }
            else
            {
                // duplicate triangles in face case
                if (normalsType == NormalsType.Face)
                {
                    MeshUtils.DuplicateSharedVertices(ref vertices, ref uvs, triangles, triIndex);
                }
            }

            mesh.vertices  = vertices;
            mesh.uv        = uvs;
            mesh.triangles = triangles;

            // generate normals by unity in face case
            if (normalsType == NormalsType.Face)
            {
                mesh.RecalculateNormals();
            }
            else
            {
                mesh.normals = normals;
            }

            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            mesh.Optimize();

            stopWatch.Stop();
            return(stopWatch.ElapsedMilliseconds);
        }
示例#51
0
        // Token: 0x06004253 RID: 16979 RVA: 0x00151090 File Offset: 0x0014F490
        public static SphericalCone Create(float radius, int segments, float coneAngle, NormalsType normals, PivotPosition pivotPosition)
        {
            GameObject gameObject = new GameObject("SphericalConePro");

            gameObject.AddComponent <MeshFilter>();
            MeshRenderer meshRenderer = gameObject.AddComponent <MeshRenderer>();

            meshRenderer.sharedMaterial = new Material(Shader.Find("Diffuse"));
            SphericalCone sphericalCone = gameObject.AddComponent <SphericalCone>();

            sphericalCone.GenerateGeometry(radius, segments, coneAngle, normals, pivotPosition);
            return(sphericalCone);
        }
示例#52
0
        /// <summary>
        /// generate mesh geometry for Spherical cone
        /// 
        /// references: 
        /// http://mathworld.wolfram.com/SphericalCone.html
        /// http://en.wikipedia.org/wiki/Spherical_sector
        /// 
        /// </summary>
        /// <param name="mesh">mesh to be generated</param>
        /// <param name="radius">radius of sphere</param>
        /// <param name="segments">number of segments</param>
        /// <param name="coneAngle">angle of conus in DEG, 360 ... complete sphere, 180 ... half-sphere</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public static float GenerateGeometry(Mesh mesh, float radius, int segments, float coneAngle, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var stopWatch = new Stopwatch();
            stopWatch.Start();

            radius = Mathf.Clamp(radius, 0, 100);
            segments = Mathf.Clamp(segments, 4, 100);
            coneAngle = Mathf.Clamp(coneAngle, 0, 360);
            var hemisphere = 1.0f - (coneAngle/360.0f);

            mesh.Clear();

            int rings = segments - 1;
            int sectors = segments;

            var hemisphereCapY = -1 + hemisphere * 2;
            int hemisphereCapRing = rings;
            //            var hemisphereYpos = -radius;

            float R = 1 / (float)(rings - 1);
            float S = 1 / (float)(sectors - 1);

            // calculate hemisphere parameters
            //            var lastY = 0.0f;
            for (int r = 0; r < rings; r++)
            {
                var y = Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * r * R);

                if (y < hemisphereCapY)
                {
                    hemisphereCapRing = r;
            //                    hemisphereYpos = lastY * radius;
                    break;
                }

            //                lastY = y;
            }

            int verticesNum = 0;
            var trianglesNum = (hemisphereCapRing) * (sectors) * 6;
            var verticesHemisphereNum = segments + 1;
            var trianglesHemisphereNum = segments * 3;

            if (hemisphereCapRing == rings)
            {
                trianglesNum -= sectors * 3;
            }

            if (normalsType == NormalsType.Vertex)
            {
                verticesNum = (hemisphereCapRing + 1) * (sectors + 1);
            }
            else
            {
                verticesNum = trianglesNum;
            }

            if (hemisphereCapRing == rings)
            {
                verticesNum -= sectors + 1;
            }

            var pivotOffset = Vector3.zero;
            switch (pivotPosition)
            {
                case PivotPosition.Botttom: pivotOffset = new Vector3(0.0f, radius, 0.0f);
                    break;
                case PivotPosition.Top: pivotOffset = new Vector3(0.0f, -radius, 0.0f);
                    break;
                case PivotPosition.Center: pivotOffset = Vector3.zero;
                    break;
            }

            if (verticesNum + verticesHemisphereNum > 60000)
            {
                UnityEngine.Debug.LogError("Too much vertices!");
                return 0.0f;
            }

            var vertices = new Vector3[verticesNum + verticesHemisphereNum];
            var normals = new Vector3[verticesNum + verticesHemisphereNum];
            var uvs = new Vector2[verticesNum + verticesHemisphereNum];
            var triangles = new int[trianglesNum + trianglesHemisphereNum];

            var vertIndex = 0;
            var triIndex = 0;

            for (int r = 0; r < hemisphereCapRing; r++)
            {
                var y = -Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * r * R);
                var sinR = Mathf.Sin(Mathf.PI * r * R);

                for (int s = 0; s < sectors; s++)
                {
                    float x = Mathf.Sin(2 * Mathf.PI * s * S) * sinR;
                    float z = Mathf.Cos(2 * Mathf.PI * s * S) * sinR;

                    vertices[vertIndex + 0] = new Vector3(x, y, z) * radius + pivotOffset;
                    normals[vertIndex + 0] = new Vector3(x, y, z);
                    uvs[vertIndex + 0] = new Vector2(1.0f - (s * S), (r * R));

                    if (r < hemisphereCapRing - 1 && s < sectors - 1)
                    {
                        //543
                        triangles[triIndex + 5] = (r + 1) * sectors + (s);
                        triangles[triIndex + 4] = r * sectors + (s + 1);
                        triangles[triIndex + 3] = r * sectors + s;
                        //210
                        triangles[triIndex + 2] = (r + 1) * sectors + (s + 1);
                        triangles[triIndex + 1] = r * sectors + (s + 1);
                        triangles[triIndex + 0] = (r + 1) * sectors + (s);

                        triIndex += 6;
                    }

                    vertIndex += 1;
                }
            }

            var hemisphereVertOffset = vertIndex;

            // calculate hemisphere plane
            if (hemisphereCapRing < rings)
            {
                // duplicate triangles in face case
                if (normalsType == NormalsType.Face)
                {
                    MeshUtils.DuplicateSharedVertices(ref vertices, ref uvs, triangles, triIndex);
                    hemisphereVertOffset = triIndex;
                }

                var triVert = hemisphereVertOffset;
                vertIndex = hemisphereVertOffset;

                var y = -Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * (hemisphereCapRing - 1) * R);
                var sinR = Mathf.Sin(Mathf.PI * (hemisphereCapRing - 1) * R);

                var zeroIndex = 0;

                for (int i = 0; i < sectors; i++)
                {
                    var x = Mathf.Sin(2 * Mathf.PI * i * S) * sinR;
                    var z = Mathf.Cos(2 * Mathf.PI * i * S) * sinR;
                    var v = new Vector3(x, y, z);

                    vertices[vertIndex + 0] = v * radius + pivotOffset;
            //                    normals[vertIndex + 0] = new Vector3(0.0f, 1.0f, 0.0f);

                    if (i > 0)
                    {
                        normals[vertIndex + 0] = -MeshUtils.ComputePolygonNormal(pivotOffset, vertices[vertIndex], vertices[vertIndex - 1]);

                        if (i == sectors - 1)
                        {
                            normals[zeroIndex] = MeshUtils.ComputePolygonNormal(pivotOffset, vertices[zeroIndex], vertices[zeroIndex+1]);
                        }
                    }
                    else
                    {
                        zeroIndex = vertIndex;
                    }

                    // make planar uv mapping for hemisphere plane
                    var uvV = new Vector2(v.x * 0.5f, v.z * .5f);
                    var uvCenter = new Vector2(0.5f, 0.5f);

                    uvs[vertIndex + 0] = uvCenter + uvV;

                    vertIndex += 1;
                }

                vertices[vertIndex + 0] = pivotOffset;
                normals[vertIndex + 0] = new Vector3(0, 1, 0);
                uvs[vertIndex + 0] = new Vector2(0.5f, 0.5f);

                vertIndex += 1;

                for (int i = 0; i < rings; i++)
                {
                    triangles[triIndex + 2] = triVert + 0;
                    triangles[triIndex + 1] = vertIndex - 1;

                    if (i == rings - 1)
                    {
                        triangles[triIndex + 0] = hemisphereVertOffset;
                    }
                    else
                    {
                        triangles[triIndex + 0] = triVert + 1;
                    }

                    triIndex += 3;
                    triVert += 1;
                }
            }

            mesh.vertices = vertices;
            mesh.uv = uvs;
            mesh.triangles = triangles;

            // generate normals by unity in face case
            if (normalsType == NormalsType.Face)
            {
                mesh.RecalculateNormals();
            }
            else
            {
                mesh.normals = normals;
            }

            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            mesh.Optimize();

            stopWatch.Stop();
            return stopWatch.ElapsedMilliseconds;
        }
示例#53
0
        /// <summary>
        /// generate geometry for GeoSphere
        /// </summary>
        /// <param name="mesh">mesh to be generated</param>
        /// <param name="radius">radius of sphere</param>
        /// <param name="subdivision">number of subdivision</param>
        /// <param name="baseType">type of generation primitive</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public static float GenerateGeometry(Mesh mesh, float radius, int subdivision, BaseType baseType, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var stopWatch = new Stopwatch();
            stopWatch.Start();

            radius = Mathf.Clamp(radius, 0, 100);
            subdivision = Mathf.Clamp(subdivision, 0, 6);

            mesh.Clear();

            var sharedVertices = normalsType == NormalsType.Vertex;

            var verticesNum = GetVertCount(baseType, subdivision, sharedVertices);
            var trianglesNum = GetTriCount(baseType, subdivision);

            // fix for too much vertices
            while (verticesNum > 60000)
            {
                subdivision -= 1;

                verticesNum = GetVertCount(baseType, subdivision, sharedVertices);
                trianglesNum = GetTriCount(baseType, subdivision);
            }

            var pivotOffset = Vector3.zero;
            switch (pivotPosition)
            {
                case PivotPosition.Botttom: pivotOffset = new Vector3(0.0f, radius, 0.0f);
                    break;
                case PivotPosition.Top: pivotOffset = new Vector3(0.0f, -radius, 0.0f);
                    break;
            }

            var triangles = new int[trianglesNum * 3];
            var trianglesTmp = new int[trianglesNum*3];
            var vertices = new Vector3[verticesNum];
            var uvs = new Vector2[verticesNum];
            Vector3[] normals = null;

            // initialize basic primitive
            InitBasePrimitive(radius, baseType, vertices, uvs, triangles);

            var indexLookup = new Dictionary<int, int>();

            var vertIndex = GetVertCount(baseType, 0, sharedVertices);

            for (int i = 0; i < subdivision; i++)
            {
                var newTriIdx = 0;
                var triCount = GetTriCount(baseType, i)*3;

                for (int triIdx = 0; triIdx < triCount; triIdx += 3)
                {
                    // get triangle
                    var v1 = triangles[triIdx + 0];
                    var v2 = triangles[triIdx + 1];
                    var v3 = triangles[triIdx + 2];

                    // split each edge in half
                    var va = AddMidPoint(vertices, radius, vertIndex++, v1, v2, indexLookup);
                    var vb = AddMidPoint(vertices, radius, vertIndex++, v2, v3, indexLookup);
                    var vc = AddMidPoint(vertices, radius, vertIndex++, v3, v1, indexLookup);

                    // create 4 new triangles
                    trianglesTmp[newTriIdx + 0] = v1;
                    trianglesTmp[newTriIdx + 1] = va;
                    trianglesTmp[newTriIdx + 2] = vc;

                    trianglesTmp[newTriIdx + 3] = v2;
                    trianglesTmp[newTriIdx + 4] = vb;
                    trianglesTmp[newTriIdx + 5] = va;

                    trianglesTmp[newTriIdx + 6] = v3;
                    trianglesTmp[newTriIdx + 7] = vc;
                    trianglesTmp[newTriIdx + 8] = vb;

                    trianglesTmp[newTriIdx + 9] = va;
                    trianglesTmp[newTriIdx + 10] = vb;
                    trianglesTmp[newTriIdx + 11] = vc;

                    newTriIdx += 12;
                }

                var swapTmp = trianglesTmp;
                trianglesTmp = triangles;
                triangles = swapTmp;
            }

            // duplicate shared vertices if we are dealing with faces normals
            if (normalsType == NormalsType.Face)
            {
                MeshUtils.DuplicateSharedVertices(ref vertices, ref uvs, triangles, -1);
            }

            // generate spherical uv mapping
            for (int i = 0; i < verticesNum; i++)
            {
                uvs[i] = GetSphericalUV(ref vertices[i]);
            }

            var verticesList = new List<Vector3>(vertices);
            var uvList = new List<Vector2>(uvs);
            var triangleList = new List<int>(triangles);

            CorrectSeam(verticesList, uvList, triangleList);
            CorrectPoles(verticesList, uvList, ref triangleList, radius);

            vertices = verticesList.ToArray();
            triangles = triangleList.ToArray();

            if (normalsType == NormalsType.Vertex)
            {
                CalculateNormals(vertices, out normals);
            }
            else
            {
                MeshUtils.ComputeVertexNormals(vertices, triangles, out normals);
            }

            CorrectPivot(verticesList, pivotPosition, ref pivotOffset);

            trianglesTmp = null;

            if (verticesList.Count > 60000)
            {
                Debug.LogError("Too much vertices!");
                return 0.0f;
            }

            mesh.vertices = verticesList.ToArray();
            mesh.uv = uvList.ToArray();
            mesh.triangles = triangleList.ToArray();
            mesh.normals = normals;

            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            mesh.Optimize();

            stopWatch.Stop();
            return stopWatch.ElapsedMilliseconds;
        }
示例#54
0
        /// <summary>
        /// generate geometry for capsule
        /// </summary>
        /// <param name="mesh">mesh to be generated</param>
        /// <param name="radius">radius of capsule</param>
        /// <param name="sides">number of segments</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="heightSegments">number of segments of central cylinder</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public static float GenerateGeometry(Mesh mesh, float radius, float height, int sides, int heightSegments, bool preserveHeight, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var stopWatch = new Stopwatch();

            stopWatch.Start();

            radius         = Mathf.Clamp(radius, 0, 100);
            height         = Mathf.Clamp(height, 0, 100);
            heightSegments = Mathf.Clamp(heightSegments, 1, 250);
            sides          = Mathf.Clamp(sides, 4, 250);

            mesh.Clear();

            if (preserveHeight)
            {
                height = height - radius * 2;
                if (height < 0)
                {
                    height = 0;
                }
            }

            int rings   = sides;
            int sectors = sides + 1;

            if ((rings & 1) == 0)
            {
                rings  += 1;
                sectors = sides + 1;
            }

            float R       = 1 / (float)(rings - 1);
            float S       = 1 / (float)(sectors - 1);
            var   midRing = rings / 2 + 1;

            int verticesNum       = 0;
            var trianglesNum      = (rings - 1) * (sectors - 1) * 6;
            var verticesCylinder  = (sides + 1) * (heightSegments + 1);
            var trianglesCylinder = sides * 6 * heightSegments;

            if (normalsType == NormalsType.Vertex)
            {
                verticesNum = rings * sectors + sectors;
            }
            else
            {
                verticesNum      = (midRing - 1) * (sectors - 1) * 4 + ((rings - 1) - (midRing - 1)) * (sectors - 1) * 4;
                verticesCylinder = sides * (4 + (heightSegments - 1) * 2);
            }

            if (verticesNum + verticesCylinder > 60000)
            {
                UnityEngine.Debug.LogError("Too much vertices!");
                return(0.0f);
            }

            var vertices  = new Vector3[verticesNum + verticesCylinder];
            var normals   = new Vector3[verticesNum + verticesCylinder];
            var uvs       = new Vector2[verticesNum + verticesCylinder];
            var triangles = new int[trianglesNum + trianglesCylinder];

            var capsuleRadius = radius + height / 2;

            var pivotOffset = Vector3.zero;

            switch (pivotPosition)
            {
            case PivotPosition.Botttom: pivotOffset = new Vector3(0.0f, capsuleRadius, 0.0f);
                break;

            case PivotPosition.Top: pivotOffset = new Vector3(0.0f, -capsuleRadius, 0.0f);
                break;
            }

            var vertIndex = 0;
            var triIndex  = 0;

            var vertIndexCyl = 0;
            var triIndexCyl  = 0;

            // calculate capsule with vertex normals
            if (normalsType == NormalsType.Vertex)
            {
                // generate upper hemisphere
                for (int r = 0; r < midRing; r++)
                {
                    var y    = Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * r * R);
                    var sinR = Mathf.Sin(Mathf.PI * r * R);

                    for (int s = 0; s < sectors; s++)
                    {
                        float x = Mathf.Sin(2 * Mathf.PI * s * S) * sinR;
                        float z = Mathf.Cos(2 * Mathf.PI * s * S) * sinR;

                        vertices[vertIndex + 0] = new Vector3(x, y, z) * radius + pivotOffset;
                        normals[vertIndex + 0]  = new Vector3(x, y, z);

                        vertices[vertIndex + 0].y += height / 2;

                        var uv = GetSphericalUV(vertices[vertIndex + 0] - pivotOffset);
                        //uvs[vertIndex + 0] = new Vector2(s * S, 1.0f - (r * R));
                        uvs[vertIndex + 0] = new Vector2(1.0f - s * S, uv.y);

                        if (r < midRing - 1 && s < sectors - 1)
                        {
                            triangles[triIndex + 0] = (r + 1) * sectors + (s);
                            triangles[triIndex + 1] = r * sectors + (s + 1);
                            triangles[triIndex + 2] = r * sectors + s;

                            triangles[triIndex + 3] = (r + 1) * sectors + (s + 1);
                            triangles[triIndex + 4] = r * sectors + (s + 1);
                            triangles[triIndex + 5] = (r + 1) * sectors + (s);

                            triIndex += 6;
                        }

                        vertIndex += 1;
                    }
                }

                // generate central cylinder
                if (height > 0)
                {
                    vertIndexCyl = verticesNum;
                    triIndexCyl  = trianglesNum;
                    var triVertCyl   = verticesNum;
                    var heightRatio  = height / heightSegments;
                    var bottomCenter = new Vector3(0.0f, -height / 2, 0.0f);

                    var sinR = Mathf.Sin(Mathf.PI * (midRing - 1) * R);

                    for (int s = 0; s <= sides; s++)
                    {
                        float x = Mathf.Sin(2 * Mathf.PI * s * S) * sinR;
                        float z = Mathf.Cos(2 * Mathf.PI * s * S) * sinR;

                        var v0 = new Vector3(x, 0.0f, z);
//                        var texV = (midRing - 1) * R;

                        var currHeight = 0.0f;

                        for (int j = 0; j <= heightSegments; j++)
                        {
                            // generate vertices
                            vertices[vertIndexCyl + 0] = bottomCenter + v0 * radius + new Vector3(0.0f, currHeight, 0.0f) + pivotOffset;
                            normals[vertIndexCyl + 0]  = v0;
//                            uvs[vertIndexCyl + 0] = new Vector2(s * S, texV/2);
//
//                            texV += 1.0f/heightSegments;

                            var uv = GetSphericalUV(vertices[vertIndexCyl + 0] - pivotOffset);
//                        uvs[vertIndex + 0] = new Vector2(s * S, 1.0f - (r * R));
                            uvs[vertIndexCyl + 0] = new Vector2(1.0f - s * S, uv.y);

                            vertIndexCyl += 1;
                            currHeight   += heightRatio;
                        }
                    }

                    for (int i = 0; i < sides; i++)
                    {
                        var triVertNext = verticesNum + (i + 1) * (heightSegments + 1);

                        for (int j = 0; j < heightSegments; j++)
                        {
                            triangles[triIndexCyl + 0] = triVertNext + 0;
                            triangles[triIndexCyl + 1] = triVertNext + 1;
                            triangles[triIndexCyl + 2] = triVertCyl + 0;

                            triangles[triIndexCyl + 3] = triVertNext + 1;
                            triangles[triIndexCyl + 4] = triVertCyl + 1;
                            triangles[triIndexCyl + 5] = triVertCyl + 0;

                            triIndexCyl += 6;
                            triVertCyl  += 1;
                            triVertNext += 1;
                        }

                        triVertCyl += 1;
                    }
                }

                // generate bottom hemisphere
                for (int r = midRing - 1; r < rings; r++)
                {
                    var y    = Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * r * R);
                    var sinR = Mathf.Sin(Mathf.PI * r * R);

                    for (int s = 0; s < sectors; s++)
                    {
                        float x = Mathf.Sin(2 * Mathf.PI * s * S) * sinR;
                        float z = Mathf.Cos(2 * Mathf.PI * s * S) * sinR;

                        vertices[vertIndex + 0] = new Vector3(x, y, z) * radius;
                        normals[vertIndex + 0]  = new Vector3(x, y, z);

                        vertices[vertIndex] += pivotOffset;

                        vertices[vertIndex + 0].y -= height / 2;

                        var uv = GetSphericalUV(vertices[vertIndex + 0] - pivotOffset);
//                        uvs[vertIndex + 0] = new Vector2(s * S, 1.0f - (r * R));
                        uvs[vertIndex + 0] = new Vector2(1.0f - s * S, uv.y);

                        if (r < rings - 1 && s < sectors - 1)
                        {
                            triangles[triIndex + 0] = ((r + 1) + 1) * sectors + (s);
                            triangles[triIndex + 1] = (r + 1) * sectors + (s + 1);
                            triangles[triIndex + 2] = (r + 1) * sectors + s;

                            triangles[triIndex + 3] = ((r + 1) + 1) * sectors + (s + 1);
                            triangles[triIndex + 4] = (r + 1) * sectors + (s + 1);
                            triangles[triIndex + 5] = ((r + 1) + 1) * sectors + (s);

                            triIndex += 6;
                        }

                        vertIndex += 1;
                    }
                }
            }
            else
            {
                // generate upper hemisphere
                for (int r = 0; r < midRing - 1; r++)
                {
                    var y     = Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * r * R);
                    var yNext = Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * (r + 1) * R);

                    var sinR  = Mathf.Sin(Mathf.PI * r * R);
                    var sinR1 = Mathf.Sin(Mathf.PI * (r + 1) * R);

                    for (int s = 0; s < sectors - 1; s++)
                    {
                        var sinS  = Mathf.Sin(2 * Mathf.PI * s * S);
                        var sinS1 = Mathf.Sin(2 * Mathf.PI * (s + 1) * S);
                        var cosS  = Mathf.Cos(2 * Mathf.PI * (s) * S);
                        var cosS1 = Mathf.Cos(2 * Mathf.PI * (s + 1) * S);

                        var x       = sinS * sinR;
                        var xNext   = sinS1 * sinR;
                        var xNextR  = sinS * sinR1;
                        var xNextRS = sinS1 * sinR1;
                        var z       = Mathf.Cos(2 * Mathf.PI * s * S) * sinR;
                        var zNext   = cosS1 * sinR;
                        var zNextR  = cosS * sinR1;
                        var zNextRS = cosS1 * sinR1;

                        // r, s
                        vertices[vertIndex + 0] = new Vector3(x, y, z) * radius + pivotOffset;
//                        uvs[vertIndex + 0] = new Vector2(s * S, 1.0f - r * R);
                        vertices[vertIndex + 0].y += height / 2;

                        var uv = GetSphericalUV(vertices[vertIndex + 0] - pivotOffset);
                        uvs[vertIndex + 0] = new Vector2(1.0f - s * S, uv.y);

                        // r+1, s
                        vertices[vertIndex + 1] = new Vector3(xNextR, yNext, zNextR) * radius + pivotOffset;
//                        uvs[vertIndex + 1] = new Vector2(s * S, 1.0f - (r+1) * R);
                        vertices[vertIndex + 1].y += height / 2;
                        uv = GetSphericalUV(vertices[vertIndex + 1] - pivotOffset);
                        uvs[vertIndex + 1] = new Vector2(1.0f - s * S, uv.y);

                        // r, s+1
                        vertices[vertIndex + 2] = new Vector3(xNext, y, zNext) * radius + pivotOffset;
//                        uvs[vertIndex + 2] = new Vector2((s+1) * S, 1.0f - (r) * R);
                        vertices[vertIndex + 2].y += height / 2;
                        uv = GetSphericalUV(vertices[vertIndex + 2] - pivotOffset);
                        uvs[vertIndex + 2] = new Vector2(1.0f - (s + 1) * S, uv.y);

                        // r+1, s+1
                        vertices[vertIndex + 3] = new Vector3(xNextRS, yNext, zNextRS) * radius + pivotOffset;
//                        uvs[vertIndex + 3] = new Vector2((s+1) * S, 1.0f - (r+1) * R);
                        vertices[vertIndex + 3].y += height / 2;
                        uv = GetSphericalUV(vertices[vertIndex + 3] - pivotOffset);
                        uvs[vertIndex + 3] = new Vector2(1.0f - (s + 1) * S, uv.y);

                        triangles[triIndex + 0] = vertIndex + 1;
                        triangles[triIndex + 1] = vertIndex + 2;
                        triangles[triIndex + 2] = vertIndex + 0;

                        triangles[triIndex + 3] = vertIndex + 3;
                        triangles[triIndex + 4] = vertIndex + 2;
                        triangles[triIndex + 5] = vertIndex + 1;

                        triIndex += 6;

                        vertIndex += 4;
                    }
                }

                // generate central cylinder
                if (height > 0)
                {
                    vertIndexCyl = verticesNum;
                    triIndexCyl  = trianglesNum;
                    var heightRatio  = height / heightSegments;
                    var bottomCenter = new Vector3(0.0f, -height / 2, 0.0f);

                    var sinR = Mathf.Sin(Mathf.PI * (midRing - 1) * R);

                    for (int s = 0; s < sides; s++)
                    {
                        var v0 = new Vector3(Mathf.Sin(2 * Mathf.PI * s * S) * sinR, 0.0f, Mathf.Cos(2 * Mathf.PI * s * S) * sinR);
                        var v1 = new Vector3(Mathf.Sin(2 * Mathf.PI * (s + 1) * S) * sinR, 0.0f, Mathf.Cos(2 * Mathf.PI * (s + 1) * S) * sinR);

//                        var texV = (midRing - 1) * R;
                        var currHeight = 0.0f;

                        var triVertCyl = vertIndexCyl;

                        var normal = (v0 + v1).normalized;

                        for (int j = 0; j <= heightSegments; j++)
                        {
                            // generate vertices
                            vertices[vertIndexCyl + 0] = bottomCenter + v0 * radius + new Vector3(0.0f, currHeight, 0.0f) + pivotOffset;
                            vertices[vertIndexCyl + 1] = bottomCenter + v1 * radius + new Vector3(0.0f, currHeight, 0.0f) + pivotOffset;

                            normals[vertIndexCyl + 0] = normal;
                            normals[vertIndexCyl + 1] = normal;

//                            uvs[vertIndexCyl + 0] = new Vector2(s * S, texV/2);
//                            uvs[vertIndexCyl + 1] = new Vector2((s + 1) * S, texV/2);
//                            texV += 1.0f/heightSegments;

                            var uv = GetSphericalUV(vertices[vertIndexCyl + 0] - pivotOffset);
                            uvs[vertIndexCyl + 0] = new Vector2(1.0f - s * S, uv.y);
                            uvs[vertIndexCyl + 1] = new Vector2(1.0f - (s + 1) * S, uv.y);

                            vertIndexCyl += 2;

                            currHeight += heightRatio;
                        }

                        for (int j = 0; j < heightSegments; j++)
                        {
                            triangles[triIndexCyl + 0] = triVertCyl + 0;
                            triangles[triIndexCyl + 1] = triVertCyl + 1;
                            triangles[triIndexCyl + 2] = triVertCyl + 3;

                            triangles[triIndexCyl + 3] = triVertCyl + 3;
                            triangles[triIndexCyl + 4] = triVertCyl + 2;
                            triangles[triIndexCyl + 5] = triVertCyl + 0;

                            triIndexCyl += 6;
                            triVertCyl  += 2;
                        }
                    }
                }

                // generate bottom hemisphere
                for (int r = midRing - 1; r < rings - 1; r++)
                {
                    var y     = Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * r * R);
                    var yNext = Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * (r + 1) * R);

                    var sinR  = Mathf.Sin(Mathf.PI * r * R);
                    var sinR1 = Mathf.Sin(Mathf.PI * (r + 1) * R);

                    for (int s = 0; s < sectors - 1; s++)
                    {
                        var sinS  = Mathf.Sin(2 * Mathf.PI * s * S);
                        var sinS1 = Mathf.Sin(2 * Mathf.PI * (s + 1) * S);
                        var cosS  = Mathf.Cos(2 * Mathf.PI * (s) * S);
                        var cosS1 = Mathf.Cos(2 * Mathf.PI * (s + 1) * S);

                        var x       = sinS * sinR;
                        var xNext   = sinS1 * sinR;
                        var xNextR  = sinS * sinR1;
                        var xNextRS = sinS1 * sinR1;
                        var z       = Mathf.Cos(2 * Mathf.PI * s * S) * sinR;
                        var zNext   = cosS1 * sinR;
                        var zNextR  = cosS * sinR1;
                        var zNextRS = cosS1 * sinR1;

                        // r, s
                        vertices[vertIndex + 0] = new Vector3(x, y, z) * radius + pivotOffset;
//                        uvs[vertIndex + 0] = new Vector2(s * S, 1.0f - r * R);
                        vertices[vertIndex + 0].y -= height / 2;
                        var uv = GetSphericalUV(vertices[vertIndex + 0] - pivotOffset);
                        uvs[vertIndex + 0] = new Vector2(1.0f - s * S, uv.y);

                        // r+1, s
                        vertices[vertIndex + 1] = new Vector3(xNextR, yNext, zNextR) * radius + pivotOffset;
//                        uvs[vertIndex + 1] = new Vector2(s * S, 1.0f - (r + 1) * R);
                        vertices[vertIndex + 1].y -= height / 2;
                        uv = GetSphericalUV(vertices[vertIndex + 1] - pivotOffset);
                        uvs[vertIndex + 1] = new Vector2(1.0f - s * S, uv.y);

                        // r, s+1
                        vertices[vertIndex + 2] = new Vector3(xNext, y, zNext) * radius + pivotOffset;
//                        uvs[vertIndex + 2] = new Vector2((s + 1) * S, 1.0f - (r) * R);
                        vertices[vertIndex + 2].y -= height / 2;
                        uv = GetSphericalUV(vertices[vertIndex + 2] - pivotOffset);
                        uvs[vertIndex + 2] = new Vector2(1.0f - (s + 1) * S, uv.y);

                        // r+1, s+1
                        vertices[vertIndex + 3] = new Vector3(xNextRS, yNext, zNextRS) * radius + pivotOffset;
//                        uvs[vertIndex + 3] = new Vector2((s + 1) * S, 1.0f - (r + 1) * R);
                        vertices[vertIndex + 3].y -= height / 2;
                        uv = GetSphericalUV(vertices[vertIndex + 3] - pivotOffset);
                        uvs[vertIndex + 3] = new Vector2(1.0f - (s + 1) * S, uv.y);

                        triangles[triIndex + 0] = vertIndex + 1;
                        triangles[triIndex + 1] = vertIndex + 2;
                        triangles[triIndex + 2] = vertIndex + 0;

                        triangles[triIndex + 3] = vertIndex + 3;
                        triangles[triIndex + 4] = vertIndex + 2;
                        triangles[triIndex + 5] = vertIndex + 1;

                        triIndex += 6;

                        vertIndex += 4;
                    }
                }
            }

            mesh.vertices  = vertices;
            mesh.normals   = normals;
            mesh.uv        = uvs;
            mesh.triangles = triangles;

            // generate normals by unity in face case
            if (normalsType == NormalsType.Face)
            {
                mesh.RecalculateNormals();
            }

            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            mesh.Optimize();

            stopWatch.Stop();
            return(stopWatch.ElapsedMilliseconds);
        }
示例#55
0
        // Token: 0x0600425C RID: 16988 RVA: 0x001512F4 File Offset: 0x0014F6F4
        public static SuperEllipsoid Create(float width, float height, float length, int segments, float n1, float n2, NormalsType normals, PivotPosition pivotPosition)
        {
            GameObject gameObject = new GameObject("SuperEllipsoidPro");

            gameObject.AddComponent <MeshFilter>();
            MeshRenderer meshRenderer = gameObject.AddComponent <MeshRenderer>();

            meshRenderer.sharedMaterial = new Material(Shader.Find("Diffuse"));
            SuperEllipsoid superEllipsoid = gameObject.AddComponent <SuperEllipsoid>();

            superEllipsoid.GenerateGeometry(width, height, length, segments, n1, n2, normals, pivotPosition);
            return(superEllipsoid);
        }
示例#56
0
文件: Cone.cs 项目: Smoothstep/VRChat
        // Token: 0x060041F0 RID: 16880 RVA: 0x0014F3B4 File Offset: 0x0014D7B4
        public static Cone Create(float radius0, float radius1, float thickness, float height, int sides, int heightSegments, NormalsType normalsType, PivotPosition pivotPosition)
        {
            GameObject gameObject = new GameObject("ConePro");

            gameObject.AddComponent <MeshFilter>();
            MeshRenderer meshRenderer = gameObject.AddComponent <MeshRenderer>();

            meshRenderer.sharedMaterial = new Material(Shader.Find("Diffuse"));
            Cone cone = gameObject.AddComponent <Cone>();

            cone.GenerateGeometry(radius0, radius1, thickness, height, sides, heightSegments, normalsType, pivotPosition);
            return(cone);
        }
示例#57
0
        /// <summary>
        /// generate mesh geometry for Ellipsoid
        /// </summary>
        /// <param name="mesh">mesh to be generated</param>
        /// <param name="width">width of ellipsoid</param>
        /// <param name="height">height of ellipsoid</param>
        /// <param name="length">length of ellipsoid</param>
        /// <param name="segments">number of segments</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public static float GenerateGeometry(Mesh mesh, float width, float height, float length, int segments, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var stopWatch = new Stopwatch();
            stopWatch.Start();

            width = Mathf.Clamp(width, 0, 100);
            height = Mathf.Clamp(height, 0, 100);
            length = Mathf.Clamp(length, 0, 100);
            segments = Mathf.Clamp(segments, 4, 100);

            mesh.Clear();

            int rings = segments-1;
            int sectors = segments;

            float R = 1 / (float)(rings - 1);
            float S = 1 / (float)(sectors - 1);

            int verticesNum = rings * sectors;
            var trianglesNum = (rings - 1)*(sectors - 1)*6;

            if (normalsType == NormalsType.Face)
            {
                verticesNum = trianglesNum;
            }

            var pivotOffset = Vector3.zero;
            switch (pivotPosition)
            {
                case PivotPosition.Botttom: pivotOffset = new Vector3(0.0f, height, 0.0f);
                    break;
                case PivotPosition.Top: pivotOffset = new Vector3(0.0f, -height, 0.0f);
                    break;
            }

            if (verticesNum > 60000)
            {
                UnityEngine.Debug.LogError("Too much vertices!");
                return 0.0f;
            }

            var vertices = new Vector3[verticesNum];
            var normals = new Vector3[verticesNum];
            var uvs = new Vector2[verticesNum];
            var triangles = new int[trianglesNum];

            var vertIndex = 0;
            var triIndex = 0;

            for (int r = 0; r < rings; r++)
            {
                var y = Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * r * R);
                var sinR = Mathf.Sin(Mathf.PI*r*R);

                for (int s = 0; s < sectors; s++)
                {
                    float x = Mathf.Sin(2 * Mathf.PI * s * S) * sinR;
                    float z = Mathf.Cos(2 * Mathf.PI * s * S) * sinR;

                    vertices[vertIndex + 0] = new Vector3(x*width, y*height, z*length) + pivotOffset;
                    normals[vertIndex + 0] = new Vector3(x, y, z);
                    uvs[vertIndex + 0] = new Vector2(1.0f - (s * S), 1.0f - (r * R));

                    if (r < rings-1 && s < sectors - 1)
                    {
                        triangles[triIndex + 0] = (r + 1) * sectors + (s);
                        triangles[triIndex + 1] = r * sectors + (s + 1);
                        triangles[triIndex + 2] = r * sectors + s;

                        triangles[triIndex + 3] = (r + 1) * sectors + (s + 1);
                        triangles[triIndex + 4] = r * sectors + (s + 1);
                        triangles[triIndex + 5] = (r + 1) * sectors + (s);

                        triIndex += 6;
                    }

                    vertIndex += 1;
                }
            }

            // duplicate triangles in face case
            if (normalsType == NormalsType.Face)
            {
                MeshUtils.DuplicateSharedVertices(ref vertices, ref uvs, triangles, -1);
            }

            mesh.vertices = vertices;
            mesh.uv = uvs;
            mesh.triangles = triangles;

            // generate normals by unity in face case
            if (normalsType == NormalsType.Face)
            {
                mesh.RecalculateNormals();
            }
            else
            {
                mesh.normals = normals;
            }

            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            mesh.Optimize();

            stopWatch.Stop();
            return stopWatch.ElapsedMilliseconds;
        }
示例#58
0
        /// <summary>
        /// generate mesh geometry for Sphere
        /// </summary>
        /// <param name="mesh">mesh to be generated</param>
        /// <param name="radius">radius of sphere</param>
        /// <param name="segments">number of segments</param>
        /// <param name="hemisphere">hemisphere, 0 ... complete sphere, 0.5 ... half-sphere</param>
        /// <param name="innerRadius">radius of the inner sphere</param>
        /// <param name="slice">vertical slice parameter</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public static float GenerateGeometry(Mesh mesh, float radius, int segments, float hemisphere, float innerRadius, float slice, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var stopWatch = new Stopwatch();
            stopWatch.Start();

            radius = Mathf.Clamp(radius, 0, 100);
            segments = Mathf.Clamp(segments, 4, 100);
            hemisphere = Mathf.Clamp(hemisphere, 0.0f, 1.0f);
            innerRadius = Mathf.Clamp01(innerRadius)*radius;
            slice = Mathf.Clamp(slice, 0.0f, 360.0f);

            mesh.Clear();

            int rings = segments-1;
            int sectors = segments;

            slice = slice / 360.0f;
            int sidesSlice = (int)(sectors * (1.0f - slice));

            if (sidesSlice == 0)
            {
                sidesSlice = 1;
            }

            var hemisphereCapY = -1 + hemisphere * 2;
            int hemisphereCapRing = rings;
            var hemisphereYpos = -radius;

            float R = 1 / (float)(rings - 1);
            float S = 1 / (float)(sectors - 1);

            // calculate hemisphere parameters
            var lastY = 0.0f;
            for (int r = 0; r < rings; r++)
            {
                var y = Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * r * R);

                if (y < hemisphereCapY)
                {
                    hemisphereCapRing = r;
                    hemisphereYpos = lastY * radius;
                    break;
                }

                lastY = y;
            }

            int verticesNum = 0;
            var trianglesNum = (hemisphereCapRing/* - 1*/) * (sectors/* - 1*/) * 6;
            var verticesHemisphereNum = segments + 1;
            var trianglesHemisphereNum = segments * 3;

            if (hemisphereCapRing == rings)
            {
                trianglesNum -= sectors * 3;
            }

            if (normalsType == NormalsType.Vertex)
            {
                verticesNum = (hemisphereCapRing + 1) * (sectors + 1);
            }
            else
            {
                verticesNum = trianglesNum;
            }

            if (hemisphereCapRing == rings)
            {
                verticesNum -= sectors + 1;
            }

            if (innerRadius > 0 && hemisphereCapRing < rings)
            {
                verticesNum *= 2;
                trianglesNum *= 2;

                verticesNum += sectors * 2;
                trianglesNum += sectors * 3;
            }

            var pivotOffset = Vector3.zero;
            var height = radius-hemisphereYpos;
            switch (pivotPosition)
            {
                case PivotPosition.Botttom: pivotOffset = new Vector3(0.0f, radius, 0.0f);
                    break;
                case PivotPosition.Top: pivotOffset = new Vector3(0.0f, hemisphereYpos, 0.0f);
                    break;
                case PivotPosition.Center: pivotOffset = new Vector3(0.0f, (hemisphereYpos + height/2), 0.0f);
                    break;
            }

            if (verticesNum + verticesHemisphereNum > 60000)
            {
                UnityEngine.Debug.LogError("Too much vertices!");
                return 0.0f;
            }

            var vertices = new Vector3[verticesNum + verticesHemisphereNum];
            var normals = new Vector3[verticesNum + verticesHemisphereNum];
            var uvs = new Vector2[verticesNum + verticesHemisphereNum];
            var triangles = new int[trianglesNum + trianglesHemisphereNum];

            var vertIndex = 0;
            var triIndex = 0;

            //            MeshUtils.Log(sectors);

            for (int r = 0; r < hemisphereCapRing; r++)
            {
                var y = -Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * r * R);
                var sinR = Mathf.Sin(Mathf.PI*r*R);

                for (int s = 0; s < sectors; s++)
                {
                    float x = Mathf.Sin(2 * Mathf.PI * s * S) * sinR;
                    float z = Mathf.Cos(2 * Mathf.PI * s * S) * sinR;

            //                    if (s < sidesSlice)
            //                    {
            //                        continue;
            //                    }

                    vertices[vertIndex + 0] = new Vector3(x, y, z) * radius + pivotOffset;
                    normals[vertIndex + 0] = new Vector3(x, y, z);
                    uvs[vertIndex + 0] = new Vector2(1.0f - (s * S), (r * R));

                    if (r < hemisphereCapRing - 1 && s < sectors - 1)
                    {
                        //543
                        triangles[triIndex + 5] = (r + 1) * sectors + (s);
                        triangles[triIndex + 4] = r * sectors + (s + 1);
                        triangles[triIndex + 3] = r * sectors + s;
                        //210
                        triangles[triIndex + 2] = (r + 1) * sectors + (s + 1);
                        triangles[triIndex + 1] = r * sectors + (s + 1);
                        triangles[triIndex + 0] = (r + 1) * sectors + (s);

                        triIndex += 6;
                    }

                    vertIndex += 1;
                }
            }

            var hemisphereVertOffset = vertIndex;

            // calculate hemisphere plane
            if (hemisphereCapRing < rings)
            {
                // generate inner sphere
                if (innerRadius > 0)
                {
                    var vertOffset = hemisphereVertOffset;
                    var outerY = -Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * (hemisphereCapRing - 1) * R) * radius;
                    var innertY = -Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * (hemisphereCapRing-1) * R) * innerRadius;
                    var diff = new Vector3(0, outerY - innertY, 0);

                    for (int r = 0; r < hemisphereCapRing; r++)
                    {
                        var y = -Mathf.Cos(-Mathf.PI*2.0f + Mathf.PI*r*R);
                        var sinR = Mathf.Sin(Mathf.PI*r*R);

                        for (int s = 0; s < sectors; s++)
                        {
                            float x = Mathf.Sin(2*Mathf.PI*s*S)*sinR;
                            float z = Mathf.Cos(2*Mathf.PI*s*S)*sinR;

                            vertices[vertIndex + 0] = new Vector3(x, y, z)*innerRadius + pivotOffset + diff;
                            normals[vertIndex + 0] = -new Vector3(x, y, z);
                            uvs[vertIndex + 0] = new Vector2(1.0f - (s*S), (r*R));

                            if (r < hemisphereCapRing - 1 && s < sectors - 1)
                            {
                                triangles[triIndex + 0] = vertOffset + (r + 1) * sectors + (s);
                                triangles[triIndex + 1] = vertOffset + r * sectors + (s + 1);
                                triangles[triIndex + 2] = vertOffset + r * sectors + s;

                                triangles[triIndex + 3] = vertOffset + (r + 1) * sectors + (s + 1);
                                triangles[triIndex + 4] = vertOffset + r * sectors + (s + 1);
                                triangles[triIndex + 5] = vertOffset + (r + 1) * sectors + (s);

                                triIndex += 6;
                            }

                            vertIndex += 1;
                        }
                    }

                    hemisphereVertOffset = vertIndex;

                    // duplicate triangles in face case
                    if (normalsType == NormalsType.Face)
                    {
                        MeshUtils.DuplicateSharedVertices(ref vertices, ref uvs, triangles, triIndex);
                        hemisphereVertOffset = triIndex;
                    }

                    // connect two hemi-spheres
                    {
                        var y = -Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * (hemisphereCapRing - 1) * R);
                        var sinR = Mathf.Sin(Mathf.PI * (hemisphereCapRing - 1) * R);

                        var triVert = hemisphereVertOffset;
                        vertIndex = triVert;

                        for (int i = 0; i < sectors; i++)
                        {
                            var x = Mathf.Sin(2 * Mathf.PI * i * S) * sinR;
                            var z = Mathf.Cos(2 * Mathf.PI * i * S) * sinR;
                            var v = new Vector3(x, y, z);

                            v.Normalize();

                            vertices[vertIndex + 0] = v * radius + pivotOffset;
                            vertices[vertIndex + 1] = v*innerRadius + pivotOffset + diff;
                            normals[vertIndex + 0] = new Vector3(0.0f, 1.0f, 0.0f);
                            normals[vertIndex + 1] = new Vector3(0.0f, 1.0f, 0.0f);

                            // make planar uv mapping for hemisphere plane
                            var uvV = new Vector2(v.x * 0.5f, v.z * .5f);
                            var uvCenter = new Vector2(0.5f, 0.5f);
                            var uvV2 = new Vector2(v.x * innerRadius / radius * 0.5f, v.z * innerRadius /radius * 0.5f);

                            uvs[vertIndex + 0] = uvCenter + uvV;
                            uvs[vertIndex + 1] = uvCenter + uvV2;

                            vertIndex += 2;
                        }

                        for (int i = 0; i < rings; i++)
                        {
                            triangles[triIndex + 2] = triVert + 1;
                            triangles[triIndex + 1] = triVert + 2;
                            triangles[triIndex + 0] = triVert + 0;

                            triangles[triIndex + 4] = triVert + 3;
                            triangles[triIndex + 5] = triVert + 1;
                            triangles[triIndex + 3] = triVert + 2;

                            triIndex += 6;
                            triVert += 2;
                        }
                    }
                }
                else
                {
                    // duplicate triangles in face case
                    if (normalsType == NormalsType.Face)
                    {
                        MeshUtils.DuplicateSharedVertices(ref vertices, ref uvs, triangles, triIndex);
                        hemisphereVertOffset = triIndex;
                    }

                    var triVert = hemisphereVertOffset;
                    vertIndex = hemisphereVertOffset;

                    var y = -Mathf.Cos(-Mathf.PI * 2.0f + Mathf.PI * (hemisphereCapRing - 1) * R);
                    var sinR = Mathf.Sin(Mathf.PI * (hemisphereCapRing - 1) * R);

                    for (int i = 0; i < sectors; i++)
                    {
                        var x = Mathf.Sin(2 * Mathf.PI * i * S) * sinR;
                        var z = Mathf.Cos(2 * Mathf.PI * i * S) * sinR;
                        var v = new Vector3(x, y, z);

                        vertices[vertIndex + 0] = v * radius + pivotOffset;
                        normals[vertIndex + 0] = new Vector3(0.0f, 1.0f, 0.0f);

                        // make planar uv mapping for hemisphere plane
                        var uvV = new Vector2(v.x * 0.5f, v.z * .5f);
                        var uvCenter = new Vector2(0.5f, 0.5f);

                        uvs[vertIndex + 0] = uvCenter + uvV;

                        vertIndex += 1;
                    }

                    vertices[vertIndex + 0] = new Vector3(0, -hemisphereYpos, 0) + pivotOffset;
                    normals[vertIndex + 0] = new Vector3(0, 1, 0);
                    uvs[vertIndex + 0] = new Vector2(0.5f, 0.5f);

                    vertIndex += 1;

                    for (int i = 0; i < rings; i++)
                    {
                        triangles[triIndex + 2] = triVert + 0;
                        triangles[triIndex + 1] = vertIndex - 1;

                        if (i == rings - 1)
                        {
                            triangles[triIndex + 0] = hemisphereVertOffset;
                        }
                        else
                        {
                            triangles[triIndex + 0] = triVert + 1;
                        }

                        triIndex += 3;
                        triVert += 1;
                    }
                }
            }
            else
            {
                // duplicate triangles in face case
                if (normalsType == NormalsType.Face)
                {
                    MeshUtils.DuplicateSharedVertices(ref vertices, ref uvs, triangles, triIndex);
                }
            }

            mesh.vertices = vertices;
            mesh.uv = uvs;
            mesh.triangles = triangles;

            // generate normals by unity in face case
            if (normalsType == NormalsType.Face)
            {
                mesh.RecalculateNormals();
            }
            else
            {
                mesh.normals = normals;
            }

            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            mesh.Optimize();

            stopWatch.Stop();
            return stopWatch.ElapsedMilliseconds;
        }
示例#59
0
        /// <summary>
        /// generate mesh geometry for cone
        /// </summary>
        /// <param name="mesh">mesh to be generated</param>
        /// <param name="radius0">fist radius of cone</param>
        /// <param name="radius1">second radius of cone</param>
        /// <param name="height">height of cone</param>
        /// <param name="sides">number of triangle segments in radius</param>
        /// <param name="heightSegments">number of triangle segments in height</param>
        /// <param name="normalsType">type of normals to be generated</param>
        /// <param name="pivotPosition">position of the model pivot</param>
        public static float GenerateGeometry(Mesh mesh, float radius0, float radius1, float height, int sides, int heightSegments, NormalsType normalsType, PivotPosition pivotPosition)
        {
            var stopWatch = new Stopwatch();
            stopWatch.Start();
            mesh.Clear();

            radius0 = Mathf.Clamp(radius0, 0, 100);
            radius1 = Mathf.Clamp(radius1, 0, 100);
            height = Mathf.Clamp(height, 0, 100);
            sides = Mathf.Clamp(sides, 3, 100);
            heightSegments = Mathf.Clamp(heightSegments, 1, 100);

            int numVertices = 0;
            int numTriangles = sides * 6 * heightSegments;
            int numVerticesCaps = 2*(sides + 1);
            int numTrianglesCaps = 2*(3*sides);

            if (normalsType == NormalsType.Face)
            {
                numVertices = sides*(4 + (heightSegments-1)*2);
            }
            else
            {
                numVertices = (sides+1)*(heightSegments + 1);
            }

            if (numVertices + numVerticesCaps > 60000)
            {
                UnityEngine.Debug.LogError("Too much vertices!");
                return 0.0f;
            }

            var vertices = new Vector3[numVertices + numVerticesCaps];
            var normals = new Vector3[numVertices + numVerticesCaps];
            var uvs = new Vector2[numVertices + numVerticesCaps];
            var triangles = new int[numTriangles + numTrianglesCaps];

            var bottomCenter = Vector3.zero;
            var coneHeight = (new Vector3(bottomCenter.x + radius0, bottomCenter.y, bottomCenter.z) -
                             new Vector3(bottomCenter.x + radius1, bottomCenter.y + height, bottomCenter.z)).magnitude;

            var pivotOffset = Vector3.zero;
            switch (pivotPosition)
            {
                case PivotPosition.Center: pivotOffset = new Vector3(0.0f, -height / 2, 0.0f);
                    break;
                case PivotPosition.Top: pivotOffset = new Vector3(0.0f, -height, 0.0f);
                    break;
            }

            if (normalsType == NormalsType.Face)
            {
                var vertIndex = 0;
                var triIndex = 0;
                var heightRatio = coneHeight/heightSegments;

                for (int i = 0; i < sides; i++)
                {
                    float angle0 = ((float)i / sides) * Mathf.PI * 2.0f;
                    var v0 = new Vector3(Mathf.Cos(angle0), 0.0f, Mathf.Sin(angle0)).normalized;

                    float angle1 = ((float)(i+1) / sides) * Mathf.PI * 2.0f;
                    var v1 = new Vector3(Mathf.Cos(angle1), 0.0f, Mathf.Sin(angle1)).normalized;

                    var currHeight = 0.0f;
                    var triVert = vertIndex;

                    var upVector0 = ((bottomCenter + new Vector3(0, height, 0)) + v0*radius1) - (bottomCenter + v0*radius0);
                    var upVector1 = ((bottomCenter + new Vector3(0, height, 0)) + v1 * radius1) - (bottomCenter + v1*radius0);

                    upVector0.Normalize();
                    upVector1.Normalize();

                    var normal = (v0 + v1).normalized;

                    for (int j = 0; j <= heightSegments; j++)
                    {
                        // generate vertices
                        vertices[vertIndex + 0] = bottomCenter + v0*radius0 + upVector0*currHeight + pivotOffset;
                        vertices[vertIndex + 1] = bottomCenter + v1 * radius0 + upVector1 * currHeight + pivotOffset;

                        normals[vertIndex + 0] = normal;
                        normals[vertIndex + 1] = normal;

                        uvs[vertIndex + 0] = new Vector2((float)i / sides, (float)j/heightSegments);
                        uvs[vertIndex + 1] = new Vector2((float)(i + 1) / sides, (float)j/heightSegments);

                        vertIndex += 2;

                        currHeight += heightRatio;
                    }

                    for (int j = 0; j < heightSegments; j++)
                    {
                        triangles[triIndex + 0] = triVert + 0;
                        triangles[triIndex + 1] = triVert + 2;
                        triangles[triIndex + 2] = triVert + 1;

                        triangles[triIndex + 3] = triVert + 2;
                        triangles[triIndex + 4] = triVert + 3;
                        triangles[triIndex + 5] = triVert + 1;

                        triIndex += 6;
                        triVert += 2;
                    }
                }
            }
            else
            {
                var vertIndex = 0;
                var triIndex = 0;
                var triVert = 0;
                var heightRatio = coneHeight / heightSegments;

                for (int i = 0; i <= sides; i++)
                {
                    float angle0 = ((float)i / sides) * Mathf.PI * 2.0f;
                    var v0 = new Vector3(Mathf.Cos(angle0), 0.0f, Mathf.Sin(angle0)).normalized;

                    var upVector = ((bottomCenter + new Vector3(0, height, 0)) + v0 * radius1) - (bottomCenter + v0 * radius0);
                    upVector.Normalize();

                    var currHeight = 0.0f;

                    for (int j = 0; j <= heightSegments; j++)
                    {
                        // generate vertices
                        vertices[vertIndex + 0] = bottomCenter + v0 * radius0 + upVector * currHeight + pivotOffset;
                        normals[vertIndex + 0] = v0;
                        uvs[vertIndex + 0] = new Vector2((float)i / sides, (float)j / heightSegments);

                        vertIndex += 1;
                        currHeight += heightRatio;
                    }
                }

                for (int i=0; i<sides; i++)
                {
                    var triVertNext = (i+1)*(heightSegments+1);

                    for (int j=0; j<heightSegments; j++)
                    {
                        triangles[triIndex + 0] = triVert + 0;
                        triangles[triIndex + 1] = triVert + 1;
                        triangles[triIndex + 2] = triVertNext + 0;

                        triangles[triIndex + 3] = triVertNext + 0;
                        triangles[triIndex + 4] = triVert + 1;
                        triangles[triIndex + 5] = triVertNext + 1;

                        triIndex += 6;
                        triVert += 1;
                        triVertNext += 1;
                    }

                    triVert += 1;
                }
            }

            // generate caps
            {
                var vertIndex = numVertices;
                var triIndex = numTriangles;
                var triVert = vertIndex;

                for (int i = 0; i <sides; i++)
                {
                    float angle0 = ((float)i / sides) * Mathf.PI * 2.0f;
                    var v0 = new Vector3(Mathf.Cos(angle0), 0.0f, Mathf.Sin(angle0)).normalized;

                    vertices[vertIndex + 0] = bottomCenter + v0 * radius0 + pivotOffset;
                    normals[vertIndex + 0] = new Vector3(0, -1, 0);
                    vertices[vertIndex + 1] = bottomCenter + v0 * radius1 + new Vector3(0, height, 0) + pivotOffset;
                    normals[vertIndex + 1] = new Vector3(0, 1, 0);

                    var uvV = new Vector2(v0.x*0.5f, v0.z*.5f);
                    var uvCenter = new Vector2(0.5f, 0.5f);
                    uvs[vertIndex + 0] = uvCenter + uvV;
                    uvs[vertIndex + 1] = uvCenter + uvV;

                    vertIndex += 2;
                }

                vertices[vertIndex + 0] = new Vector3(0, 0, 0) + pivotOffset;
                vertices[vertIndex + 1] = new Vector3(0, height, 0) + pivotOffset;
                normals[vertIndex + 0] = new Vector3(0, -1, 0);
                normals[vertIndex + 1] = new Vector3(0, 1, 0);
                uvs[vertIndex + 0] = new Vector2(0.5f, 0.5f);
                uvs[vertIndex + 1] = new Vector2(0.5f, 0.5f);

                vertIndex += 2;

                for (int i=0; i<sides; i++)
                {
                    triangles[triIndex + 0] = triVert + 0;
                    triangles[triIndex + 2] = vertIndex - 2;
                    triangles[triIndex + 3] = triVert + 1;
                    triangles[triIndex + 4] = vertIndex - 1;

                    if (i == sides - 1)
                    {
                        triangles[triIndex + 1] = numVertices;
                        triangles[triIndex + 5] = numVertices + 1;
                    }
                    else
                    {
                        triangles[triIndex + 1] = triVert + 2;
                        triangles[triIndex + 5] = triVert + 3;
                    }

                    triIndex += 6;
                    triVert += 2;
                }
            }

            mesh.vertices = vertices;
            mesh.normals = normals;
            mesh.uv = uvs;
            mesh.triangles = triangles;
            mesh.RecalculateBounds();
            MeshUtils.CalculateTangents(mesh);
            mesh.Optimize();

            stopWatch.Stop();
            return stopWatch.ElapsedMilliseconds;
        }