1 /**
  2  * Copyright (C) 2009-2012 Klaus Reimer <k@ailis.de>
  3  * See LICENSE.txt for licensing information
  4  * 
  5  * @require threedee.js
  6  * @require threedee/model/Material.js
  7  * @use threedee/model/Polygon.js
  8  * @use threedee/Vector.js */
  9 
 10 /**
 11  * Constructs a new model with the specified vertices and polygons.
 12  * 
 13  * @param {!Array.<!threedee.Vector>} vertices
 14  *            The model vertices
 15  * @param {!Array.<!threedee.Polygon>} polygons
 16  *            The model polygons
 17  * @param {?threedee.Material=} material
 18  *            Optional material.
 19  * @constructor
 20  * @class 
 21  * The base class for all models.
 22  */
 23 threedee.Model = function(vertices, polygons, material)
 24 {
 25     this.vertices = vertices;
 26     this.polygons = polygons;
 27     if (material) this.material = material;
 28 };
 29 
 30 /** 
 31  * The vertices. 
 32  * @private 
 33  * @type {!Array.<!threedee.Vector>} 
 34  */
 35 threedee.Model.prototype.vertices;
 36 
 37 /** 
 38  * The polygons. 
 39  * @private 
 40  * @type {!Array.<!threedee.Polygon>} 
 41  */
 42 threedee.Model.prototype.polygons;
 43 
 44 /** 
 45  * The material. 
 46  * @private 
 47  * @type {!threedee.Material} 
 48  */
 49 threedee.Model.prototype.material = threedee.Material.DEFAULT;
 50 
 51 /**
 52  * Returns the number of vertices used in this model.
 53  * 
 54  * @return {number} The number of vertices used in this model
 55  */
 56 threedee.Model.prototype.countVertices = function()
 57 {
 58     return this.vertices.length;
 59 };
 60 
 61 /**
 62  * Returns the vertex with the specified index.
 63  * 
 64  * @param {number} index
 65  *            The index
 66  * @return {!threedee.Vector}
 67  *            The vertex
 68  */
 69 threedee.Model.prototype.getVertex = function(index)
 70 {
 71     return this.vertices[index];
 72 };
 73 
 74 /**
 75  * Returns the number of polygons used in this model.
 76  * 
 77  * @return {number} The number of polygons used in this model
 78  */
 79 threedee.Model.prototype.countPolygons = function()
 80 {
 81     return this.polygons.length;
 82 };
 83 
 84 /**
 85  * Returns the polygon with the specified index.
 86  * 
 87  * @param {number} index
 88  *            The index
 89  * @return {!threedee.Polygon} The polygon
 90  */
 91 threedee.Model.prototype.getPolygon = function(index)
 92 {
 93     return this.polygons[index];
 94 };
 95 
 96 /**
 97  * Returns the material of the model.
 98  * 
 99  * @return {threedee.Material}
100  *            The material of the model. Never null.
101  */
102 threedee.Model.prototype.getMaterial = function()
103 {
104     return this.material;
105 };
106 
107 /**
108  * Converts the model into a JSON object with keys 'm', 'v' and 'p'.
109  * 
110  * @return {Object} 
111  *            The model as a JSON object.
112  */
113 threedee.Model.prototype.toJSON = function()
114 {
115     var data, vertices, polygons, i, max;
116     
117     vertices = [];
118     polygons = [];
119     
120     for (i = 0, max = this.vertices.length; i < max; i++)
121         vertices.push(this.vertices[i].toJSON());
122     for (i = 0, max = this.polygons.length; i < max; i++)
123         polygons.push(this.polygons[i].toJSON());
124     
125     data = { "v": vertices, "p": polygons };
126     if (this.material) data.m = this.material.toJSON();
127     return data;
128 };
129 
130 /**
131  * Creates a new model instance with the data read from the
132  * specified JSON object (with keys 'm' (Global model material), 'v' (Vertices)
133  * and 'p' (Polygons)). Returns null if data
134  * was empty.
135  * 
136  * @param {{m:?Object,v:!Array.<!{x:number,y:number,z:number}>,p:!Array.<!Object>}} data
137  *            The model as JSON object.
138  * @return {!threedee.Model} The model object or null if data was empty.
139  */
140 threedee.Model.fromJSON = function(data)
141 {
142     var material, i, max, vertices, polygons;
143     
144     // Parse polygons
145     polygons = [];
146     for (i = 0, max = data.p.length; i < max; i++)
147         polygons.push(threedee.Polygon.fromJSON(data.p[i]));
148 
149     // Parse vertexes
150     vertices = [];
151     for (i = 0, max = data.v.length; i < max; i++)
152         vertices.push(threedee.Vector.fromJSON(data.v[i]));
153     
154     // Parse model material
155     material = threedee.Material.fromJSON(data.m);
156 
157     // Construct the model
158     return new threedee.Model(vertices, polygons, material);
159 };
160