1 /**
  2  Copyright (c) 2008-2010 Ricardo Quesada
  3  Copyright (c) 2011-2012 cocos2d-x.org
  4  Copyright (c) 2013-2014 Chukong Technologies Inc.
  5  Copyright (c) 2008, Luke Benstead.
  6  All rights reserved.
  7 
  8  Redistribution and use in source and binary forms, with or without modification,
  9  are permitted provided that the following conditions are met:
 10 
 11  Redistributions of source code must retain the above copyright notice,
 12  this list of conditions and the following disclaimer.
 13  Redistributions in binary form must reproduce the above copyright notice,
 14  this list of conditions and the following disclaimer in the documentation
 15  and/or other materials provided with the distribution.
 16 
 17  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 18  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 19  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 20  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 21  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 22  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 23  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 24  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 25  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 26  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 27  */
 28 
 29 /**
 30  * @ignore
 31  */
 32 cc.KM_PLANE_LEFT = 0;
 33 
 34 cc.KM_PLANE_RIGHT = 1;
 35 
 36 cc.KM_PLANE_BOTTOM = 2;
 37 
 38 cc.KM_PLANE_TOP = 3;
 39 
 40 cc.KM_PLANE_NEAR = 4;
 41 
 42 cc.KM_PLANE_FAR = 5;
 43 
 44 cc.kmPlane = function (a, b, c, d) {
 45     this.a = a || 0;
 46     this.b = b || 0;
 47     this.c = c || 0;
 48     this.d = d || 0;
 49 };
 50 
 51 cc.POINT_INFRONT_OF_PLANE = 0;
 52 
 53 cc.POINT_BEHIND_PLANE = 1;
 54 
 55 cc.POINT_ON_PLANE = 2;
 56 
 57 cc.kmPlaneDot = function(pP, pV){
 58     //a*x + b*y + c*z + d*w
 59     return (pP.a * pV.x +
 60         pP.b * pV.y +
 61         pP.c * pV.z +
 62         pP.d * pV.w);
 63 };
 64 
 65 cc.kmPlaneDotCoord = function(pP, pV){
 66     return (pP.a * pV.x +
 67         pP.b * pV.y +
 68         pP.c * pV.z + pP.d);
 69 };
 70 
 71 cc.kmPlaneDotNormal = function(pP, pV){
 72     return (pP.a * pV.x +
 73         pP.b * pV.y +
 74         pP.c * pV.z);
 75 };
 76 
 77 cc.kmPlaneFromPointNormal = function(pOut, pPoint, pNormal){
 78     /*
 79      Planea = Nx
 80      Planeb = Ny
 81      Planec = Nz
 82      Planed = −N⋅P
 83      */
 84     pOut.a = pNormal.x;
 85     pOut.b = pNormal.y;
 86     pOut.c = pNormal.z;
 87     pOut.d = -cc.kmVec3Dot(pNormal, pPoint);
 88 
 89     return pOut;
 90 };
 91 
 92 /**
 93  * Creates a plane from 3 points. The result is stored in pOut.
 94  * pOut is returned.
 95  */
 96 cc.kmPlaneFromPoints = function(pOut, p1, p2, p3){
 97     /*
 98      v = (B − A) × (C − A)
 99      n = 1⁄|v| v
100      Outa = nx
101      Outb = ny
102      Outc = nz
103      Outd = −n⋅A
104      */
105 
106     var n = new cc.kmVec3(), v1 = new cc.kmVec3(), v2 = new cc.kmVec3();
107     cc.kmVec3Subtract(v1, p2, p1); //Create the vectors for the 2 sides of the triangle
108     cc.kmVec3Subtract(v2, p3, p1);
109     cc.kmVec3Cross(n, v1, v2); //Use the cross product to get the normal
110 
111     cc.kmVec3Normalize(n, n); //Normalize it and assign to pOut.m_N
112 
113     pOut.a = n.x;
114     pOut.b = n.y;
115     pOut.c = n.z;
116     pOut.d = cc.kmVec3Dot(cc.kmVec3Scale(n, n, -1.0), p1);
117 
118     return pOut;
119 };
120 
121 cc.kmPlaneIntersectLine = function(pOut, pP, pV1, pV2){
122     throw "cc.kmPlaneIntersectLine() hasn't been implemented.";
123     /*
124      n = (Planea, Planeb, Planec)
125      d = V − U
126      Out = U − d⋅(Pd + n⋅U)⁄(d⋅n) [iff d⋅n ≠ 0]
127      */
128     //var d = new cc.kmVec3();
129 
130     //cc.kmVec3Subtract(d, pV2, pV1); //Get the direction vector
131 
132     //TODO: Continue here!
133     /*if (fabs(kmVec3Dot(&pP.m_N, &d)) > kmEpsilon)
134      {
135      //If we get here then the plane and line are parallel (i.e. no intersection)
136      pOut = nullptr; //Set to nullptr
137 
138      return pOut;
139      } */
140 
141     //return null;
142 };
143 
144 cc.kmPlaneNormalize = function(pOut, pP){
145     var n = new cc.kmVec3();
146 
147     n.x = pP.a;
148     n.y = pP.b;
149     n.z = pP.c;
150 
151     var l = 1.0 / cc.kmVec3Length(n); //Get 1/length
152     cc.kmVec3Normalize(n, n); //Normalize the vector and assign to pOut
153 
154     pOut.a = n.x;
155     pOut.b = n.y;
156     pOut.c = n.z;
157 
158     pOut.d = pP.d * l; //Scale the D value and assign to pOut
159 
160     return pOut;
161 };
162 
163 cc.kmPlaneScale = function(pOut, pP, s){
164     cc.log("cc.kmPlaneScale() has not been implemented.");
165 };
166 
167 /**
168  * Returns POINT_INFRONT_OF_PLANE if pP is infront of pIn. Returns
169  * POINT_BEHIND_PLANE if it is behind. Returns POINT_ON_PLANE otherwise
170  */
171 cc.kmPlaneClassifyPoint = function(pIn, pP){
172     // This function will determine if a point is on, in front of, or behind
173     // the plane.  First we store the dot product of the plane and the point.
174     var distance = pIn.a * pP.x + pIn.b * pP.y + pIn.c * pP.z + pIn.d;
175 
176     // Simply put if the dot product is greater than 0 then it is infront of it.
177     // If it is less than 0 then it is behind it.  And if it is 0 then it is on it.
178     if(distance > 0.001) return cc.POINT_INFRONT_OF_PLANE;
179     if(distance < -0.001) return cc.POINT_BEHIND_PLANE;
180 
181     return cc.POINT_ON_PLANE;
182 };
183 
184 
185