mirror of
				https://github.com/MapMakersAndProgrammers/alternativa3d-archive.git
				synced 2025-10-31 01:06:16 -07:00 
			
		
		
		
	more versions added
This commit is contained in:
		
							
								
								
									
										264
									
								
								Alternativa3D5/5.4.1/alternativa/engine3d/primitives/Cone.as
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										264
									
								
								Alternativa3D5/5.4.1/alternativa/engine3d/primitives/Cone.as
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,264 @@ | ||||
| package alternativa.engine3d.primitives { | ||||
| 	import alternativa.engine3d.*; | ||||
| 	import alternativa.engine3d.core.Mesh; | ||||
| 	import alternativa.engine3d.core.Object3D; | ||||
| 	import alternativa.engine3d.core.Surface; | ||||
| 	import alternativa.engine3d.core.Vertex; | ||||
| 	import alternativa.utils.MathUtils; | ||||
| 	import alternativa.engine3d.core.Face; | ||||
| 	import flash.geom.Point; | ||||
| 	 | ||||
| 	use namespace alternativa3d; | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Усеченный конус или цилиндр. | ||||
| 	 */ | ||||
| 	public class Cone extends Mesh { | ||||
|  | ||||
| 		/** | ||||
| 		 * Создает примитив усеченный конус или цилиндр. | ||||
| 		 * <p>Различные значения параметров позволяют создавать различные примитивы.  | ||||
| 		 * Так при установленном параметре <code>topRadius = 0</code> или <code>bottomRadius = 0</code> будет построен конус. При установленном </code>bottomRadius = topRadius</code> будет построен цилиндр.</p> | ||||
| 		 * <p>По умолчанию параметр <code>triangulate</code> установлен в <code>false</code> и на примитив не может быть наложена текстура.  | ||||
| 		 * Только при установленном параметре <code>triangulate</code> в <code>true</code> это возможно.</p> | ||||
| 		 * <p>После создания примитив всегда содержит в себе поверхность <code>"side"</code>. | ||||
| 		 * При установленном параметре <code>bottomRadius</code> не равном нулю в примитиве создается поверхность <code>"bottom"</code>,  | ||||
| 		 * при установленном параметре <code>topRadius</code> в примитиве создается поверхность <code>"top"</code>. | ||||
| 		 * На каждую из поверхностей может быть наложен свой материал</p> | ||||
| 		 *  | ||||
| 		 * @param height высота примтива. Размерность по оси Z. Не может быть меньше нуля. | ||||
| 		 * @param bottomRadius нижний радиус примитива | ||||
| 		 * @param topRadius верхний радиус примтива | ||||
| 		 * @param heightSegments количество сегментов по высоте примитива | ||||
| 		 * @param radialSegments количество сегментов по радиусу примтива | ||||
| 		 * @param reverse задает направление нормалей. При значении <code>true</code> нормли будут направлены внутрь примитива. | ||||
| 		 * @param triangulate флаг триангуляции. При значении <code>true</code> все четырехугольные грани примитива будут триангулированы | ||||
| 		 * и появится возможность наложить на примитив текстуру. | ||||
| 		 */ | ||||
| 		public function Cone(height:Number = 100, bottomRadius:Number = 100, topRadius:Number = 0, heightSegments:uint = 1, radialSegments:uint = 12, reverse:Boolean = false, triangulate:Boolean = false) { | ||||
|  | ||||
| 			if ((radialSegments < 3) || (heightSegments < 1) || (heightSegments == 1 && topRadius == 0 && bottomRadius == 0)) { | ||||
| 				return; | ||||
| 			} | ||||
| 			height = (height < 0)? 0 : height; | ||||
| 			bottomRadius = (bottomRadius < 0)? 0 : bottomRadius; | ||||
| 			topRadius = (topRadius < 0)? 0 : topRadius; | ||||
|  | ||||
| 			const radialSegment:Number = MathUtils.DEG360/radialSegments; | ||||
| 			const radiusSegment:Number = (bottomRadius - topRadius)/heightSegments; | ||||
| 			const heightSegment:Number = height/heightSegments; | ||||
| 			const halfHeight:Number = height*0.5 | ||||
| 			const uSegment:Number = 1/radialSegments; | ||||
| 			const vSegment:Number = 1/heightSegments; | ||||
| 			 | ||||
| 			// Создание вершин | ||||
| 			if (topRadius == 0 || triangulate) { | ||||
| 				var poleUp:Vertex = createVertex(0, 0, halfHeight, "poleUp"); | ||||
| 			} | ||||
| 			if (bottomRadius == 0 || triangulate) { | ||||
| 				var poleDown:Vertex = createVertex(0, 0, -halfHeight, "poleDown"); | ||||
| 			} | ||||
|  | ||||
| 			var radial:uint; | ||||
| 			var segment:uint; | ||||
|  | ||||
| 			var topSegment:uint = heightSegments - int(topRadius == 0); | ||||
| 			var bottomSegment:uint = int(bottomRadius == 0) ; | ||||
| 			for (segment = bottomSegment; segment <= topSegment; segment++) { | ||||
| 				for (radial = 0; radial < radialSegments; radial++) { | ||||
| 					var currentAngle:Number = radialSegment*radial; | ||||
| 					var currentRadius:Number = bottomRadius - (radiusSegment*segment); | ||||
| 					createVertex(Math.cos(currentAngle)*currentRadius, Math.sin(currentAngle)*currentRadius, heightSegment*segment - halfHeight, radial + "_" + segment); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			// Создание граней и поверхности | ||||
| 			var face:Face; | ||||
|  | ||||
| 			var points:Array; | ||||
|  | ||||
|  			var side:Surface = createSurface(null, "side"); | ||||
|  | ||||
| 			if (topRadius == 0) { | ||||
| 				// Создание граней у верхнего полюса | ||||
| 				var prevRadial:uint = radialSegments - 1; | ||||
| 				var centerUV:Point = new Point(0.5, 1);  | ||||
|  				var v:Number =  topSegment*vSegment; | ||||
|  				if (reverse) { | ||||
| 					for (radial = 0; radial < radialSegments; radial++) { | ||||
| 						face = createFace([poleUp, radial + "_" + topSegment, prevRadial + "_" + topSegment], prevRadial + "_" + topSegment); | ||||
| 						if (triangulate) { | ||||
| 							setUVsToFace(centerUV, new Point(1 - (prevRadial + 1)*uSegment, v) , new Point(1 - prevRadial*uSegment, v), face); | ||||
| 						} | ||||
| 						side.addFace(face); | ||||
| 						prevRadial = radial; | ||||
| 					} | ||||
| 				} else  { | ||||
| 					for (radial = 0; radial < radialSegments; radial++) { | ||||
| 						face = createFace([poleUp, prevRadial + "_" + topSegment, radial + "_" + topSegment], prevRadial + "_" + topSegment); | ||||
| 						if (triangulate) { | ||||
| 							setUVsToFace(centerUV, new Point(prevRadial*uSegment, v), new Point((prevRadial + 1)*uSegment, v), face); | ||||
| 						} | ||||
| 						side.addFace(face); | ||||
| 						prevRadial = radial; | ||||
| 					} | ||||
| 				} | ||||
|  			} else { | ||||
| 				// Создание граней верхней крышки | ||||
| 				var top:Surface = createSurface(null, "top"); | ||||
| 				if (triangulate) { | ||||
| 					prevRadial = radialSegments - 1;  | ||||
| 					centerUV = new Point(0.5, 0.5); | ||||
| 					var UV:Point; | ||||
| 					var prevUV:Point; | ||||
|  					if (reverse) { | ||||
| 						prevUV = new Point(0.5 - Math.cos(-radialSegment)*0.5, Math.sin(-radialSegment)*0.5 + 0.5); | ||||
| 						for (radial = 0; radial < radialSegments; radial++) { | ||||
| 							face = createFace([poleUp, radial + "_" + topSegment, prevRadial + "_" + topSegment], "top_" + prevRadial); | ||||
| 							currentAngle = radial * radialSegment; | ||||
| 							UV = new Point(0.5 - Math.cos(currentAngle)*0.5, Math.sin(currentAngle)*0.5 + 0.5); | ||||
| 							setUVsToFace(centerUV, UV, prevUV, face);  | ||||
| 							top.addFace(face); | ||||
| 							prevUV = UV; | ||||
| 							prevRadial = radial; | ||||
| 						} | ||||
| 					} else  { | ||||
|  						prevUV = new Point(Math.cos(-radialSegment)*0.5 + 0.5, Math.sin(-radialSegment)*0.5 + 0.5); | ||||
| 						for (radial = 0; radial < radialSegments; radial++) { | ||||
| 							face = createFace([poleUp, prevRadial + "_" + topSegment, radial + "_" + topSegment], "top_" + prevRadial); | ||||
| 							currentAngle = radial*radialSegment; | ||||
| 							UV = new Point(Math.cos(currentAngle)*0.5 + 0.5, Math.sin(currentAngle)*0.5 + 0.5); 							 | ||||
| 							setUVsToFace(centerUV, prevUV, UV, face);  | ||||
| 							top.addFace(face); | ||||
| 							prevUV = UV; | ||||
| 							prevRadial = radial; | ||||
| 						} | ||||
| 					} | ||||
|    				} else { | ||||
| 					points = new Array(); | ||||
| 					if (reverse) { | ||||
| 						for (radial = (radialSegments - 1); radial < uint(-1); radial--) { | ||||
| 							points.push(radial + "_" + topSegment); | ||||
| 						} | ||||
| 					} else { | ||||
| 						for (radial = 0; radial < radialSegments; radial++) { | ||||
| 							points.push(radial + "_" + topSegment); | ||||
| 						} | ||||
| 					} | ||||
| 					top.addFace(createFace(points, "top")); | ||||
| 				} | ||||
| 			} | ||||
| 			// Создание боковых граней | ||||
| 			var face2:Face; | ||||
| 			var aUV:Point; | ||||
| 			var cUV:Point; | ||||
| 			for (segment = bottomSegment; segment < topSegment; segment++) { | ||||
| 				prevRadial = radialSegments - 1; | ||||
| 				v = segment * vSegment; | ||||
| 				for (radial = 0; radial < radialSegments; radial++) { | ||||
| 					if (triangulate) { | ||||
| 						if (reverse) { | ||||
| 							face = createFace([radial + "_" + (segment + 1), radial + "_" + segment, prevRadial + "_" + segment], prevRadial + "_" + segment + ":0"); | ||||
| 							face2 = createFace([prevRadial + "_" + segment, prevRadial + "_" + (segment + 1), radial + "_" + (segment + 1)], prevRadial + "_" + segment + ":1"); | ||||
| 							aUV = new Point(1 - (prevRadial + 1)*uSegment, v + vSegment) | ||||
| 							cUV = new Point(1 - prevRadial*uSegment, v); | ||||
| 							setUVsToFace(aUV, new Point(1 - (prevRadial + 1)*uSegment, v), cUV, face); | ||||
| 							setUVsToFace(cUV, new Point(1 - prevRadial*uSegment, v + vSegment), aUV, face2);  | ||||
| 						} else { | ||||
| 							face = createFace([prevRadial + "_" + segment, radial + "_" + segment, radial + "_" + (segment + 1)], prevRadial + "_" + segment + ":0"); | ||||
| 							face2 = createFace([radial + "_" + (segment + 1), prevRadial + "_" + (segment + 1), prevRadial + "_" + segment], prevRadial + "_" + segment + ":1"); | ||||
| 							aUV = new Point(prevRadial*uSegment, v) | ||||
| 							cUV = new Point((prevRadial + 1)*uSegment, v + vSegment); | ||||
| 							setUVsToFace(aUV, new Point((prevRadial + 1)*uSegment, v), cUV, face); | ||||
| 							setUVsToFace(cUV, new Point(prevRadial*uSegment, v + vSegment), aUV, face2);  | ||||
| 						} | ||||
| 						side.addFace(face); | ||||
| 						side.addFace(face2); | ||||
| 					} else { | ||||
| 						if (reverse) { | ||||
| 							side.addFace(createFace([prevRadial + "_" + segment, prevRadial + "_" + (segment + 1), radial + "_" + (segment + 1), radial + "_" + segment], prevRadial + "_" + segment)); | ||||
| 						} else { | ||||
| 							side.addFace(createFace([prevRadial + "_" + segment, radial + "_" + segment, radial + "_" + (segment + 1), prevRadial + "_" + (segment + 1)], prevRadial + "_" + segment)); | ||||
| 						} | ||||
| 					} | ||||
| 					prevRadial = radial; | ||||
| 				} | ||||
| 			} | ||||
| 			 | ||||
| 			if (bottomRadius == 0) { | ||||
| 				// Создание граней у нижнего полюса | ||||
| 				prevRadial = radialSegments - 1;  | ||||
| 				centerUV = new Point(0.5, 0); | ||||
|  				v =  bottomSegment*vSegment; | ||||
|  				if (reverse) { | ||||
| 					for (radial = 0; radial < radialSegments; radial++) { | ||||
| 						face = createFace([poleDown, prevRadial + "_" + bottomSegment, radial + "_" + bottomSegment], prevRadial + "_0"); | ||||
| 						if (triangulate) { | ||||
| 							setUVsToFace(centerUV, new Point(1 - prevRadial*uSegment, v), new Point(1 - (prevRadial + 1)*uSegment, v), face); | ||||
| 						} | ||||
| 						side.addFace(face); | ||||
| 						prevRadial = radial; | ||||
| 					} | ||||
| 				} else  { | ||||
| 					for (radial = 0; radial < radialSegments; radial++) { | ||||
| 						face = createFace([poleDown, radial + "_" + bottomSegment, prevRadial + "_" + bottomSegment], prevRadial + "_0"); | ||||
| 						if (triangulate) { | ||||
| 							setUVsToFace(centerUV, new Point((prevRadial + 1)*uSegment, v), new Point(prevRadial*uSegment, v), face); | ||||
| 						} | ||||
| 						side.addFace(face); | ||||
| 						prevRadial = radial; | ||||
| 					} | ||||
| 				} | ||||
|  			} else { | ||||
| 				// Создание граней нижней крышки | ||||
| 				var bottom:Surface = createSurface(null, "bottom"); | ||||
| 				if (triangulate) { | ||||
| 					prevRadial = radialSegments - 1;  | ||||
| 					centerUV = new Point(0.5, 0.5); | ||||
|  					if (reverse) { | ||||
|  						prevUV = new Point(Math.cos(-radialSegment)*0.5 + 0.5, Math.sin(-radialSegment)*0.5 + 0.5); | ||||
| 						for (radial = 0; radial < radialSegments; radial++) { | ||||
| 							face = createFace([poleDown, prevRadial + "_" + bottomSegment, radial + "_" + bottomSegment], "bottom_" + prevRadial); | ||||
| 							currentAngle = radial*radialSegment; | ||||
| 							UV = new Point(Math.cos(currentAngle)*0.5 + 0.5, Math.sin(currentAngle)*0.5 + 0.5); 							 | ||||
| 							setUVsToFace(centerUV, prevUV, UV, face);  | ||||
| 							bottom.addFace(face); | ||||
| 							prevUV = UV; | ||||
| 							prevRadial = radial; | ||||
| 						} | ||||
| 					} else  { | ||||
| 						prevUV = new Point(0.5 - Math.cos(-radialSegment)*0.5, Math.sin(-radialSegment)*0.5 + 0.5); | ||||
| 						for (radial = 0; radial < radialSegments; radial++) { | ||||
| 							face = createFace([poleDown, radial + "_" + bottomSegment, prevRadial + "_" + bottomSegment], "bottom_" + prevRadial); | ||||
| 							currentAngle = radial * radialSegment; | ||||
| 							UV = new Point(0.5 - Math.cos(currentAngle)*0.5, Math.sin(currentAngle)*0.5 + 0.5); | ||||
| 							setUVsToFace(centerUV, UV, prevUV, face);  | ||||
| 							bottom.addFace(face); | ||||
| 							prevUV = UV; | ||||
| 							prevRadial = radial; | ||||
| 						} | ||||
| 					} | ||||
|    				} else { | ||||
| 					points = new Array(); | ||||
| 					if (reverse) { | ||||
| 						for (radial = 0; radial < radialSegments; radial++) { | ||||
| 							points.push(radial + "_" + bottomSegment); | ||||
| 						} | ||||
| 					} else { | ||||
| 						for (radial = (radialSegments - 1); radial < uint(-1); radial--) { | ||||
| 							points.push(radial + "_" + bottomSegment); | ||||
| 						} | ||||
| 					} | ||||
| 					bottom.addFace(createFace(points, "bottom")); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		/** | ||||
| 		 * @inheritDoc | ||||
| 		 */ | ||||
| 		protected override function createEmptyObject():Object3D { | ||||
| 			return new Cone(0, 0, 0, 0); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Tubix
					Tubix