1 /**************************************************************************** 2 Copyright (c) 2010-2012 cocos2d-x.org 3 4 http://www.cocos2d-x.org 5 6 Permission is hereby granted, free of charge, to any person obtaining a copy 7 of this software and associated documentation files (the "Software"), to deal 8 in the Software without restriction, including without limitation the rights 9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 copies of the Software, and to permit persons to whom the Software is 11 furnished to do so, subject to the following conditions: 12 13 The above copyright notice and this permission notice shall be included in 14 all copies or substantial portions of the Software. 15 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 THE SOFTWARE. 23 ****************************************************************************/ 24 25 /** 26 * @ignore 27 */ 28 ccs.PT_RATIO = 32; 29 /** 30 * Base class for ccs.ColliderFilter 31 * @class 32 * @extends ccs.Class 33 */ 34 ccs.ColliderFilter = ccs.Class.extend(/** @lends ccs.ColliderFilter# */{ 35 _collisionType: 0, 36 _group: 0, 37 ctor: function (collisionType, group) { 38 this._collisionType = collisionType || 0; 39 this._group = group || 0; 40 }, 41 updateShape: function (shape) { 42 shape.collision_type = this._collisionType; 43 shape.group = this._group; 44 } 45 }); 46 /** 47 * Base class for ccs.ColliderBody 48 * @class 49 * @extends ccs.Class 50 * 51 * @property {ccs.ContourData} contourData - The contour data of collider body 52 * @property {ccs.Shape} shape - The shape of collider body 53 * @property {ccs.ColliderFilter} colliderFilter - The collider filter of collider body 54 * 55 */ 56 ccs.ColliderBody = ccs.Class.extend(/** @lends ccs.ColliderBody# */{ 57 shape: null, 58 coutourData: null, 59 colliderFilter:null, 60 _calculatedVertexList:null, 61 ctor: function (contourData) { 62 this.shape = null; 63 this.coutourData = contourData; 64 this.colliderFilter = new ccs.ColliderFilter(); 65 if(ccs.ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX){ 66 this._calculatedVertexList = []; 67 } 68 }, 69 70 /** 71 * contourData getter 72 * @returns {ccs.ContourData} 73 */ 74 getContourData: function () { 75 return this.coutourData; 76 }, 77 78 /** 79 * contourData setter 80 * @param {ccs.ContourData} contourData 81 */ 82 setContourData: function (contourData) { 83 this.coutourData = contourData; 84 }, 85 86 /** 87 * shape setter 88 * @return {ccs.Shape} 89 */ 90 getShape: function () { 91 return this.shape; 92 }, 93 94 /** 95 * shape getter 96 * @param {ccs.Shape} shape 97 */ 98 setShape: function (shape) { 99 this.shape = shape; 100 }, 101 102 /** 103 * colliderFilter getter 104 * @returns {ccs.ColliderFilter} 105 */ 106 getColliderFilter: function () { 107 return this.colliderFilter; 108 }, 109 110 /** 111 * colliderFilter setter 112 * @param {ccs.ColliderFilter} colliderFilter 113 */ 114 setColliderFilter: function (colliderFilter) { 115 this.colliderFilter = colliderFilter; 116 }, 117 118 /** 119 * get calculated vertex list 120 * @returns {Array} 121 */ 122 getCalculatedVertexList:function(){ 123 return this._calculatedVertexList; 124 } 125 }); 126 127 /** 128 * Base class for ccs.ColliderDetector 129 * @class 130 * @extends ccs.Class 131 * 132 * @property {ccs.ColliderFilter} colliderFilter - The collider filter of the collider detector 133 * @property {Boolean} active - Indicate whether the collider detector is active 134 * @property {Object} body - The collider body 135 */ 136 ccs.ColliderDetector = ccs.Class.extend(/** @lends ccs.ColliderDetector# */{ 137 _colliderBodyList: null, 138 _bone: null, 139 _body: null, 140 _active: false, 141 _filter: null, 142 ctor: function () { 143 this._colliderBodyList = []; 144 this._bone = null; 145 this._body = null; 146 this._active = false; 147 this._filter = null; 148 }, 149 init: function (bone) { 150 this._colliderBodyList = []; 151 if (bone) 152 this._bone = bone; 153 this._filter = new ccs.ColliderFilter(); 154 return true; 155 }, 156 157 /** 158 * add contourData 159 * @param {ccs.ContourData} contourData 160 */ 161 addContourData: function (contourData) { 162 var colliderBody = new ccs.ColliderBody(contourData); 163 this._colliderBodyList.push(colliderBody); 164 if (ccs.ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX) { 165 var calculatedVertexList = colliderBody.getCalculatedVertexList(); 166 var vertexList = contourData.vertexList; 167 for (var i = 0; i < vertexList.length; i++) { 168 var newVertex = new ccs.ContourVertex2(0, 0); 169 calculatedVertexList.push(newVertex); 170 } 171 } 172 }, 173 174 /** 175 * add contourData 176 * @param {Array} contourDataList 177 */ 178 addContourDataList: function (contourDataList) { 179 for (var i = 0; i < contourDataList.length; i++) { 180 this.addContourData(contourDataList[i]); 181 } 182 }, 183 184 /** 185 * remove contourData 186 * @param contourData 187 */ 188 removeContourData: function (contourData) { 189 var locColliderBodyList = this._colliderBodyList; 190 for (var i = 0; i < locColliderBodyList.length; i++) { 191 if(locColliderBodyList[i].getContourData()==contourData){ 192 locColliderBodyList.splice(i, 1); 193 return; 194 } 195 } 196 }, 197 198 /** 199 * remove all body 200 */ 201 removeAll: function () { 202 this._colliderBodyList = []; 203 }, 204 205 /** 206 * set colliderFilter 207 * @param {ccs.ColliderFilter} filter 208 */ 209 setColliderFilter: function (filter) { 210 this._filter = filter; 211 for (var i = 0; i < this._colliderBodyList.length; i++) { 212 var colliderBody = this._colliderBodyList[i]; 213 colliderBody.setColliderFilter(filter); 214 if (ccs.ENABLE_PHYSICS_CHIPMUNK_DETECT) { 215 if (colliderBody.getShape()) { 216 colliderBody.getColliderFilter().updateShape(colliderBody.getShape()); 217 } 218 } 219 } 220 }, 221 222 /** 223 * get colliderFilter 224 * @returns {ccs.ColliderFilter} 225 */ 226 getColliderFilter:function(){ 227 return this._filter; 228 }, 229 230 setActive: function (active) { 231 if (this._active == active) 232 return; 233 this._active = active; 234 var locBody = this._body; 235 var locShape; 236 if (locBody) { 237 var colliderBody = null; 238 if (this._active) { 239 for (var i = 0; i < this._colliderBodyList.length; i++) { 240 colliderBody = this._colliderBodyList[i]; 241 locShape = colliderBody.getShape(); 242 locBody.space.addShape(locShape); 243 } 244 } 245 else { 246 for (var i = 0; i < this._colliderBodyList.length; i++) { 247 colliderBody = this._colliderBodyList[i]; 248 locShape = colliderBody.getShape(); 249 locBody.space.removeShape(locShape); 250 } 251 } 252 } 253 }, 254 getActive: function () { 255 return this._active; 256 }, 257 getColliderBodyList: function () { 258 return this._colliderBodyList; 259 }, 260 helpPoint: cc.p(0, 0), 261 updateTransform: function (t) { 262 if (!this._active) 263 return; 264 265 var colliderBody = null; 266 var locBody = this._body; 267 var locHelpPoint = this.helpPoint; 268 for (var i = 0; i < this._colliderBodyList.length; i++) { 269 colliderBody = this._colliderBodyList[i]; 270 var contourData = colliderBody.getContourData(); 271 var shape = null; 272 if (locBody) { 273 shape = colliderBody.getShape(); 274 } 275 var vs = contourData.vertexList; 276 var cvs = colliderBody.getCalculatedVertexList(); 277 for (var j = 0; j < vs.length; j++) { 278 locHelpPoint.x = vs[j].x; 279 locHelpPoint.y = vs[j].y; 280 locHelpPoint = cc.PointApplyAffineTransform(locHelpPoint, t); 281 if (shape) { 282 shape.verts[j * 2] = locHelpPoint.x; 283 shape.verts[j * 2 + 1] = locHelpPoint.y; 284 } 285 if (ccs.ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX) { 286 var v = cc.p(0, 0); 287 v.x = locHelpPoint.x; 288 v.y = locHelpPoint.y; 289 cvs[j] = v; 290 } 291 } 292 if (shape) { 293 for (var j = 0; j < vs.length; j++) { 294 var b = shape.verts[(j + 1) % shape.verts.length]; 295 var n = cp.v.normalize(cp.v.perp(cp.v.sub(b, shape.verts[j]))); 296 shape.axes[j].n = n; 297 shape.axes[j].d = cp.v.dot(n, shape.verts[j]); 298 } 299 } 300 } 301 }, 302 getBody: function () { 303 return this._body; 304 }, 305 setBody: function (body) { 306 this._body = body; 307 var colliderBody; 308 for (var i = 0; i < this._colliderBodyList.length; i++) { 309 colliderBody = this._colliderBodyList[i]; 310 var contourData = colliderBody.getContourData(); 311 var verts = []; 312 var vs = contourData.vertexList; 313 for (var i = 0; i < vs.length; i++) { 314 var v = vs[i]; 315 verts.push(v.x); 316 verts.push(v.y); 317 } 318 var shape = new cp.PolyShape(this._body, verts, cp.vzero); 319 shape.sensor = true; 320 shape.data = this._bone; 321 if (this._active){ 322 this._body.space.addShape(shape); 323 } 324 colliderBody.setShape(shape); 325 colliderBody.getColliderFilter().updateShape(shape); 326 } 327 } 328 }); 329 330 window._p = ccs.ColliderDetector.prototype; 331 332 // Extended properties 333 /** @expose */ 334 _p.colliderFilter; 335 cc.defineGetterSetter(_p, "colliderFilter", _p.getColliderFilter, _p.setColliderFilter); 336 /** @expose */ 337 _p.active; 338 cc.defineGetterSetter(_p, "active", _p.getActive, _p.setActive); 339 /** @expose */ 340 _p.body; 341 cc.defineGetterSetter(_p, "body", _p.getBody, _p.setBody); 342 343 delete window._p; 344 345 ccs.ColliderDetector.create = function (bone) { 346 var colliderDetector = new ccs.ColliderDetector(); 347 if (colliderDetector && colliderDetector.init(bone)) { 348 return colliderDetector; 349 } 350 return null; 351 };