1 /**
  2 	@private
  3 
  4 	class A Model is an object which has a geometric representation composed of 
  5 	vertices, normals and uv coordinates. Models may also  have textures
  6 	applied to them.
  7 */
  8 c3dl.BoundingSphere = function()
  9 {
 10 	// When a model is first loaded, the longestVector will be set.  Once the
 11 	// model is scaled for example by (2,2,2), this scaled vector will be multiplied by
 12 	// the longest vector and the radius will be recomputed.  It is not
 13 	// sufficient to only store the radius (a scalar) value.  If the scaling
 14 	// is uniform, the boundingSphere will always tightly enclose the model.  If
 15 	// non-uniform scaling is applied to the model, the enclosure will not.
 16 	// For the enclosure to do so would incur an O(n) operation everytime the 
 17 	// a model is scaled non-uniformly.
 18 	this.longestVector = [0,0,0];
 19 	
 20 	this.original = [0,0,0];
 21 
 22 	// position of the boundingSphere in world space.
 23 	this.position =[0,0,0];
 24 	
 25 	//
 26 	this.radius = 0;
 27 	
 28 	// This varialbe exists here to solve the problem of the Model and Bounding Sphere
 29 	// having the same scaling.
 30 	// The first time the BS is initialized it gets the longest vector of the object.
 31 	// However the user may then scale the Model, we cannot scale the BS at that time
 32 	// since the scale method is inside the primitive class, not model.  We also cannot
 33 	// scale the BS to reflect the proper size in getBoundingSphere() since it would
 34 	// keep incrementing the size of the BS everytime it it called.
 35 	//
 36 	// The hierarchy of our classes should be changed to 
 37 	//   Actor (currently Primitive)
 38 	//     ^
 39 	//     |
 40 	// VisualActor
 41 	//     ^
 42 	//     |
 43 	//   Model 
 44 	//
 45 	// Then we could add BoundingSphere on the VisualActor and when it is scaled, the BS can be
 46 	// also scaled.
 47 	
 48 
 49 	/**
 50 		@private
 51 		Initialize the object by providing a 1-dimensional array which contains
 52 		the vertices of the object. This is O(n) since we need to find the longest
 53 		vector as to adjust the sphere's radius.
 54 				
 55 		@param {Array} vertices The vertices of the visible object.  Since the array
 56 		is 1-dimensional, the values could look similar to:<br />
 57 		[-0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, .... ]<br />
 58 		in which case values at 0,1 and 2 are x,y,z coordinates.
 59 	*/
 60 	this.init = function(vertices)
 61 	{
 62 		// start the longest to zero, so it will be overritten probably by the first
 63 		// vector found.
 64 		var longestLengthFound = 0;
 65 	
 66 		// do not allocate a new vector for every iteration to prevent
 67 		// too much allocation. So allocate outside the loop.
 68 		var vector = [0,0,0];
 69 		var currVector;
 70 		
 71 		// iterate over the vertices and find the longest vector.
 72 		for (var i = 0; i < vertices.length; i+=3)
 73 		{
 74 			// 
 75 			vector[0] = vertices[i+0];
 76 			vector[1] = vertices[i+1];
 77 			vector[2] = vertices[i+2];
 78 
 79 			currVector = c3dl.vectorLength(vector);
 80 
 81 			// once the longest vector is found, this becomes our radius.
 82 			if(currVector > longestLengthFound)
 83 			{
 84 				longestLengthFound = currVector;
 85 				this.longestVector = [vertices[i+0], vertices[i+1], vertices[i+2] ];
 86 			}
 87 		}
 88 
 89 		// now that we have found the longest vector, we can assign the radius.
 90 		// use copyVector for this
 91 		this.original[0] = this.longestVector[0];
 92 		this.original[1] = this.longestVector[1];
 93 		this.original[2] = this.longestVector[2];
 94 	}
 95 	
 96 	/**
 97 		@private
 98 		Set a new position of the bounding sphere.
 99 		
100 		@param {Array} position An three element array which contains the x,y,z values
101 		of the new position of the bounding sphere.
102 	*/
103 	this.setPosition = function(position)
104 	{
105 		this.position = [position[0],position[1],position[2]];
106 	}
107 	
108 	/**
109 		@private
110 	
111 		Primitive will call this when it is scaled. Thus keeping the sphere bounds around
112 		the Model.
113 		
114 		@param {Array} scaleVec
115 	*/
116 	this.scale = function(scaleVec)
117 	{
118 		// The object could have been scaled non-uniformly, so we have to get the component
119 		// which has the greatest scaling factor.  We will use that to recalculate the 
120 		// bounding sphere's radius.
121 
122 		var largestScale = scaleVec[0] > scaleVec[1] ? scaleVec[0] : scaleVec[1];
123 		largestScale = largestScale > scaleVec[2] ? largestScale : scaleVec[2];		
124 						
125 		this.longestVector[0] = this.original[0] * largestScale;
126 		this.longestVector[1] = this.original[1] * largestScale;
127 		this.longestVector[2] = this.original[2] * largestScale;
128 	}
129 	
130 	/**
131 		@private
132 		Render the bounding sphere
133 		
134 		@param {c3dl.Scene} scene
135 	*/
136 	this.render = function(scene)
137 	{
138 		if(scene.getBoundingVolumeVisibility())
139 		{
140 			scene.getRenderer().renderBoundingSphere(this);
141 		}
142 	}
143 	
144 	/**
145 		@private
146 	*/
147 	this.getRadius = function()
148 	{
149 		return c3dl.vectorLength(this.longestVector);
150 	}
151 	
152 	/**
153 		@private
154 
155 		Get the position of the bounding sphere.
156 		
157 		@returns {Array} A three element array of the bounding spheres position.
158 	*/
159 	this.getPosition = function()
160 	{
161 		return [this.position[0],this.position[1],this.position[2]];
162 	}
163 }
164