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