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