/// <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; }
/// <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; }
/// <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); }
/// <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); }
/// <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; }
/// <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; }
/// <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; }
/// <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; }
/// <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; }
/// <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; }
/// <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; }
/// <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; }
/// <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; }
// 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; }
/// <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; }
/// <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; }
/// <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; }
/// <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; }
/// <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; }
/// <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; }
/// <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); }
/// <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; }
/// <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; }
// 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); }
// 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); }
// 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); }
/// <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; }
// 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; }
/// <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); }
/// <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); }
// 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; }
// 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); }
/// <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); }
/// <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; }
/// <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); }
/// <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); }
// 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); }
/// <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; }
/// <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; }
/// <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; }
/// <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; }
/// <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); }
/// <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; }
// 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; }
/// <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); }
// 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); }
/// <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; }
/// <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; }
/// <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); }
// 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); }
// 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); }
/// <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; }
/// <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; }
/// <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; }