Browse Source

Merge pull request #12797 from Mugen87/dev4

Curves: Added serialization/ deserialization
Mr.doob 7 years ago
parent
commit
130a02ea8c

+ 8 - 2
docs/api/extras/core/Curve.html

@@ -98,10 +98,16 @@
 		</div>
 
 		<h3>[method:Curve clone]()</h3>
-		<div>Creates a clone of this curve.</div>
+		<div>Creates a clone of this instance.</div>
 
 		<h3>[method:Curve copy]( [page:Curve source] )</h3>
-		<div>Copies another curve to this instance.</div>
+		<div>Copies another [name] object to this instance.</div>
+
+		<h3>[method:Object toJSON]()</h3>
+		<div>Returns a JSON object representation of this instance.</div>
+
+		<h3>[method:Curve fromJSON]( [page:Object json] )</h3>
+		<div>Copies the data from the given JSON object to this instance.</div>
 
 		<h2>Source</h2>
 

+ 5 - 0
docs/api/extras/core/Shape.html

@@ -62,6 +62,11 @@
 		<h2>Properties</h2>
 		<div>See the base [page:Path] class for common properties.</div>
 
+		<h3>[property:String uuid]</h3>
+		<div>
+		[link:http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] of this instance. This gets automatically assigned, so this shouldn't be edited.
+		</div>
+
 		<h3>[property:array holes]</h3>
 		<div>An array of [page:Path paths] that define the holes in the shape.</div>
 

+ 1 - 10
src/Three.js

@@ -139,16 +139,7 @@ export { Box3Helper } from './helpers/Box3Helper.js';
 export { PlaneHelper } from './helpers/PlaneHelper.js';
 export { ArrowHelper } from './helpers/ArrowHelper.js';
 export { AxesHelper } from './helpers/AxesHelper.js';
-export { CatmullRomCurve3 } from './extras/curves/CatmullRomCurve3.js';
-export { CubicBezierCurve3 } from './extras/curves/CubicBezierCurve3.js';
-export { QuadraticBezierCurve3 } from './extras/curves/QuadraticBezierCurve3.js';
-export { LineCurve3 } from './extras/curves/LineCurve3.js';
-export { ArcCurve } from './extras/curves/ArcCurve.js';
-export { EllipseCurve } from './extras/curves/EllipseCurve.js';
-export { SplineCurve } from './extras/curves/SplineCurve.js';
-export { CubicBezierCurve } from './extras/curves/CubicBezierCurve.js';
-export { QuadraticBezierCurve } from './extras/curves/QuadraticBezierCurve.js';
-export { LineCurve } from './extras/curves/LineCurve.js';
+export * from './extras/curves/Curves.js';
 export { Shape } from './extras/core/Shape.js';
 export { Path } from './extras/core/Path.js';
 export { ShapePath } from './extras/core/ShapePath.js';

+ 28 - 1
src/core/Object3D.js

@@ -628,7 +628,8 @@ Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 				geometries: {},
 				materials: {},
 				textures: {},
-				images: {}
+				images: {},
+				shapes: {}
 			};
 
 			output.metadata = {
@@ -672,6 +673,30 @@ Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 
 			object.geometry = serialize( meta.geometries, this.geometry );
 
+			var parameters = this.geometry.parameters;
+
+			if ( parameters !== undefined && parameters.shapes !== undefined ) {
+
+				var shapes = parameters.shapes;
+
+				if ( Array.isArray( shapes ) ) {
+
+					for ( var i = 0, l = shapes.length; i < l; i ++ ) {
+
+						var shape = shapes[ i ];
+
+						serialize( meta.shapes, shape );
+
+					}
+
+				} else {
+
+					serialize( meta.shapes, shapes );
+
+				}
+
+			}
+
 		}
 
 		if ( this.material !== undefined ) {
@@ -716,11 +741,13 @@ Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
 			var materials = extractFromCache( meta.materials );
 			var textures = extractFromCache( meta.textures );
 			var images = extractFromCache( meta.images );
+			var shapes = extractFromCache( meta.shapes );
 
 			if ( geometries.length > 0 ) output.geometries = geometries;
 			if ( materials.length > 0 ) output.materials = materials;
 			if ( textures.length > 0 ) output.textures = textures;
 			if ( images.length > 0 ) output.images = images;
+			if ( shapes.length > 0 ) output.shapes = shapes;
 
 		}
 

+ 25 - 0
src/extras/core/Curve.js

@@ -392,6 +392,31 @@ Object.assign( Curve.prototype, {
 
 		return this;
 
+	},
+
+	toJSON: function () {
+
+		var data = {
+			metadata: {
+				version: 4.5,
+				type: 'Curve',
+				generator: 'Curve.toJSON'
+			}
+		};
+
+		data.arcLengthDivisions = this.arcLengthDivisions;
+		data.type = this.type;
+
+		return data;
+
+	},
+
+	fromJSON: function ( json ) {
+
+		this.arcLengthDivisions = json.arcLengthDivisions;
+
+		return this;
+
 	}
 
 } );

+ 38 - 2
src/extras/core/CurvePath.js

@@ -1,5 +1,5 @@
 import { Curve } from './Curve.js';
-import { LineCurve } from '../curves/LineCurve.js';
+import * as Curves from '../curves/Curves.js';
 
 /**
  * @author zz85 / http://www.lab4games.net/zz85/blog
@@ -40,7 +40,7 @@ CurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {
 
 		if ( ! startPoint.equals( endPoint ) ) {
 
-			this.curves.push( new LineCurve( endPoint, startPoint ) );
+			this.curves.push( new Curves[ 'LineCurve' ]( endPoint, startPoint ) );
 
 		}
 
@@ -217,6 +217,42 @@ CurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {
 
 		return this;
 
+	},
+
+	toJSON: function () {
+
+		var data = Curve.prototype.toJSON.call( this );
+
+		data.autoClose = this.autoClose;
+		data.curves = [];
+
+		for ( var i = 0, l = this.curves.length; i < l; i ++ ) {
+
+			var curve = this.curves[ i ];
+			data.curves.push( curve.toJSON() );
+
+		}
+
+		return data;
+
+	},
+
+	fromJSON: function ( json ) {
+
+		Curve.prototype.fromJSON.call( this, json );
+
+		this.autoClose = json.autoClose;
+		this.curves = [];
+
+		for ( var i = 0, l = json.curves.length; i < l; i ++ ) {
+
+			var curve = json.curves[ i ];
+			this.curves.push( new Curves[ curve.type ]().fromJSON( curve ) );
+
+		}
+
+		return this;
+
 	}
 
 } );

+ 20 - 0
src/extras/core/Path.js

@@ -155,6 +155,26 @@ Path.prototype = Object.assign( Object.create( CurvePath.prototype ), {
 
 		return this;
 
+	},
+
+	toJSON: function () {
+
+		var data = CurvePath.prototype.toJSON.call( this );
+
+		data.currentPoint = this.currentPoint.toArray();
+
+		return data;
+
+	},
+
+	fromJSON: function ( json ) {
+
+		CurvePath.prototype.fromJSON.call( this, json );
+
+		this.currentPoint.fromArray( json.currentPoint );
+
+		return this;
+
 	}
 
 } );

+ 39 - 0
src/extras/core/Shape.js

@@ -1,4 +1,5 @@
 import { Path } from './Path.js';
+import { _Math } from '../../math/Math.js';
 
 /**
  * @author zz85 / http://www.lab4games.net/zz85/blog
@@ -15,6 +16,8 @@ function Shape( points ) {
 
 	Path.call( this, points );
 
+	this.uuid = _Math.generateUUID();
+
 	this.type = 'Shape';
 
 	this.holes = [];
@@ -68,6 +71,42 @@ Shape.prototype = Object.assign( Object.create( Path.prototype ), {
 
 		return this;
 
+	},
+
+	toJSON: function () {
+
+		var data = Path.prototype.toJSON.call( this );
+
+		data.uuid = this.uuid;
+		data.holes = [];
+
+		for ( var i = 0, l = this.holes.length; i < l; i ++ ) {
+
+			var hole = this.holes[ i ];
+			data.holes.push( hole.toJSON() );
+
+		}
+
+		return data;
+
+	},
+
+	fromJSON: function ( json ) {
+
+		Path.prototype.fromJSON.call( this, json );
+
+		this.uuid = json.uuid;
+		this.holes = [];
+
+		for ( var i = 0, l = json.holes.length; i < l; i ++ ) {
+
+			var hole = json.holes[ i ];
+			this.holes.push( new Path().fromJSON( hole ) );
+
+		}
+
+		return this;
+
 	}
 
 } );

+ 42 - 0
src/extras/curves/CatmullRomCurve3.js

@@ -209,5 +209,47 @@ CatmullRomCurve3.prototype.copy = function ( source ) {
 
 };
 
+CatmullRomCurve3.prototype.toJSON = function () {
+
+	var data = Curve.prototype.toJSON.call( this );
+
+	data.points = [];
+
+	for ( var i = 0, l = this.points.length; i < l; i ++ ) {
+
+		var point = this.points[ i ];
+		data.points.push( point.toArray() );
+
+	}
+
+	data.closed = this.closed;
+	data.curveType = this.curveType;
+	data.tension = this.tension;
+
+	return data;
+
+};
+
+CatmullRomCurve3.prototype.fromJSON = function ( json ) {
+
+	Curve.prototype.fromJSON.call( this, json );
+
+	this.points = [];
+
+	for ( var i = 0, l = json.points.length; i < l; i ++ ) {
+
+		var point = json.points[ i ];
+		this.points.push( new Vector3().fromArray( point ) );
+
+	}
+
+	this.closed = json.closed;
+	this.curveType = json.curveType;
+	this.tension = json.tension;
+
+	return this;
+
+};
+
 
 export { CatmullRomCurve3 };

+ 26 - 0
src/extras/curves/CubicBezierCurve.js

@@ -49,5 +49,31 @@ CubicBezierCurve.prototype.copy = function ( source ) {
 
 };
 
+CubicBezierCurve.prototype.toJSON = function () {
+
+	var data = Curve.prototype.toJSON.call( this );
+
+	data.v0 = this.v0.toArray();
+	data.v1 = this.v1.toArray();
+	data.v2 = this.v2.toArray();
+	data.v3 = this.v3.toArray();
+
+	return data;
+
+};
+
+CubicBezierCurve.prototype.fromJSON = function ( json ) {
+
+	Curve.prototype.fromJSON.call( this, json );
+
+	this.v0.fromArray( json.v0 );
+	this.v1.fromArray( json.v1 );
+	this.v2.fromArray( json.v2 );
+	this.v3.fromArray( json.v3 );
+
+	return this;
+
+};
+
 
 export { CubicBezierCurve };

+ 26 - 0
src/extras/curves/CubicBezierCurve3.js

@@ -50,5 +50,31 @@ CubicBezierCurve3.prototype.copy = function ( source ) {
 
 };
 
+CubicBezierCurve3.prototype.toJSON = function () {
+
+	var data = Curve.prototype.toJSON.call( this );
+
+	data.v0 = this.v0.toArray();
+	data.v1 = this.v1.toArray();
+	data.v2 = this.v2.toArray();
+	data.v3 = this.v3.toArray();
+
+	return data;
+
+};
+
+CubicBezierCurve3.prototype.fromJSON = function ( json ) {
+
+	Curve.prototype.fromJSON.call( this, json );
+
+	this.v0.fromArray( json.v0 );
+	this.v1.fromArray( json.v1 );
+	this.v2.fromArray( json.v2 );
+	this.v3.fromArray( json.v3 );
+
+	return this;
+
+};
+
 
 export { CubicBezierCurve3 };

+ 10 - 0
src/extras/curves/Curves.js

@@ -0,0 +1,10 @@
+export { ArcCurve } from './ArcCurve.js';
+export { CatmullRomCurve3 } from './CatmullRomCurve3.js';
+export { CubicBezierCurve } from './CubicBezierCurve.js';
+export { CubicBezierCurve3 } from './CubicBezierCurve3.js';
+export { EllipseCurve } from './EllipseCurve.js';
+export { LineCurve } from './LineCurve.js';
+export { LineCurve3 } from './LineCurve3.js';
+export { QuadraticBezierCurve } from './QuadraticBezierCurve.js';
+export { QuadraticBezierCurve3 } from './QuadraticBezierCurve3.js';
+export { SplineCurve } from './SplineCurve.js';

+ 43 - 0
src/extras/curves/EllipseCurve.js

@@ -112,4 +112,47 @@ EllipseCurve.prototype.copy = function ( source ) {
 };
 
 
+EllipseCurve.prototype.toJSON = function () {
+
+	var data = Curve.prototype.toJSON.call( this );
+
+	data.aX = this.aX;
+	data.aY = this.aY;
+
+	data.xRadius = this.xRadius;
+	data.yRadius = this.yRadius;
+
+	data.aStartAngle = this.aStartAngle;
+	data.aEndAngle = this.aEndAngle;
+
+	data.aClockwise = this.aClockwise;
+
+	data.aRotation = this.aRotation;
+
+	return data;
+
+};
+
+EllipseCurve.prototype.fromJSON = function ( json ) {
+
+	Curve.prototype.fromJSON.call( this, json );
+
+	this.aX = json.aX;
+	this.aY = json.aY;
+
+	this.xRadius = json.xRadius;
+	this.yRadius = json.yRadius;
+
+	this.aStartAngle = json.aStartAngle;
+	this.aEndAngle = json.aEndAngle;
+
+	this.aClockwise = json.aClockwise;
+
+	this.aRotation = json.aRotation;
+
+	return this;
+
+};
+
+
 export { EllipseCurve };

+ 22 - 0
src/extras/curves/LineCurve.js

@@ -64,5 +64,27 @@ LineCurve.prototype.copy = function ( source ) {
 
 };
 
+LineCurve.prototype.toJSON = function () {
+
+	var data = Curve.prototype.toJSON.call( this );
+
+	data.v1 = this.v1.toArray();
+	data.v2 = this.v2.toArray();
+
+	return data;
+
+};
+
+LineCurve.prototype.fromJSON = function ( json ) {
+
+	Curve.prototype.fromJSON.call( this, json );
+
+	this.v1.fromArray( json.v1 );
+	this.v2.fromArray( json.v2 );
+
+	return this;
+
+};
+
 
 export { LineCurve };

+ 22 - 0
src/extras/curves/LineCurve3.js

@@ -56,5 +56,27 @@ LineCurve3.prototype.copy = function ( source ) {
 
 };
 
+LineCurve3.prototype.toJSON = function () {
+
+	var data = Curve.prototype.toJSON.call( this );
+
+	data.v1 = this.v1.toArray();
+	data.v2 = this.v2.toArray();
+
+	return data;
+
+};
+
+LineCurve3.prototype.fromJSON = function ( json ) {
+
+	Curve.prototype.fromJSON.call( this, json );
+
+	this.v1.fromArray( json.v1 );
+	this.v2.fromArray( json.v2 );
+
+	return this;
+
+};
+
 
 export { LineCurve3 };

+ 24 - 0
src/extras/curves/QuadraticBezierCurve.js

@@ -47,5 +47,29 @@ QuadraticBezierCurve.prototype.copy = function ( source ) {
 
 };
 
+QuadraticBezierCurve.prototype.toJSON = function () {
+
+	var data = Curve.prototype.toJSON.call( this );
+
+	data.v0 = this.v0.toArray();
+	data.v1 = this.v1.toArray();
+	data.v2 = this.v2.toArray();
+
+	return data;
+
+};
+
+QuadraticBezierCurve.prototype.fromJSON = function ( json ) {
+
+	Curve.prototype.fromJSON.call( this, json );
+
+	this.v0.fromArray( json.v0 );
+	this.v1.fromArray( json.v1 );
+	this.v2.fromArray( json.v2 );
+
+	return this;
+
+};
+
 
 export { QuadraticBezierCurve };

+ 24 - 0
src/extras/curves/QuadraticBezierCurve3.js

@@ -48,5 +48,29 @@ QuadraticBezierCurve3.prototype.copy = function ( source ) {
 
 };
 
+QuadraticBezierCurve3.prototype.toJSON = function () {
+
+	var data = Curve.prototype.toJSON.call( this );
+
+	data.v0 = this.v0.toArray();
+	data.v1 = this.v1.toArray();
+	data.v2 = this.v2.toArray();
+
+	return data;
+
+};
+
+QuadraticBezierCurve3.prototype.fromJSON = function ( json ) {
+
+	Curve.prototype.fromJSON.call( this, json );
+
+	this.v0.fromArray( json.v0 );
+	this.v1.fromArray( json.v1 );
+	this.v2.fromArray( json.v2 );
+
+	return this;
+
+};
+
 
 export { QuadraticBezierCurve3 };

+ 34 - 0
src/extras/curves/SplineCurve.js

@@ -60,5 +60,39 @@ SplineCurve.prototype.copy = function ( source ) {
 
 };
 
+SplineCurve.prototype.toJSON = function () {
+
+	var data = Curve.prototype.toJSON.call( this );
+
+	data.points = [];
+
+	for ( var i = 0, l = this.points.length; i < l; i ++ ) {
+
+		var point = this.points[ i ];
+		data.points.push( point.toArray() );
+
+	}
+
+	return data;
+
+};
+
+SplineCurve.prototype.fromJSON = function ( json ) {
+
+	Curve.prototype.fromJSON.call( this, json );
+
+	this.points = [];
+
+	for ( var i = 0, l = json.points.length; i < l; i ++ ) {
+
+		var point = json.points[ i ];
+		this.points.push( new Vector2().fromArray( point ) );
+
+	}
+
+	return this;
+
+};
+
 
 export { SplineCurve };

+ 46 - 0
src/geometries/ShapeGeometry.js

@@ -37,6 +37,16 @@ function ShapeGeometry( shapes, curveSegments ) {
 ShapeGeometry.prototype = Object.create( Geometry.prototype );
 ShapeGeometry.prototype.constructor = ShapeGeometry;
 
+ShapeGeometry.prototype.toJSON = function () {
+
+	var data = Geometry.prototype.toJSON.call( this );
+
+	var shapes = this.parameters.shapes;
+
+	return toJSON( shapes, data );
+
+};
+
 // ShapeBufferGeometry
 
 function ShapeBufferGeometry( shapes, curveSegments ) {
@@ -172,5 +182,41 @@ function ShapeBufferGeometry( shapes, curveSegments ) {
 ShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
 ShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry;
 
+ShapeBufferGeometry.prototype.toJSON = function () {
+
+	var data = BufferGeometry.prototype.toJSON.call( this );
+
+	var shapes = this.parameters.shapes;
+
+	return toJSON( shapes, data );
+
+};
+
+//
+
+function toJSON( shapes, data ) {
+
+	data.shapes = [];
+
+	if ( Array.isArray( shapes ) ) {
+
+		for ( var i = 0, l = shapes.length; i < l; i ++ ) {
+
+			var shape = shapes[ i ];
+
+			data.shapes.push( shape.uuid );
+
+		}
+
+	} else {
+
+		data.shapes.push( shapes.uuid );
+
+	}
+
+	return data;
+
+}
+
 
 export { ShapeGeometry, ShapeBufferGeometry };

+ 44 - 2
src/loaders/ObjectLoader.js

@@ -31,6 +31,7 @@ import { LineSegments } from '../objects/LineSegments.js';
 import { LOD } from '../objects/LOD.js';
 import { Mesh } from '../objects/Mesh.js';
 import { SkinnedMesh } from '../objects/SkinnedMesh.js';
+import { Shape } from '../extras/core/Shape.js';
 import { Fog } from '../scenes/Fog.js';
 import { FogExp2 } from '../scenes/FogExp2.js';
 import { HemisphereLight } from '../lights/HemisphereLight.js';
@@ -123,7 +124,8 @@ Object.assign( ObjectLoader.prototype, {
 
 	parse: function ( json, onLoad ) {
 
-		var geometries = this.parseGeometries( json.geometries );
+		var shapes = this.parseShape( json.shapes );
+		var geometries = this.parseGeometries( json.geometries, shapes );
 
 		var images = this.parseImages( json.images, function () {
 
@@ -152,7 +154,27 @@ Object.assign( ObjectLoader.prototype, {
 
 	},
 
-	parseGeometries: function ( json ) {
+	parseShape: function ( json ) {
+
+		var shapes = {};
+
+		if ( json !== undefined ) {
+
+			for ( var i = 0, l = json.length; i < l; i ++ ) {
+
+				var shape = new Shape().fromJSON( json[ i ] );
+
+				shapes[ shape.uuid ] = shape;
+
+			}
+
+		}
+
+		return shapes;
+
+	},
+
+	parseGeometries: function ( json, shapes ) {
 
 		var geometries = {};
 
@@ -334,6 +356,26 @@ Object.assign( ObjectLoader.prototype, {
 
 						break;
 
+					case 'ShapeGeometry':
+					case 'ShapeBufferGeometry':
+
+						var geometryShapes = [];
+
+						for ( var i = 0, l = data.shapes.length; i < l; i ++ ) {
+
+							var shape = shapes[ data.shapes[ i ] ];
+
+							geometryShapes.push( shape );
+
+						}
+
+						geometry = new Geometries[ data.type ](
+							geometryShapes,
+							data.curveSegments
+						);
+
+						break;
+
 					case 'BufferGeometry':
 
 						geometry = bufferGeometryLoader.parse( data );