Răsfoiți Sursa

First try at Geometry2.

Mr.doob 11 ani în urmă
părinte
comite
eb2e2f23b8

+ 218 - 0
examples/canvas_geometry2_cube.html

@@ -0,0 +1,218 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js canvas - geometry - cube</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				font-family: Monospace;
+				background-color: #f0f0f0;
+				margin: 0px;
+				overflow: hidden;
+			}
+		</style>
+	</head>
+	<body>
+
+		<script src="../build/three.min.js"></script>
+
+		<script src="js/libs/stats.min.js"></script>
+
+		<script>
+
+			var container, stats;
+
+			var camera, scene, renderer;
+
+			var cube, plane;
+
+			var targetRotation = 0;
+			var targetRotationOnMouseDown = 0;
+
+			var mouseX = 0;
+			var mouseXOnMouseDown = 0;
+
+			var windowHalfX = window.innerWidth / 2;
+			var windowHalfY = window.innerHeight / 2;
+
+			init();
+			animate();
+
+			function init() {
+
+				container = document.createElement( 'div' );
+				document.body.appendChild( container );
+
+				var info = document.createElement( 'div' );
+				info.style.position = 'absolute';
+				info.style.top = '10px';
+				info.style.width = '100%';
+				info.style.textAlign = 'center';
+				info.innerHTML = 'Drag to spin the cube';
+				container.appendChild( info );
+
+				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera.position.y = 150;
+				camera.position.z = 500;
+
+				scene = new THREE.Scene();
+
+				// Cube
+
+				console.time( 'box' );
+
+				var geometry = new THREE.BoxGeometry2( 200, 200, 200, 20, 20, 20 );
+
+				console.timeEnd( 'box' );
+
+				/*
+				for ( var i = 0; i < geometry.faces.length; i += 2 ) {
+
+					var hex = Math.random() * 0xffffff;
+					geometry.faces[ i ].color.setHex( hex );
+					geometry.faces[ i + 1 ].color.setHex( hex );
+
+				}
+				*/
+
+				var material = new THREE.MeshBasicMaterial( { /*vertexColors: THREE.FaceColors,*/ overdraw: 0.5, wireframe: true } );
+
+				cube = new THREE.Mesh( geometry, material );
+				cube.position.y = 150;
+				scene.add( cube );
+
+				// Plane
+
+				console.time( 'plane' );
+
+				var geometry = new THREE.PlaneGeometry2( 200, 200, 20, 20 );
+
+				console.timeEnd( 'plane' );
+
+				geometry.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) );
+
+				var material = new THREE.MeshBasicMaterial( { color: 0xff0000, overdraw: 0.5, wireframe: true } );
+
+				plane = new THREE.Mesh( geometry, material );
+				scene.add( plane );
+
+				renderer = new THREE.CanvasRenderer();
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+				container.appendChild( renderer.domElement );
+
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
+				container.appendChild( stats.domElement );
+
+				document.addEventListener( 'mousedown', onDocumentMouseDown, false );
+				document.addEventListener( 'touchstart', onDocumentTouchStart, false );
+				document.addEventListener( 'touchmove', onDocumentTouchMove, false );
+
+				//
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				windowHalfX = window.innerWidth / 2;
+				windowHalfY = window.innerHeight / 2;
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			//
+
+			function onDocumentMouseDown( event ) {
+
+				event.preventDefault();
+
+				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+				document.addEventListener( 'mouseup', onDocumentMouseUp, false );
+				document.addEventListener( 'mouseout', onDocumentMouseOut, false );
+
+				mouseXOnMouseDown = event.clientX - windowHalfX;
+				targetRotationOnMouseDown = targetRotation;
+
+			}
+
+			function onDocumentMouseMove( event ) {
+
+				mouseX = event.clientX - windowHalfX;
+
+				targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.02;
+
+			}
+
+			function onDocumentMouseUp( event ) {
+
+				document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
+				document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
+				document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
+
+			}
+
+			function onDocumentMouseOut( event ) {
+
+				document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
+				document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
+				document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
+
+			}
+
+			function onDocumentTouchStart( event ) {
+
+				if ( event.touches.length === 1 ) {
+
+					event.preventDefault();
+
+					mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX;
+					targetRotationOnMouseDown = targetRotation;
+
+				}
+
+			}
+
+			function onDocumentTouchMove( event ) {
+
+				if ( event.touches.length === 1 ) {
+
+					event.preventDefault();
+
+					mouseX = event.touches[ 0 ].pageX - windowHalfX;
+					targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.05;
+
+				}
+
+			}
+
+			//
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+				stats.update();
+
+			}
+
+			function render() {
+
+				plane.rotation.y = cube.rotation.y += ( targetRotation - cube.rotation.y ) * 0.05;
+				renderer.render( scene, camera );
+
+			}
+
+		</script>
+
+	</body>
+</html>

+ 15 - 4
examples/canvas_geometry_cube.html

@@ -60,8 +60,13 @@
 
 				// Cube
 
-				var geometry = new THREE.BoxGeometry( 200, 200, 200 );
+				console.time( 'box' );
 
+				var geometry = new THREE.BoxGeometry( 200, 200, 200, 20, 20, 20 );
+
+				console.timeEnd( 'box' );
+
+				/*
 				for ( var i = 0; i < geometry.faces.length; i += 2 ) {
 
 					var hex = Math.random() * 0xffffff;
@@ -69,8 +74,9 @@
 					geometry.faces[ i + 1 ].color.setHex( hex );
 
 				}
+				*/
 
-				var material = new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors, overdraw: 0.5 } );
+				var material = new THREE.MeshBasicMaterial( { /*vertexColors: THREE.FaceColors,*/ overdraw: 0.5, wireframe: true } );
 
 				cube = new THREE.Mesh( geometry, material );
 				cube.position.y = 150;
@@ -78,10 +84,15 @@
 
 				// Plane
 
-				var geometry = new THREE.PlaneGeometry( 200, 200 );
+				console.time( 'plane' );
+
+				var geometry = new THREE.PlaneGeometry( 200, 200, 20, 20 );
+
+				console.timeEnd( 'plane' );
+
 				geometry.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) );
 
-				var material = new THREE.MeshBasicMaterial( { color: 0xe0e0e0, overdraw: 0.5 } );
+				var material = new THREE.MeshBasicMaterial( { color: 0xff0000, overdraw: 0.5, wireframe: true } );
 
 				plane = new THREE.Mesh( geometry, material );
 				scene.add( plane );

+ 81 - 0
src/core/Geometry2.js

@@ -0,0 +1,81 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+THREE.Geometry2 = function ( size ) {
+
+	this.id = THREE.GeometryIdCount ++;
+	this.uuid = THREE.Math.generateUUID();
+
+	this.name = '';
+
+	this.positions = size !== undefined ? new Float32Array( size * 3 ) : [];
+	this.normals = size !== undefined ? new Float32Array( size * 3 ) : [];
+	this.uvs = size !== undefined ? new Float32Array( size * 2 ) : [];
+
+	this.boundingBox = null;
+	this.boundingSphere = null;
+
+};
+
+THREE.Geometry2.prototype = {
+
+	constructor: THREE.Geometry2,
+
+	applyMatrix: function ( matrix ) {
+
+		matrix.multiplyVector3Array( this.positions );
+
+	},
+
+	computeBoundingSphere: function () {
+
+		var box = new THREE.Box3();
+		var vector = new THREE.Vector3();
+
+		return function () {
+
+			if ( this.boundingSphere === null ) {
+
+				this.boundingSphere = new THREE.Sphere();
+
+			}
+
+			box.makeEmpty();
+
+			var positions = this.positions;
+			var center = this.boundingSphere.center;
+
+			for ( var i = 0, il = positions.length; i < il; i += 3 ) {
+
+				vector.set( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] );
+				box.addPoint( vector );
+
+			}
+
+			box.center( center );
+
+			var maxRadiusSq = 0;
+
+			for ( var i = 0, il = positions.length; i < il; i += 3 ) {
+
+				vector.set( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] );
+				maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
+
+			}
+
+			this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
+
+		}
+
+	}(),
+
+	dispose: function () {
+
+		this.dispatchEvent( { type: 'dispose' } );
+
+	}
+
+};
+
+THREE.EventDispatcher.prototype.apply( THREE.Geometry2.prototype );

+ 16 - 0
src/core/Projector.js

@@ -340,6 +340,22 @@ THREE.Projector = function () {
 
 					}
 
+				} else if ( geometry instanceof THREE.Geometry2 ) {
+
+					var positions = geometry.positions;
+
+					for ( var i = 0, l = positions.length; i < l; i += 3 ) {
+
+						renderList.handleVertex( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] );
+
+					}
+
+					for ( var i = 0, l = positions.length / 3; i < l; i += 3 ) {
+
+						renderList.handleTriangle( i, i + 1, i + 2 );
+
+					}
+
 				} else if ( geometry instanceof THREE.Geometry ) {
 
 					vertices = geometry.vertices;

+ 127 - 0
src/extras/geometries/BoxGeometry2.js

@@ -0,0 +1,127 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as
+ */
+
+THREE.BoxGeometry2 = function ( width, height, depth, widthSegments, heightSegments, depthSegments ) {
+
+	THREE.Geometry2.call( this );
+
+	var scope = this;
+
+	this.width = width;
+	this.height = height;
+	this.depth = depth;
+
+	this.widthSegments = widthSegments || 1;
+	this.heightSegments = heightSegments || 1;
+	this.depthSegments = depthSegments || 1;
+
+	var width_half = this.width / 2;
+	var height_half = this.height / 2;
+	var depth_half = this.depth / 2;
+
+	var vector = new THREE.Vector3();
+
+	var vertices = [];
+	var positions = [];
+
+	var addPosition = function ( a, b, c ) {
+
+		positions.push(
+			vertices[ a ],
+			vertices[ a + 1 ],
+			vertices[ a + 2 ]
+		);
+
+		positions.push(
+			vertices[ b ],
+			vertices[ b + 1 ],
+			vertices[ b + 2 ]
+		);
+
+		positions.push(
+			vertices[ c ],
+			vertices[ c + 1 ],
+			vertices[ c + 2 ]
+		);
+
+	};
+
+	buildPlane( 'z', 'y', - 1, - 1, this.depth, this.height, width_half, 0 ); // px
+	buildPlane( 'z', 'y',   1, - 1, this.depth, this.height, - width_half, 1 ); // nx
+	buildPlane( 'x', 'z',   1,   1, this.width, this.depth, height_half, 2 ); // py
+	buildPlane( 'x', 'z',   1, - 1, this.width, this.depth, - height_half, 3 ); // ny
+	buildPlane( 'x', 'y',   1, - 1, this.width, this.height, depth_half, 4 ); // pz
+	buildPlane( 'x', 'y', - 1, - 1, this.width, this.height, - depth_half, 5 ); // nz
+
+	function buildPlane( u, v, udir, vdir, width, height, depth, materialIndex ) {
+
+		var w, ix, iy,
+		gridX = scope.widthSegments,
+		gridY = scope.heightSegments,
+		width_half = width / 2,
+		height_half = height / 2,
+		offset = vertices.length;
+
+		if ( ( u === 'x' && v === 'y' ) || ( u === 'y' && v === 'x' ) ) {
+
+			w = 'z';
+
+		} else if ( ( u === 'x' && v === 'z' ) || ( u === 'z' && v === 'x' ) ) {
+
+			w = 'y';
+			gridY = scope.depthSegments;
+
+		} else if ( ( u === 'z' && v === 'y' ) || ( u === 'y' && v === 'z' ) ) {
+
+			w = 'x';
+			gridX = scope.depthSegments;
+
+		}
+
+		var gridX1 = gridX + 1,
+		gridY1 = gridY + 1,
+		segment_width = width / gridX,
+		segment_height = height / gridY,
+		normal = new THREE.Vector3();
+
+		normal[ w ] = depth > 0 ? 1 : - 1;
+
+		for ( iy = 0; iy < gridY1; iy ++ ) {
+
+			for ( ix = 0; ix < gridX1; ix ++ ) {
+
+				vector[ u ] = ( ix * segment_width - width_half ) * udir;
+				vector[ v ] = ( iy * segment_height - height_half ) * vdir;
+				vector[ w ] = depth;
+
+				vertices.push( vector.x, vector.y, vector.z );
+
+			}
+
+		}
+
+		for ( iy = 0; iy < gridY; iy++ ) {
+
+			for ( ix = 0; ix < gridX; ix++ ) {
+
+				var a = ix + gridX1 * iy;
+				var b = ix + gridX1 * ( iy + 1 );
+				var c = ( ix + 1 ) + gridX1 * ( iy + 1 );
+				var d = ( ix + 1 ) + gridX1 * iy;
+
+				addPosition( a * 3 + offset, b * 3 + offset, d * 3 + offset );
+				addPosition( b * 3 + offset, c * 3 + offset, d * 3 + offset );
+
+			}
+
+		}
+
+	}
+
+	this.positions = new Float32Array( positions );
+
+};
+
+THREE.BoxGeometry2.prototype = Object.create( THREE.Geometry2.prototype );

+ 79 - 0
src/extras/geometries/PlaneGeometry2.js

@@ -0,0 +1,79 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as
+ */
+
+THREE.PlaneGeometry2 = function ( width, height, widthSegments, heightSegments ) {
+
+	THREE.Geometry2.call( this, ( widthSegments * heightSegments ) * 2 * 3 );
+
+	var positions = this.positions;
+	var normals = this.normals;
+	var uvs = this.uvs;
+
+	this.width = width;
+	this.height = height;
+
+	this.widthSegments = widthSegments || 1;
+	this.heightSegments = heightSegments || 1;
+
+	var widthHalf = width / 2;
+	var heightHalf = height / 2;
+
+	var gridX = this.widthSegments;
+	var gridY = this.heightSegments;
+
+	var segmentWidth = this.width / gridX;
+	var segmentHeight = this.height / gridY;
+
+	var offset = 0;
+
+	var normal = new THREE.Vector3( 0, 0, 1 );
+
+	for ( var iy = 0; iy < gridY; iy ++ ) {
+
+		var y1 = iy * segmentHeight - heightHalf;
+		var y2 = ( iy + 1 ) * segmentHeight - heightHalf;
+
+		for ( var ix = 0; ix < gridX; ix ++ ) {
+
+			var x1 = ix * segmentWidth - widthHalf;
+			var x2 = ( ix + 1 ) * segmentWidth - widthHalf;
+
+			positions[ offset ++ ] = x1;
+			positions[ offset ++ ] = y1;
+
+			offset ++;
+
+			positions[ offset ++ ] = x2;
+			positions[ offset ++ ] = y1;
+
+			offset ++;
+
+			positions[ offset ++ ] = x1;
+			positions[ offset ++ ] = y2;
+
+			offset ++;
+
+			positions[ offset ++ ] = x2;
+			positions[ offset ++ ] = y1;
+
+			offset ++;
+
+			positions[ offset ++ ] = x2;
+			positions[ offset ++ ] = y2;
+
+			offset ++;
+
+			positions[ offset ++ ] = x1;
+			positions[ offset ++ ] = y2;
+
+			offset ++;
+
+		}
+
+	}
+
+};
+
+THREE.PlaneGeometry2.prototype = Object.create( THREE.Geometry2.prototype );

+ 1 - 0
utils/build/includes/common.json

@@ -28,6 +28,7 @@
 	"src/core/Face3.js",
 	"src/core/Face4.js",
 	"src/core/Geometry.js",
+	"src/core/Geometry2.js",
 	"src/core/BufferGeometry.js",
 	"src/cameras/Camera.js",
 	"src/cameras/OrthographicCamera.js",

+ 2 - 0
utils/build/includes/extras.json

@@ -26,6 +26,7 @@
 	"src/extras/cameras/CubeCamera.js",
 	"src/extras/cameras/CombinedCamera.js",
 	"src/extras/geometries/BoxGeometry.js",
+	"src/extras/geometries/BoxGeometry2.js",
 	"src/extras/geometries/CircleGeometry.js",
 	"src/extras/geometries/CubeGeometry.js",
 	"src/extras/geometries/CylinderGeometry.js",
@@ -33,6 +34,7 @@
 	"src/extras/geometries/ShapeGeometry.js",
 	"src/extras/geometries/LatheGeometry.js",
 	"src/extras/geometries/PlaneGeometry.js",
+	"src/extras/geometries/PlaneGeometry2.js",
 	"src/extras/geometries/RingGeometry.js",
 	"src/extras/geometries/SphereGeometry.js",
 	"src/extras/geometries/TextGeometry.js",