mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2025-11-24 04:57:34 +00:00
初始化
This commit is contained in:
282
cocos2d-x/cocos/math/CCGeometry.cpp
Normal file
282
cocos2d-x/cocos/math/CCGeometry.cpp
Normal file
@@ -0,0 +1,282 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "math/CCGeometry.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include "base/ccMacros.h"
|
||||
|
||||
// implementation of Vec2
|
||||
NS_CC_BEGIN
|
||||
|
||||
// implementation of Size
|
||||
|
||||
Size::Size(void) : width(0), height(0)
|
||||
{
|
||||
}
|
||||
|
||||
Size::Size(float w, float h) : width(w), height(h)
|
||||
{
|
||||
}
|
||||
|
||||
Size::Size(const Size& other) : width(other.width), height(other.height)
|
||||
{
|
||||
}
|
||||
|
||||
Size::Size(const Vec2& point) : width(point.x), height(point.y)
|
||||
{
|
||||
}
|
||||
|
||||
Size& Size::operator= (const Size& other)
|
||||
{
|
||||
setSize(other.width, other.height);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Size& Size::operator= (const Vec2& point)
|
||||
{
|
||||
setSize(point.x, point.y);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Size Size::operator+(const Size& right) const
|
||||
{
|
||||
return Size(this->width + right.width, this->height + right.height);
|
||||
}
|
||||
|
||||
Size Size::operator-(const Size& right) const
|
||||
{
|
||||
return Size(this->width - right.width, this->height - right.height);
|
||||
}
|
||||
|
||||
Size Size::operator*(float a) const
|
||||
{
|
||||
return Size(this->width * a, this->height * a);
|
||||
}
|
||||
|
||||
Size Size::operator/(float a) const
|
||||
{
|
||||
CCASSERT(a!=0, "CCSize division by 0.");
|
||||
return Size(this->width / a, this->height / a);
|
||||
}
|
||||
|
||||
void Size::setSize(float w, float h)
|
||||
{
|
||||
this->width = w;
|
||||
this->height = h;
|
||||
}
|
||||
|
||||
bool Size::equals(const Size& target) const
|
||||
{
|
||||
return (std::abs(this->width - target.width) < FLT_EPSILON)
|
||||
&& (std::abs(this->height - target.height) < FLT_EPSILON);
|
||||
}
|
||||
|
||||
const Size Size::ZERO = Size(0, 0);
|
||||
|
||||
// implementation of Rect
|
||||
|
||||
Rect::Rect(void)
|
||||
{
|
||||
setRect(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
Rect::Rect(float x, float y, float width, float height)
|
||||
{
|
||||
setRect(x, y, width, height);
|
||||
}
|
||||
Rect::Rect(const Vec2& pos, const Size& dimension)
|
||||
{
|
||||
setRect(pos.x, pos.y, dimension.width, dimension.height);
|
||||
}
|
||||
|
||||
Rect::Rect(const Rect& other)
|
||||
{
|
||||
setRect(other.origin.x, other.origin.y, other.size.width, other.size.height);
|
||||
}
|
||||
|
||||
Rect& Rect::operator= (const Rect& other)
|
||||
{
|
||||
setRect(other.origin.x, other.origin.y, other.size.width, other.size.height);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Rect::setRect(float x, float y, float width, float height)
|
||||
{
|
||||
// CGRect can support width<0 or height<0
|
||||
// CCASSERT(width >= 0.0f && height >= 0.0f, "width and height of Rect must not less than 0.");
|
||||
|
||||
origin.x = x;
|
||||
origin.y = y;
|
||||
|
||||
size.width = width;
|
||||
size.height = height;
|
||||
}
|
||||
|
||||
bool Rect::equals(const Rect& rect) const
|
||||
{
|
||||
return (origin.equals(rect.origin) &&
|
||||
size.equals(rect.size));
|
||||
}
|
||||
|
||||
float Rect::getMaxX() const
|
||||
{
|
||||
return origin.x + size.width;
|
||||
}
|
||||
|
||||
float Rect::getMidX() const
|
||||
{
|
||||
return origin.x + size.width / 2.0f;
|
||||
}
|
||||
|
||||
float Rect::getMinX() const
|
||||
{
|
||||
return origin.x;
|
||||
}
|
||||
|
||||
float Rect::getMaxY() const
|
||||
{
|
||||
return origin.y + size.height;
|
||||
}
|
||||
|
||||
float Rect::getMidY() const
|
||||
{
|
||||
return origin.y + size.height / 2.0f;
|
||||
}
|
||||
|
||||
float Rect::getMinY() const
|
||||
{
|
||||
return origin.y;
|
||||
}
|
||||
|
||||
bool Rect::containsPoint(const Vec2& point) const
|
||||
{
|
||||
bool bRet = false;
|
||||
|
||||
if (point.x >= getMinX() && point.x <= getMaxX()
|
||||
&& point.y >= getMinY() && point.y <= getMaxY())
|
||||
{
|
||||
bRet = true;
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
bool Rect::intersectsRect(const Rect& rect) const
|
||||
{
|
||||
return !( getMaxX() < rect.getMinX() ||
|
||||
rect.getMaxX() < getMinX() ||
|
||||
getMaxY() < rect.getMinY() ||
|
||||
rect.getMaxY() < getMinY());
|
||||
}
|
||||
|
||||
bool Rect::intersectsCircle(const cocos2d::Vec2 ¢er, float radius) const
|
||||
{
|
||||
Vec2 rectangleCenter((origin.x + size.width / 2),
|
||||
(origin.y + size.height / 2));
|
||||
|
||||
float w = size.width / 2;
|
||||
float h = size.height / 2;
|
||||
|
||||
float dx = std::abs(center.x - rectangleCenter.x);
|
||||
float dy = std::abs(center.y - rectangleCenter.y);
|
||||
|
||||
if (dx > (radius + w) || dy > (radius + h))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Vec2 circleDistance(std::abs(center.x - origin.x - w),
|
||||
std::abs(center.y - origin.y - h));
|
||||
|
||||
if (circleDistance.x <= (w))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (circleDistance.y <= (h))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
float cornerDistanceSq = powf(circleDistance.x - w, 2) + powf(circleDistance.y - h, 2);
|
||||
|
||||
return (cornerDistanceSq <= (powf(radius, 2)));
|
||||
}
|
||||
|
||||
void Rect::merge(const Rect& rect)
|
||||
{
|
||||
float minX = std::min(getMinX(), rect.getMinX());
|
||||
float minY = std::min(getMinY(), rect.getMinY());
|
||||
float maxX = std::max(getMaxX(), rect.getMaxX());
|
||||
float maxY = std::max(getMaxY(), rect.getMaxY());
|
||||
setRect(minX, minY, maxX - minX, maxY - minY);
|
||||
}
|
||||
|
||||
Rect Rect::unionWithRect(const Rect & rect) const
|
||||
{
|
||||
float thisLeftX = origin.x;
|
||||
float thisRightX = origin.x + size.width;
|
||||
float thisTopY = origin.y + size.height;
|
||||
float thisBottomY = origin.y;
|
||||
|
||||
if (thisRightX < thisLeftX)
|
||||
{
|
||||
std::swap(thisRightX, thisLeftX); // This rect has negative width
|
||||
}
|
||||
|
||||
if (thisTopY < thisBottomY)
|
||||
{
|
||||
std::swap(thisTopY, thisBottomY); // This rect has negative height
|
||||
}
|
||||
|
||||
float otherLeftX = rect.origin.x;
|
||||
float otherRightX = rect.origin.x + rect.size.width;
|
||||
float otherTopY = rect.origin.y + rect.size.height;
|
||||
float otherBottomY = rect.origin.y;
|
||||
|
||||
if (otherRightX < otherLeftX)
|
||||
{
|
||||
std::swap(otherRightX, otherLeftX); // Other rect has negative width
|
||||
}
|
||||
|
||||
if (otherTopY < otherBottomY)
|
||||
{
|
||||
std::swap(otherTopY, otherBottomY); // Other rect has negative height
|
||||
}
|
||||
|
||||
float combinedLeftX = std::min(thisLeftX, otherLeftX);
|
||||
float combinedRightX = std::max(thisRightX, otherRightX);
|
||||
float combinedTopY = std::max(thisTopY, otherTopY);
|
||||
float combinedBottomY = std::min(thisBottomY, otherBottomY);
|
||||
|
||||
return Rect(combinedLeftX, combinedBottomY, combinedRightX - combinedLeftX, combinedTopY - combinedBottomY);
|
||||
}
|
||||
|
||||
const Rect Rect::ZERO = Rect(0, 0, 0, 0);
|
||||
|
||||
NS_CC_END
|
||||
223
cocos2d-x/cocos/math/CCGeometry.h
Normal file
223
cocos2d-x/cocos/math/CCGeometry.h
Normal file
@@ -0,0 +1,223 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __MATH_CCGEOMETRY_H__
|
||||
#define __MATH_CCGEOMETRY_H__
|
||||
|
||||
#include "base/ccMacros.h"
|
||||
#include "math/CCMath.h"
|
||||
|
||||
/**
|
||||
* @addtogroup base
|
||||
* @{
|
||||
*/
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
class CC_DLL Size
|
||||
{
|
||||
public:
|
||||
/**Width of the Size.*/
|
||||
float width;
|
||||
/**Height of the Size.*/
|
||||
float height;
|
||||
public:
|
||||
/**Conversion from Vec2 to Size.*/
|
||||
operator Vec2() const
|
||||
{
|
||||
return Vec2(width, height);
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
@{
|
||||
Constructor.
|
||||
@param width Width of the size.
|
||||
@param height Height of the size.
|
||||
@param other Copy constructor.
|
||||
@param point Conversion from a point.
|
||||
*/
|
||||
Size();
|
||||
Size(float width, float height);
|
||||
Size(const Size& other);
|
||||
explicit Size(const Vec2& point);
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
Size& operator= (const Size& other);
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
Size& operator= (const Vec2& point);
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
Size operator+(const Size& right) const;
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
Size operator-(const Size& right) const;
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
Size operator*(float a) const;
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
Size operator/(float a) const;
|
||||
/**
|
||||
Set the width and height of Size.
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
void setSize(float width, float height);
|
||||
/**
|
||||
Check if two size is the same.
|
||||
* @js NA
|
||||
*/
|
||||
bool equals(const Size& target) const;
|
||||
/**Size(0,0).*/
|
||||
static const Size ZERO;
|
||||
};
|
||||
|
||||
/**Rectangle area.*/
|
||||
class CC_DLL Rect
|
||||
{
|
||||
public:
|
||||
/**Low left point of rect.*/
|
||||
Vec2 origin;
|
||||
/**Width and height of the rect.*/
|
||||
Size size;
|
||||
|
||||
public:
|
||||
/**
|
||||
Constructor an empty Rect.
|
||||
* @js NA
|
||||
*/
|
||||
Rect();
|
||||
/**
|
||||
Constructor a rect.
|
||||
* @js NA
|
||||
*/
|
||||
Rect(float x, float y, float width, float height);
|
||||
/**
|
||||
Constructor a rect.
|
||||
* @js NA
|
||||
*/
|
||||
Rect(const Vec2& pos, const Size& dimension);
|
||||
/**
|
||||
Copy constructor.
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
Rect(const Rect& other);
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
Rect& operator= (const Rect& other);
|
||||
/**
|
||||
Set the x, y, width and height of Rect.
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
void setRect(float x, float y, float width, float height);
|
||||
/**
|
||||
Get the left of the rect.
|
||||
* @js NA
|
||||
*/
|
||||
float getMinX() const; /// return the leftmost x-value of current rect
|
||||
/**
|
||||
Get the X coordinate of center point.
|
||||
* @js NA
|
||||
*/
|
||||
float getMidX() const; /// return the midpoint x-value of current rect
|
||||
/**
|
||||
Get the right of rect.
|
||||
* @js NA
|
||||
*/
|
||||
float getMaxX() const; /// return the rightmost x-value of current rect
|
||||
/**
|
||||
Get the bottom of rect.
|
||||
* @js NA
|
||||
*/
|
||||
float getMinY() const; /// return the bottommost y-value of current rect
|
||||
/**
|
||||
Get the Y coordinate of center point.
|
||||
* @js NA
|
||||
*/
|
||||
float getMidY() const; /// return the midpoint y-value of current rect
|
||||
/**
|
||||
Get top of rect.
|
||||
* @js NA
|
||||
*/
|
||||
float getMaxY() const; /// return the topmost y-value of current rect
|
||||
/**
|
||||
Compare two rects.
|
||||
* @js NA
|
||||
*/
|
||||
bool equals(const Rect& rect) const;
|
||||
/**
|
||||
Check if the points is contained in the rect.
|
||||
* @js NA
|
||||
*/
|
||||
bool containsPoint(const Vec2& point) const;
|
||||
/**
|
||||
Check the intersect status of two rects.
|
||||
* @js NA
|
||||
*/
|
||||
bool intersectsRect(const Rect& rect) const;
|
||||
/**
|
||||
Check the intersect status of the rect and a circle.
|
||||
* @js NA
|
||||
*/
|
||||
bool intersectsCircle(const Vec2& center, float radius) const;
|
||||
/**
|
||||
Get the min rect which can contain this and rect.
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
Rect unionWithRect(const Rect & rect) const;
|
||||
/**Compute the min rect which can contain this and rect, assign it to this.*/
|
||||
void merge(const Rect& rect);
|
||||
/**An empty Rect.*/
|
||||
static const Rect ZERO;
|
||||
};
|
||||
|
||||
NS_CC_END
|
||||
|
||||
// end of base group
|
||||
/// @}
|
||||
|
||||
#endif // __MATH_CCGEOMETRY_H__
|
||||
36
cocos2d-x/cocos/math/CCMath.h
Normal file
36
cocos2d-x/cocos/math/CCMath.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __CC_MATH_H__
|
||||
#define __CC_MATH_H__
|
||||
|
||||
#include "math/Vec2.h"
|
||||
#include "math/Vec3.h"
|
||||
#include "math/Vec4.h"
|
||||
#include "math/Mat4.h"
|
||||
#include "math/Quaternion.h"
|
||||
#include "math/Mat3.hpp"
|
||||
|
||||
#endif
|
||||
78
cocos2d-x/cocos/math/CCMathBase.h
Normal file
78
cocos2d-x/cocos/math/CCMathBase.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __CCMATHBASE_H__
|
||||
#define __CCMATHBASE_H__
|
||||
|
||||
#include <memory>
|
||||
#include <string.h>
|
||||
#include "base/ccMacros.h"
|
||||
/**
|
||||
* @addtogroup base
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**Util macro for conversion from degrees to radians.*/
|
||||
#define MATH_DEG_TO_RAD(x) ((x) * 0.0174532925f)
|
||||
/**Util macro for conversion from radians to degrees.*/
|
||||
#define MATH_RAD_TO_DEG(x) ((x)* 57.29577951f)
|
||||
/**
|
||||
@{ Util macro for const float such as epsilon, small float and float precision tolerance.
|
||||
*/
|
||||
#define MATH_FLOAT_SMALL 1.0e-37f
|
||||
#define MATH_TOLERANCE 2e-37f
|
||||
#define MATH_PIOVER2 1.57079632679489661923f
|
||||
#define MATH_EPSILON 0.000001f
|
||||
/**@}*/
|
||||
|
||||
//#define MATH_PIOVER4 0.785398163397448309616f
|
||||
//#define MATH_PIX2 6.28318530717958647693f
|
||||
//#define MATH_E 2.71828182845904523536f
|
||||
//#define MATH_LOG10E 0.4342944819032518f
|
||||
//#define MATH_LOG2E 1.442695040888963387f
|
||||
//#define MATH_PI 3.14159265358979323846f
|
||||
//#define MATH_RANDOM_MINUS1_1() ((2.0f*((float)rand()/RAND_MAX))-1.0f) // Returns a random float between -1 and 1.
|
||||
//#define MATH_RANDOM_0_1() ((float)rand()/RAND_MAX) // Returns a random float between 0 and 1.
|
||||
//#define MATH_CLAMP(x, lo, hi) ((x < lo) ? lo : ((x > hi) ? hi : x))
|
||||
//#ifndef M_1_PI
|
||||
//#define M_1_PI 0.31830988618379067154
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define NS_CC_MATH_BEGIN namespace cocos2d {
|
||||
#define NS_CC_MATH_END }
|
||||
#define USING_NS_CC_MATH using namespace cocos2d
|
||||
#else
|
||||
#define NS_CC_MATH_BEGIN
|
||||
#define NS_CC_MATH_END
|
||||
#define USING_NS_CC_MATH
|
||||
#endif
|
||||
|
||||
/**
|
||||
* end of base group
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif // __CCMATHBASE_H__
|
||||
|
||||
142
cocos2d-x/cocos/math/CCVertex.cpp
Normal file
142
cocos2d-x/cocos/math/CCVertex.cpp
Normal file
@@ -0,0 +1,142 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
Copyright (c) 2011 ForzeField Studios S.L
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "math/CCVertex.h"
|
||||
#include "base/ccMacros.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
void ccVertexLineToPolygon(Vec2 *points, float stroke, Vec2 *vertices, unsigned int offset, unsigned int nuPoints)
|
||||
{
|
||||
nuPoints += offset;
|
||||
if(nuPoints<=1) return;
|
||||
|
||||
stroke *= 0.5f;
|
||||
|
||||
unsigned int idx;
|
||||
unsigned int nuPointsMinus = nuPoints-1;
|
||||
|
||||
for(unsigned int i = offset; i<nuPoints; i++)
|
||||
{
|
||||
idx = i*2;
|
||||
Vec2 p1 = points[i];
|
||||
Vec2 perpVector;
|
||||
|
||||
if(i == 0)
|
||||
perpVector = (p1 - points[i+1]).getNormalized().getPerp();
|
||||
else if(i == nuPointsMinus)
|
||||
perpVector = (points[i-1] - p1).getNormalized().getPerp();
|
||||
else
|
||||
{
|
||||
Vec2 p2 = points[i+1];
|
||||
Vec2 p0 = points[i-1];
|
||||
|
||||
Vec2 p2p1 = (p2 - p1).getNormalized();
|
||||
Vec2 p0p1 = (p0 - p1).getNormalized();
|
||||
|
||||
// Calculate angle between vectors
|
||||
float angle = acosf(p2p1.dot(p0p1));
|
||||
|
||||
if(angle < CC_DEGREES_TO_RADIANS(70))
|
||||
perpVector = p2p1.getMidpoint(p0p1).getNormalized().getPerp();
|
||||
else if(angle < CC_DEGREES_TO_RADIANS(170))
|
||||
perpVector = p2p1.getMidpoint(p0p1).getNormalized();
|
||||
else
|
||||
perpVector = (p2 - p0).getNormalized().getPerp();
|
||||
}
|
||||
perpVector = perpVector * stroke;
|
||||
|
||||
vertices[idx].set(p1.x + perpVector.x, p1.y + perpVector.y);
|
||||
vertices[idx + 1].set(p1.x - perpVector.x, p1.y - perpVector.y);
|
||||
|
||||
}
|
||||
|
||||
// Validate vertexes
|
||||
offset = (offset==0) ? 0 : offset-1;
|
||||
for(unsigned int i = offset; i<nuPointsMinus; i++)
|
||||
{
|
||||
idx = i*2;
|
||||
const unsigned int idx1 = idx+2;
|
||||
|
||||
Vec2 p1 = vertices[idx];
|
||||
Vec2 p2 = vertices[idx+1];
|
||||
Vec2 p3 = vertices[idx1];
|
||||
Vec2 p4 = vertices[idx1+1];
|
||||
|
||||
float s;
|
||||
//BOOL fixVertex = !ccpLineIntersect(Vec2(p1.x, p1.y), Vec2(p4.x, p4.y), Vec2(p2.x, p2.y), Vec2(p3.x, p3.y), &s, &t);
|
||||
bool fixVertex = !ccVertexLineIntersect(p1.x, p1.y, p4.x, p4.y, p2.x, p2.y, p3.x, p3.y, &s);
|
||||
if(!fixVertex)
|
||||
if (s<0.0f || s>1.0f)
|
||||
fixVertex = true;
|
||||
|
||||
if(fixVertex)
|
||||
{
|
||||
vertices[idx1] = p4;
|
||||
vertices[idx1+1] = p3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ccVertexLineIntersect(float Ax, float Ay,
|
||||
float Bx, float By,
|
||||
float Cx, float Cy,
|
||||
float Dx, float Dy, float *T)
|
||||
{
|
||||
float distAB, theCos, theSin, newX;
|
||||
|
||||
// FAIL: Line undefined
|
||||
if ((Ax==Bx && Ay==By) || (Cx==Dx && Cy==Dy)) return false;
|
||||
|
||||
// Translate system to make A the origin
|
||||
Bx-=Ax; By-=Ay;
|
||||
Cx-=Ax; Cy-=Ay;
|
||||
Dx-=Ax; Dy-=Ay;
|
||||
|
||||
// Length of segment AB
|
||||
distAB = sqrtf(Bx*Bx+By*By);
|
||||
|
||||
// Rotate the system so that point B is on the positive X axis.
|
||||
theCos = Bx/distAB;
|
||||
theSin = By/distAB;
|
||||
newX = Cx*theCos+Cy*theSin;
|
||||
Cy = Cy*theCos-Cx*theSin; Cx = newX;
|
||||
newX = Dx*theCos+Dy*theSin;
|
||||
Dy = Dy*theCos-Dx*theSin; Dx = newX;
|
||||
|
||||
// FAIL: Lines are parallel.
|
||||
if (Cy == Dy) return false;
|
||||
|
||||
// Discover the relative position of the intersection in the line AB
|
||||
*T = (Dx+(Cx-Dx)*Dy/(Dy-Cy))/distAB;
|
||||
|
||||
// Success.
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
||||
57
cocos2d-x/cocos/math/CCVertex.h
Normal file
57
cocos2d-x/cocos/math/CCVertex.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
Copyright (c) 2011 ForzeField Studios S.L
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
#ifndef __CCVERTEX_H__
|
||||
#define __CCVERTEX_H__
|
||||
|
||||
#include "base/ccTypes.h"
|
||||
|
||||
/**
|
||||
* @addtogroup base
|
||||
* @{
|
||||
*/
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
/** @file CCVertex.h */
|
||||
|
||||
/** converts a line to a polygon */
|
||||
void CC_DLL ccVertexLineToPolygon(Vec2 *points, float stroke, Vec2 *vertices, unsigned int offset, unsigned int nuPoints);
|
||||
|
||||
/** returns whether or not the line intersects */
|
||||
bool CC_DLL ccVertexLineIntersect(float Ax, float Ay,
|
||||
float Bx, float By,
|
||||
float Cx, float Cy,
|
||||
float Dx, float Dy, float *T);
|
||||
|
||||
NS_CC_END
|
||||
|
||||
|
||||
// end of base group
|
||||
/// @}
|
||||
|
||||
#endif /* __CCVERTEX_H__ */
|
||||
|
||||
375
cocos2d-x/cocos/math/Mat3.cpp
Normal file
375
cocos2d-x/cocos/math/Mat3.cpp
Normal file
@@ -0,0 +1,375 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "math/Mat3.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include "math/Quaternion.h"
|
||||
#include "math/MathUtil.h"
|
||||
#include "base/ccMacros.h"
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
Mat3::Mat3()
|
||||
{
|
||||
*this = IDENTITY;
|
||||
}
|
||||
|
||||
Mat3::Mat3(float m11, float m12, float m13, float m21, float m22, float m23,
|
||||
float m31, float m32, float m33)
|
||||
{
|
||||
set(m11, m12, m13, m21, m22, m23, m31, m32, m33);
|
||||
}
|
||||
|
||||
Mat3::Mat3(const float* mat)
|
||||
{
|
||||
set(mat);
|
||||
}
|
||||
|
||||
Mat3::Mat3(const Mat3& copy)
|
||||
{
|
||||
memcpy(m, copy.m, MATRIX3_SIZE);
|
||||
}
|
||||
|
||||
Mat3::~Mat3()
|
||||
{
|
||||
}
|
||||
|
||||
void Mat3::set(float m11, float m12, float m13, float m21, float m22, float m23, float m31, float m32, float m33)
|
||||
{
|
||||
m[0] = m11;
|
||||
m[1] = m21;
|
||||
m[2] = m31;
|
||||
m[3] = m12;
|
||||
m[4] = m22;
|
||||
m[5] = m32;
|
||||
m[6] = m13;
|
||||
m[7] = m23;
|
||||
m[8] = m33;
|
||||
}
|
||||
|
||||
void Mat3::set(const float* mat)
|
||||
{
|
||||
GP_ASSERT(mat);
|
||||
memcpy(this->m, mat, MATRIX3_SIZE);
|
||||
}
|
||||
|
||||
void Mat3::set(const Mat3& mat)
|
||||
{
|
||||
memcpy(this->m, mat.m, MATRIX3_SIZE);
|
||||
}
|
||||
|
||||
void Mat3::identity(Mat3& mat)
|
||||
{
|
||||
mat.m[0] = 1;
|
||||
mat.m[1] = 0;
|
||||
mat.m[2] = 0;
|
||||
mat.m[3] = 0;
|
||||
mat.m[4] = 1;
|
||||
mat.m[5] = 0;
|
||||
mat.m[6] = 0;
|
||||
mat.m[7] = 0;
|
||||
mat.m[8] = 1;
|
||||
}
|
||||
|
||||
void Mat3::transpose()
|
||||
{
|
||||
float a01 = m[1], a02 = m[2], a12 = m[5];
|
||||
m[1] = m[3];
|
||||
m[2] = m[6];
|
||||
m[3] = a01;
|
||||
m[5] = m[7];
|
||||
m[6] = a02;
|
||||
m[7] = a12;
|
||||
}
|
||||
|
||||
void Mat3::transpose(Mat3 &out, const Mat3 &mat)
|
||||
{
|
||||
out.m[0] = mat.m[0];
|
||||
out.m[1] = mat.m[3];
|
||||
out.m[2] = mat.m[6];
|
||||
out.m[3] = mat.m[1];
|
||||
out.m[4] = mat.m[4];
|
||||
out.m[5] = mat.m[7];
|
||||
out.m[6] = mat.m[2];
|
||||
out.m[7] = mat.m[5];
|
||||
out.m[8] = mat.m[8];
|
||||
}
|
||||
|
||||
void Mat3::inverse()
|
||||
{
|
||||
float a00 = m[0], a01 = m[1], a02 = m[2];
|
||||
float a10 = m[3], a11 = m[4], a12 = m[5];
|
||||
float a20 = m[6], a21 = m[7], a22 = m[8];
|
||||
|
||||
float b01 = a22 * a11 - a12 * a21;
|
||||
float b11 = -a22 * a10 + a12 * a20;
|
||||
float b21 = a21 * a10 - a11 * a20;
|
||||
|
||||
// Calculate the determinant
|
||||
float det = a00 * b01 + a01 * b11 + a02 * b21;
|
||||
|
||||
det = 1.0 / det;
|
||||
m[0] = b01 * det;
|
||||
m[1] = (-a22 * a01 + a02 * a21) * det;
|
||||
m[2] = (a12 * a01 - a02 * a11) * det;
|
||||
m[3] = b11 * det;
|
||||
m[4] = (a22 * a00 - a02 * a20) * det;
|
||||
m[5] = (-a12 * a00 + a02 * a10) * det;
|
||||
m[6] = b21 * det;
|
||||
m[7] = (-a21 * a00 + a01 * a20) * det;
|
||||
m[8] = (a11 * a00 - a01 * a10) * det;
|
||||
}
|
||||
|
||||
void Mat3::adjoint(Mat3 &out, const Mat3 &mat)
|
||||
{
|
||||
float a00 = mat.m[0], a01 = mat.m[1], a02 = mat.m[2];
|
||||
float a10 = mat.m[3], a11 = mat.m[4], a12 = mat.m[5];
|
||||
float a20 = mat.m[6], a21 = mat.m[7], a22 = mat.m[8];
|
||||
|
||||
out.m[0] = (a11 * a22 - a12 * a21);
|
||||
out.m[1] = (a02 * a21 - a01 * a22);
|
||||
out.m[2] = (a01 * a12 - a02 * a11);
|
||||
out.m[3] = (a12 * a20 - a10 * a22);
|
||||
out.m[4] = (a00 * a22 - a02 * a20);
|
||||
out.m[5] = (a02 * a10 - a00 * a12);
|
||||
out.m[6] = (a10 * a21 - a11 * a20);
|
||||
out.m[7] = (a01 * a20 - a00 * a21);
|
||||
out.m[8] = (a00 * a11 - a01 * a10);
|
||||
}
|
||||
|
||||
float Mat3::determinant()
|
||||
{
|
||||
return m[0] * (m[8] * m[4] - m[5] * m[7]) + m[1] * (-m[8] * m[3] + m[5] * m[6]) + m[2] * (m[7] * m[3] - m[4] * m[6]);
|
||||
}
|
||||
|
||||
void Mat3::multiply(Mat3 &out, const Mat3 &a, const Mat3 &b)
|
||||
{
|
||||
float a00 = a.m[0], a01 = a.m[1], a02 = a.m[2];
|
||||
float a10 = a.m[3], a11 = a.m[4], a12 = a.m[5];
|
||||
float a20 = a.m[6], a21 = a.m[7], a22 = a.m[8];
|
||||
|
||||
float b00 = b.m[0], b01 = b.m[1], b02 = b.m[2];
|
||||
float b10 = b.m[3], b11 = b.m[4], b12 = b.m[5];
|
||||
float b20 = b.m[6], b21 = b.m[7], b22 = b.m[8];
|
||||
|
||||
out.m[0] = b00 * a00 + b01 * a10 + b02 * a20;
|
||||
out.m[1] = b00 * a01 + b01 * a11 + b02 * a21;
|
||||
out.m[2] = b00 * a02 + b01 * a12 + b02 * a22;
|
||||
|
||||
out.m[3] = b10 * a00 + b11 * a10 + b12 * a20;
|
||||
out.m[4] = b10 * a01 + b11 * a11 + b12 * a21;
|
||||
out.m[5] = b10 * a02 + b11 * a12 + b12 * a22;
|
||||
|
||||
out.m[6] = b20 * a00 + b21 * a10 + b22 * a20;
|
||||
out.m[7] = b20 * a01 + b21 * a11 + b22 * a21;
|
||||
out.m[8] = b20 * a02 + b21 * a12 + b22 * a22;
|
||||
}
|
||||
|
||||
void Mat3::translate(Mat3 &out, const Mat3 &mat, const Vec2 &vec)
|
||||
{
|
||||
float a00 = mat.m[0], a01 = mat.m[1], a02 = mat.m[2];
|
||||
float a10 = mat.m[3], a11 = mat.m[4], a12 = mat.m[5];
|
||||
float a20 = mat.m[6], a21 = mat.m[7], a22 = mat.m[8];
|
||||
float x = vec.x, y = vec.y;
|
||||
|
||||
out.m[0] = a00;
|
||||
out.m[1] = a01;
|
||||
out.m[2] = a02;
|
||||
|
||||
out.m[3] = a10;
|
||||
out.m[4] = a11;
|
||||
out.m[5] = a12;
|
||||
|
||||
out.m[6] = x * a00 + y * a10 + a20;
|
||||
out.m[7] = x * a01 + y * a11 + a21;
|
||||
out.m[8] = x * a02 + y * a12 + a22;
|
||||
}
|
||||
|
||||
void Mat3::rotate(Mat3 &out, const Mat3 &mat, float rad)
|
||||
{
|
||||
float a00 = mat.m[0], a01 = mat.m[1], a02 = mat.m[2];
|
||||
float a10 = mat.m[3], a11 = mat.m[4], a12 = mat.m[5];
|
||||
float a20 = mat.m[6], a21 = mat.m[7], a22 = mat.m[8];
|
||||
|
||||
float s = sin(rad);
|
||||
float c = cos(rad);
|
||||
|
||||
out.m[0] = c * a00 + s * a10;
|
||||
out.m[1] = c * a01 + s * a11;
|
||||
out.m[2] = c * a02 + s * a12;
|
||||
|
||||
out.m[3] = c * a10 - s * a00;
|
||||
out.m[4] = c * a11 - s * a01;
|
||||
out.m[5] = c * a12 - s * a02;
|
||||
|
||||
out.m[6] = a20;
|
||||
out.m[7] = a21;
|
||||
out.m[8] = a22;
|
||||
}
|
||||
|
||||
void Mat3::scale(Mat3 &out, const Mat3 &mat, const Vec2 &vec)
|
||||
{
|
||||
float x = vec.x, y = vec.y;
|
||||
|
||||
out.m[0] = x * mat.m[0];
|
||||
out.m[1] = x * mat.m[1];
|
||||
out.m[2] = x * mat.m[2];
|
||||
|
||||
out.m[3] = y * mat.m[3];
|
||||
out.m[4] = y * mat.m[4];
|
||||
out.m[5] = y * mat.m[5];
|
||||
|
||||
out.m[6] = mat.m[6];
|
||||
out.m[7] = mat.m[7];
|
||||
out.m[8] = mat.m[8];
|
||||
}
|
||||
|
||||
void Mat3::fromMat4(Mat3 &out, const Mat4 &mat)
|
||||
{
|
||||
out.m[0] = mat.m[0];
|
||||
out.m[1] = mat.m[1];
|
||||
out.m[2] = mat.m[2];
|
||||
out.m[3] = mat.m[4];
|
||||
out.m[4] = mat.m[5];
|
||||
out.m[5] = mat.m[6];
|
||||
out.m[6] = mat.m[8];
|
||||
out.m[7] = mat.m[9];
|
||||
out.m[8] = mat.m[10];
|
||||
}
|
||||
|
||||
void Mat3::fromTranslation(Mat3 &out, const Vec2 &vec)
|
||||
{
|
||||
out.m[0] = 1;
|
||||
out.m[1] = 0;
|
||||
out.m[2] = 0;
|
||||
out.m[3] = 0;
|
||||
out.m[4] = 1;
|
||||
out.m[5] = 0;
|
||||
out.m[6] = vec.x;
|
||||
out.m[7] = vec.y;
|
||||
out.m[8] = 1;
|
||||
}
|
||||
|
||||
void Mat3::fromRotation(Mat3 &out, float rad)
|
||||
{
|
||||
float s = sin(rad);
|
||||
float c = cos(rad);
|
||||
|
||||
out.m[0] = c;
|
||||
out.m[1] = s;
|
||||
out.m[2] = 0;
|
||||
|
||||
out.m[3] = -s;
|
||||
out.m[4] = c;
|
||||
out.m[5] = 0;
|
||||
|
||||
out.m[6] = 0;
|
||||
out.m[7] = 0;
|
||||
out.m[8] = 1;
|
||||
}
|
||||
|
||||
void Mat3::fromScaling(Mat3 &out, const Vec2 &vec)
|
||||
{
|
||||
out.m[0] = vec.x;
|
||||
out.m[1] = 0;
|
||||
out.m[2] = 0;
|
||||
|
||||
out.m[3] = 0;
|
||||
out.m[4] = vec.y;
|
||||
out.m[5] = 0;
|
||||
|
||||
out.m[6] = 0;
|
||||
out.m[7] = 0;
|
||||
out.m[8] = 1;
|
||||
}
|
||||
|
||||
void Mat3::fromQuat(Mat3 &out, const Quaternion &quat)
|
||||
{
|
||||
float x = quat.x, y = quat.y, z = quat.z, w = quat.w;
|
||||
float x2 = x + x;
|
||||
float y2 = y + y;
|
||||
float z2 = z + z;
|
||||
|
||||
float xx = x * x2;
|
||||
float yx = y * x2;
|
||||
float yy = y * y2;
|
||||
float zx = z * x2;
|
||||
float zy = z * y2;
|
||||
float zz = z * z2;
|
||||
float wx = w * x2;
|
||||
float wy = w * y2;
|
||||
float wz = w * z2;
|
||||
|
||||
out.m[0] = 1 - yy - zz;
|
||||
out.m[3] = yx - wz;
|
||||
out.m[6] = zx + wy;
|
||||
|
||||
out.m[1] = yx + wz;
|
||||
out.m[4] = 1 - xx - zz;
|
||||
out.m[7] = zy - wx;
|
||||
|
||||
out.m[2] = zx - wy;
|
||||
out.m[5] = zy + wx;
|
||||
out.m[8] = 1 - xx - yy;
|
||||
}
|
||||
|
||||
void Mat3::add(Mat3 &out, const Mat3 &a, const Mat3 &b)
|
||||
{
|
||||
out.m[0] = a.m[0] + b.m[0];
|
||||
out.m[1] = a.m[1] + b.m[1];
|
||||
out.m[2] = a.m[2] + b.m[2];
|
||||
out.m[3] = a.m[3] + b.m[3];
|
||||
out.m[4] = a.m[4] + b.m[4];
|
||||
out.m[5] = a.m[5] + b.m[5];
|
||||
out.m[6] = a.m[6] + b.m[6];
|
||||
out.m[7] = a.m[7] + b.m[7];
|
||||
out.m[8] = a.m[8] + b.m[8];
|
||||
}
|
||||
|
||||
void Mat3::subtract(Mat3 &out, const Mat3 &a, const Mat3 &b)
|
||||
{
|
||||
out.m[0] = a.m[0] - b.m[0];
|
||||
out.m[1] = a.m[1] - b.m[1];
|
||||
out.m[2] = a.m[2] - b.m[2];
|
||||
out.m[3] = a.m[3] - b.m[3];
|
||||
out.m[4] = a.m[4] - b.m[4];
|
||||
out.m[5] = a.m[5] - b.m[5];
|
||||
out.m[6] = a.m[6] - b.m[6];
|
||||
out.m[7] = a.m[7] - b.m[7];
|
||||
out.m[8] = a.m[8] - b.m[8];
|
||||
}
|
||||
|
||||
const Mat3 Mat3::IDENTITY = Mat3(
|
||||
1.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f);
|
||||
|
||||
const Mat3 Mat3::ZERO = Mat3(
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0);
|
||||
|
||||
NS_CC_MATH_END
|
||||
|
||||
232
cocos2d-x/cocos/math/Mat3.hpp
Normal file
232
cocos2d-x/cocos/math/Mat3.hpp
Normal file
@@ -0,0 +1,232 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef MATH_MAT3_H
|
||||
#define MATH_MAT3_H
|
||||
|
||||
#define MATRIX3_SIZE ( sizeof(float) * 9)
|
||||
|
||||
#include "base/ccMacros.h"
|
||||
|
||||
#include "math/Vec2.h"
|
||||
#include "math/Vec3.h"
|
||||
#include "math/Vec4.h"
|
||||
#include "math/Mat4.h"
|
||||
|
||||
/**
|
||||
* @addtogroup base
|
||||
* @{
|
||||
*/
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
class CC_DLL Mat3
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Stores the columns of this 3x3 matrix.
|
||||
* */
|
||||
float m[9];
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
* Constructs a matrix initialized to the identity matrix:
|
||||
*
|
||||
* 1 0 0
|
||||
* 0 1 0
|
||||
* 0 0 1
|
||||
*/
|
||||
Mat3();
|
||||
|
||||
/**
|
||||
* Constructs a matrix initialized to the specified value.
|
||||
*
|
||||
* @param m11 The first element of the first row.
|
||||
* @param m12 The second element of the first row.
|
||||
* @param m13 The third element of the first row.
|
||||
* @param m21 The first element of the second row.
|
||||
* @param m22 The second element of the second row.
|
||||
* @param m23 The third element of the second row.
|
||||
* @param m31 The first element of the third row.
|
||||
* @param m32 The second element of the third row.
|
||||
* @param m33 The third element of the third row.
|
||||
*/
|
||||
Mat3(float m11, float m12, float m13, float m21, float m22, float m23, float m31, float m32, float m33);
|
||||
|
||||
/**
|
||||
* Creates a matrix initialized to the specified column-major array.
|
||||
*
|
||||
* The passed-in array is in column-major order, so the memory layout of the array is as follows:
|
||||
*
|
||||
* 0 3 6
|
||||
* 1 4 7
|
||||
* 2 5 8
|
||||
*
|
||||
* @param mat An array containing 16 elements in column-major order.
|
||||
*/
|
||||
Mat3(const float* mat);
|
||||
|
||||
/**
|
||||
* Constructs a new matrix by copying the values from the specified matrix.
|
||||
*
|
||||
* @param copy The matrix to copy.
|
||||
*/
|
||||
Mat3(const Mat3& copy);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~Mat3();
|
||||
|
||||
/**
|
||||
* Sets the values of this matrix.
|
||||
*
|
||||
* @param m11 The first element of the first row.
|
||||
* @param m12 The second element of the first row.
|
||||
* @param m13 The third element of the first row.
|
||||
* @param m21 The first element of the second row.
|
||||
* @param m22 The second element of the second row.
|
||||
* @param m23 The third element of the second row.
|
||||
* @param m31 The first element of the third row.
|
||||
* @param m32 The second element of the third row.
|
||||
* @param m33 The third element of the third row.
|
||||
*/
|
||||
void set(float m11, float m12, float m13, float m21, float m22, float m23,
|
||||
float m31, float m32, float m33);
|
||||
|
||||
/**
|
||||
* Sets the values of this matrix to those in the specified column-major array.
|
||||
*
|
||||
* @param mat An array containing 9 elements in column-major format.
|
||||
*/
|
||||
void set(const float* mat);
|
||||
|
||||
/**
|
||||
* Sets the values of this matrix to those of the specified matrix.
|
||||
*
|
||||
* @param mat The source matrix.
|
||||
*/
|
||||
void set(const Mat3& mat);
|
||||
|
||||
/**
|
||||
* return an identity matrix.
|
||||
*/
|
||||
static void identity(Mat3& mat);
|
||||
|
||||
/**
|
||||
* Transposes matrix.
|
||||
*/
|
||||
void transpose();
|
||||
|
||||
/**
|
||||
* Transposes a matrix.
|
||||
*/
|
||||
static void transpose(Mat3& out, const Mat3& mat);
|
||||
|
||||
/**
|
||||
* Inverts a matrix.
|
||||
*/
|
||||
void inverse();
|
||||
|
||||
/**
|
||||
* Calculates the adjugate of a matrix.
|
||||
*/
|
||||
static void adjoint(Mat3& out, const Mat3& mat);
|
||||
|
||||
/**
|
||||
* Calculates the determinant of a matrix.
|
||||
*/
|
||||
float determinant();
|
||||
|
||||
/**
|
||||
* Multiply two matrices explicitly.
|
||||
*/
|
||||
static void multiply(Mat3& out, const Mat3& a, const Mat3& b);
|
||||
|
||||
/**
|
||||
* Multiply a matrix with a translation matrix given by a translation offset.
|
||||
*/
|
||||
static void translate(Mat3& out, const Mat3& mat, const Vec2& vec);
|
||||
|
||||
/**
|
||||
* Rotates a matrix by the given angle.
|
||||
*/
|
||||
static void rotate(Mat3& out, const Mat3& mat, float rad);
|
||||
|
||||
/**
|
||||
* Multiply a matrix with a scale matrix given by a scale vector.
|
||||
*/
|
||||
static void scale(Mat3& out, const Mat3& mat, const Vec2& vec);
|
||||
|
||||
/**
|
||||
* Copies the upper-left 3x3 values of a 4x4 matrix into a 3x3 matrix.
|
||||
*/
|
||||
static void fromMat4(Mat3& out, const Mat4& mat);
|
||||
|
||||
/**
|
||||
* Creates a matrix from a translation offset.
|
||||
*/
|
||||
static void fromTranslation(Mat3& out, const Vec2& vec);
|
||||
|
||||
/**
|
||||
* Creates a matrix from a given angle.
|
||||
*/
|
||||
static void fromRotation(Mat3& out, float rad);
|
||||
|
||||
/**
|
||||
* Creates a matrix from a scale vector.
|
||||
*/
|
||||
static void fromScaling(Mat3& out, const Vec2& vec);
|
||||
|
||||
/**
|
||||
* Calculates a 3x3 matrix from the given quaternion.
|
||||
*/
|
||||
|
||||
static void fromQuat(Mat3& out, const Quaternion& quat);
|
||||
|
||||
/**
|
||||
* Adds two matrices.
|
||||
*/
|
||||
static void add(Mat3& out, const Mat3& a, const Mat3& b);
|
||||
|
||||
/**
|
||||
* Subtracts matrix b from matrix a.
|
||||
*/
|
||||
static void subtract(Mat3& out, const Mat3& a, const Mat3& b);
|
||||
|
||||
/** equals to a matrix full of zeros */
|
||||
static const Mat3 ZERO;
|
||||
/** equals to the identity matrix */
|
||||
static const Mat3 IDENTITY;
|
||||
};
|
||||
|
||||
NS_CC_MATH_END
|
||||
|
||||
/**
|
||||
end of base group
|
||||
@}
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
981
cocos2d-x/cocos/math/Mat4.cpp
Normal file
981
cocos2d-x/cocos/math/Mat4.cpp
Normal file
@@ -0,0 +1,981 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
|
||||
#include "math/Mat4.h"
|
||||
|
||||
#include <cmath>
|
||||
#include "math/Quaternion.h"
|
||||
#include "math/MathUtil.h"
|
||||
#include "base/ccMacros.h"
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
Mat4::Mat4()
|
||||
{
|
||||
*this = IDENTITY;
|
||||
}
|
||||
|
||||
Mat4::Mat4(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24,
|
||||
float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44)
|
||||
{
|
||||
set(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44);
|
||||
}
|
||||
|
||||
Mat4::Mat4(const float* mat)
|
||||
{
|
||||
set(mat);
|
||||
}
|
||||
|
||||
Mat4::Mat4(const Mat4& copy)
|
||||
{
|
||||
memcpy(m, copy.m, MATRIX_SIZE);
|
||||
}
|
||||
|
||||
Mat4::~Mat4()
|
||||
{
|
||||
}
|
||||
|
||||
void Mat4::createLookAt(const Vec3& eyePosition, const Vec3& targetPosition, const Vec3& up, Mat4* dst)
|
||||
{
|
||||
createLookAt(eyePosition.x, eyePosition.y, eyePosition.z, targetPosition.x, targetPosition.y, targetPosition.z,
|
||||
up.x, up.y, up.z, dst);
|
||||
}
|
||||
|
||||
void Mat4::createLookAt(float eyePositionX, float eyePositionY, float eyePositionZ,
|
||||
float targetPositionX, float targetPositionY, float targetPositionZ,
|
||||
float upX, float upY, float upZ, Mat4* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
Vec3 eye(eyePositionX, eyePositionY, eyePositionZ);
|
||||
Vec3 target(targetPositionX, targetPositionY, targetPositionZ);
|
||||
Vec3 up(upX, upY, upZ);
|
||||
up.normalize();
|
||||
|
||||
Vec3 zaxis;
|
||||
Vec3::subtract(eye, target, &zaxis);
|
||||
zaxis.normalize();
|
||||
|
||||
Vec3 xaxis;
|
||||
Vec3::cross(up, zaxis, &xaxis);
|
||||
xaxis.normalize();
|
||||
|
||||
Vec3 yaxis;
|
||||
Vec3::cross(zaxis, xaxis, &yaxis);
|
||||
yaxis.normalize();
|
||||
|
||||
dst->m[0] = xaxis.x;
|
||||
dst->m[1] = yaxis.x;
|
||||
dst->m[2] = zaxis.x;
|
||||
dst->m[3] = 0.0f;
|
||||
|
||||
dst->m[4] = xaxis.y;
|
||||
dst->m[5] = yaxis.y;
|
||||
dst->m[6] = zaxis.y;
|
||||
dst->m[7] = 0.0f;
|
||||
|
||||
dst->m[8] = xaxis.z;
|
||||
dst->m[9] = yaxis.z;
|
||||
dst->m[10] = zaxis.z;
|
||||
dst->m[11] = 0.0f;
|
||||
|
||||
dst->m[12] = -Vec3::dot(xaxis, eye);
|
||||
dst->m[13] = -Vec3::dot(yaxis, eye);
|
||||
dst->m[14] = -Vec3::dot(zaxis, eye);
|
||||
dst->m[15] = 1.0f;
|
||||
}
|
||||
|
||||
void Mat4::createPerspective(float fieldOfView, float aspectRatio,
|
||||
float zNearPlane, float zFarPlane, Mat4* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
GP_ASSERT(zFarPlane != zNearPlane);
|
||||
|
||||
float f_n = 1.0f / (zFarPlane - zNearPlane);
|
||||
float theta = MATH_DEG_TO_RAD(fieldOfView) * 0.5f;
|
||||
if (std::abs(std::fmod(theta, MATH_PIOVER2)) < MATH_EPSILON)
|
||||
{
|
||||
CCLOGERROR("Invalid field of view value (%f) causes attempted calculation tan(%f), which is undefined.", fieldOfView, theta);
|
||||
return;
|
||||
}
|
||||
float divisor = std::tan(theta);
|
||||
GP_ASSERT(divisor);
|
||||
float factor = 1.0f / divisor;
|
||||
|
||||
memset(dst, 0, MATRIX_SIZE);
|
||||
|
||||
GP_ASSERT(aspectRatio);
|
||||
dst->m[0] = (1.0f / aspectRatio) * factor;
|
||||
dst->m[5] = factor;
|
||||
dst->m[10] = (-(zFarPlane + zNearPlane)) * f_n;
|
||||
dst->m[11] = -1.0f;
|
||||
dst->m[14] = -2.0f * zFarPlane * zNearPlane * f_n;
|
||||
}
|
||||
|
||||
void Mat4::createOrthographic(float left, float right, float bottom, float top, float zNearPlane, float zFarPlane, Mat4* dst)
|
||||
{
|
||||
createOrthographicOffCenter(left, right, bottom, top, zNearPlane, zFarPlane, dst);
|
||||
}
|
||||
|
||||
void Mat4::createOrthographicOffCenter(float left, float right, float bottom, float top,
|
||||
float zNearPlane, float zFarPlane, Mat4* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
GP_ASSERT(right != left);
|
||||
GP_ASSERT(top != bottom);
|
||||
GP_ASSERT(zFarPlane != zNearPlane);
|
||||
|
||||
memset(dst, 0, MATRIX_SIZE);
|
||||
dst->m[0] = 2 / (right - left);
|
||||
dst->m[5] = 2 / (top - bottom);
|
||||
dst->m[10] = 2 / (zNearPlane - zFarPlane);
|
||||
dst->m[12] = (left + right) / (left - right);
|
||||
dst->m[13] = (top + bottom) / (bottom - top);
|
||||
dst->m[14] = (zNearPlane + zFarPlane) / (zNearPlane - zFarPlane);
|
||||
dst->m[15] = 1;
|
||||
}
|
||||
|
||||
void Mat4::createBillboard(const Vec3& objectPosition, const Vec3& cameraPosition,
|
||||
const Vec3& cameraUpVector, Mat4* dst)
|
||||
{
|
||||
createBillboardHelper(objectPosition, cameraPosition, cameraUpVector, nullptr, dst);
|
||||
}
|
||||
|
||||
void Mat4::createBillboard(const Vec3& objectPosition, const Vec3& cameraPosition,
|
||||
const Vec3& cameraUpVector, const Vec3& cameraForwardVector,
|
||||
Mat4* dst)
|
||||
{
|
||||
createBillboardHelper(objectPosition, cameraPosition, cameraUpVector, &cameraForwardVector, dst);
|
||||
}
|
||||
|
||||
void Mat4::createBillboardHelper(const Vec3& objectPosition, const Vec3& cameraPosition,
|
||||
const Vec3& cameraUpVector, const Vec3* cameraForwardVector,
|
||||
Mat4* dst)
|
||||
{
|
||||
Vec3 delta(objectPosition, cameraPosition);
|
||||
bool isSufficientDelta = delta.lengthSquared() > MATH_EPSILON;
|
||||
|
||||
dst->setIdentity();
|
||||
dst->m[3] = objectPosition.x;
|
||||
dst->m[7] = objectPosition.y;
|
||||
dst->m[11] = objectPosition.z;
|
||||
|
||||
// As per the contracts for the 2 variants of createBillboard, we need
|
||||
// either a safe default or a sufficient distance between object and camera.
|
||||
if (cameraForwardVector || isSufficientDelta)
|
||||
{
|
||||
Vec3 target = isSufficientDelta ? cameraPosition : (objectPosition - *cameraForwardVector);
|
||||
|
||||
// A billboard is the inverse of a lookAt rotation
|
||||
Mat4 lookAt;
|
||||
createLookAt(objectPosition, target, cameraUpVector, &lookAt);
|
||||
dst->m[0] = lookAt.m[0];
|
||||
dst->m[1] = lookAt.m[4];
|
||||
dst->m[2] = lookAt.m[8];
|
||||
dst->m[4] = lookAt.m[1];
|
||||
dst->m[5] = lookAt.m[5];
|
||||
dst->m[6] = lookAt.m[9];
|
||||
dst->m[8] = lookAt.m[2];
|
||||
dst->m[9] = lookAt.m[6];
|
||||
dst->m[10] = lookAt.m[10];
|
||||
}
|
||||
}
|
||||
|
||||
// void Mat4::createReflection(const Plane& plane, Mat4* dst)
|
||||
// {
|
||||
// Vec3 normal(plane.getNormal());
|
||||
// float k = -2.0f * plane.getDistance();
|
||||
|
||||
// dst->setIdentity();
|
||||
|
||||
// dst->m[0] -= 2.0f * normal.x * normal.x;
|
||||
// dst->m[5] -= 2.0f * normal.y * normal.y;
|
||||
// dst->m[10] -= 2.0f * normal.z * normal.z;
|
||||
// dst->m[1] = dst->m[4] = -2.0f * normal.x * normal.y;
|
||||
// dst->m[2] = dst->m[8] = -2.0f * normal.x * normal.z;
|
||||
// dst->m[6] = dst->m[9] = -2.0f * normal.y * normal.z;
|
||||
|
||||
// dst->m[3] = k * normal.x;
|
||||
// dst->m[7] = k * normal.y;
|
||||
// dst->m[11] = k * normal.z;
|
||||
// }
|
||||
|
||||
void Mat4::createScale(const Vec3& scale, Mat4* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
memcpy(dst, &IDENTITY, MATRIX_SIZE);
|
||||
|
||||
dst->m[0] = scale.x;
|
||||
dst->m[5] = scale.y;
|
||||
dst->m[10] = scale.z;
|
||||
}
|
||||
|
||||
void Mat4::createScale(float xScale, float yScale, float zScale, Mat4* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
memcpy(dst, &IDENTITY, MATRIX_SIZE);
|
||||
|
||||
dst->m[0] = xScale;
|
||||
dst->m[5] = yScale;
|
||||
dst->m[10] = zScale;
|
||||
}
|
||||
|
||||
|
||||
void Mat4::createRotation(const Quaternion& q, Mat4* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
float x2 = q.x + q.x;
|
||||
float y2 = q.y + q.y;
|
||||
float z2 = q.z + q.z;
|
||||
|
||||
float xx2 = q.x * x2;
|
||||
float yy2 = q.y * y2;
|
||||
float zz2 = q.z * z2;
|
||||
float xy2 = q.x * y2;
|
||||
float xz2 = q.x * z2;
|
||||
float yz2 = q.y * z2;
|
||||
float wx2 = q.w * x2;
|
||||
float wy2 = q.w * y2;
|
||||
float wz2 = q.w * z2;
|
||||
|
||||
dst->m[0] = 1.0f - yy2 - zz2;
|
||||
dst->m[1] = xy2 + wz2;
|
||||
dst->m[2] = xz2 - wy2;
|
||||
dst->m[3] = 0.0f;
|
||||
|
||||
dst->m[4] = xy2 - wz2;
|
||||
dst->m[5] = 1.0f - xx2 - zz2;
|
||||
dst->m[6] = yz2 + wx2;
|
||||
dst->m[7] = 0.0f;
|
||||
|
||||
dst->m[8] = xz2 + wy2;
|
||||
dst->m[9] = yz2 - wx2;
|
||||
dst->m[10] = 1.0f - xx2 - yy2;
|
||||
dst->m[11] = 0.0f;
|
||||
|
||||
dst->m[12] = 0.0f;
|
||||
dst->m[13] = 0.0f;
|
||||
dst->m[14] = 0.0f;
|
||||
dst->m[15] = 1.0f;
|
||||
}
|
||||
|
||||
void Mat4::createRotation(const Vec3& axis, float angle, Mat4* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
float x = axis.x;
|
||||
float y = axis.y;
|
||||
float z = axis.z;
|
||||
|
||||
// Make sure the input axis is normalized.
|
||||
float n = x*x + y*y + z*z;
|
||||
if (n != 1.0f)
|
||||
{
|
||||
// Not normalized.
|
||||
n = std::sqrt(n);
|
||||
// Prevent divide too close to zero.
|
||||
if (n > 0.000001f)
|
||||
{
|
||||
n = 1.0f / n;
|
||||
x *= n;
|
||||
y *= n;
|
||||
z *= n;
|
||||
}
|
||||
}
|
||||
|
||||
float c = std::cos(angle);
|
||||
float s = std::sin(angle);
|
||||
|
||||
float t = 1.0f - c;
|
||||
float tx = t * x;
|
||||
float ty = t * y;
|
||||
float tz = t * z;
|
||||
float txy = tx * y;
|
||||
float txz = tx * z;
|
||||
float tyz = ty * z;
|
||||
float sx = s * x;
|
||||
float sy = s * y;
|
||||
float sz = s * z;
|
||||
|
||||
dst->m[0] = c + tx*x;
|
||||
dst->m[1] = txy + sz;
|
||||
dst->m[2] = txz - sy;
|
||||
dst->m[3] = 0.0f;
|
||||
|
||||
dst->m[4] = txy - sz;
|
||||
dst->m[5] = c + ty*y;
|
||||
dst->m[6] = tyz + sx;
|
||||
dst->m[7] = 0.0f;
|
||||
|
||||
dst->m[8] = txz + sy;
|
||||
dst->m[9] = tyz - sx;
|
||||
dst->m[10] = c + tz*z;
|
||||
dst->m[11] = 0.0f;
|
||||
|
||||
dst->m[12] = 0.0f;
|
||||
dst->m[13] = 0.0f;
|
||||
dst->m[14] = 0.0f;
|
||||
dst->m[15] = 1.0f;
|
||||
}
|
||||
|
||||
void Mat4::createRotationX(float angle, Mat4* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
memcpy(dst, &IDENTITY, MATRIX_SIZE);
|
||||
|
||||
float c = std::cos(angle);
|
||||
float s = std::sin(angle);
|
||||
|
||||
dst->m[5] = c;
|
||||
dst->m[6] = s;
|
||||
dst->m[9] = -s;
|
||||
dst->m[10] = c;
|
||||
}
|
||||
|
||||
void Mat4::createRotationY(float angle, Mat4* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
memcpy(dst, &IDENTITY, MATRIX_SIZE);
|
||||
|
||||
float c = std::cos(angle);
|
||||
float s = std::sin(angle);
|
||||
|
||||
dst->m[0] = c;
|
||||
dst->m[2] = -s;
|
||||
dst->m[8] = s;
|
||||
dst->m[10] = c;
|
||||
}
|
||||
|
||||
void Mat4::createRotationZ(float angle, Mat4* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
memcpy(dst, &IDENTITY, MATRIX_SIZE);
|
||||
|
||||
float c = std::cos(angle);
|
||||
float s = std::sin(angle);
|
||||
|
||||
dst->m[0] = c;
|
||||
dst->m[1] = s;
|
||||
dst->m[4] = -s;
|
||||
dst->m[5] = c;
|
||||
}
|
||||
|
||||
void Mat4::createTranslation(const Vec3& translation, Mat4* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
memcpy(dst, &IDENTITY, MATRIX_SIZE);
|
||||
|
||||
dst->m[12] = translation.x;
|
||||
dst->m[13] = translation.y;
|
||||
dst->m[14] = translation.z;
|
||||
}
|
||||
|
||||
void Mat4::createTranslation(float xTranslation, float yTranslation, float zTranslation, Mat4* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
memcpy(dst, &IDENTITY, MATRIX_SIZE);
|
||||
|
||||
dst->m[12] = xTranslation;
|
||||
dst->m[13] = yTranslation;
|
||||
dst->m[14] = zTranslation;
|
||||
}
|
||||
|
||||
void Mat4::add(float scalar)
|
||||
{
|
||||
add(scalar, this);
|
||||
}
|
||||
|
||||
void Mat4::add(float scalar, Mat4* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
#ifdef __SSE__
|
||||
MathUtil::addMatrix(col, scalar, dst->col);
|
||||
#else
|
||||
MathUtil::addMatrix(m, scalar, dst->m);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Mat4::add(const Mat4& mat)
|
||||
{
|
||||
add(*this, mat, this);
|
||||
}
|
||||
|
||||
void Mat4::add(const Mat4& m1, const Mat4& m2, Mat4* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
#ifdef __SSE__
|
||||
MathUtil::addMatrix(m1.col, m2.col, dst->col);
|
||||
#else
|
||||
MathUtil::addMatrix(m1.m, m2.m, dst->m);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Mat4::decompose(Vec3* scale, Quaternion* rotation, Vec3* translation) const
|
||||
{
|
||||
if (translation)
|
||||
{
|
||||
// Extract the translation.
|
||||
translation->x = m[12];
|
||||
translation->y = m[13];
|
||||
translation->z = m[14];
|
||||
}
|
||||
|
||||
// Nothing left to do.
|
||||
if (scale == nullptr && rotation == nullptr)
|
||||
return true;
|
||||
|
||||
// Extract the scale.
|
||||
// This is simply the length of each axis (row/column) in the matrix.
|
||||
Vec3 xaxis(m[0], m[1], m[2]);
|
||||
float scaleX = xaxis.length();
|
||||
|
||||
Vec3 yaxis(m[4], m[5], m[6]);
|
||||
float scaleY = yaxis.length();
|
||||
|
||||
Vec3 zaxis(m[8], m[9], m[10]);
|
||||
float scaleZ = zaxis.length();
|
||||
|
||||
// Determine if we have a negative scale (true if determinant is less than zero).
|
||||
// In this case, we simply negate a single axis of the scale.
|
||||
float det = determinant();
|
||||
if (det < 0)
|
||||
scaleZ = -scaleZ;
|
||||
|
||||
if (scale)
|
||||
{
|
||||
scale->x = scaleX;
|
||||
scale->y = scaleY;
|
||||
scale->z = scaleZ;
|
||||
}
|
||||
|
||||
// Nothing left to do.
|
||||
if (rotation == nullptr)
|
||||
return true;
|
||||
|
||||
// Scale too close to zero, can't decompose rotation.
|
||||
if (scaleX < MATH_TOLERANCE || scaleY < MATH_TOLERANCE || std::abs(scaleZ) < MATH_TOLERANCE)
|
||||
return false;
|
||||
|
||||
float rn;
|
||||
|
||||
// Factor the scale out of the matrix axes.
|
||||
rn = 1.0f / scaleX;
|
||||
xaxis.x *= rn;
|
||||
xaxis.y *= rn;
|
||||
xaxis.z *= rn;
|
||||
|
||||
rn = 1.0f / scaleY;
|
||||
yaxis.x *= rn;
|
||||
yaxis.y *= rn;
|
||||
yaxis.z *= rn;
|
||||
|
||||
rn = 1.0f / scaleZ;
|
||||
zaxis.x *= rn;
|
||||
zaxis.y *= rn;
|
||||
zaxis.z *= rn;
|
||||
|
||||
// Now calculate the rotation from the resulting matrix (axes).
|
||||
float trace = xaxis.x + yaxis.y + zaxis.z + 1.0f;
|
||||
|
||||
if (trace > MATH_EPSILON)
|
||||
{
|
||||
float s = 0.5f / std::sqrt(trace);
|
||||
rotation->w = 0.25f / s;
|
||||
rotation->x = (yaxis.z - zaxis.y) * s;
|
||||
rotation->y = (zaxis.x - xaxis.z) * s;
|
||||
rotation->z = (xaxis.y - yaxis.x) * s;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Note: since xaxis, yaxis, and zaxis are normalized,
|
||||
// we will never divide by zero in the code below.
|
||||
if (xaxis.x > yaxis.y && xaxis.x > zaxis.z)
|
||||
{
|
||||
float s = 0.5f / std::sqrt(1.0f + xaxis.x - yaxis.y - zaxis.z);
|
||||
rotation->w = (yaxis.z - zaxis.y) * s;
|
||||
rotation->x = 0.25f / s;
|
||||
rotation->y = (yaxis.x + xaxis.y) * s;
|
||||
rotation->z = (zaxis.x + xaxis.z) * s;
|
||||
}
|
||||
else if (yaxis.y > zaxis.z)
|
||||
{
|
||||
float s = 0.5f / std::sqrt(1.0f + yaxis.y - xaxis.x - zaxis.z);
|
||||
rotation->w = (zaxis.x - xaxis.z) * s;
|
||||
rotation->x = (yaxis.x + xaxis.y) * s;
|
||||
rotation->y = 0.25f / s;
|
||||
rotation->z = (zaxis.y + yaxis.z) * s;
|
||||
}
|
||||
else
|
||||
{
|
||||
float s = 0.5f / std::sqrt(1.0f + zaxis.z - xaxis.x - yaxis.y);
|
||||
rotation->w = (xaxis.y - yaxis.x ) * s;
|
||||
rotation->x = (zaxis.x + xaxis.z ) * s;
|
||||
rotation->y = (zaxis.y + yaxis.z ) * s;
|
||||
rotation->z = 0.25f / s;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
float Mat4::determinant() const
|
||||
{
|
||||
float a0 = m[0] * m[5] - m[1] * m[4];
|
||||
float a1 = m[0] * m[6] - m[2] * m[4];
|
||||
float a2 = m[0] * m[7] - m[3] * m[4];
|
||||
float a3 = m[1] * m[6] - m[2] * m[5];
|
||||
float a4 = m[1] * m[7] - m[3] * m[5];
|
||||
float a5 = m[2] * m[7] - m[3] * m[6];
|
||||
float b0 = m[8] * m[13] - m[9] * m[12];
|
||||
float b1 = m[8] * m[14] - m[10] * m[12];
|
||||
float b2 = m[8] * m[15] - m[11] * m[12];
|
||||
float b3 = m[9] * m[14] - m[10] * m[13];
|
||||
float b4 = m[9] * m[15] - m[11] * m[13];
|
||||
float b5 = m[10] * m[15] - m[11] * m[14];
|
||||
|
||||
// Calculate the determinant.
|
||||
return (a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0);
|
||||
}
|
||||
|
||||
void Mat4::getScale(Vec3* scale) const
|
||||
{
|
||||
decompose(scale, nullptr, nullptr);
|
||||
}
|
||||
|
||||
bool Mat4::getRotation(Quaternion* rotation) const
|
||||
{
|
||||
return decompose(nullptr, rotation, nullptr);
|
||||
}
|
||||
|
||||
void Mat4::getTranslation(Vec3* translation) const
|
||||
{
|
||||
decompose(nullptr, nullptr, translation);
|
||||
}
|
||||
|
||||
void Mat4::getUpVector(Vec3* dst) const
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
dst->x = m[4];
|
||||
dst->y = m[5];
|
||||
dst->z = m[6];
|
||||
}
|
||||
|
||||
void Mat4::getDownVector(Vec3* dst) const
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
dst->x = -m[4];
|
||||
dst->y = -m[5];
|
||||
dst->z = -m[6];
|
||||
}
|
||||
|
||||
void Mat4::getLeftVector(Vec3* dst) const
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
dst->x = -m[0];
|
||||
dst->y = -m[1];
|
||||
dst->z = -m[2];
|
||||
}
|
||||
|
||||
void Mat4::getRightVector(Vec3* dst) const
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
dst->x = m[0];
|
||||
dst->y = m[1];
|
||||
dst->z = m[2];
|
||||
}
|
||||
|
||||
void Mat4::getForwardVector(Vec3* dst) const
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
dst->x = -m[8];
|
||||
dst->y = -m[9];
|
||||
dst->z = -m[10];
|
||||
}
|
||||
|
||||
void Mat4::getBackVector(Vec3* dst) const
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
dst->x = m[8];
|
||||
dst->y = m[9];
|
||||
dst->z = m[10];
|
||||
}
|
||||
|
||||
Mat4 Mat4::getInversed() const
|
||||
{
|
||||
Mat4 mat(*this);
|
||||
mat.inverse();
|
||||
return mat;
|
||||
}
|
||||
|
||||
bool Mat4::inverse()
|
||||
{
|
||||
float a0 = m[0] * m[5] - m[1] * m[4];
|
||||
float a1 = m[0] * m[6] - m[2] * m[4];
|
||||
float a2 = m[0] * m[7] - m[3] * m[4];
|
||||
float a3 = m[1] * m[6] - m[2] * m[5];
|
||||
float a4 = m[1] * m[7] - m[3] * m[5];
|
||||
float a5 = m[2] * m[7] - m[3] * m[6];
|
||||
float b0 = m[8] * m[13] - m[9] * m[12];
|
||||
float b1 = m[8] * m[14] - m[10] * m[12];
|
||||
float b2 = m[8] * m[15] - m[11] * m[12];
|
||||
float b3 = m[9] * m[14] - m[10] * m[13];
|
||||
float b4 = m[9] * m[15] - m[11] * m[13];
|
||||
float b5 = m[10] * m[15] - m[11] * m[14];
|
||||
|
||||
// Calculate the determinant.
|
||||
float det = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0;
|
||||
|
||||
// Close to zero, can't invert.
|
||||
if (std::abs(det) <= MATH_TOLERANCE)
|
||||
return false;
|
||||
|
||||
// Support the case where m == dst.
|
||||
Mat4 inverse;
|
||||
inverse.m[0] = m[5] * b5 - m[6] * b4 + m[7] * b3;
|
||||
inverse.m[1] = -m[1] * b5 + m[2] * b4 - m[3] * b3;
|
||||
inverse.m[2] = m[13] * a5 - m[14] * a4 + m[15] * a3;
|
||||
inverse.m[3] = -m[9] * a5 + m[10] * a4 - m[11] * a3;
|
||||
|
||||
inverse.m[4] = -m[4] * b5 + m[6] * b2 - m[7] * b1;
|
||||
inverse.m[5] = m[0] * b5 - m[2] * b2 + m[3] * b1;
|
||||
inverse.m[6] = -m[12] * a5 + m[14] * a2 - m[15] * a1;
|
||||
inverse.m[7] = m[8] * a5 - m[10] * a2 + m[11] * a1;
|
||||
|
||||
inverse.m[8] = m[4] * b4 - m[5] * b2 + m[7] * b0;
|
||||
inverse.m[9] = -m[0] * b4 + m[1] * b2 - m[3] * b0;
|
||||
inverse.m[10] = m[12] * a4 - m[13] * a2 + m[15] * a0;
|
||||
inverse.m[11] = -m[8] * a4 + m[9] * a2 - m[11] * a0;
|
||||
|
||||
inverse.m[12] = -m[4] * b3 + m[5] * b1 - m[6] * b0;
|
||||
inverse.m[13] = m[0] * b3 - m[1] * b1 + m[2] * b0;
|
||||
inverse.m[14] = -m[12] * a3 + m[13] * a1 - m[14] * a0;
|
||||
inverse.m[15] = m[8] * a3 - m[9] * a1 + m[10] * a0;
|
||||
|
||||
multiply(inverse, 1.0f / det, this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Mat4::isIdentity() const
|
||||
{
|
||||
return (memcmp(m, &IDENTITY, MATRIX_SIZE) == 0);
|
||||
}
|
||||
|
||||
void Mat4::multiply(float scalar)
|
||||
{
|
||||
multiply(scalar, this);
|
||||
}
|
||||
|
||||
void Mat4::multiply(float scalar, Mat4* dst) const
|
||||
{
|
||||
multiply(*this, scalar, dst);
|
||||
}
|
||||
|
||||
void Mat4::multiply(const Mat4& m, float scalar, Mat4* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
#ifdef __SSE__
|
||||
MathUtil::multiplyMatrix(m.col, scalar, dst->col);
|
||||
#else
|
||||
MathUtil::multiplyMatrix(m.m, scalar, dst->m);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Mat4::multiply(const Mat4& mat)
|
||||
{
|
||||
multiply(*this, mat, this);
|
||||
}
|
||||
|
||||
void Mat4::multiply(const Mat4& m1, const Mat4& m2, Mat4* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
#ifdef __SSE__
|
||||
MathUtil::multiplyMatrix(m1.col, m2.col, dst->col);
|
||||
#else
|
||||
MathUtil::multiplyMatrix(m1.m, m2.m, dst->m);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Mat4::negate()
|
||||
{
|
||||
#ifdef __SSE__
|
||||
MathUtil::negateMatrix(col, col);
|
||||
#else
|
||||
MathUtil::negateMatrix(m, m);
|
||||
#endif
|
||||
}
|
||||
|
||||
Mat4 Mat4::getNegated() const
|
||||
{
|
||||
Mat4 mat(*this);
|
||||
mat.negate();
|
||||
return mat;
|
||||
}
|
||||
|
||||
void Mat4::rotate(const Quaternion& q)
|
||||
{
|
||||
rotate(q, this);
|
||||
}
|
||||
|
||||
void Mat4::rotate(const Quaternion& q, Mat4* dst) const
|
||||
{
|
||||
Mat4 r;
|
||||
createRotation(q, &r);
|
||||
multiply(*this, r, dst);
|
||||
}
|
||||
|
||||
void Mat4::rotate(const Vec3& axis, float angle)
|
||||
{
|
||||
rotate(axis, angle, this);
|
||||
}
|
||||
|
||||
void Mat4::rotate(const Vec3& axis, float angle, Mat4* dst) const
|
||||
{
|
||||
Mat4 r;
|
||||
createRotation(axis, angle, &r);
|
||||
multiply(*this, r, dst);
|
||||
}
|
||||
|
||||
void Mat4::rotateX(float angle)
|
||||
{
|
||||
rotateX(angle, this);
|
||||
}
|
||||
|
||||
void Mat4::rotateX(float angle, Mat4* dst) const
|
||||
{
|
||||
Mat4 r;
|
||||
createRotationX(angle, &r);
|
||||
multiply(*this, r, dst);
|
||||
}
|
||||
|
||||
void Mat4::rotateY(float angle)
|
||||
{
|
||||
rotateY(angle, this);
|
||||
}
|
||||
|
||||
void Mat4::rotateY(float angle, Mat4* dst) const
|
||||
{
|
||||
Mat4 r;
|
||||
createRotationY(angle, &r);
|
||||
multiply(*this, r, dst);
|
||||
}
|
||||
|
||||
void Mat4::rotateZ(float angle)
|
||||
{
|
||||
rotateZ(angle, this);
|
||||
}
|
||||
|
||||
void Mat4::rotateZ(float angle, Mat4* dst) const
|
||||
{
|
||||
Mat4 r;
|
||||
createRotationZ(angle, &r);
|
||||
multiply(*this, r, dst);
|
||||
}
|
||||
|
||||
void Mat4::scale(float value)
|
||||
{
|
||||
scale(value, this);
|
||||
}
|
||||
|
||||
void Mat4::scale(float value, Mat4* dst) const
|
||||
{
|
||||
scale(value, value, value, dst);
|
||||
}
|
||||
|
||||
void Mat4::scale(float xScale, float yScale, float zScale)
|
||||
{
|
||||
scale(xScale, yScale, zScale, this);
|
||||
}
|
||||
|
||||
void Mat4::scale(float xScale, float yScale, float zScale, Mat4* dst) const
|
||||
{
|
||||
Mat4 s;
|
||||
createScale(xScale, yScale, zScale, &s);
|
||||
multiply(*this, s, dst);
|
||||
}
|
||||
|
||||
void Mat4::scale(const Vec3& s)
|
||||
{
|
||||
scale(s.x, s.y, s.z, this);
|
||||
}
|
||||
|
||||
void Mat4::scale(const Vec3& s, Mat4* dst) const
|
||||
{
|
||||
scale(s.x, s.y, s.z, dst);
|
||||
}
|
||||
|
||||
void Mat4::set(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24,
|
||||
float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44)
|
||||
{
|
||||
m[0] = m11;
|
||||
m[1] = m21;
|
||||
m[2] = m31;
|
||||
m[3] = m41;
|
||||
m[4] = m12;
|
||||
m[5] = m22;
|
||||
m[6] = m32;
|
||||
m[7] = m42;
|
||||
m[8] = m13;
|
||||
m[9] = m23;
|
||||
m[10] = m33;
|
||||
m[11] = m43;
|
||||
m[12] = m14;
|
||||
m[13] = m24;
|
||||
m[14] = m34;
|
||||
m[15] = m44;
|
||||
}
|
||||
|
||||
void Mat4::set(const float* mat)
|
||||
{
|
||||
GP_ASSERT(mat);
|
||||
memcpy(this->m, mat, MATRIX_SIZE);
|
||||
}
|
||||
|
||||
void Mat4::set(const Mat4& mat)
|
||||
{
|
||||
memcpy(this->m, mat.m, MATRIX_SIZE);
|
||||
}
|
||||
|
||||
void Mat4::setIdentity()
|
||||
{
|
||||
memcpy(m, &IDENTITY, MATRIX_SIZE);
|
||||
}
|
||||
|
||||
void Mat4::setZero()
|
||||
{
|
||||
memset(m, 0, MATRIX_SIZE);
|
||||
}
|
||||
|
||||
void Mat4::subtract(const Mat4& mat)
|
||||
{
|
||||
subtract(*this, mat, this);
|
||||
}
|
||||
|
||||
void Mat4::subtract(const Mat4& m1, const Mat4& m2, Mat4* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
#ifdef __SSE__
|
||||
MathUtil::subtractMatrix(m1.col, m2.col, dst->col);
|
||||
#else
|
||||
MathUtil::subtractMatrix(m1.m, m2.m, dst->m);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Mat4::transformVector(Vec3* vector) const
|
||||
{
|
||||
GP_ASSERT(vector);
|
||||
transformVector(vector->x, vector->y, vector->z, 0.0f, vector);
|
||||
}
|
||||
|
||||
void Mat4::transformVector(const Vec3& vector, Vec3* dst) const
|
||||
{
|
||||
transformVector(vector.x, vector.y, vector.z, 0.0f, dst);
|
||||
}
|
||||
|
||||
void Mat4::transformVector(float x, float y, float z, float w, Vec3* dst) const
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
MathUtil::transformVec4(m, x, y, z, w, (float*)dst);
|
||||
}
|
||||
|
||||
void Mat4::transformVector(Vec4* vector) const
|
||||
{
|
||||
GP_ASSERT(vector);
|
||||
transformVector(*vector, vector);
|
||||
}
|
||||
|
||||
void Mat4::transformVector(const Vec4& vector, Vec4* dst) const
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
#ifdef __SSE__
|
||||
MathUtil::transformVec4(col, vector.v, dst->v);
|
||||
#else
|
||||
MathUtil::transformVec4(m, (const float*) &vector, (float*)dst);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Mat4::translate(float x, float y, float z)
|
||||
{
|
||||
translate(x, y, z, this);
|
||||
}
|
||||
|
||||
void Mat4::translate(float x, float y, float z, Mat4* dst) const
|
||||
{
|
||||
Mat4 t;
|
||||
createTranslation(x, y, z, &t);
|
||||
multiply(*this, t, dst);
|
||||
}
|
||||
|
||||
void Mat4::translate(const Vec3& t)
|
||||
{
|
||||
translate(t.x, t.y, t.z, this);
|
||||
}
|
||||
|
||||
void Mat4::translate(const Vec3& t, Mat4* dst) const
|
||||
{
|
||||
translate(t.x, t.y, t.z, dst);
|
||||
}
|
||||
|
||||
void Mat4::transpose()
|
||||
{
|
||||
#ifdef __SSE__
|
||||
MathUtil::transposeMatrix(col, col);
|
||||
#else
|
||||
MathUtil::transposeMatrix(m, m);
|
||||
#endif
|
||||
}
|
||||
|
||||
Mat4 Mat4::getTransposed() const
|
||||
{
|
||||
Mat4 mat(*this);
|
||||
mat.transpose();
|
||||
return mat;
|
||||
}
|
||||
|
||||
const Mat4 Mat4::IDENTITY = Mat4(
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
const Mat4 Mat4::ZERO = Mat4(
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0 );
|
||||
|
||||
NS_CC_MATH_END
|
||||
999
cocos2d-x/cocos/math/Mat4.h
Normal file
999
cocos2d-x/cocos/math/Mat4.h
Normal file
@@ -0,0 +1,999 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
|
||||
#ifndef MATH_MAT4_H
|
||||
#define MATH_MAT4_H
|
||||
|
||||
#include "base/ccMacros.h"
|
||||
|
||||
#include "math/Vec3.h"
|
||||
#include "math/Vec4.h"
|
||||
|
||||
#ifdef __SSE__
|
||||
#include <xmmintrin.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup base
|
||||
* @{
|
||||
*/
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
//class Plane;
|
||||
|
||||
/**
|
||||
* Defines a 4 x 4 floating point matrix representing a 3D transformation.
|
||||
*
|
||||
* Vectors are treated as columns, resulting in a matrix that is represented as follows,
|
||||
* where x, y and z are the translation components of the matrix:
|
||||
*
|
||||
* 1 0 0 x
|
||||
* 0 1 0 y
|
||||
* 0 0 1 z
|
||||
* 0 0 0 1
|
||||
*
|
||||
* This matrix class is directly compatible with OpenGL since its elements are
|
||||
* laid out in memory exactly as they are expected by OpenGL.
|
||||
* The matrix uses column-major format such that array indices increase down column first.
|
||||
* Since matrix multiplication is not commutative, multiplication must be done in the
|
||||
* correct order when combining transformations. Suppose we have a translation
|
||||
* matrix T and a rotation matrix R. To first rotate an object around the origin
|
||||
* and then translate it, you would multiply the two matrices as TR.
|
||||
*
|
||||
* Likewise, to first translate the object and then rotate it, you would do RT.
|
||||
* So generally, matrices must be multiplied in the reverse order in which you
|
||||
* want the transformations to take place (this also applies to
|
||||
* the scale, rotate, and translate methods below; these methods are convenience
|
||||
* methods for post-multiplying by a matrix representing a scale, rotation, or translation).
|
||||
*
|
||||
* In the case of repeated local transformations (i.e. rotate around the Z-axis by 0.76 radians,
|
||||
* then translate by 2.1 along the X-axis, then ...), it is better to use the Transform class
|
||||
* (which is optimized for that kind of usage).
|
||||
*
|
||||
* @see Transform
|
||||
*/
|
||||
class CC_DLL Mat4
|
||||
{
|
||||
public:
|
||||
// //temp add conversion
|
||||
// operator kmMat4() const
|
||||
// {
|
||||
// kmMat4 result;
|
||||
// kmMat4Fill(&result, m);
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// Mat4(const kmMat4& mat)
|
||||
// {
|
||||
// set(mat.mat);
|
||||
// }
|
||||
/**
|
||||
* Stores the columns of this 4x4 matrix.
|
||||
* */
|
||||
#ifdef __SSE__
|
||||
union {
|
||||
__m128 col[4];
|
||||
float m[16];
|
||||
};
|
||||
#else
|
||||
float m[16];
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
* Constructs a matrix initialized to the identity matrix:
|
||||
*
|
||||
* 1 0 0 0
|
||||
* 0 1 0 0
|
||||
* 0 0 1 0
|
||||
* 0 0 0 1
|
||||
*/
|
||||
Mat4();
|
||||
|
||||
/**
|
||||
* Constructs a matrix initialized to the specified value.
|
||||
*
|
||||
* @param m11 The first element of the first row.
|
||||
* @param m12 The second element of the first row.
|
||||
* @param m13 The third element of the first row.
|
||||
* @param m14 The fourth element of the first row.
|
||||
* @param m21 The first element of the second row.
|
||||
* @param m22 The second element of the second row.
|
||||
* @param m23 The third element of the second row.
|
||||
* @param m24 The fourth element of the second row.
|
||||
* @param m31 The first element of the third row.
|
||||
* @param m32 The second element of the third row.
|
||||
* @param m33 The third element of the third row.
|
||||
* @param m34 The fourth element of the third row.
|
||||
* @param m41 The first element of the fourth row.
|
||||
* @param m42 The second element of the fourth row.
|
||||
* @param m43 The third element of the fourth row.
|
||||
* @param m44 The fourth element of the fourth row.
|
||||
*/
|
||||
Mat4(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24,
|
||||
float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44);
|
||||
|
||||
/**
|
||||
* Creates a matrix initialized to the specified column-major array.
|
||||
*
|
||||
* The passed-in array is in column-major order, so the memory layout of the array is as follows:
|
||||
*
|
||||
* 0 4 8 12
|
||||
* 1 5 9 13
|
||||
* 2 6 10 14
|
||||
* 3 7 11 15
|
||||
*
|
||||
* @param mat An array containing 16 elements in column-major order.
|
||||
*/
|
||||
Mat4(const float* mat);
|
||||
|
||||
/**
|
||||
* Constructs a new matrix by copying the values from the specified matrix.
|
||||
*
|
||||
* @param copy The matrix to copy.
|
||||
*/
|
||||
Mat4(const Mat4& copy);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~Mat4();
|
||||
|
||||
/**
|
||||
* Creates a view matrix based on the specified input parameters.
|
||||
*
|
||||
* @param eyePosition The eye position.
|
||||
* @param targetPosition The target's center position.
|
||||
* @param up The up vector.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
static void createLookAt(const Vec3& eyePosition, const Vec3& targetPosition, const Vec3& up, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Creates a view matrix based on the specified input parameters.
|
||||
*
|
||||
* @param eyePositionX The eye x-coordinate position.
|
||||
* @param eyePositionY The eye y-coordinate position.
|
||||
* @param eyePositionZ The eye z-coordinate position.
|
||||
* @param targetCenterX The target's center x-coordinate position.
|
||||
* @param targetCenterY The target's center y-coordinate position.
|
||||
* @param targetCenterZ The target's center z-coordinate position.
|
||||
* @param upX The up vector x-coordinate value.
|
||||
* @param upY The up vector y-coordinate value.
|
||||
* @param upZ The up vector z-coordinate value.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
static void createLookAt(float eyePositionX, float eyePositionY, float eyePositionZ,
|
||||
float targetCenterX, float targetCenterY, float targetCenterZ,
|
||||
float upX, float upY, float upZ, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Builds a perspective projection matrix based on a field of view and returns by value.
|
||||
*
|
||||
* Projection space refers to the space after applying projection transformation from view space.
|
||||
* After the projection transformation, visible content has x- and y-coordinates ranging from -1 to 1,
|
||||
* and a z-coordinate ranging from 0 to 1. To obtain the viewable area (in world space) of a scene,
|
||||
* create a BoundingFrustum and pass the combined view and projection matrix to the constructor.
|
||||
*
|
||||
* @param fieldOfView The field of view in the y direction (in degrees).
|
||||
* @param aspectRatio The aspect ratio, defined as view space width divided by height.
|
||||
* @param zNearPlane The distance to the near view plane.
|
||||
* @param zFarPlane The distance to the far view plane.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
static void createPerspective(float fieldOfView, float aspectRatio, float zNearPlane, float zFarPlane, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Creates an orthographic projection matrix.
|
||||
*
|
||||
* @param width The width of the view.
|
||||
* @param height The height of the view.
|
||||
* @param zNearPlane The minimum z-value of the view volume.
|
||||
* @param zFarPlane The maximum z-value of the view volume.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
static void createOrthographic(float left, float right, float bottom, float top, float zNearPlane, float zFarPlane, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Creates an orthographic projection matrix.
|
||||
*
|
||||
* Projection space refers to the space after applying
|
||||
* projection transformation from view space. After the
|
||||
* projection transformation, visible content has
|
||||
* x and y coordinates ranging from -1 to 1, and z coordinates
|
||||
* ranging from 0 to 1.
|
||||
*
|
||||
* Unlike perspective projection, in orthographic projection
|
||||
* there is no perspective foreshortening.
|
||||
*
|
||||
* The viewable area of this orthographic projection extends
|
||||
* from left to right on the x-axis, bottom to top on the y-axis,
|
||||
* and zNearPlane to zFarPlane on the z-axis. These values are
|
||||
* relative to the position and x, y, and z-axes of the view.
|
||||
* To obtain the viewable area (in world space) of a scene,
|
||||
* create a BoundingFrustum and pass the combined view and
|
||||
* projection matrix to the constructor.
|
||||
*
|
||||
* @param left The minimum x-value of the view volume.
|
||||
* @param right The maximum x-value of the view volume.
|
||||
* @param bottom The minimum y-value of the view volume.
|
||||
* @param top The maximum y-value of the view volume.
|
||||
* @param zNearPlane The minimum z-value of the view volume.
|
||||
* @param zFarPlane The maximum z-value of the view volume.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
static void createOrthographicOffCenter(float left, float right, float bottom, float top,
|
||||
float zNearPlane, float zFarPlane, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Creates a spherical billboard that rotates around a specified object position.
|
||||
*
|
||||
* This method computes the facing direction of the billboard from the object position
|
||||
* and camera position. When the object and camera positions are too close, the matrix
|
||||
* will not be accurate. To avoid this problem, this method defaults to the identity
|
||||
* rotation if the positions are too close. (See the other overload of createBillboard
|
||||
* for an alternative approach).
|
||||
*
|
||||
* @param objectPosition The position of the object the billboard will rotate around.
|
||||
* @param cameraPosition The position of the camera.
|
||||
* @param cameraUpVector The up vector of the camera.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
static void createBillboard(const Vec3& objectPosition, const Vec3& cameraPosition,
|
||||
const Vec3& cameraUpVector, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Creates a spherical billboard that rotates around a specified object position with
|
||||
* provision for a safe default orientation.
|
||||
*
|
||||
* This method computes the facing direction of the billboard from the object position
|
||||
* and camera position. When the object and camera positions are too close, the matrix
|
||||
* will not be accurate. To avoid this problem, this method uses the specified camera
|
||||
* forward vector if the positions are too close. (See the other overload of createBillboard
|
||||
* for an alternative approach).
|
||||
*
|
||||
* @param objectPosition The position of the object the billboard will rotate around.
|
||||
* @param cameraPosition The position of the camera.
|
||||
* @param cameraUpVector The up vector of the camera.
|
||||
* @param cameraForwardVector The forward vector of the camera, used if the positions are too close.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
static void createBillboard(const Vec3& objectPosition, const Vec3& cameraPosition,
|
||||
const Vec3& cameraUpVector, const Vec3& cameraForwardVector,
|
||||
Mat4* dst);
|
||||
|
||||
//Fills in an existing Mat4 so that it reflects the coordinate system about a specified Plane.
|
||||
//plane The Plane about which to create a reflection.
|
||||
//dst A matrix to store the result in.
|
||||
//static void createReflection(const Plane& plane, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Creates a scale matrix.
|
||||
*
|
||||
* @param scale The amount to scale.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
static void createScale(const Vec3& scale, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Creates a scale matrix.
|
||||
*
|
||||
* @param xScale The amount to scale along the x-axis.
|
||||
* @param yScale The amount to scale along the y-axis.
|
||||
* @param zScale The amount to scale along the z-axis.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
static void createScale(float xScale, float yScale, float zScale, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Creates a rotation matrix from the specified quaternion.
|
||||
*
|
||||
* @param quat A quaternion describing a 3D orientation.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
static void createRotation(const Quaternion& quat, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Creates a rotation matrix from the specified axis and angle.
|
||||
*
|
||||
* @param axis A vector describing the axis to rotate about.
|
||||
* @param angle The angle (in radians).
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
static void createRotation(const Vec3& axis, float angle, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Creates a matrix describing a rotation around the x-axis.
|
||||
*
|
||||
* @param angle The angle of rotation (in radians).
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
static void createRotationX(float angle, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Creates a matrix describing a rotation around the y-axis.
|
||||
*
|
||||
* @param angle The angle of rotation (in radians).
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
static void createRotationY(float angle, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Creates a matrix describing a rotation around the z-axis.
|
||||
*
|
||||
* @param angle The angle of rotation (in radians).
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
static void createRotationZ(float angle, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Creates a translation matrix.
|
||||
*
|
||||
* @param translation The translation.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
static void createTranslation(const Vec3& translation, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Creates a translation matrix.
|
||||
*
|
||||
* @param xTranslation The translation on the x-axis.
|
||||
* @param yTranslation The translation on the y-axis.
|
||||
* @param zTranslation The translation on the z-axis.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
static void createTranslation(float xTranslation, float yTranslation, float zTranslation, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Adds a scalar value to each component of this matrix.
|
||||
*
|
||||
* @param scalar The scalar to add.
|
||||
*/
|
||||
void add(float scalar);
|
||||
|
||||
/**
|
||||
* Adds a scalar value to each component of this matrix and stores the result in dst.
|
||||
*
|
||||
* @param scalar The scalar value to add.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
void add(float scalar, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Adds the specified matrix to this matrix.
|
||||
*
|
||||
* @param mat The matrix to add.
|
||||
*/
|
||||
void add(const Mat4& mat);
|
||||
|
||||
/**
|
||||
* Adds the specified matrices and stores the result in dst.
|
||||
*
|
||||
* @param m1 The first matrix.
|
||||
* @param m2 The second matrix.
|
||||
* @param dst The destination matrix to add to.
|
||||
*/
|
||||
static void add(const Mat4& m1, const Mat4& m2, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Decomposes the scale, rotation and translation components of this matrix.
|
||||
*
|
||||
* @param scale The scale.
|
||||
* @param rotation The rotation.
|
||||
* @param translation The translation.
|
||||
*/
|
||||
bool decompose(Vec3* scale, Quaternion* rotation, Vec3* translation) const;
|
||||
|
||||
/**
|
||||
* Computes the determinant of this matrix.
|
||||
*
|
||||
* @return The determinant.
|
||||
*/
|
||||
float determinant() const;
|
||||
|
||||
/**
|
||||
* Gets the scalar component of this matrix in the specified vector.
|
||||
*
|
||||
* If the scalar component of this matrix has negative parts,
|
||||
* it is not possible to always extract the exact scalar component;
|
||||
* instead, a scale vector that is mathematically equivalent to the
|
||||
* original scale vector is extracted and returned.
|
||||
*
|
||||
* @param scale A vector to receive the scale.
|
||||
*/
|
||||
void getScale(Vec3* scale) const;
|
||||
|
||||
/**
|
||||
* Gets the rotational component of this matrix in the specified quaternion.
|
||||
*
|
||||
* @param rotation A quaternion to receive the rotation.
|
||||
*
|
||||
* @return true if the rotation is successfully extracted, false otherwise.
|
||||
*/
|
||||
bool getRotation(Quaternion* rotation) const;
|
||||
|
||||
/**
|
||||
* Gets the translational component of this matrix in the specified vector.
|
||||
*
|
||||
* @param translation A vector to receive the translation.
|
||||
*/
|
||||
void getTranslation(Vec3* translation) const;
|
||||
|
||||
/**
|
||||
* Gets the up vector of this matrix.
|
||||
*
|
||||
* @param dst The destination vector.
|
||||
*/
|
||||
void getUpVector(Vec3* dst) const;
|
||||
|
||||
/**
|
||||
* Gets the down vector of this matrix.
|
||||
*
|
||||
* @param dst The destination vector.
|
||||
*/
|
||||
void getDownVector(Vec3* dst) const;
|
||||
|
||||
/**
|
||||
* Gets the left vector of this matrix.
|
||||
*
|
||||
* @param dst The destination vector.
|
||||
*/
|
||||
void getLeftVector(Vec3* dst) const;
|
||||
|
||||
/**
|
||||
* Gets the right vector of this matrix.
|
||||
*
|
||||
* @param dst The destination vector.
|
||||
*/
|
||||
void getRightVector(Vec3* dst) const;
|
||||
|
||||
/**
|
||||
* Gets the forward vector of this matrix.
|
||||
*
|
||||
* @param dst The destination vector.
|
||||
*/
|
||||
void getForwardVector(Vec3* dst) const;
|
||||
|
||||
/**
|
||||
* Gets the backward vector of this matrix.
|
||||
*
|
||||
* @param dst The destination vector.
|
||||
*/
|
||||
void getBackVector(Vec3* dst) const;
|
||||
|
||||
/**
|
||||
* Inverts this matrix.
|
||||
*
|
||||
* @return true if the matrix can be inverted, false otherwise.
|
||||
*/
|
||||
bool inverse();
|
||||
|
||||
/**
|
||||
* Get the inversed matrix.
|
||||
*/
|
||||
Mat4 getInversed() const;
|
||||
|
||||
/**
|
||||
* Determines if this matrix is equal to the identity matrix.
|
||||
*
|
||||
* @return true if the matrix is an identity matrix, false otherwise.
|
||||
*/
|
||||
bool isIdentity() const;
|
||||
|
||||
/**
|
||||
* Multiplies the components of this matrix by the specified scalar.
|
||||
*
|
||||
* @param scalar The scalar value.
|
||||
*/
|
||||
void multiply(float scalar);
|
||||
|
||||
/**
|
||||
* Multiplies the components of this matrix by a scalar and stores the result in dst.
|
||||
*
|
||||
* @param scalar The scalar value.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
void multiply(float scalar, Mat4* dst) const;
|
||||
|
||||
/**
|
||||
* Multiplies the components of the specified matrix by a scalar and stores the result in dst.
|
||||
*
|
||||
* @param mat The matrix.
|
||||
* @param scalar The scalar value.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
static void multiply(const Mat4& mat, float scalar, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Multiplies this matrix by the specified one.
|
||||
*
|
||||
* @param mat The matrix to multiply.
|
||||
*/
|
||||
void multiply(const Mat4& mat);
|
||||
|
||||
/**
|
||||
* Multiplies m1 by m2 and stores the result in dst.
|
||||
*
|
||||
* @param m1 The first matrix to multiply.
|
||||
* @param m2 The second matrix to multiply.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
static void multiply(const Mat4& m1, const Mat4& m2, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Negates this matrix.
|
||||
*/
|
||||
void negate();
|
||||
|
||||
/**
|
||||
Get the Negated matrix.
|
||||
*/
|
||||
Mat4 getNegated() const;
|
||||
|
||||
/**
|
||||
* Post-multiplies this matrix by the matrix corresponding to the
|
||||
* specified quaternion rotation.
|
||||
*
|
||||
* @param q The quaternion to rotate by.
|
||||
*/
|
||||
void rotate(const Quaternion& q);
|
||||
|
||||
/**
|
||||
* Post-multiplies this matrix by the matrix corresponding to the
|
||||
* specified quaternion rotation and stores the result in dst.
|
||||
*
|
||||
* @param q The quaternion to rotate by.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
void rotate(const Quaternion& q, Mat4* dst) const;
|
||||
|
||||
/**
|
||||
* Post-multiplies this matrix by the matrix corresponding to the
|
||||
* specified rotation about the specified axis.
|
||||
*
|
||||
* @param axis The axis to rotate about.
|
||||
* @param angle The angle (in radians).
|
||||
*/
|
||||
void rotate(const Vec3& axis, float angle);
|
||||
|
||||
/**
|
||||
* Post-multiplies this matrix by the matrix corresponding to the specified
|
||||
* rotation about the specified axis and stores the result in dst.
|
||||
*
|
||||
* @param axis The axis to rotate about.
|
||||
* @param angle The angle (in radians).
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
void rotate(const Vec3& axis, float angle, Mat4* dst) const;
|
||||
|
||||
/**
|
||||
* Post-multiplies this matrix by the matrix corresponding to the
|
||||
* specified rotation around the x-axis.
|
||||
*
|
||||
* @param angle The angle (in radians).
|
||||
*/
|
||||
void rotateX(float angle);
|
||||
|
||||
/**
|
||||
* Post-multiplies this matrix by the matrix corresponding to the
|
||||
* specified rotation around the x-axis and stores the result in dst.
|
||||
*
|
||||
* @param angle The angle (in radians).
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
void rotateX(float angle, Mat4* dst) const;
|
||||
|
||||
/**
|
||||
* Post-multiplies this matrix by the matrix corresponding to the
|
||||
* specified rotation around the y-axis.
|
||||
*
|
||||
* @param angle The angle (in radians).
|
||||
*/
|
||||
void rotateY(float angle);
|
||||
|
||||
/**
|
||||
* Post-multiplies this matrix by the matrix corresponding to the
|
||||
* specified rotation around the y-axis and stores the result in dst.
|
||||
*
|
||||
* @param angle The angle (in radians).
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
void rotateY(float angle, Mat4* dst) const;
|
||||
|
||||
/**
|
||||
* Post-multiplies this matrix by the matrix corresponding to the
|
||||
* specified rotation around the z-axis.
|
||||
*
|
||||
* @param angle The angle (in radians).
|
||||
*/
|
||||
void rotateZ(float angle);
|
||||
|
||||
/**
|
||||
* Post-multiplies this matrix by the matrix corresponding to the
|
||||
* specified rotation around the z-axis and stores the result in dst.
|
||||
*
|
||||
* @param angle The angle (in radians).
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
void rotateZ(float angle, Mat4* dst) const;
|
||||
|
||||
/**
|
||||
* Post-multiplies this matrix by the matrix corresponding to the
|
||||
* specified scale transformation.
|
||||
*
|
||||
* @param value The amount to scale along all axes.
|
||||
*/
|
||||
void scale(float value);
|
||||
|
||||
/**
|
||||
* Post-multiplies this matrix by the matrix corresponding to the
|
||||
* specified scale transformation and stores the result in dst.
|
||||
*
|
||||
* @param value The amount to scale along all axes.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
void scale(float value, Mat4* dst) const;
|
||||
|
||||
/**
|
||||
* Post-multiplies this matrix by the matrix corresponding to the
|
||||
* specified scale transformation.
|
||||
*
|
||||
* @param xScale The amount to scale along the x-axis.
|
||||
* @param yScale The amount to scale along the y-axis.
|
||||
* @param zScale The amount to scale along the z-axis.
|
||||
*/
|
||||
void scale(float xScale, float yScale, float zScale);
|
||||
|
||||
/**
|
||||
* Post-multiplies this matrix by the matrix corresponding to the
|
||||
* specified scale transformation and stores the result in dst.
|
||||
*
|
||||
* @param xScale The amount to scale along the x-axis.
|
||||
* @param yScale The amount to scale along the y-axis.
|
||||
* @param zScale The amount to scale along the z-axis.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
void scale(float xScale, float yScale, float zScale, Mat4* dst) const;
|
||||
|
||||
/**
|
||||
* Post-multiplies this matrix by the matrix corresponding to the
|
||||
* specified scale transformation.
|
||||
*
|
||||
* @param s The scale values along the x, y and z axes.
|
||||
*/
|
||||
void scale(const Vec3& s);
|
||||
|
||||
/**
|
||||
* Post-multiplies this matrix by the matrix corresponding to the
|
||||
* specified scale transformation and stores the result in dst.
|
||||
*
|
||||
* @param s The scale values along the x, y and z axes.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
void scale(const Vec3& s, Mat4* dst) const;
|
||||
|
||||
/**
|
||||
* Sets the values of this matrix.
|
||||
*
|
||||
* @param m11 The first element of the first row.
|
||||
* @param m12 The second element of the first row.
|
||||
* @param m13 The third element of the first row.
|
||||
* @param m14 The fourth element of the first row.
|
||||
* @param m21 The first element of the second row.
|
||||
* @param m22 The second element of the second row.
|
||||
* @param m23 The third element of the second row.
|
||||
* @param m24 The fourth element of the second row.
|
||||
* @param m31 The first element of the third row.
|
||||
* @param m32 The second element of the third row.
|
||||
* @param m33 The third element of the third row.
|
||||
* @param m34 The fourth element of the third row.
|
||||
* @param m41 The first element of the fourth row.
|
||||
* @param m42 The second element of the fourth row.
|
||||
* @param m43 The third element of the fourth row.
|
||||
* @param m44 The fourth element of the fourth row.
|
||||
*/
|
||||
void set(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24,
|
||||
float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44);
|
||||
|
||||
/**
|
||||
* Sets the values of this matrix to those in the specified column-major array.
|
||||
*
|
||||
* @param mat An array containing 16 elements in column-major format.
|
||||
*/
|
||||
void set(const float* mat);
|
||||
|
||||
/**
|
||||
* Sets the values of this matrix to those of the specified matrix.
|
||||
*
|
||||
* @param mat The source matrix.
|
||||
*/
|
||||
void set(const Mat4& mat);
|
||||
|
||||
/**
|
||||
* Sets this matrix to the identity matrix.
|
||||
*/
|
||||
void setIdentity();
|
||||
|
||||
/**
|
||||
* Sets all elements of the current matrix to zero.
|
||||
*/
|
||||
void setZero();
|
||||
|
||||
/**
|
||||
* Subtracts the specified matrix from the current matrix.
|
||||
*
|
||||
* @param mat The matrix to subtract.
|
||||
*/
|
||||
void subtract(const Mat4& mat);
|
||||
|
||||
/**
|
||||
* Subtracts the specified matrix from the current matrix.
|
||||
*
|
||||
* @param m1 The first matrix.
|
||||
* @param m2 The second matrix.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
static void subtract(const Mat4& m1, const Mat4& m2, Mat4* dst);
|
||||
|
||||
/**
|
||||
* Transforms the specified point by this matrix.
|
||||
*
|
||||
* The result of the transformation is stored directly into point.
|
||||
*
|
||||
* @param point The point to transform and also a vector to hold the result in.
|
||||
*/
|
||||
inline void transformPoint(Vec3* point) const { GP_ASSERT(point); transformVector(point->x, point->y, point->z, 1.0f, point); }
|
||||
|
||||
/**
|
||||
* Transforms the specified point by this matrix, and stores
|
||||
* the result in dst.
|
||||
*
|
||||
* @param point The point to transform.
|
||||
* @param dst A vector to store the transformed point in.
|
||||
*/
|
||||
inline void transformPoint(const Vec3& point, Vec3* dst) const { GP_ASSERT(dst); transformVector(point.x, point.y, point.z, 1.0f, dst); }
|
||||
|
||||
/**
|
||||
* Transforms the specified vector by this matrix by
|
||||
* treating the fourth (w) coordinate as zero.
|
||||
*
|
||||
* The result of the transformation is stored directly into vector.
|
||||
*
|
||||
* @param vector The vector to transform and also a vector to hold the result in.
|
||||
*/
|
||||
void transformVector(Vec3* vector) const;
|
||||
|
||||
/**
|
||||
* Transforms the specified vector by this matrix by
|
||||
* treating the fourth (w) coordinate as zero, and stores the
|
||||
* result in dst.
|
||||
*
|
||||
* @param vector The vector to transform.
|
||||
* @param dst A vector to store the transformed vector in.
|
||||
*/
|
||||
void transformVector(const Vec3& vector, Vec3* dst) const;
|
||||
|
||||
/**
|
||||
* Transforms the specified vector by this matrix.
|
||||
*
|
||||
* @param x The vector x-coordinate to transform by.
|
||||
* @param y The vector y-coordinate to transform by.
|
||||
* @param z The vector z-coordinate to transform by.
|
||||
* @param w The vector w-coordinate to transform by.
|
||||
* @param dst A vector to store the transformed point in.
|
||||
*/
|
||||
void transformVector(float x, float y, float z, float w, Vec3* dst) const;
|
||||
|
||||
/**
|
||||
* Transforms the specified vector by this matrix.
|
||||
*
|
||||
* The result of the transformation is stored directly into vector.
|
||||
*
|
||||
* @param vector The vector to transform.
|
||||
*/
|
||||
void transformVector(Vec4* vector) const;
|
||||
|
||||
/**
|
||||
* Transforms the specified vector by this matrix.
|
||||
*
|
||||
* @param vector The vector to transform.
|
||||
* @param dst A vector to store the transformed point in.
|
||||
*/
|
||||
void transformVector(const Vec4& vector, Vec4* dst) const;
|
||||
|
||||
/**
|
||||
* Post-multiplies this matrix by the matrix corresponding to the
|
||||
* specified translation.
|
||||
*
|
||||
* @param x The amount to translate along the x-axis.
|
||||
* @param y The amount to translate along the y-axis.
|
||||
* @param z The amount to translate along the z-axis.
|
||||
*/
|
||||
void translate(float x, float y, float z);
|
||||
|
||||
/**
|
||||
* Post-multiplies this matrix by the matrix corresponding to the
|
||||
* specified translation and stores the result in dst.
|
||||
*
|
||||
* @param x The amount to translate along the x-axis.
|
||||
* @param y The amount to translate along the y-axis.
|
||||
* @param z The amount to translate along the z-axis.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
void translate(float x, float y, float z, Mat4* dst) const;
|
||||
|
||||
/**
|
||||
* Post-multiplies this matrix by the matrix corresponding to the
|
||||
* specified translation.
|
||||
*
|
||||
* @param t The translation values along the x, y and z axes.
|
||||
*/
|
||||
void translate(const Vec3& t);
|
||||
|
||||
/**
|
||||
* Post-multiplies this matrix by the matrix corresponding to the
|
||||
* specified translation and stores the result in dst.
|
||||
*
|
||||
* @param t The translation values along the x, y and z axes.
|
||||
* @param dst A matrix to store the result in.
|
||||
*/
|
||||
void translate(const Vec3& t, Mat4* dst) const;
|
||||
|
||||
/**
|
||||
* Transposes this matrix.
|
||||
*/
|
||||
void transpose();
|
||||
|
||||
/**
|
||||
* Get the Transposed matrix.
|
||||
*/
|
||||
Mat4 getTransposed() const;
|
||||
|
||||
/**
|
||||
* Calculates the sum of this matrix with the given matrix.
|
||||
*
|
||||
* Note: this does not modify this matrix.
|
||||
*
|
||||
* @param mat The matrix to add.
|
||||
* @return The matrix sum.
|
||||
*/
|
||||
inline const Mat4 operator+(const Mat4& mat) const;
|
||||
|
||||
/**
|
||||
* Adds the given matrix to this matrix.
|
||||
*
|
||||
* @param mat The matrix to add.
|
||||
* @return This matrix, after the addition occurs.
|
||||
*/
|
||||
inline Mat4& operator+=(const Mat4& mat);
|
||||
|
||||
/**
|
||||
* Calculates the difference of this matrix with the given matrix.
|
||||
*
|
||||
* Note: this does not modify this matrix.
|
||||
*
|
||||
* @param mat The matrix to subtract.
|
||||
* @return The matrix difference.
|
||||
*/
|
||||
inline const Mat4 operator-(const Mat4& mat) const;
|
||||
|
||||
/**
|
||||
* Subtracts the given matrix from this matrix.
|
||||
*
|
||||
* @param mat The matrix to subtract.
|
||||
* @return This matrix, after the subtraction occurs.
|
||||
*/
|
||||
inline Mat4& operator-=(const Mat4& mat);
|
||||
|
||||
/**
|
||||
* Calculates the negation of this matrix.
|
||||
*
|
||||
* Note: this does not modify this matrix.
|
||||
*
|
||||
* @return The negation of this matrix.
|
||||
*/
|
||||
inline const Mat4 operator-() const;
|
||||
|
||||
/**
|
||||
* Calculates the matrix product of this matrix with the given matrix.
|
||||
*
|
||||
* Note: this does not modify this matrix.
|
||||
*
|
||||
* @param mat The matrix to multiply by.
|
||||
* @return The matrix product.
|
||||
*/
|
||||
inline const Mat4 operator*(const Mat4& mat) const;
|
||||
|
||||
/**
|
||||
* Right-multiplies this matrix by the given matrix.
|
||||
*
|
||||
* @param mat The matrix to multiply by.
|
||||
* @return This matrix, after the multiplication occurs.
|
||||
*/
|
||||
inline Mat4& operator*=(const Mat4& mat);
|
||||
|
||||
/** equals to a matrix full of zeros */
|
||||
static const Mat4 ZERO;
|
||||
/** equals to the identity matrix */
|
||||
static const Mat4 IDENTITY;
|
||||
|
||||
private:
|
||||
|
||||
static void createBillboardHelper(const Vec3& objectPosition, const Vec3& cameraPosition,
|
||||
const Vec3& cameraUpVector, const Vec3* cameraForwardVector,
|
||||
Mat4* dst);
|
||||
};
|
||||
|
||||
/**
|
||||
* Transforms the given vector by the given matrix.
|
||||
*
|
||||
* Note: this treats the given vector as a vector and not as a point.
|
||||
*
|
||||
* @param v The vector to transform.
|
||||
* @param m The matrix to transform by.
|
||||
* @return This vector, after the transformation occurs.
|
||||
*/
|
||||
inline Vec3& operator*=(Vec3& v, const Mat4& m);
|
||||
|
||||
/**
|
||||
* Transforms the given vector by the given matrix.
|
||||
*
|
||||
* Note: this treats the given vector as a vector and not as a point.
|
||||
*
|
||||
* @param m The matrix to transform by.
|
||||
* @param v The vector to transform.
|
||||
* @return The resulting transformed vector.
|
||||
*/
|
||||
inline const Vec3 operator*(const Mat4& m, const Vec3& v);
|
||||
|
||||
/**
|
||||
* Transforms the given vector by the given matrix.
|
||||
*
|
||||
* Note: this treats the given vector as a vector and not as a point.
|
||||
*
|
||||
* @param v The vector to transform.
|
||||
* @param m The matrix to transform by.
|
||||
* @return This vector, after the transformation occurs.
|
||||
*/
|
||||
inline Vec4& operator*=(Vec4& v, const Mat4& m);
|
||||
|
||||
/**
|
||||
* Transforms the given vector by the given matrix.
|
||||
*
|
||||
* Note: this treats the given vector as a vector and not as a point.
|
||||
*
|
||||
* @param m The matrix to transform by.
|
||||
* @param v The vector to transform.
|
||||
* @return The resulting transformed vector.
|
||||
*/
|
||||
inline const Vec4 operator*(const Mat4& m, const Vec4& v);
|
||||
|
||||
NS_CC_MATH_END
|
||||
/**
|
||||
end of base group
|
||||
@}
|
||||
*/
|
||||
#include "math/Mat4.inl"
|
||||
|
||||
#endif // MATH_MAT4_H
|
||||
|
||||
97
cocos2d-x/cocos/math/Mat4.inl
Normal file
97
cocos2d-x/cocos/math/Mat4.inl
Normal file
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
|
||||
#include "math/Mat4.h"
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
inline const Mat4 Mat4::operator+(const Mat4& mat) const
|
||||
{
|
||||
Mat4 result(*this);
|
||||
result.add(mat);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline Mat4& Mat4::operator+=(const Mat4& mat)
|
||||
{
|
||||
add(mat);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const Mat4 Mat4::operator-(const Mat4& mat) const
|
||||
{
|
||||
Mat4 result(*this);
|
||||
result.subtract(mat);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline Mat4& Mat4::operator-=(const Mat4& mat)
|
||||
{
|
||||
subtract(mat);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const Mat4 Mat4::operator-() const
|
||||
{
|
||||
Mat4 mat(*this);
|
||||
mat.negate();
|
||||
return mat;
|
||||
}
|
||||
|
||||
inline const Mat4 Mat4::operator*(const Mat4& mat) const
|
||||
{
|
||||
Mat4 result(*this);
|
||||
result.multiply(mat);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline Mat4& Mat4::operator*=(const Mat4& mat)
|
||||
{
|
||||
multiply(mat);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vec3& operator*=(Vec3& v, const Mat4& m)
|
||||
{
|
||||
m.transformVector(&v);
|
||||
return v;
|
||||
}
|
||||
|
||||
inline const Vec3 operator*(const Mat4& m, const Vec3& v)
|
||||
{
|
||||
Vec3 x;
|
||||
m.transformVector(v, &x);
|
||||
return x;
|
||||
}
|
||||
|
||||
inline Vec4& operator*=(Vec4& v, const Mat4& m)
|
||||
{
|
||||
m.transformVector(&v);
|
||||
return v;
|
||||
}
|
||||
|
||||
inline const Vec4 operator*(const Mat4& m, const Vec4& v)
|
||||
{
|
||||
Vec4 x;
|
||||
m.transformVector(v, &x);
|
||||
return x;
|
||||
}
|
||||
|
||||
NS_CC_MATH_END
|
||||
286
cocos2d-x/cocos/math/MathUtil.cpp
Normal file
286
cocos2d-x/cocos/math/MathUtil.cpp
Normal file
@@ -0,0 +1,286 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
|
||||
#include "math/MathUtil.h"
|
||||
#include "base/ccMacros.h"
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
||||
#include <cpu-features.h>
|
||||
#endif
|
||||
|
||||
//#define USE_NEON32 : neon 32 code will be used
|
||||
//#define USE_NEON64 : neon 64 code will be used
|
||||
//#define INCLUDE_NEON32 : neon 32 code included
|
||||
//#define INCLUDE_NEON64 : neon 64 code included
|
||||
//#define USE_SSE : SSE code used
|
||||
//#define INCLUDE_SSE : SSE code included
|
||||
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
||||
#if defined (__arm64__)
|
||||
#define USE_NEON64
|
||||
#define INCLUDE_NEON64
|
||||
#elif defined (__ARM_NEON__)
|
||||
#define USE_NEON32
|
||||
#define INCLUDE_NEON32
|
||||
#else
|
||||
#endif
|
||||
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
|
||||
#if defined (__arm64__) || defined (__aarch64__)
|
||||
#define USE_NEON64
|
||||
#define INCLUDE_NEON64
|
||||
#elif defined (__ARM_NEON__)
|
||||
#define INCLUDE_NEON32
|
||||
#else
|
||||
#endif
|
||||
#else
|
||||
|
||||
#endif
|
||||
|
||||
#if defined (__SSE__)
|
||||
#define USE_SSE
|
||||
#define INCLUDE_SSE
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_NEON32
|
||||
#include "math/MathUtilNeon.inl"
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_NEON64
|
||||
#include "math/MathUtilNeon64.inl"
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_SSE
|
||||
#include "math/MathUtilSSE.inl"
|
||||
#endif
|
||||
|
||||
#include "math/MathUtil.inl"
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
void MathUtil::smooth(float* x, float target, float elapsedTime, float responseTime)
|
||||
{
|
||||
GP_ASSERT(x);
|
||||
|
||||
if (elapsedTime > 0)
|
||||
{
|
||||
*x += (target - *x) * elapsedTime / (elapsedTime + responseTime);
|
||||
}
|
||||
}
|
||||
|
||||
void MathUtil::smooth(float* x, float target, float elapsedTime, float riseTime, float fallTime)
|
||||
{
|
||||
GP_ASSERT(x);
|
||||
|
||||
if (elapsedTime > 0)
|
||||
{
|
||||
float delta = target - *x;
|
||||
*x += delta * elapsedTime / (elapsedTime + (delta > 0 ? riseTime : fallTime));
|
||||
}
|
||||
}
|
||||
|
||||
float MathUtil::lerp(float from, float to, float alpha)
|
||||
{
|
||||
return from * (1.0f - alpha) + to * alpha;
|
||||
}
|
||||
|
||||
bool MathUtil::isNeon32Enabled()
|
||||
{
|
||||
#ifdef USE_NEON32
|
||||
return true;
|
||||
#elif (defined (INCLUDE_NEON32) && (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) )
|
||||
class AndroidNeonChecker
|
||||
{
|
||||
public:
|
||||
AndroidNeonChecker()
|
||||
{
|
||||
if (android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM && (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0)
|
||||
_isNeonEnabled = true;
|
||||
else
|
||||
_isNeonEnabled = false;
|
||||
}
|
||||
bool isNeonEnabled() const { return _isNeonEnabled; }
|
||||
private:
|
||||
bool _isNeonEnabled;
|
||||
};
|
||||
static AndroidNeonChecker checker;
|
||||
return checker.isNeonEnabled();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool MathUtil::isNeon64Enabled()
|
||||
{
|
||||
#ifdef USE_NEON64
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void MathUtil::addMatrix(const float* m, float scalar, float* dst)
|
||||
{
|
||||
#ifdef USE_NEON32
|
||||
MathUtilNeon::addMatrix(m, scalar, dst);
|
||||
#elif defined (USE_NEON64)
|
||||
MathUtilNeon64::addMatrix(m, scalar, dst);
|
||||
#elif defined (INCLUDE_NEON32)
|
||||
if(isNeon32Enabled()) MathUtilNeon::addMatrix(m, scalar, dst);
|
||||
else MathUtilC::addMatrix(m, scalar, dst);
|
||||
#else
|
||||
MathUtilC::addMatrix(m, scalar, dst);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MathUtil::addMatrix(const float* m1, const float* m2, float* dst)
|
||||
{
|
||||
#ifdef USE_NEON32
|
||||
MathUtilNeon::addMatrix(m1, m2, dst);
|
||||
#elif defined (USE_NEON64)
|
||||
MathUtilNeon64::addMatrix(m1, m2, dst);
|
||||
#elif defined (INCLUDE_NEON32)
|
||||
if(isNeon32Enabled()) MathUtilNeon::addMatrix(m1, m2, dst);
|
||||
else MathUtilC::addMatrix(m1, m2, dst);
|
||||
#else
|
||||
MathUtilC::addMatrix(m1, m2, dst);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MathUtil::subtractMatrix(const float* m1, const float* m2, float* dst)
|
||||
{
|
||||
#ifdef USE_NEON32
|
||||
MathUtilNeon::subtractMatrix(m1, m2, dst);
|
||||
#elif defined (USE_NEON64)
|
||||
MathUtilNeon64::subtractMatrix(m1, m2, dst);
|
||||
#elif defined (INCLUDE_NEON32)
|
||||
if(isNeon32Enabled()) MathUtilNeon::subtractMatrix(m1, m2, dst);
|
||||
else MathUtilC::subtractMatrix(m1, m2, dst);
|
||||
#else
|
||||
MathUtilC::subtractMatrix(m1, m2, dst);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MathUtil::multiplyMatrix(const float* m, float scalar, float* dst)
|
||||
{
|
||||
#ifdef USE_NEON32
|
||||
MathUtilNeon::multiplyMatrix(m, scalar, dst);
|
||||
#elif defined (USE_NEON64)
|
||||
MathUtilNeon64::multiplyMatrix(m, scalar, dst);
|
||||
#elif defined (INCLUDE_NEON32)
|
||||
if(isNeon32Enabled()) MathUtilNeon::multiplyMatrix(m, scalar, dst);
|
||||
else MathUtilC::multiplyMatrix(m, scalar, dst);
|
||||
#else
|
||||
MathUtilC::multiplyMatrix(m, scalar, dst);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MathUtil::multiplyMatrix(const float* m1, const float* m2, float* dst)
|
||||
{
|
||||
#ifdef USE_NEON32
|
||||
MathUtilNeon::multiplyMatrix(m1, m2, dst);
|
||||
#elif defined (USE_NEON64)
|
||||
MathUtilNeon64::multiplyMatrix(m1, m2, dst);
|
||||
#elif defined (INCLUDE_NEON32)
|
||||
if(isNeon32Enabled()) MathUtilNeon::multiplyMatrix(m1, m2, dst);
|
||||
else MathUtilC::multiplyMatrix(m1, m2, dst);
|
||||
#else
|
||||
MathUtilC::multiplyMatrix(m1, m2, dst);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MathUtil::negateMatrix(const float* m, float* dst)
|
||||
{
|
||||
#ifdef USE_NEON32
|
||||
MathUtilNeon::negateMatrix(m, dst);
|
||||
#elif defined (USE_NEON64)
|
||||
MathUtilNeon64::negateMatrix(m, dst);
|
||||
#elif defined (INCLUDE_NEON32)
|
||||
if(isNeon32Enabled()) MathUtilNeon::negateMatrix(m, dst);
|
||||
else MathUtilC::negateMatrix(m, dst);
|
||||
#else
|
||||
MathUtilC::negateMatrix(m, dst);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MathUtil::transposeMatrix(const float* m, float* dst)
|
||||
{
|
||||
#ifdef USE_NEON32
|
||||
MathUtilNeon::transposeMatrix(m, dst);
|
||||
#elif defined (USE_NEON64)
|
||||
MathUtilNeon64::transposeMatrix(m, dst);
|
||||
#elif defined (INCLUDE_NEON32)
|
||||
if(isNeon32Enabled()) MathUtilNeon::transposeMatrix(m, dst);
|
||||
else MathUtilC::transposeMatrix(m, dst);
|
||||
#else
|
||||
MathUtilC::transposeMatrix(m, dst);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MathUtil::transformVec4(const float* m, float x, float y, float z, float w, float* dst)
|
||||
{
|
||||
#ifdef USE_NEON32
|
||||
MathUtilNeon::transformVec4(m, x, y, z, w, dst);
|
||||
#elif defined (USE_NEON64)
|
||||
MathUtilNeon64::transformVec4(m, x, y, z, w, dst);
|
||||
#elif defined (INCLUDE_NEON32)
|
||||
if(isNeon32Enabled()) MathUtilNeon::transformVec4(m, x, y, z, w, dst);
|
||||
else MathUtilC::transformVec4(m, x, y, z, w, dst);
|
||||
#else
|
||||
MathUtilC::transformVec4(m, x, y, z, w, dst);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MathUtil::transformVec4(const float* m, const float* v, float* dst)
|
||||
{
|
||||
#ifdef USE_NEON32
|
||||
MathUtilNeon::transformVec4(m, v, dst);
|
||||
#elif defined (USE_NEON64)
|
||||
MathUtilNeon64::transformVec4(m, v, dst);
|
||||
#elif defined (INCLUDE_NEON32)
|
||||
if(isNeon32Enabled()) MathUtilNeon::transformVec4(m, v, dst);
|
||||
else MathUtilC::transformVec4(m, v, dst);
|
||||
#else
|
||||
MathUtilC::transformVec4(m, v, dst);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MathUtil::crossVec3(const float* v1, const float* v2, float* dst)
|
||||
{
|
||||
#ifdef USE_NEON32
|
||||
MathUtilNeon::crossVec3(v1, v2, dst);
|
||||
#elif defined (USE_NEON64)
|
||||
MathUtilNeon64::crossVec3(v1, v2, dst);
|
||||
#elif defined (INCLUDE_NEON32)
|
||||
if(isNeon32Enabled()) MathUtilNeon::crossVec3(v1, v2, dst);
|
||||
else MathUtilC::crossVec3(v1, v2, dst);
|
||||
#else
|
||||
MathUtilC::crossVec3(v1, v2, dst);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MathUtil::combineHash(size_t& seed, const size_t& v)
|
||||
{
|
||||
seed ^= v + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
||||
}
|
||||
|
||||
|
||||
NS_CC_MATH_END
|
||||
149
cocos2d-x/cocos/math/MathUtil.h
Normal file
149
cocos2d-x/cocos/math/MathUtil.h
Normal file
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
|
||||
#ifndef MATHUTIL_H_
|
||||
#define MATHUTIL_H_
|
||||
|
||||
#ifdef __SSE__
|
||||
#include <xmmintrin.h>
|
||||
#endif
|
||||
|
||||
#include "math/CCMathBase.h"
|
||||
|
||||
/**
|
||||
* @addtogroup base
|
||||
* @{
|
||||
*/
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
/**
|
||||
* Defines a math utility class.
|
||||
*
|
||||
* This is primarily used for optimized internal math operations.
|
||||
*/
|
||||
class CC_DLL MathUtil
|
||||
{
|
||||
friend class Mat4;
|
||||
friend class Vec3;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Updates the given scalar towards the given target using a smoothing function.
|
||||
* The given response time determines the amount of smoothing (lag). A longer
|
||||
* response time yields a smoother result and more lag. To force the scalar to
|
||||
* follow the target closely, provide a response time that is very small relative
|
||||
* to the given elapsed time.
|
||||
*
|
||||
* @param x the scalar to update.
|
||||
* @param target target value.
|
||||
* @param elapsedTime elapsed time between calls.
|
||||
* @param responseTime response time (in the same units as elapsedTime).
|
||||
*/
|
||||
static void smooth(float* x, float target, float elapsedTime, float responseTime);
|
||||
|
||||
/**
|
||||
* Updates the given scalar towards the given target using a smoothing function.
|
||||
* The given rise and fall times determine the amount of smoothing (lag). Longer
|
||||
* rise and fall times yield a smoother result and more lag. To force the scalar to
|
||||
* follow the target closely, provide rise and fall times that are very small relative
|
||||
* to the given elapsed time.
|
||||
*
|
||||
* @param x the scalar to update.
|
||||
* @param target target value.
|
||||
* @param elapsedTime elapsed time between calls.
|
||||
* @param riseTime response time for rising slope (in the same units as elapsedTime).
|
||||
* @param fallTime response time for falling slope (in the same units as elapsedTime).
|
||||
*/
|
||||
static void smooth(float* x, float target, float elapsedTime, float riseTime, float fallTime);
|
||||
|
||||
/**
|
||||
* Linearly interpolates between from value to to value by alpha which is in
|
||||
* the range [0,1]
|
||||
*
|
||||
* @param from the from value.
|
||||
* @param to the to value.
|
||||
* @param alpha the alpha value between [0,1]
|
||||
*
|
||||
* @return interpolated float value
|
||||
*/
|
||||
static float lerp(float from, float to, float alpha);
|
||||
|
||||
/**
|
||||
* Add hash_combine math according to:
|
||||
* https://www.boost.org/doc/libs/1_55_0/doc/html/hash/reference.html#boost.hash_combine
|
||||
* @param seed
|
||||
* @param v
|
||||
*/
|
||||
static void combineHash(size_t& seed, const size_t& v);
|
||||
private:
|
||||
//Indicates that if neon is enabled
|
||||
static bool isNeon32Enabled();
|
||||
static bool isNeon64Enabled();
|
||||
private:
|
||||
#ifdef __SSE__
|
||||
static void addMatrix(const __m128 m[4], float scalar, __m128 dst[4]);
|
||||
|
||||
static void addMatrix(const __m128 m1[4], const __m128 m2[4], __m128 dst[4]);
|
||||
|
||||
static void subtractMatrix(const __m128 m1[4], const __m128 m2[4], __m128 dst[4]);
|
||||
|
||||
static void multiplyMatrix(const __m128 m[4], float scalar, __m128 dst[4]);
|
||||
|
||||
static void multiplyMatrix(const __m128 m1[4], const __m128 m2[4], __m128 dst[4]);
|
||||
|
||||
static void negateMatrix(const __m128 m[4], __m128 dst[4]);
|
||||
|
||||
static void transposeMatrix(const __m128 m[4], __m128 dst[4]);
|
||||
|
||||
static void transformVec4(const __m128 m[4], const __m128& v, __m128& dst);
|
||||
#endif
|
||||
static void addMatrix(const float* m, float scalar, float* dst);
|
||||
|
||||
static void addMatrix(const float* m1, const float* m2, float* dst);
|
||||
|
||||
static void subtractMatrix(const float* m1, const float* m2, float* dst);
|
||||
|
||||
static void multiplyMatrix(const float* m, float scalar, float* dst);
|
||||
|
||||
static void multiplyMatrix(const float* m1, const float* m2, float* dst);
|
||||
|
||||
static void negateMatrix(const float* m, float* dst);
|
||||
|
||||
static void transposeMatrix(const float* m, float* dst);
|
||||
|
||||
static void transformVec4(const float* m, float x, float y, float z, float w, float* dst);
|
||||
|
||||
static void transformVec4(const float* m, const float* v, float* dst);
|
||||
|
||||
static void crossVec3(const float* v1, const float* v2, float* dst);
|
||||
};
|
||||
|
||||
NS_CC_MATH_END
|
||||
/**
|
||||
end of base group
|
||||
@}
|
||||
*/
|
||||
#define MATRIX_SIZE ( sizeof(float) * 16)
|
||||
|
||||
#endif
|
||||
218
cocos2d-x/cocos/math/MathUtil.inl
Normal file
218
cocos2d-x/cocos/math/MathUtil.inl
Normal file
@@ -0,0 +1,218 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
class MathUtilC
|
||||
{
|
||||
public:
|
||||
inline static void addMatrix(const float* m, float scalar, float* dst);
|
||||
|
||||
inline static void addMatrix(const float* m1, const float* m2, float* dst);
|
||||
|
||||
inline static void subtractMatrix(const float* m1, const float* m2, float* dst);
|
||||
|
||||
inline static void multiplyMatrix(const float* m, float scalar, float* dst);
|
||||
|
||||
inline static void multiplyMatrix(const float* m1, const float* m2, float* dst);
|
||||
|
||||
inline static void negateMatrix(const float* m, float* dst);
|
||||
|
||||
inline static void transposeMatrix(const float* m, float* dst);
|
||||
|
||||
inline static void transformVec4(const float* m, float x, float y, float z, float w, float* dst);
|
||||
|
||||
inline static void transformVec4(const float* m, const float* v, float* dst);
|
||||
|
||||
inline static void crossVec3(const float* v1, const float* v2, float* dst);
|
||||
};
|
||||
|
||||
inline void MathUtilC::addMatrix(const float* m, float scalar, float* dst)
|
||||
{
|
||||
dst[0] = m[0] + scalar;
|
||||
dst[1] = m[1] + scalar;
|
||||
dst[2] = m[2] + scalar;
|
||||
dst[3] = m[3] + scalar;
|
||||
dst[4] = m[4] + scalar;
|
||||
dst[5] = m[5] + scalar;
|
||||
dst[6] = m[6] + scalar;
|
||||
dst[7] = m[7] + scalar;
|
||||
dst[8] = m[8] + scalar;
|
||||
dst[9] = m[9] + scalar;
|
||||
dst[10] = m[10] + scalar;
|
||||
dst[11] = m[11] + scalar;
|
||||
dst[12] = m[12] + scalar;
|
||||
dst[13] = m[13] + scalar;
|
||||
dst[14] = m[14] + scalar;
|
||||
dst[15] = m[15] + scalar;
|
||||
}
|
||||
|
||||
inline void MathUtilC::addMatrix(const float* m1, const float* m2, float* dst)
|
||||
{
|
||||
dst[0] = m1[0] + m2[0];
|
||||
dst[1] = m1[1] + m2[1];
|
||||
dst[2] = m1[2] + m2[2];
|
||||
dst[3] = m1[3] + m2[3];
|
||||
dst[4] = m1[4] + m2[4];
|
||||
dst[5] = m1[5] + m2[5];
|
||||
dst[6] = m1[6] + m2[6];
|
||||
dst[7] = m1[7] + m2[7];
|
||||
dst[8] = m1[8] + m2[8];
|
||||
dst[9] = m1[9] + m2[9];
|
||||
dst[10] = m1[10] + m2[10];
|
||||
dst[11] = m1[11] + m2[11];
|
||||
dst[12] = m1[12] + m2[12];
|
||||
dst[13] = m1[13] + m2[13];
|
||||
dst[14] = m1[14] + m2[14];
|
||||
dst[15] = m1[15] + m2[15];
|
||||
}
|
||||
|
||||
inline void MathUtilC::subtractMatrix(const float* m1, const float* m2, float* dst)
|
||||
{
|
||||
dst[0] = m1[0] - m2[0];
|
||||
dst[1] = m1[1] - m2[1];
|
||||
dst[2] = m1[2] - m2[2];
|
||||
dst[3] = m1[3] - m2[3];
|
||||
dst[4] = m1[4] - m2[4];
|
||||
dst[5] = m1[5] - m2[5];
|
||||
dst[6] = m1[6] - m2[6];
|
||||
dst[7] = m1[7] - m2[7];
|
||||
dst[8] = m1[8] - m2[8];
|
||||
dst[9] = m1[9] - m2[9];
|
||||
dst[10] = m1[10] - m2[10];
|
||||
dst[11] = m1[11] - m2[11];
|
||||
dst[12] = m1[12] - m2[12];
|
||||
dst[13] = m1[13] - m2[13];
|
||||
dst[14] = m1[14] - m2[14];
|
||||
dst[15] = m1[15] - m2[15];
|
||||
}
|
||||
|
||||
inline void MathUtilC::multiplyMatrix(const float* m, float scalar, float* dst)
|
||||
{
|
||||
dst[0] = m[0] * scalar;
|
||||
dst[1] = m[1] * scalar;
|
||||
dst[2] = m[2] * scalar;
|
||||
dst[3] = m[3] * scalar;
|
||||
dst[4] = m[4] * scalar;
|
||||
dst[5] = m[5] * scalar;
|
||||
dst[6] = m[6] * scalar;
|
||||
dst[7] = m[7] * scalar;
|
||||
dst[8] = m[8] * scalar;
|
||||
dst[9] = m[9] * scalar;
|
||||
dst[10] = m[10] * scalar;
|
||||
dst[11] = m[11] * scalar;
|
||||
dst[12] = m[12] * scalar;
|
||||
dst[13] = m[13] * scalar;
|
||||
dst[14] = m[14] * scalar;
|
||||
dst[15] = m[15] * scalar;
|
||||
}
|
||||
|
||||
inline void MathUtilC::multiplyMatrix(const float* m1, const float* m2, float* dst)
|
||||
{
|
||||
// Support the case where m1 or m2 is the same array as dst.
|
||||
float product[16];
|
||||
|
||||
product[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3];
|
||||
product[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3];
|
||||
product[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3];
|
||||
product[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3];
|
||||
|
||||
product[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7];
|
||||
product[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7];
|
||||
product[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7];
|
||||
product[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7];
|
||||
|
||||
product[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11];
|
||||
product[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11];
|
||||
product[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11];
|
||||
product[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11];
|
||||
|
||||
product[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15];
|
||||
product[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15];
|
||||
product[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15];
|
||||
product[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15];
|
||||
|
||||
memcpy(dst, product, MATRIX_SIZE);
|
||||
}
|
||||
|
||||
inline void MathUtilC::negateMatrix(const float* m, float* dst)
|
||||
{
|
||||
dst[0] = -m[0];
|
||||
dst[1] = -m[1];
|
||||
dst[2] = -m[2];
|
||||
dst[3] = -m[3];
|
||||
dst[4] = -m[4];
|
||||
dst[5] = -m[5];
|
||||
dst[6] = -m[6];
|
||||
dst[7] = -m[7];
|
||||
dst[8] = -m[8];
|
||||
dst[9] = -m[9];
|
||||
dst[10] = -m[10];
|
||||
dst[11] = -m[11];
|
||||
dst[12] = -m[12];
|
||||
dst[13] = -m[13];
|
||||
dst[14] = -m[14];
|
||||
dst[15] = -m[15];
|
||||
}
|
||||
|
||||
inline void MathUtilC::transposeMatrix(const float* m, float* dst)
|
||||
{
|
||||
float t[16] = {
|
||||
m[0], m[4], m[8], m[12],
|
||||
m[1], m[5], m[9], m[13],
|
||||
m[2], m[6], m[10], m[14],
|
||||
m[3], m[7], m[11], m[15]
|
||||
};
|
||||
memcpy(dst, t, MATRIX_SIZE);
|
||||
}
|
||||
|
||||
inline void MathUtilC::transformVec4(const float* m, float x, float y, float z, float w, float* dst)
|
||||
{
|
||||
dst[0] = x * m[0] + y * m[4] + z * m[8] + w * m[12];
|
||||
dst[1] = x * m[1] + y * m[5] + z * m[9] + w * m[13];
|
||||
dst[2] = x * m[2] + y * m[6] + z * m[10] + w * m[14];
|
||||
}
|
||||
|
||||
inline void MathUtilC::transformVec4(const float* m, const float* v, float* dst)
|
||||
{
|
||||
// Handle case where v == dst.
|
||||
float x = v[0] * m[0] + v[1] * m[4] + v[2] * m[8] + v[3] * m[12];
|
||||
float y = v[0] * m[1] + v[1] * m[5] + v[2] * m[9] + v[3] * m[13];
|
||||
float z = v[0] * m[2] + v[1] * m[6] + v[2] * m[10] + v[3] * m[14];
|
||||
float w = v[0] * m[3] + v[1] * m[7] + v[2] * m[11] + v[3] * m[15];
|
||||
|
||||
dst[0] = x;
|
||||
dst[1] = y;
|
||||
dst[2] = z;
|
||||
dst[3] = w;
|
||||
}
|
||||
|
||||
inline void MathUtilC::crossVec3(const float* v1, const float* v2, float* dst)
|
||||
{
|
||||
float x = (v1[1] * v2[2]) - (v1[2] * v2[1]);
|
||||
float y = (v1[2] * v2[0]) - (v1[0] * v2[2]);
|
||||
float z = (v1[0] * v2[1]) - (v1[1] * v2[0]);
|
||||
|
||||
dst[0] = x;
|
||||
dst[1] = y;
|
||||
dst[2] = z;
|
||||
}
|
||||
|
||||
NS_CC_MATH_END
|
||||
271
cocos2d-x/cocos/math/MathUtilNeon.inl
Normal file
271
cocos2d-x/cocos/math/MathUtilNeon.inl
Normal file
@@ -0,0 +1,271 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
class MathUtilNeon
|
||||
{
|
||||
public:
|
||||
inline static void addMatrix(const float* m, float scalar, float* dst);
|
||||
|
||||
inline static void addMatrix(const float* m1, const float* m2, float* dst);
|
||||
|
||||
inline static void subtractMatrix(const float* m1, const float* m2, float* dst);
|
||||
|
||||
inline static void multiplyMatrix(const float* m, float scalar, float* dst);
|
||||
|
||||
inline static void multiplyMatrix(const float* m1, const float* m2, float* dst);
|
||||
|
||||
inline static void negateMatrix(const float* m, float* dst);
|
||||
|
||||
inline static void transposeMatrix(const float* m, float* dst);
|
||||
|
||||
inline static void transformVec4(const float* m, float x, float y, float z, float w, float* dst);
|
||||
|
||||
inline static void transformVec4(const float* m, const float* v, float* dst);
|
||||
|
||||
inline static void crossVec3(const float* v1, const float* v2, float* dst);
|
||||
};
|
||||
|
||||
inline void MathUtilNeon::addMatrix(const float* m, float scalar, float* dst)
|
||||
{
|
||||
asm volatile(
|
||||
"vld1.32 {q0, q1}, [%1]! \n\t" // M[m0-m7]
|
||||
"vld1.32 {q2, q3}, [%1] \n\t" // M[m8-m15]
|
||||
"vld1.32 {d8[0]}, [%2] \n\t" // s
|
||||
"vmov.f32 s17, s16 \n\t" // s
|
||||
"vmov.f32 s18, s16 \n\t" // s
|
||||
"vmov.f32 s19, s16 \n\t" // s
|
||||
|
||||
"vadd.f32 q8, q0, q4 \n\t" // DST->M[m0-m3] = M[m0-m3] + s
|
||||
"vadd.f32 q9, q1, q4 \n\t" // DST->M[m4-m7] = M[m4-m7] + s
|
||||
"vadd.f32 q10, q2, q4 \n\t" // DST->M[m8-m11] = M[m8-m11] + s
|
||||
"vadd.f32 q11, q3, q4 \n\t" // DST->M[m12-m15] = M[m12-m15] + s
|
||||
|
||||
"vst1.32 {q8, q9}, [%0]! \n\t" // DST->M[m0-m7]
|
||||
"vst1.32 {q10, q11}, [%0] \n\t" // DST->M[m8-m15]
|
||||
:
|
||||
: "r"(dst), "r"(m), "r"(&scalar)
|
||||
: "q0", "q1", "q2", "q3", "q4", "q8", "q9", "q10", "q11", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
inline void MathUtilNeon::addMatrix(const float* m1, const float* m2, float* dst)
|
||||
{
|
||||
asm volatile(
|
||||
"vld1.32 {q0, q1}, [%1]! \n\t" // M1[m0-m7]
|
||||
"vld1.32 {q2, q3}, [%1] \n\t" // M1[m8-m15]
|
||||
"vld1.32 {q8, q9}, [%2]! \n\t" // M2[m0-m7]
|
||||
"vld1.32 {q10, q11}, [%2] \n\t" // M2[m8-m15]
|
||||
|
||||
"vadd.f32 q12, q0, q8 \n\t" // DST->M[m0-m3] = M1[m0-m3] + M2[m0-m3]
|
||||
"vadd.f32 q13, q1, q9 \n\t" // DST->M[m4-m7] = M1[m4-m7] + M2[m4-m7]
|
||||
"vadd.f32 q14, q2, q10 \n\t" // DST->M[m8-m11] = M1[m8-m11] + M2[m8-m11]
|
||||
"vadd.f32 q15, q3, q11 \n\t" // DST->M[m12-m15] = M1[m12-m15] + M2[m12-m15]
|
||||
|
||||
"vst1.32 {q12, q13}, [%0]! \n\t" // DST->M[m0-m7]
|
||||
"vst1.32 {q14, q15}, [%0] \n\t" // DST->M[m8-m15]
|
||||
:
|
||||
: "r"(dst), "r"(m1), "r"(m2)
|
||||
: "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
inline void MathUtilNeon::subtractMatrix(const float* m1, const float* m2, float* dst)
|
||||
{
|
||||
asm volatile(
|
||||
"vld1.32 {q0, q1}, [%1]! \n\t" // M1[m0-m7]
|
||||
"vld1.32 {q2, q3}, [%1] \n\t" // M1[m8-m15]
|
||||
"vld1.32 {q8, q9}, [%2]! \n\t" // M2[m0-m7]
|
||||
"vld1.32 {q10, q11}, [%2] \n\t" // M2[m8-m15]
|
||||
|
||||
"vsub.f32 q12, q0, q8 \n\t" // DST->M[m0-m3] = M1[m0-m3] - M2[m0-m3]
|
||||
"vsub.f32 q13, q1, q9 \n\t" // DST->M[m4-m7] = M1[m4-m7] - M2[m4-m7]
|
||||
"vsub.f32 q14, q2, q10 \n\t" // DST->M[m8-m11] = M1[m8-m11] - M2[m8-m11]
|
||||
"vsub.f32 q15, q3, q11 \n\t" // DST->M[m12-m15] = M1[m12-m15] - M2[m12-m15]
|
||||
|
||||
"vst1.32 {q12, q13}, [%0]! \n\t" // DST->M[m0-m7]
|
||||
"vst1.32 {q14, q15}, [%0] \n\t" // DST->M[m8-m15]
|
||||
:
|
||||
: "r"(dst), "r"(m1), "r"(m2)
|
||||
: "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
inline void MathUtilNeon::multiplyMatrix(const float* m, float scalar, float* dst)
|
||||
{
|
||||
asm volatile(
|
||||
"vld1.32 {d0[0]}, [%2] \n\t" // M[m0-m7]
|
||||
"vld1.32 {q4-q5}, [%1]! \n\t" // M[m8-m15]
|
||||
"vld1.32 {q6-q7}, [%1] \n\t" // s
|
||||
|
||||
"vmul.f32 q8, q4, d0[0] \n\t" // DST->M[m0-m3] = M[m0-m3] * s
|
||||
"vmul.f32 q9, q5, d0[0] \n\t" // DST->M[m4-m7] = M[m4-m7] * s
|
||||
"vmul.f32 q10, q6, d0[0] \n\t" // DST->M[m8-m11] = M[m8-m11] * s
|
||||
"vmul.f32 q11, q7, d0[0] \n\t" // DST->M[m12-m15] = M[m12-m15] * s
|
||||
|
||||
"vst1.32 {q8-q9}, [%0]! \n\t" // DST->M[m0-m7]
|
||||
"vst1.32 {q10-q11}, [%0] \n\t" // DST->M[m8-m15]
|
||||
:
|
||||
: "r"(dst), "r"(m), "r"(&scalar)
|
||||
: "q0", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
inline void MathUtilNeon::multiplyMatrix(const float* m1, const float* m2, float* dst)
|
||||
{
|
||||
asm volatile(
|
||||
"vld1.32 {d16 - d19}, [%1]! \n\t" // M1[m0-m7]
|
||||
"vld1.32 {d20 - d23}, [%1] \n\t" // M1[m8-m15]
|
||||
"vld1.32 {d0 - d3}, [%2]! \n\t" // M2[m0-m7]
|
||||
"vld1.32 {d4 - d7}, [%2] \n\t" // M2[m8-m15]
|
||||
|
||||
"vmul.f32 q12, q8, d0[0] \n\t" // DST->M[m0-m3] = M1[m0-m3] * M2[m0]
|
||||
"vmul.f32 q13, q8, d2[0] \n\t" // DST->M[m4-m7] = M1[m4-m7] * M2[m4]
|
||||
"vmul.f32 q14, q8, d4[0] \n\t" // DST->M[m8-m11] = M1[m8-m11] * M2[m8]
|
||||
"vmul.f32 q15, q8, d6[0] \n\t" // DST->M[m12-m15] = M1[m12-m15] * M2[m12]
|
||||
|
||||
"vmla.f32 q12, q9, d0[1] \n\t" // DST->M[m0-m3] += M1[m0-m3] * M2[m1]
|
||||
"vmla.f32 q13, q9, d2[1] \n\t" // DST->M[m4-m7] += M1[m4-m7] * M2[m5]
|
||||
"vmla.f32 q14, q9, d4[1] \n\t" // DST->M[m8-m11] += M1[m8-m11] * M2[m9]
|
||||
"vmla.f32 q15, q9, d6[1] \n\t" // DST->M[m12-m15] += M1[m12-m15] * M2[m13]
|
||||
|
||||
"vmla.f32 q12, q10, d1[0] \n\t" // DST->M[m0-m3] += M1[m0-m3] * M2[m2]
|
||||
"vmla.f32 q13, q10, d3[0] \n\t" // DST->M[m4-m7] += M1[m4-m7] * M2[m6]
|
||||
"vmla.f32 q14, q10, d5[0] \n\t" // DST->M[m8-m11] += M1[m8-m11] * M2[m10]
|
||||
"vmla.f32 q15, q10, d7[0] \n\t" // DST->M[m12-m15] += M1[m12-m15] * M2[m14]
|
||||
|
||||
"vmla.f32 q12, q11, d1[1] \n\t" // DST->M[m0-m3] += M1[m0-m3] * M2[m3]
|
||||
"vmla.f32 q13, q11, d3[1] \n\t" // DST->M[m4-m7] += M1[m4-m7] * M2[m7]
|
||||
"vmla.f32 q14, q11, d5[1] \n\t" // DST->M[m8-m11] += M1[m8-m11] * M2[m11]
|
||||
"vmla.f32 q15, q11, d7[1] \n\t" // DST->M[m12-m15] += M1[m12-m15] * M2[m15]
|
||||
|
||||
"vst1.32 {d24 - d27}, [%0]! \n\t" // DST->M[m0-m7]
|
||||
"vst1.32 {d28 - d31}, [%0] \n\t" // DST->M[m8-m15]
|
||||
|
||||
: // output
|
||||
: "r"(dst), "r"(m1), "r"(m2) // input - note *value* of pointer doesn't change.
|
||||
: "memory", "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
||||
);
|
||||
}
|
||||
|
||||
inline void MathUtilNeon::negateMatrix(const float* m, float* dst)
|
||||
{
|
||||
asm volatile(
|
||||
"vld1.32 {q0-q1}, [%1]! \n\t" // load m0-m7
|
||||
"vld1.32 {q2-q3}, [%1] \n\t" // load m8-m15
|
||||
|
||||
"vneg.f32 q4, q0 \n\t" // negate m0-m3
|
||||
"vneg.f32 q5, q1 \n\t" // negate m4-m7
|
||||
"vneg.f32 q6, q2 \n\t" // negate m8-m15
|
||||
"vneg.f32 q7, q3 \n\t" // negate m8-m15
|
||||
|
||||
"vst1.32 {q4-q5}, [%0]! \n\t" // store m0-m7
|
||||
"vst1.32 {q6-q7}, [%0] \n\t" // store m8-m15
|
||||
:
|
||||
: "r"(dst), "r"(m)
|
||||
: "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
inline void MathUtilNeon::transposeMatrix(const float* m, float* dst)
|
||||
{
|
||||
asm volatile(
|
||||
"vld4.32 {d0[0], d2[0], d4[0], d6[0]}, [%1]! \n\t" // DST->M[m0, m4, m8, m12] = M[m0-m3]
|
||||
"vld4.32 {d0[1], d2[1], d4[1], d6[1]}, [%1]! \n\t" // DST->M[m1, m5, m9, m12] = M[m4-m7]
|
||||
"vld4.32 {d1[0], d3[0], d5[0], d7[0]}, [%1]! \n\t" // DST->M[m2, m6, m10, m12] = M[m8-m11]
|
||||
"vld4.32 {d1[1], d3[1], d5[1], d7[1]}, [%1] \n\t" // DST->M[m3, m7, m11, m12] = M[m12-m15]
|
||||
|
||||
"vst1.32 {q0-q1}, [%0]! \n\t" // DST->M[m0-m7]
|
||||
"vst1.32 {q2-q3}, [%0] \n\t" // DST->M[m8-m15]
|
||||
:
|
||||
: "r"(dst), "r"(m)
|
||||
: "q0", "q1", "q2", "q3", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
inline void MathUtilNeon::transformVec4(const float* m, float x, float y, float z, float w, float* dst)
|
||||
{
|
||||
asm volatile(
|
||||
"vld1.32 {d0[0]}, [%1] \n\t" // V[x]
|
||||
"vld1.32 {d0[1]}, [%2] \n\t" // V[y]
|
||||
"vld1.32 {d1[0]}, [%3] \n\t" // V[z]
|
||||
"vld1.32 {d1[1]}, [%4] \n\t" // V[w]
|
||||
"vld1.32 {d18 - d21}, [%5]! \n\t" // M[m0-m7]
|
||||
"vld1.32 {d22 - d25}, [%5] \n\t" // M[m8-m15]
|
||||
|
||||
"vmul.f32 q13, q9, d0[0] \n\t" // DST->V = M[m0-m3] * V[x]
|
||||
"vmla.f32 q13, q10, d0[1] \n\t" // DST->V += M[m4-m7] * V[y]
|
||||
"vmla.f32 q13, q11, d1[0] \n\t" // DST->V += M[m8-m11] * V[z]
|
||||
"vmla.f32 q13, q12, d1[1] \n\t" // DST->V += M[m12-m15] * V[w]
|
||||
|
||||
"vst1.32 {d26}, [%0]! \n\t" // DST->V[x, y]
|
||||
"vst1.32 {d27[0]}, [%0] \n\t" // DST->V[z]
|
||||
:
|
||||
: "r"(dst), "r"(&x), "r"(&y), "r"(&z), "r"(&w), "r"(m)
|
||||
: "q0", "q9", "q10","q11", "q12", "q13", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
inline void MathUtilNeon::transformVec4(const float* m, const float* v, float* dst)
|
||||
{
|
||||
asm volatile
|
||||
(
|
||||
"vld1.32 {d0, d1}, [%1] \n\t" // V[x, y, z, w]
|
||||
"vld1.32 {d18 - d21}, [%2]! \n\t" // M[m0-m7]
|
||||
"vld1.32 {d22 - d25}, [%2] \n\t" // M[m8-m15]
|
||||
|
||||
"vmul.f32 q13, q9, d0[0] \n\t" // DST->V = M[m0-m3] * V[x]
|
||||
"vmla.f32 q13, q10, d0[1] \n\t" // DST->V = M[m4-m7] * V[y]
|
||||
"vmla.f32 q13, q11, d1[0] \n\t" // DST->V = M[m8-m11] * V[z]
|
||||
"vmla.f32 q13, q12, d1[1] \n\t" // DST->V = M[m12-m15] * V[w]
|
||||
|
||||
"vst1.32 {d26, d27}, [%0] \n\t" // DST->V
|
||||
:
|
||||
: "r"(dst), "r"(v), "r"(m)
|
||||
: "q0", "q9", "q10","q11", "q12", "q13", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
inline void MathUtilNeon::crossVec3(const float* v1, const float* v2, float* dst)
|
||||
{
|
||||
asm volatile(
|
||||
"vld1.32 {d1[1]}, [%1] \n\t" //
|
||||
"vld1.32 {d0}, [%2] \n\t" //
|
||||
"vmov.f32 s2, s1 \n\t" // q0 = (v1y, v1z, v1z, v1x)
|
||||
|
||||
"vld1.32 {d2[1]}, [%3] \n\t" //
|
||||
"vld1.32 {d3}, [%4] \n\t" //
|
||||
"vmov.f32 s4, s7 \n\t" // q1 = (v2z, v2x, v2y, v2z)
|
||||
|
||||
"vmul.f32 d4, d0, d2 \n\t" // x = v1y * v2z, y = v1z * v2x
|
||||
"vmls.f32 d4, d1, d3 \n\t" // x -= v1z * v2y, y-= v1x - v2z
|
||||
|
||||
"vmul.f32 d5, d3, d1[1] \n\t" // z = v1x * v2y
|
||||
"vmls.f32 d5, d0, d2[1] \n\t" // z-= v1y * vx
|
||||
|
||||
"vst1.32 {d4}, [%0]! \n\t" // V[x, y]
|
||||
"vst1.32 {d5[0]}, [%0] \n\t" // V[z]
|
||||
:
|
||||
: "r"(dst), "r"(v1), "r"((v1+1)), "r"(v2), "r"((v2+1))
|
||||
: "q0", "q1", "q2", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
NS_CC_MATH_END
|
||||
265
cocos2d-x/cocos/math/MathUtilNeon64.inl
Normal file
265
cocos2d-x/cocos/math/MathUtilNeon64.inl
Normal file
@@ -0,0 +1,265 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
class MathUtilNeon64
|
||||
{
|
||||
public:
|
||||
inline static void addMatrix(const float* m, float scalar, float* dst);
|
||||
|
||||
inline static void addMatrix(const float* m1, const float* m2, float* dst);
|
||||
|
||||
inline static void subtractMatrix(const float* m1, const float* m2, float* dst);
|
||||
|
||||
inline static void multiplyMatrix(const float* m, float scalar, float* dst);
|
||||
|
||||
inline static void multiplyMatrix(const float* m1, const float* m2, float* dst);
|
||||
|
||||
inline static void negateMatrix(const float* m, float* dst);
|
||||
|
||||
inline static void transposeMatrix(const float* m, float* dst);
|
||||
|
||||
inline static void transformVec4(const float* m, float x, float y, float z, float w, float* dst);
|
||||
|
||||
inline static void transformVec4(const float* m, const float* v, float* dst);
|
||||
|
||||
inline static void crossVec3(const float* v1, const float* v2, float* dst);
|
||||
};
|
||||
|
||||
inline void MathUtilNeon64::addMatrix(const float* m, float scalar, float* dst)
|
||||
{
|
||||
asm volatile(
|
||||
"ld4 {v0.4s, v1.4s, v2.4s, v3.4s}, [%1] \n\t" // M[m0-m7] M[m8-m15]
|
||||
"ld1r {v4.4s}, [%2] \n\t" //ssss
|
||||
|
||||
"fadd v8.4s, v0.4s, v4.4s \n\t" // DST->M[m0-m3] = M[m0-m3] + s
|
||||
"fadd v9.4s, v1.4s, v4.4s \n\t" // DST->M[m4-m7] = M[m4-m7] + s
|
||||
"fadd v10.4s, v2.4s, v4.4s \n\t" // DST->M[m8-m11] = M[m8-m11] + s
|
||||
"fadd v11.4s, v3.4s, v4.4s \n\t" // DST->M[m12-m15] = M[m12-m15] + s
|
||||
|
||||
"st4 {v8.4s, v9.4s, v10.4s, v11.4s}, [%0] \n\t" // Result in V9
|
||||
:
|
||||
: "r"(dst), "r"(m), "r"(&scalar)
|
||||
: "v0", "v1", "v2", "v3", "v4", "v8", "v9", "v10", "v11", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
inline void MathUtilNeon64::addMatrix(const float* m1, const float* m2, float* dst)
|
||||
{
|
||||
asm volatile(
|
||||
"ld4 {v0.4s, v1.4s, v2.4s, v3.4s}, [%1] \n\t" // M1[m0-m7] M1[m8-m15]
|
||||
"ld4 {v8.4s, v9.4s, v10.4s, v11.4s}, [%2] \n\t" // M2[m0-m7] M2[m8-m15]
|
||||
|
||||
"fadd v12.4s, v0.4s, v8.4s \n\t" // DST->M[m0-m3] = M1[m0-m3] + M2[m0-m3]
|
||||
"fadd v13.4s, v1.4s, v9.4s \n\t" // DST->M[m4-m7] = M1[m4-m7] + M2[m4-m7]
|
||||
"fadd v14.4s, v2.4s, v10.4s \n\t" // DST->M[m8-m11] = M1[m8-m11] + M2[m8-m11]
|
||||
"fadd v15.4s, v3.4s, v11.4s \n\t" // DST->M[m12-m15] = M1[m12-m15] + M2[m12-m15]
|
||||
|
||||
"st4 {v12.4s, v13.4s, v14.4s, v15.4s}, [%0] \n\t" // DST->M[m0-m7] DST->M[m8-m15]
|
||||
:
|
||||
: "r"(dst), "r"(m1), "r"(m2)
|
||||
: "v0", "v1", "v2", "v3", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
inline void MathUtilNeon64::subtractMatrix(const float* m1, const float* m2, float* dst)
|
||||
{
|
||||
asm volatile(
|
||||
"ld4 {v0.4s, v1.4s, v2.4s, v3.4s}, [%1] \n\t" // M1[m0-m7] M1[m8-m15]
|
||||
"ld4 {v8.4s, v9.4s, v10.4s, v11.4s}, [%2] \n\t" // M2[m0-m7] M2[m8-m15]
|
||||
|
||||
"fsub v12.4s, v0.4s, v8.4s \n\t" // DST->M[m0-m3] = M1[m0-m3] - M2[m0-m3]
|
||||
"fsub v13.4s, v1.4s, v9.4s \n\t" // DST->M[m4-m7] = M1[m4-m7] - M2[m4-m7]
|
||||
"fsub v14.4s, v2.4s, v10.4s \n\t" // DST->M[m8-m11] = M1[m8-m11] - M2[m8-m11]
|
||||
"fsub v15.4s, v3.4s, v11.4s \n\t" // DST->M[m12-m15] = M1[m12-m15] - M2[m12-m15]
|
||||
|
||||
"st4 {v12.4s, v13.4s, v14.4s, v15.4s}, [%0] \n\t" // DST->M[m0-m7] DST->M[m8-m15]
|
||||
:
|
||||
: "r"(dst), "r"(m1), "r"(m2)
|
||||
: "v0", "v1", "v2", "v3", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
inline void MathUtilNeon64::multiplyMatrix(const float* m, float scalar, float* dst)
|
||||
{
|
||||
asm volatile(
|
||||
"ld1 {v0.s}[0], [%2] \n\t" //s
|
||||
"ld4 {v4.4s, v5.4s, v6.4s, v7.4s}, [%1] \n\t" //M[m0-m7] M[m8-m15]
|
||||
|
||||
"fmul v8.4s, v4.4s, v0.s[0] \n\t" // DST->M[m0-m3] = M[m0-m3] * s
|
||||
"fmul v9.4s, v5.4s, v0.s[0] \n\t" // DST->M[m4-m7] = M[m4-m7] * s
|
||||
"fmul v10.4s, v6.4s, v0.s[0] \n\t" // DST->M[m8-m11] = M[m8-m11] * s
|
||||
"fmul v11.4s, v7.4s, v0.s[0] \n\t" // DST->M[m12-m15] = M[m12-m15] * s
|
||||
|
||||
"st4 {v8.4s, v9.4s, v10.4s, v11.4s}, [%0] \n\t" // DST->M[m0-m7] DST->M[m8-m15]
|
||||
:
|
||||
: "r"(dst), "r"(m), "r"(&scalar)
|
||||
: "v0", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
inline void MathUtilNeon64::multiplyMatrix(const float* m1, const float* m2, float* dst)
|
||||
{
|
||||
asm volatile(
|
||||
"ld1 {v8.4s, v9.4s, v10.4s, v11.4s}, [%1] \n\t" // M1[m0-m7] M1[m8-m15] M2[m0-m7] M2[m8-m15]
|
||||
"ld4 {v0.4s, v1.4s, v2.4s, v3.4s}, [%2] \n\t" // M2[m0-m15]
|
||||
|
||||
|
||||
"fmul v12.4s, v8.4s, v0.s[0] \n\t" // DST->M[m0-m3] = M1[m0-m3] * M2[m0]
|
||||
"fmul v13.4s, v8.4s, v0.s[1] \n\t" // DST->M[m4-m7] = M1[m4-m7] * M2[m4]
|
||||
"fmul v14.4s, v8.4s, v0.s[2] \n\t" // DST->M[m8-m11] = M1[m8-m11] * M2[m8]
|
||||
"fmul v15.4s, v8.4s, v0.s[3] \n\t" // DST->M[m12-m15] = M1[m12-m15] * M2[m12]
|
||||
|
||||
"fmla v12.4s, v9.4s, v1.s[0] \n\t" // DST->M[m0-m3] += M1[m0-m3] * M2[m1]
|
||||
"fmla v13.4s, v9.4s, v1.s[1] \n\t" // DST->M[m4-m7] += M1[m4-m7] * M2[m5]
|
||||
"fmla v14.4s, v9.4s, v1.s[2] \n\t" // DST->M[m8-m11] += M1[m8-m11] * M2[m9]
|
||||
"fmla v15.4s, v9.4s, v1.s[3] \n\t" // DST->M[m12-m15] += M1[m12-m15] * M2[m13]
|
||||
|
||||
"fmla v12.4s, v10.4s, v2.s[0] \n\t" // DST->M[m0-m3] += M1[m0-m3] * M2[m2]
|
||||
"fmla v13.4s, v10.4s, v2.s[1] \n\t" // DST->M[m4-m7] += M1[m4-m7] * M2[m6]
|
||||
"fmla v14.4s, v10.4s, v2.s[2] \n\t" // DST->M[m8-m11] += M1[m8-m11] * M2[m10]
|
||||
"fmla v15.4s, v10.4s, v2.s[3] \n\t" // DST->M[m12-m15] += M1[m12-m15] * M2[m14]
|
||||
|
||||
"fmla v12.4s, v11.4s, v3.s[0] \n\t" // DST->M[m0-m3] += M1[m0-m3] * M2[m3]
|
||||
"fmla v13.4s, v11.4s, v3.s[1] \n\t" // DST->M[m4-m7] += M1[m4-m7] * M2[m7]
|
||||
"fmla v14.4s, v11.4s, v3.s[2] \n\t" // DST->M[m8-m11] += M1[m8-m11] * M2[m11]
|
||||
"fmla v15.4s, v11.4s, v3.s[3] \n\t" // DST->M[m12-m15] += M1[m12-m15] * M2[m15]
|
||||
|
||||
"st1 {v12.4s, v13.4s, v14.4s, v15.4s}, [%0] \n\t" // DST->M[m0-m7]// DST->M[m8-m15]
|
||||
|
||||
: // output
|
||||
: "r"(dst), "r"(m1), "r"(m2) // input - note *value* of pointer doesn't change.
|
||||
: "memory", "v0", "v1", "v2", "v3", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15"
|
||||
);
|
||||
}
|
||||
|
||||
inline void MathUtilNeon64::negateMatrix(const float* m, float* dst)
|
||||
{
|
||||
asm volatile(
|
||||
"ld4 {v0.4s, v1.4s, v2.4s, v3.4s}, [%1] \n\t" // load m0-m7 load m8-m15
|
||||
|
||||
"fneg v4.4s, v0.4s \n\t" // negate m0-m3
|
||||
"fneg v5.4s, v1.4s \n\t" // negate m4-m7
|
||||
"fneg v6.4s, v2.4s \n\t" // negate m8-m15
|
||||
"fneg v7.4s, v3.4s \n\t" // negate m8-m15
|
||||
|
||||
"st4 {v4.4s, v5.4s, v6.4s, v7.4s}, [%0] \n\t" // store m0-m7 store m8-m15
|
||||
:
|
||||
: "r"(dst), "r"(m)
|
||||
: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
inline void MathUtilNeon64::transposeMatrix(const float* m, float* dst)
|
||||
{
|
||||
asm volatile(
|
||||
"ld4 {v0.4s, v1.4s, v2.4s, v3.4s}, [%1] \n\t" // DST->M[m0, m4, m8, m12] = M[m0-m3]
|
||||
//DST->M[m1, m5, m9, m12] = M[m4-m7]
|
||||
"st1 {v0.4s, v1.4s, v2.4s, v3.4s}, [%0] \n\t"
|
||||
:
|
||||
: "r"(dst), "r"(m)
|
||||
: "v0", "v1", "v2", "v3", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
inline void MathUtilNeon64::transformVec4(const float* m, float x, float y, float z, float w, float* dst)
|
||||
{
|
||||
asm volatile(
|
||||
"ld1 {v0.s}[0], [%1] \n\t" // V[x]
|
||||
"ld1 {v0.s}[1], [%2] \n\t" // V[y]
|
||||
"ld1 {v0.s}[2], [%3] \n\t" // V[z]
|
||||
"ld1 {v0.s}[3], [%4] \n\t" // V[w]
|
||||
"ld1 {v9.4s, v10.4s, v11.4s, v12.4s}, [%5] \n\t" // M[m0-m7] M[m8-m15]
|
||||
|
||||
|
||||
"fmul v13.4s, v9.4s, v0.s[0] \n\t" // DST->V = M[m0-m3] * V[x]
|
||||
"fmla v13.4s, v10.4s, v0.s[1] \n\t" // DST->V += M[m4-m7] * V[y]
|
||||
"fmla v13.4s, v11.4s, v0.s[2] \n\t" // DST->V += M[m8-m11] * V[z]
|
||||
"fmla v13.4s, v12.4s, v0.s[3] \n\t" // DST->V += M[m12-m15] * V[w]
|
||||
|
||||
//"st1 {v13.4s}, [%0] \n\t" // DST->V[x, y] // DST->V[z]
|
||||
"st1 {v13.2s}, [%0], 8 \n\t"
|
||||
"st1 {v13.s}[2], [%0] \n\t"
|
||||
:
|
||||
: "r"(dst), "r"(&x), "r"(&y), "r"(&z), "r"(&w), "r"(m)
|
||||
: "v0", "v9", "v10","v11", "v12", "v13", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
inline void MathUtilNeon64::transformVec4(const float* m, const float* v, float* dst)
|
||||
{
|
||||
asm volatile
|
||||
(
|
||||
"ld1 {v0.4s}, [%1] \n\t" // V[x, y, z, w]
|
||||
"ld1 {v9.4s, v10.4s, v11.4s, v12.4s}, [%2] \n\t" // M[m0-m7] M[m8-m15]
|
||||
|
||||
"fmul v13.4s, v9.4s, v0.s[0] \n\t" // DST->V = M[m0-m3] * V[x]
|
||||
"fmla v13.4s, v10.4s, v0.s[1] \n\t" // DST->V = M[m4-m7] * V[y]
|
||||
"fmla v13.4s, v11.4s, v0.s[2] \n\t" // DST->V = M[m8-m11] * V[z]
|
||||
"fmla v13.4s, v12.4s, v0.s[3] \n\t" // DST->V = M[m12-m15] * V[w]
|
||||
|
||||
"st1 {v13.4s}, [%0] \n\t" // DST->V
|
||||
:
|
||||
: "r"(dst), "r"(v), "r"(m)
|
||||
: "v0", "v9", "v10","v11", "v12", "v13", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
inline void MathUtilNeon64::crossVec3(const float* v1, const float* v2, float* dst)
|
||||
{
|
||||
asm volatile(
|
||||
"ld1 {v0.2s}, [%2] \n\t"
|
||||
"ld1 {v0.s}[2], [%1] \n\t"
|
||||
"mov v0.s[3], v0.s[0] \n\t" // q0 = (v1y, v1z, v1x, v1x)
|
||||
|
||||
"ld1 {v1.4s}, [%3] \n\t"
|
||||
"mov v1.s[3], v1.s[0] \n\t" // q1 = (v2x, v2y, v2z, v2x)
|
||||
|
||||
"fmul v2.4s, v0.4s, v1.4s \n\t" // x = v1y * v2z, y = v1z * v2x
|
||||
|
||||
|
||||
"mov v0.s[0], v0.s[1] \n\t"
|
||||
"mov v0.s[1], v0.s[2] \n\t"
|
||||
"mov v0.s[2], v0.s[3] \n\t"
|
||||
|
||||
"mov v1.s[3], v1.s[2] \n\t"
|
||||
|
||||
"fmul v0.4s, v0.4s, v1.4s \n\t"
|
||||
|
||||
"mov v0.s[3], v0.s[1] \n\t"
|
||||
"mov v0.s[1], v0.s[2] \n\t"
|
||||
"mov v0.s[2], v0.s[0] \n\t"
|
||||
|
||||
"fsub v2.4s, v0.4s, v2.4s \n\t"
|
||||
|
||||
"mov v2.s[0], v2.s[1] \n\t"
|
||||
"mov v2.s[1], v2.s[2] \n\t"
|
||||
"mov v2.s[2], v2.s[3] \n\t"
|
||||
|
||||
"st1 {v2.2s}, [%0], 8 \n\t" // V[x, y]
|
||||
"st1 {v2.s}[2], [%0] \n\t" // V[z]
|
||||
:
|
||||
: "r"(dst), "r"(v1), "r"((v1+1)), "r"(v2), "r"((v2+1))
|
||||
: "v0", "v1", "v2", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
NS_CC_MATH_END
|
||||
157
cocos2d-x/cocos/math/MathUtilSSE.inl
Normal file
157
cocos2d-x/cocos/math/MathUtilSSE.inl
Normal file
@@ -0,0 +1,157 @@
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
#ifdef __SSE__
|
||||
|
||||
void MathUtil::addMatrix(const __m128 m[4], float scalar, __m128 dst[4])
|
||||
{
|
||||
__m128 s = _mm_set1_ps(scalar);
|
||||
dst[0] = _mm_add_ps(m[0], s);
|
||||
dst[1] = _mm_add_ps(m[1], s);
|
||||
dst[2] = _mm_add_ps(m[2], s);
|
||||
dst[3] = _mm_add_ps(m[3], s);
|
||||
}
|
||||
|
||||
void MathUtil::addMatrix(const __m128 m1[4], const __m128 m2[4], __m128 dst[4])
|
||||
{
|
||||
dst[0] = _mm_add_ps(m1[0], m2[0]);
|
||||
dst[1] = _mm_add_ps(m1[1], m2[1]);
|
||||
dst[2] = _mm_add_ps(m1[2], m2[2]);
|
||||
dst[3] = _mm_add_ps(m1[3], m2[3]);
|
||||
}
|
||||
|
||||
void MathUtil::subtractMatrix(const __m128 m1[4], const __m128 m2[4], __m128 dst[4])
|
||||
{
|
||||
dst[0] = _mm_sub_ps(m1[0], m2[0]);
|
||||
dst[1] = _mm_sub_ps(m1[1], m2[1]);
|
||||
dst[2] = _mm_sub_ps(m1[2], m2[2]);
|
||||
dst[3] = _mm_sub_ps(m1[3], m2[3]);
|
||||
}
|
||||
|
||||
void MathUtil::multiplyMatrix(const __m128 m[4], float scalar, __m128 dst[4])
|
||||
{
|
||||
__m128 s = _mm_set1_ps(scalar);
|
||||
dst[0] = _mm_mul_ps(m[0], s);
|
||||
dst[1] = _mm_mul_ps(m[1], s);
|
||||
dst[2] = _mm_mul_ps(m[2], s);
|
||||
dst[3] = _mm_mul_ps(m[3], s);
|
||||
}
|
||||
|
||||
void MathUtil::multiplyMatrix(const __m128 m1[4], const __m128 m2[4], __m128 dst[4])
|
||||
{
|
||||
__m128 dst0, dst1, dst2, dst3;
|
||||
{
|
||||
__m128 e0 = _mm_shuffle_ps(m2[0], m2[0], _MM_SHUFFLE(0, 0, 0, 0));
|
||||
__m128 e1 = _mm_shuffle_ps(m2[0], m2[0], _MM_SHUFFLE(1, 1, 1, 1));
|
||||
__m128 e2 = _mm_shuffle_ps(m2[0], m2[0], _MM_SHUFFLE(2, 2, 2, 2));
|
||||
__m128 e3 = _mm_shuffle_ps(m2[0], m2[0], _MM_SHUFFLE(3, 3, 3, 3));
|
||||
|
||||
__m128 v0 = _mm_mul_ps(m1[0], e0);
|
||||
__m128 v1 = _mm_mul_ps(m1[1], e1);
|
||||
__m128 v2 = _mm_mul_ps(m1[2], e2);
|
||||
__m128 v3 = _mm_mul_ps(m1[3], e3);
|
||||
|
||||
__m128 a0 = _mm_add_ps(v0, v1);
|
||||
__m128 a1 = _mm_add_ps(v2, v3);
|
||||
__m128 a2 = _mm_add_ps(a0, a1);
|
||||
|
||||
dst0 = a2;
|
||||
}
|
||||
|
||||
{
|
||||
__m128 e0 = _mm_shuffle_ps(m2[1], m2[1], _MM_SHUFFLE(0, 0, 0, 0));
|
||||
__m128 e1 = _mm_shuffle_ps(m2[1], m2[1], _MM_SHUFFLE(1, 1, 1, 1));
|
||||
__m128 e2 = _mm_shuffle_ps(m2[1], m2[1], _MM_SHUFFLE(2, 2, 2, 2));
|
||||
__m128 e3 = _mm_shuffle_ps(m2[1], m2[1], _MM_SHUFFLE(3, 3, 3, 3));
|
||||
|
||||
__m128 v0 = _mm_mul_ps(m1[0], e0);
|
||||
__m128 v1 = _mm_mul_ps(m1[1], e1);
|
||||
__m128 v2 = _mm_mul_ps(m1[2], e2);
|
||||
__m128 v3 = _mm_mul_ps(m1[3], e3);
|
||||
|
||||
__m128 a0 = _mm_add_ps(v0, v1);
|
||||
__m128 a1 = _mm_add_ps(v2, v3);
|
||||
__m128 a2 = _mm_add_ps(a0, a1);
|
||||
|
||||
dst1 = a2;
|
||||
}
|
||||
|
||||
{
|
||||
__m128 e0 = _mm_shuffle_ps(m2[2], m2[2], _MM_SHUFFLE(0, 0, 0, 0));
|
||||
__m128 e1 = _mm_shuffle_ps(m2[2], m2[2], _MM_SHUFFLE(1, 1, 1, 1));
|
||||
__m128 e2 = _mm_shuffle_ps(m2[2], m2[2], _MM_SHUFFLE(2, 2, 2, 2));
|
||||
__m128 e3 = _mm_shuffle_ps(m2[2], m2[2], _MM_SHUFFLE(3, 3, 3, 3));
|
||||
|
||||
__m128 v0 = _mm_mul_ps(m1[0], e0);
|
||||
__m128 v1 = _mm_mul_ps(m1[1], e1);
|
||||
__m128 v2 = _mm_mul_ps(m1[2], e2);
|
||||
__m128 v3 = _mm_mul_ps(m1[3], e3);
|
||||
|
||||
__m128 a0 = _mm_add_ps(v0, v1);
|
||||
__m128 a1 = _mm_add_ps(v2, v3);
|
||||
__m128 a2 = _mm_add_ps(a0, a1);
|
||||
|
||||
dst2 = a2;
|
||||
}
|
||||
|
||||
{
|
||||
__m128 e0 = _mm_shuffle_ps(m2[3], m2[3], _MM_SHUFFLE(0, 0, 0, 0));
|
||||
__m128 e1 = _mm_shuffle_ps(m2[3], m2[3], _MM_SHUFFLE(1, 1, 1, 1));
|
||||
__m128 e2 = _mm_shuffle_ps(m2[3], m2[3], _MM_SHUFFLE(2, 2, 2, 2));
|
||||
__m128 e3 = _mm_shuffle_ps(m2[3], m2[3], _MM_SHUFFLE(3, 3, 3, 3));
|
||||
|
||||
__m128 v0 = _mm_mul_ps(m1[0], e0);
|
||||
__m128 v1 = _mm_mul_ps(m1[1], e1);
|
||||
__m128 v2 = _mm_mul_ps(m1[2], e2);
|
||||
__m128 v3 = _mm_mul_ps(m1[3], e3);
|
||||
|
||||
__m128 a0 = _mm_add_ps(v0, v1);
|
||||
__m128 a1 = _mm_add_ps(v2, v3);
|
||||
__m128 a2 = _mm_add_ps(a0, a1);
|
||||
|
||||
dst3 = a2;
|
||||
}
|
||||
dst[0] = dst0;
|
||||
dst[1] = dst1;
|
||||
dst[2] = dst2;
|
||||
dst[3] = dst3;
|
||||
}
|
||||
|
||||
void MathUtil::negateMatrix(const __m128 m[4], __m128 dst[4])
|
||||
{
|
||||
__m128 z = _mm_setzero_ps();
|
||||
dst[0] = _mm_sub_ps(z, m[0]);
|
||||
dst[1] = _mm_sub_ps(z, m[1]);
|
||||
dst[2] = _mm_sub_ps(z, m[2]);
|
||||
dst[3] = _mm_sub_ps(z, m[3]);
|
||||
}
|
||||
|
||||
void MathUtil::transposeMatrix(const __m128 m[4], __m128 dst[4])
|
||||
{
|
||||
__m128 tmp0 = _mm_shuffle_ps(m[0], m[1], 0x44);
|
||||
__m128 tmp2 = _mm_shuffle_ps(m[0], m[1], 0xEE);
|
||||
__m128 tmp1 = _mm_shuffle_ps(m[2], m[3], 0x44);
|
||||
__m128 tmp3 = _mm_shuffle_ps(m[2], m[3], 0xEE);
|
||||
|
||||
dst[0] = _mm_shuffle_ps(tmp0, tmp1, 0x88);
|
||||
dst[1] = _mm_shuffle_ps(tmp0, tmp1, 0xDD);
|
||||
dst[2] = _mm_shuffle_ps(tmp2, tmp3, 0x88);
|
||||
dst[3] = _mm_shuffle_ps(tmp2, tmp3, 0xDD);
|
||||
}
|
||||
|
||||
void MathUtil::transformVec4(const __m128 m[4], const __m128& v, __m128& dst)
|
||||
{
|
||||
__m128 col1 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0));
|
||||
__m128 col2 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1));
|
||||
__m128 col3 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2));
|
||||
__m128 col4 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(3, 3, 3, 3));
|
||||
|
||||
dst = _mm_add_ps(
|
||||
_mm_add_ps(_mm_mul_ps(m[0], col1), _mm_mul_ps(m[1], col2)),
|
||||
_mm_add_ps(_mm_mul_ps(m[2], col3), _mm_mul_ps(m[3], col4))
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
NS_CC_MATH_END
|
||||
479
cocos2d-x/cocos/math/Quaternion.cpp
Normal file
479
cocos2d-x/cocos/math/Quaternion.cpp
Normal file
@@ -0,0 +1,479 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
|
||||
#include "math/Quaternion.h"
|
||||
|
||||
#include <cmath>
|
||||
#include "base/ccMacros.h"
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
const Quaternion Quaternion::ZERO(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
Quaternion::Quaternion()
|
||||
: x(0.0f), y(0.0f), z(0.0f), w(1.0f)
|
||||
{
|
||||
}
|
||||
|
||||
Quaternion::Quaternion(float xx, float yy, float zz, float ww)
|
||||
: x(xx), y(yy), z(zz), w(ww)
|
||||
{
|
||||
}
|
||||
|
||||
Quaternion::Quaternion(float* array)
|
||||
{
|
||||
set(array);
|
||||
}
|
||||
|
||||
Quaternion::Quaternion(const Mat4& m)
|
||||
{
|
||||
set(m);
|
||||
}
|
||||
|
||||
Quaternion::Quaternion(const Vec3& axis, float angle)
|
||||
{
|
||||
set(axis, angle);
|
||||
}
|
||||
|
||||
Quaternion::Quaternion(const Quaternion& copy)
|
||||
{
|
||||
set(copy);
|
||||
}
|
||||
|
||||
Quaternion::~Quaternion()
|
||||
{
|
||||
}
|
||||
|
||||
const Quaternion& Quaternion::identity()
|
||||
{
|
||||
static Quaternion value(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
return value;
|
||||
}
|
||||
|
||||
const Quaternion& Quaternion::zero()
|
||||
{
|
||||
static Quaternion value(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
return value;
|
||||
}
|
||||
|
||||
bool Quaternion::isIdentity() const
|
||||
{
|
||||
return x == 0.0f && y == 0.0f && z == 0.0f && w == 1.0f;
|
||||
}
|
||||
|
||||
bool Quaternion::isZero() const
|
||||
{
|
||||
return x == 0.0f && y == 0.0f && z == 0.0f && w == 0.0f;
|
||||
}
|
||||
|
||||
void Quaternion::createFromRotationMatrix(const Mat4& m, Quaternion* dst)
|
||||
{
|
||||
m.getRotation(dst);
|
||||
}
|
||||
|
||||
void Quaternion::createFromAxisAngle(const Vec3& axis, float angle, Quaternion* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
float halfAngle = angle * 0.5f;
|
||||
float sinHalfAngle = sinf(halfAngle);
|
||||
|
||||
Vec3 normal(axis);
|
||||
normal.normalize();
|
||||
dst->x = normal.x * sinHalfAngle;
|
||||
dst->y = normal.y * sinHalfAngle;
|
||||
dst->z = normal.z * sinHalfAngle;
|
||||
dst->w = cosf(halfAngle);
|
||||
}
|
||||
|
||||
void Quaternion::conjugate()
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
z = -z;
|
||||
//w = w;
|
||||
}
|
||||
|
||||
Quaternion Quaternion::getConjugated() const
|
||||
{
|
||||
Quaternion q(*this);
|
||||
q.conjugate();
|
||||
return q;
|
||||
}
|
||||
|
||||
bool Quaternion::inverse()
|
||||
{
|
||||
float n = x * x + y * y + z * z + w * w;
|
||||
if (n == 1.0f)
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
z = -z;
|
||||
//w = w;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Too close to zero.
|
||||
if (n < 0.000001f)
|
||||
return false;
|
||||
|
||||
n = 1.0f / n;
|
||||
x = -x * n;
|
||||
y = -y * n;
|
||||
z = -z * n;
|
||||
w = w * n;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Quaternion Quaternion::getInversed() const
|
||||
{
|
||||
Quaternion q(*this);
|
||||
q.inverse();
|
||||
return q;
|
||||
}
|
||||
|
||||
void Quaternion::multiply(const Quaternion& q)
|
||||
{
|
||||
multiply(*this, q, this);
|
||||
}
|
||||
|
||||
void Quaternion::multiply(const Quaternion& q1, const Quaternion& q2, Quaternion* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
float x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y;
|
||||
float y = q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x;
|
||||
float z = q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w;
|
||||
float w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z;
|
||||
|
||||
dst->x = x;
|
||||
dst->y = y;
|
||||
dst->z = z;
|
||||
dst->w = w;
|
||||
}
|
||||
|
||||
void Quaternion::normalize()
|
||||
{
|
||||
float n = x * x + y * y + z * z + w * w;
|
||||
|
||||
// Already normalized.
|
||||
if (n == 1.0f)
|
||||
return;
|
||||
|
||||
n = std::sqrt(n);
|
||||
// Too close to zero.
|
||||
if (n < 0.000001f)
|
||||
return;
|
||||
|
||||
n = 1.0f / n;
|
||||
x *= n;
|
||||
y *= n;
|
||||
z *= n;
|
||||
w *= n;
|
||||
}
|
||||
|
||||
Quaternion Quaternion::getNormalized() const
|
||||
{
|
||||
Quaternion q(*this);
|
||||
q.normalize();
|
||||
return q;
|
||||
}
|
||||
|
||||
void Quaternion::set(float xx, float yy, float zz, float ww)
|
||||
{
|
||||
this->x = xx;
|
||||
this->y = yy;
|
||||
this->z = zz;
|
||||
this->w = ww;
|
||||
}
|
||||
|
||||
void Quaternion::set(float* array)
|
||||
{
|
||||
GP_ASSERT(array);
|
||||
|
||||
x = array[0];
|
||||
y = array[1];
|
||||
z = array[2];
|
||||
w = array[3];
|
||||
}
|
||||
|
||||
void Quaternion::set(const Mat4& m)
|
||||
{
|
||||
Quaternion::createFromRotationMatrix(m, this);
|
||||
}
|
||||
|
||||
void Quaternion::set(const Vec3& axis, float angle)
|
||||
{
|
||||
Quaternion::createFromAxisAngle(axis, angle, this);
|
||||
}
|
||||
|
||||
void Quaternion::set(const Quaternion& q)
|
||||
{
|
||||
this->x = q.x;
|
||||
this->y = q.y;
|
||||
this->z = q.z;
|
||||
this->w = q.w;
|
||||
}
|
||||
|
||||
void Quaternion::setIdentity()
|
||||
{
|
||||
x = 0.0f;
|
||||
y = 0.0f;
|
||||
z = 0.0f;
|
||||
w = 1.0f;
|
||||
}
|
||||
|
||||
float Quaternion::toAxisAngle(Vec3* axis) const
|
||||
{
|
||||
GP_ASSERT(axis);
|
||||
|
||||
Quaternion q(x, y, z, w);
|
||||
q.normalize();
|
||||
axis->x = q.x;
|
||||
axis->y = q.y;
|
||||
axis->z = q.z;
|
||||
axis->normalize();
|
||||
|
||||
return (2.0f * std::acos(q.w));
|
||||
}
|
||||
|
||||
void Quaternion::toEuler(Vec3* e) const
|
||||
{
|
||||
toEuler(*this, e);
|
||||
}
|
||||
|
||||
void Quaternion::toEuler(const Quaternion& q, Vec3* e, bool outerZ)
|
||||
{
|
||||
float bank = 0;
|
||||
float heading = 0;
|
||||
float attitude = 0;
|
||||
const float test = q.x * q.y + q.z * q.w;
|
||||
if (test > 0.499999) {
|
||||
bank = 0; // default to zero
|
||||
heading = CC_RADIANS_TO_DEGREES(2 * atan2(q.x, q.w));
|
||||
attitude = 90;
|
||||
}
|
||||
else if (test < -0.499999) {
|
||||
bank = 0; // default to zero
|
||||
heading = -CC_RADIANS_TO_DEGREES(2 * atan2(q.x, q.w));
|
||||
attitude = -90;
|
||||
}
|
||||
else {
|
||||
const float sqx = q.x * q.x;
|
||||
const float sqy = q.y * q.y;
|
||||
const float sqz = q.z * q.z;
|
||||
bank = CC_RADIANS_TO_DEGREES(atan2(2 * q.x * q.w - 2 * q.y * q.z, 1 - 2 * sqx - 2 * sqz));
|
||||
heading = CC_RADIANS_TO_DEGREES(atan2(2 * q.y * q.w - 2 * q.x * q.z, 1 - 2 * sqy - 2 * sqz));
|
||||
attitude = CC_RADIANS_TO_DEGREES(asin(2 * test));
|
||||
if (outerZ) {
|
||||
bank = -180 * CC_SIGN(bank + 1e-6) + bank;
|
||||
heading = -180 * CC_SIGN(heading + 1e-6) + heading;
|
||||
attitude = 180 * CC_SIGN(attitude + 1e-6) - attitude;
|
||||
}
|
||||
}
|
||||
e->x = bank;
|
||||
e->y = heading;
|
||||
e->z = attitude;
|
||||
}
|
||||
|
||||
void Quaternion::lerp(const Quaternion& q1, const Quaternion& q2, float t, Quaternion* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
GP_ASSERT(!(t < 0.0f || t > 1.0f));
|
||||
|
||||
if (t == 0.0f)
|
||||
{
|
||||
memcpy(dst, &q1, sizeof(float) * 4);
|
||||
return;
|
||||
}
|
||||
else if (t == 1.0f)
|
||||
{
|
||||
memcpy(dst, &q2, sizeof(float) * 4);
|
||||
return;
|
||||
}
|
||||
|
||||
float t1 = 1.0f - t;
|
||||
|
||||
dst->x = t1 * q1.x + t * q2.x;
|
||||
dst->y = t1 * q1.y + t * q2.y;
|
||||
dst->z = t1 * q1.z + t * q2.z;
|
||||
dst->w = t1 * q1.w + t * q2.w;
|
||||
}
|
||||
|
||||
void Quaternion::slerp(const Quaternion& q1, const Quaternion& q2, float t, Quaternion* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
slerp(q1.x, q1.y, q1.z, q1.w, q2.x, q2.y, q2.z, q2.w, t, &dst->x, &dst->y, &dst->z, &dst->w);
|
||||
}
|
||||
|
||||
void Quaternion::squad(const Quaternion& q1, const Quaternion& q2, const Quaternion& s1, const Quaternion& s2, float t, Quaternion* dst)
|
||||
{
|
||||
GP_ASSERT(!(t < 0.0f || t > 1.0f));
|
||||
|
||||
Quaternion dstQ(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
Quaternion dstS(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
slerpForSquad(q1, q2, t, &dstQ);
|
||||
slerpForSquad(s1, s2, t, &dstS);
|
||||
slerpForSquad(dstQ, dstS, 2.0f * t * (1.0f - t), dst);
|
||||
}
|
||||
|
||||
void Quaternion::slerp(float q1x, float q1y, float q1z, float q1w, float q2x, float q2y, float q2z, float q2w, float t, float* dstx, float* dsty, float* dstz, float* dstw)
|
||||
{
|
||||
// Fast slerp implementation by kwhatmough:
|
||||
// It contains no division operations, no trig, no inverse trig
|
||||
// and no sqrt. Not only does this code tolerate small constraint
|
||||
// errors in the input quaternions, it actually corrects for them.
|
||||
GP_ASSERT(dstx && dsty && dstz && dstw);
|
||||
GP_ASSERT(!(t < 0.0f || t > 1.0f));
|
||||
|
||||
if (t == 0.0f)
|
||||
{
|
||||
*dstx = q1x;
|
||||
*dsty = q1y;
|
||||
*dstz = q1z;
|
||||
*dstw = q1w;
|
||||
return;
|
||||
}
|
||||
else if (t == 1.0f)
|
||||
{
|
||||
*dstx = q2x;
|
||||
*dsty = q2y;
|
||||
*dstz = q2z;
|
||||
*dstw = q2w;
|
||||
return;
|
||||
}
|
||||
|
||||
if (q1x == q2x && q1y == q2y && q1z == q2z && q1w == q2w)
|
||||
{
|
||||
*dstx = q1x;
|
||||
*dsty = q1y;
|
||||
*dstz = q1z;
|
||||
*dstw = q1w;
|
||||
return;
|
||||
}
|
||||
|
||||
float halfY, alpha, beta;
|
||||
float u, f1, f2a, f2b;
|
||||
float ratio1, ratio2;
|
||||
float halfSecHalfTheta, versHalfTheta;
|
||||
float sqNotU, sqU;
|
||||
|
||||
float cosTheta = q1w * q2w + q1x * q2x + q1y * q2y + q1z * q2z;
|
||||
|
||||
// As usual in all slerp implementations, we fold theta.
|
||||
alpha = cosTheta >= 0 ? 1.0f : -1.0f;
|
||||
halfY = 1.0f + alpha * cosTheta;
|
||||
|
||||
// Here we bisect the interval, so we need to fold t as well.
|
||||
f2b = t - 0.5f;
|
||||
u = f2b >= 0 ? f2b : -f2b;
|
||||
f2a = u - f2b;
|
||||
f2b += u;
|
||||
u += u;
|
||||
f1 = 1.0f - u;
|
||||
|
||||
// One iteration of Newton to get 1-cos(theta / 2) to good accuracy.
|
||||
halfSecHalfTheta = 1.09f - (0.476537f - 0.0903321f * halfY) * halfY;
|
||||
halfSecHalfTheta *= 1.5f - halfY * halfSecHalfTheta * halfSecHalfTheta;
|
||||
versHalfTheta = 1.0f - halfY * halfSecHalfTheta;
|
||||
|
||||
// Evaluate series expansions of the coefficients.
|
||||
sqNotU = f1 * f1;
|
||||
ratio2 = 0.0000440917108f * versHalfTheta;
|
||||
ratio1 = -0.00158730159f + (sqNotU - 16.0f) * ratio2;
|
||||
ratio1 = 0.0333333333f + ratio1 * (sqNotU - 9.0f) * versHalfTheta;
|
||||
ratio1 = -0.333333333f + ratio1 * (sqNotU - 4.0f) * versHalfTheta;
|
||||
ratio1 = 1.0f + ratio1 * (sqNotU - 1.0f) * versHalfTheta;
|
||||
|
||||
sqU = u * u;
|
||||
ratio2 = -0.00158730159f + (sqU - 16.0f) * ratio2;
|
||||
ratio2 = 0.0333333333f + ratio2 * (sqU - 9.0f) * versHalfTheta;
|
||||
ratio2 = -0.333333333f + ratio2 * (sqU - 4.0f) * versHalfTheta;
|
||||
ratio2 = 1.0f + ratio2 * (sqU - 1.0f) * versHalfTheta;
|
||||
|
||||
// Perform the bisection and resolve the folding done earlier.
|
||||
f1 *= ratio1 * halfSecHalfTheta;
|
||||
f2a *= ratio2;
|
||||
f2b *= ratio2;
|
||||
alpha *= f1 + f2a;
|
||||
beta = f1 + f2b;
|
||||
|
||||
// Apply final coefficients to a and b as usual.
|
||||
float w = alpha * q1w + beta * q2w;
|
||||
float x = alpha * q1x + beta * q2x;
|
||||
float y = alpha * q1y + beta * q2y;
|
||||
float z = alpha * q1z + beta * q2z;
|
||||
|
||||
// This final adjustment to the quaternion's length corrects for
|
||||
// any small constraint error in the inputs q1 and q2 But as you
|
||||
// can see, it comes at the cost of 9 additional multiplication
|
||||
// operations. If this error-correcting feature is not required,
|
||||
// the following code may be removed.
|
||||
f1 = 1.5f - 0.5f * (w * w + x * x + y * y + z * z);
|
||||
*dstw = w * f1;
|
||||
*dstx = x * f1;
|
||||
*dsty = y * f1;
|
||||
*dstz = z * f1;
|
||||
}
|
||||
|
||||
void Quaternion::slerpForSquad(const Quaternion& q1, const Quaternion& q2, float t, Quaternion* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
// cos(omega) = q1 * q2;
|
||||
// slerp(q1, q2, t) = (q1*sin((1-t)*omega) + q2*sin(t*omega))/sin(omega);
|
||||
// q1 = +- q2, slerp(q1,q2,t) = q1.
|
||||
// This is a straight-forward implementation of the formula of slerp. It does not do any sign switching.
|
||||
float c = q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w;
|
||||
|
||||
if (std::abs(c) >= 1.0f)
|
||||
{
|
||||
dst->x = q1.x;
|
||||
dst->y = q1.y;
|
||||
dst->z = q1.z;
|
||||
dst->w = q1.w;
|
||||
return;
|
||||
}
|
||||
|
||||
float omega = std::acos(c);
|
||||
float s = std::sqrt(1.0f - c * c);
|
||||
if (std::abs(s) <= 0.00001f)
|
||||
{
|
||||
dst->x = q1.x;
|
||||
dst->y = q1.y;
|
||||
dst->z = q1.z;
|
||||
dst->w = q1.w;
|
||||
return;
|
||||
}
|
||||
|
||||
float r1 = std::sin((1 - t) * omega) / s;
|
||||
float r2 = std::sin(t * omega) / s;
|
||||
dst->x = (q1.x * r1 + q2.x * r2);
|
||||
dst->y = (q1.y * r1 + q2.y * r2);
|
||||
dst->z = (q1.z * r1 + q2.z * r2);
|
||||
dst->w = (q1.w * r1 + q2.w * r2);
|
||||
}
|
||||
|
||||
NS_CC_MATH_END
|
||||
435
cocos2d-x/cocos/math/Quaternion.h
Normal file
435
cocos2d-x/cocos/math/Quaternion.h
Normal file
@@ -0,0 +1,435 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
|
||||
#ifndef QUATERNION_H_
|
||||
#define QUATERNION_H_
|
||||
|
||||
#include "math/Vec3.h"
|
||||
#include "math/Mat4.h"
|
||||
//#include "Plane.h"
|
||||
|
||||
/**
|
||||
* @addtogroup base
|
||||
* @{
|
||||
*/
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
class Mat4;
|
||||
|
||||
/**
|
||||
* Defines a 4-element quaternion that represents the orientation of an object in space.
|
||||
*
|
||||
* Quaternions are typically used as a replacement for euler angles and rotation matrices as a way to achieve smooth interpolation and avoid gimbal lock.
|
||||
*
|
||||
* Note that this quaternion class does not automatically keep the quaternion normalized. Therefore, care must be taken to normalize the quaternion when necessary, by calling the normalize method.
|
||||
* This class provides three methods for doing quaternion interpolation: lerp, slerp, and squad.
|
||||
*
|
||||
* lerp (linear interpolation): the interpolation curve gives a straight line in quaternion space. It is simple and fast to compute. The only problem is that it does not provide constant angular velocity. Note that a constant velocity is not necessarily a requirement for a curve;
|
||||
* slerp (spherical linear interpolation): the interpolation curve forms a great arc on the quaternion unit sphere. Slerp provides constant angular velocity;
|
||||
* squad (spherical spline interpolation): interpolating between a series of rotations using slerp leads to the following problems:
|
||||
* - the curve is not smooth at the control points;
|
||||
* - the angular velocity is not constant;
|
||||
* - the angular velocity is not continuous at the control points.
|
||||
*
|
||||
* Since squad is continuously differentiable, it remedies the first and third problems mentioned above.
|
||||
* The slerp method provided here is intended for interpolation of principal rotations. It treats +q and -q as the same principal rotation and is at liberty to use the negative of either input. The resulting path is always the shorter arc.
|
||||
*
|
||||
* The lerp method provided here interpolates strictly in quaternion space. Note that the resulting path may pass through the origin if interpolating between a quaternion and its exact negative.
|
||||
*
|
||||
* As an example, consider the following quaternions:
|
||||
*
|
||||
* q1 = (0.6, 0.8, 0.0, 0.0),
|
||||
* q2 = (0.0, 0.6, 0.8, 0.0),
|
||||
* q3 = (0.6, 0.0, 0.8, 0.0), and
|
||||
* q4 = (-0.8, 0.0, -0.6, 0.0).
|
||||
* For the point p = (1.0, 1.0, 1.0), the following figures show the trajectories of p using lerp, slerp, and squad.
|
||||
*/
|
||||
class CC_DLL Quaternion
|
||||
{
|
||||
friend class Curve;
|
||||
friend class Transform;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* The x-value of the quaternion's vector component.
|
||||
*/
|
||||
float x;
|
||||
/**
|
||||
* The y-value of the quaternion's vector component.
|
||||
*/
|
||||
float y;
|
||||
/**
|
||||
* The z-value of the quaternion's vector component.
|
||||
*/
|
||||
float z;
|
||||
/**
|
||||
* The scalar component of the quaternion.
|
||||
*/
|
||||
float w;
|
||||
|
||||
/**
|
||||
* Constructs a quaternion initialized to (0, 0, 0, 1).
|
||||
*/
|
||||
Quaternion();
|
||||
|
||||
/**
|
||||
* Constructs a quaternion initialized to (0, 0, 0, 1).
|
||||
*
|
||||
* @param xx The x component of the quaternion.
|
||||
* @param yy The y component of the quaternion.
|
||||
* @param zz The z component of the quaternion.
|
||||
* @param ww The w component of the quaternion.
|
||||
*/
|
||||
Quaternion(float xx, float yy, float zz, float ww);
|
||||
|
||||
/**
|
||||
* Constructs a new quaternion from the values in the specified array.
|
||||
*
|
||||
* @param array The values for the new quaternion.
|
||||
*/
|
||||
Quaternion(float* array);
|
||||
|
||||
/**
|
||||
* Constructs a quaternion equal to the rotational part of the specified matrix.
|
||||
*
|
||||
* @param m The matrix.
|
||||
*/
|
||||
Quaternion(const Mat4& m);
|
||||
|
||||
/**
|
||||
* Constructs a quaternion equal to the rotation from the specified axis and angle.
|
||||
*
|
||||
* @param axis A vector describing the axis of rotation.
|
||||
* @param angle The angle of rotation (in radians).
|
||||
*/
|
||||
Quaternion(const Vec3& axis, float angle);
|
||||
|
||||
/**
|
||||
* Constructs a new quaternion that is a copy of the specified one.
|
||||
*
|
||||
* @param copy The quaternion to copy.
|
||||
*/
|
||||
Quaternion(const Quaternion& copy);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~Quaternion();
|
||||
|
||||
/**
|
||||
* Returns the identity quaternion.
|
||||
*
|
||||
* @return The identity quaternion.
|
||||
*/
|
||||
static const Quaternion& identity();
|
||||
|
||||
/**
|
||||
* Returns the quaternion with all zeros.
|
||||
*
|
||||
* @return The quaternion.
|
||||
*/
|
||||
static const Quaternion& zero();
|
||||
|
||||
/**
|
||||
* Determines if this quaternion is equal to the identity quaternion.
|
||||
*
|
||||
* @return true if it is the identity quaternion, false otherwise.
|
||||
*/
|
||||
bool isIdentity() const;
|
||||
|
||||
/**
|
||||
* Determines if this quaternion is all zeros.
|
||||
*
|
||||
* @return true if this quaternion is all zeros, false otherwise.
|
||||
*/
|
||||
bool isZero() const;
|
||||
|
||||
/**
|
||||
* Creates a quaternion equal to the rotational part of the specified matrix
|
||||
* and stores the result in dst.
|
||||
*
|
||||
* @param m The matrix.
|
||||
* @param dst A quaternion to store the conjugate in.
|
||||
*/
|
||||
static void createFromRotationMatrix(const Mat4& m, Quaternion* dst);
|
||||
|
||||
/**
|
||||
* Creates this quaternion equal to the rotation from the specified axis and angle
|
||||
* and stores the result in dst.
|
||||
*
|
||||
* @param axis A vector describing the axis of rotation.
|
||||
* @param angle The angle of rotation (in radians).
|
||||
* @param dst A quaternion to store the conjugate in.
|
||||
*/
|
||||
static void createFromAxisAngle(const Vec3& axis, float angle, Quaternion* dst);
|
||||
|
||||
/**
|
||||
* Sets this quaternion to the conjugate of itself.
|
||||
*/
|
||||
void conjugate();
|
||||
|
||||
/**
|
||||
* Gets the conjugate of this quaternion.
|
||||
*
|
||||
*/
|
||||
Quaternion getConjugated() const;
|
||||
|
||||
/**
|
||||
* Sets this quaternion to the inverse of itself.
|
||||
*
|
||||
* Note that the inverse of a quaternion is equal to its conjugate
|
||||
* when the quaternion is unit-length. For this reason, it is more
|
||||
* efficient to use the conjugate method directly when you know your
|
||||
* quaternion is already unit-length.
|
||||
*
|
||||
* @return true if the inverse can be computed, false otherwise.
|
||||
*/
|
||||
bool inverse();
|
||||
|
||||
/**
|
||||
* Gets the inverse of this quaternion.
|
||||
*
|
||||
* Note that the inverse of a quaternion is equal to its conjugate
|
||||
* when the quaternion is unit-length. For this reason, it is more
|
||||
* efficient to use the conjugate method directly when you know your
|
||||
* quaternion is already unit-length.
|
||||
*/
|
||||
Quaternion getInversed() const;
|
||||
|
||||
/**
|
||||
* Multiplies this quaternion by the specified one and stores the result in this quaternion.
|
||||
*
|
||||
* @param q The quaternion to multiply.
|
||||
*/
|
||||
void multiply(const Quaternion& q);
|
||||
|
||||
/**
|
||||
* Multiplies the specified quaternions and stores the result in dst.
|
||||
*
|
||||
* @param q1 The first quaternion.
|
||||
* @param q2 The second quaternion.
|
||||
* @param dst A quaternion to store the result in.
|
||||
*/
|
||||
static void multiply(const Quaternion& q1, const Quaternion& q2, Quaternion* dst);
|
||||
|
||||
/**
|
||||
* Normalizes this quaternion to have unit length.
|
||||
*
|
||||
* If the quaternion already has unit length or if the length
|
||||
* of the quaternion is zero, this method does nothing.
|
||||
*/
|
||||
void normalize();
|
||||
|
||||
/**
|
||||
* Get the normalized quaternion.
|
||||
*
|
||||
* If the quaternion already has unit length or if the length
|
||||
* of the quaternion is zero, this method simply copies
|
||||
* this vector.
|
||||
*/
|
||||
Quaternion getNormalized() const;
|
||||
|
||||
/**
|
||||
* Sets the elements of the quaternion to the specified values.
|
||||
*
|
||||
* @param xx The new x-value.
|
||||
* @param yy The new y-value.
|
||||
* @param zz The new z-value.
|
||||
* @param ww The new w-value.
|
||||
*/
|
||||
void set(float xx, float yy, float zz, float ww);
|
||||
|
||||
/**
|
||||
* Sets the elements of the quaternion from the values in the specified array.
|
||||
*
|
||||
* @param array An array containing the elements of the quaternion in the order x, y, z, w.
|
||||
*/
|
||||
void set(float* array);
|
||||
|
||||
/**
|
||||
* Sets the quaternion equal to the rotational part of the specified matrix.
|
||||
*
|
||||
* @param m The matrix.
|
||||
*/
|
||||
void set(const Mat4& m);
|
||||
|
||||
/**
|
||||
* Sets the quaternion equal to the rotation from the specified axis and angle.
|
||||
*
|
||||
* @param axis The axis of rotation.
|
||||
* @param angle The angle of rotation (in radians).
|
||||
*/
|
||||
void set(const Vec3& axis, float angle);
|
||||
|
||||
/**
|
||||
* Sets the elements of this quaternion to a copy of the specified quaternion.
|
||||
*
|
||||
* @param q The quaternion to copy.
|
||||
*/
|
||||
void set(const Quaternion& q);
|
||||
|
||||
/**
|
||||
* Sets this quaternion to be equal to the identity quaternion.
|
||||
*/
|
||||
void setIdentity();
|
||||
|
||||
/**
|
||||
* Converts this Quaternion4f to axis-angle notation. The axis is normalized.
|
||||
*
|
||||
* @param e The Vec3f which stores the axis.
|
||||
*
|
||||
* @return The angle (in radians).
|
||||
*/
|
||||
float toAxisAngle(Vec3* e) const;
|
||||
|
||||
/**
|
||||
* Converts this Quaternion4f to euler angle.
|
||||
*
|
||||
* @param e The Vec3f which stores the euler angle.
|
||||
*/
|
||||
void toEuler(Vec3* e) const;
|
||||
|
||||
/**
|
||||
* Converts this Quaternion4f to euler angle.
|
||||
*
|
||||
* @param e The Vec3f which stores the euler angle.
|
||||
*/
|
||||
static void toEuler(const Quaternion& q, Vec3* e, bool outerZ = false);
|
||||
|
||||
/**
|
||||
* Interpolates between two quaternions using linear interpolation.
|
||||
*
|
||||
* The interpolation curve for linear interpolation between
|
||||
* quaternions gives a straight line in quaternion space.
|
||||
*
|
||||
* @param q1 The first quaternion.
|
||||
* @param q2 The second quaternion.
|
||||
* @param t The interpolation coefficient.
|
||||
* @param dst A quaternion to store the result in.
|
||||
*/
|
||||
static void lerp(const Quaternion& q1, const Quaternion& q2, float t, Quaternion* dst);
|
||||
|
||||
/**
|
||||
* Interpolates between two quaternions using spherical linear interpolation.
|
||||
*
|
||||
* Spherical linear interpolation provides smooth transitions between different
|
||||
* orientations and is often useful for animating models or cameras in 3D.
|
||||
*
|
||||
* Note: For accurate interpolation, the input quaternions must be at (or close to) unit length.
|
||||
* This method does not automatically normalize the input quaternions, so it is up to the
|
||||
* caller to ensure they call normalize beforehand, if necessary.
|
||||
*
|
||||
* @param q1 The first quaternion.
|
||||
* @param q2 The second quaternion.
|
||||
* @param t The interpolation coefficient.
|
||||
* @param dst A quaternion to store the result in.
|
||||
*/
|
||||
static void slerp(const Quaternion& q1, const Quaternion& q2, float t, Quaternion* dst);
|
||||
|
||||
/**
|
||||
* Interpolates over a series of quaternions using spherical spline interpolation.
|
||||
*
|
||||
* Spherical spline interpolation provides smooth transitions between different
|
||||
* orientations and is often useful for animating models or cameras in 3D.
|
||||
*
|
||||
* Note: For accurate interpolation, the input quaternions must be unit.
|
||||
* This method does not automatically normalize the input quaternions,
|
||||
* so it is up to the caller to ensure they call normalize beforehand, if necessary.
|
||||
*
|
||||
* @param q1 The first quaternion.
|
||||
* @param q2 The second quaternion.
|
||||
* @param s1 The first control point.
|
||||
* @param s2 The second control point.
|
||||
* @param t The interpolation coefficient.
|
||||
* @param dst A quaternion to store the result in.
|
||||
*/
|
||||
static void squad(const Quaternion& q1, const Quaternion& q2, const Quaternion& s1, const Quaternion& s2, float t, Quaternion* dst);
|
||||
|
||||
/**
|
||||
* Calculates the quaternion product of this quaternion with the given quaternion.
|
||||
*
|
||||
* Note: this does not modify this quaternion.
|
||||
*
|
||||
* @param q The quaternion to multiply.
|
||||
* @return The quaternion product.
|
||||
*/
|
||||
inline const Quaternion operator*(const Quaternion& q) const;
|
||||
|
||||
/**
|
||||
* Calculates the quaternion product of this quaternion with the given vec3.
|
||||
* @param v The vec3 to multiply.
|
||||
* @return The vec3 product.
|
||||
*/
|
||||
inline Vec3 operator*(const Vec3& v) const;
|
||||
|
||||
/**
|
||||
* Multiplies this quaternion with the given quaternion.
|
||||
*
|
||||
* @param q The quaternion to multiply.
|
||||
* @return This quaternion, after the multiplication occurs.
|
||||
*/
|
||||
inline Quaternion& operator*=(const Quaternion& q);
|
||||
|
||||
/** equals to Quaternion(0,0,0, 0) */
|
||||
static const Quaternion ZERO;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Interpolates between two quaternions using spherical linear interpolation.
|
||||
*
|
||||
* Spherical linear interpolation provides smooth transitions between different
|
||||
* orientations and is often useful for animating models or cameras in 3D.
|
||||
*
|
||||
* Note: For accurate interpolation, the input quaternions must be at (or close to) unit length.
|
||||
* This method does not automatically normalize the input quaternions, so it is up to the
|
||||
* caller to ensure they call normalize beforehand, if necessary.
|
||||
*
|
||||
* @param q1x The x component of the first quaternion.
|
||||
* @param q1y The y component of the first quaternion.
|
||||
* @param q1z The z component of the first quaternion.
|
||||
* @param q1w The w component of the first quaternion.
|
||||
* @param q2x The x component of the second quaternion.
|
||||
* @param q2y The y component of the second quaternion.
|
||||
* @param q2z The z component of the second quaternion.
|
||||
* @param q2w The w component of the second quaternion.
|
||||
* @param t The interpolation coefficient.
|
||||
* @param dstx A pointer to store the x component of the slerp in.
|
||||
* @param dsty A pointer to store the y component of the slerp in.
|
||||
* @param dstz A pointer to store the z component of the slerp in.
|
||||
* @param dstw A pointer to store the w component of the slerp in.
|
||||
*/
|
||||
static void slerp(float q1x, float q1y, float q1z, float q1w, float q2x, float q2y, float q2z, float q2w, float t, float* dstx, float* dsty, float* dstz, float* dstw);
|
||||
|
||||
static void slerpForSquad(const Quaternion& q1, const Quaternion& q2, float t, Quaternion* dst);
|
||||
};
|
||||
|
||||
NS_CC_MATH_END
|
||||
/**
|
||||
end of base group
|
||||
@}
|
||||
*/
|
||||
#include "math/Quaternion.inl"
|
||||
|
||||
#endif
|
||||
51
cocos2d-x/cocos/math/Quaternion.inl
Normal file
51
cocos2d-x/cocos/math/Quaternion.inl
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
|
||||
#include "math/Quaternion.h"
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
inline const Quaternion Quaternion::operator*(const Quaternion& q) const
|
||||
{
|
||||
Quaternion result(*this);
|
||||
result.multiply(q);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline Quaternion& Quaternion::operator*=(const Quaternion& q)
|
||||
{
|
||||
multiply(q);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vec3 Quaternion::operator*(const Vec3& v) const
|
||||
{
|
||||
Vec3 uv, uuv;
|
||||
Vec3 qvec(x, y, z);
|
||||
Vec3::cross(qvec, v, &uv);
|
||||
Vec3::cross(qvec, uv, &uuv);
|
||||
|
||||
uv *= (2.0f * w);
|
||||
uuv *= 2.0f;
|
||||
|
||||
return v + uv + uuv;
|
||||
}
|
||||
|
||||
NS_CC_MATH_END
|
||||
350
cocos2d-x/cocos/math/Vec2.cpp
Normal file
350
cocos2d-x/cocos/math/Vec2.cpp
Normal file
@@ -0,0 +1,350 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
|
||||
#include "math/Vec2.h"
|
||||
#include "math/MathUtil.h"
|
||||
#include "base/ccMacros.h"
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
// returns true if segment A-B intersects with segment C-D. S->E is the overlap part
|
||||
bool isOneDimensionSegmentOverlap(float A, float B, float C, float D, float *S, float * E)
|
||||
{
|
||||
float ABmin = std::min(A, B);
|
||||
float ABmax = std::max(A, B);
|
||||
float CDmin = std::min(C, D);
|
||||
float CDmax = std::max(C, D);
|
||||
|
||||
if (ABmax < CDmin || CDmax < ABmin)
|
||||
{
|
||||
// ABmin->ABmax->CDmin->CDmax or CDmin->CDmax->ABmin->ABmax
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ABmin >= CDmin && ABmin <= CDmax)
|
||||
{
|
||||
// CDmin->ABmin->CDmax->ABmax or CDmin->ABmin->ABmax->CDmax
|
||||
if (S != nullptr) *S = ABmin;
|
||||
if (E != nullptr) *E = CDmax < ABmax ? CDmax : ABmax;
|
||||
}
|
||||
else if (ABmax >= CDmin && ABmax <= CDmax)
|
||||
{
|
||||
// ABmin->CDmin->ABmax->CDmax
|
||||
if (S != nullptr) *S = CDmin;
|
||||
if (E != nullptr) *E = ABmax;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ABmin->CDmin->CDmax->ABmax
|
||||
if (S != nullptr) *S = CDmin;
|
||||
if (E != nullptr) *E = CDmax;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// cross product of 2 vector. A->B X C->D
|
||||
float crossProduct2Vector(const Vec2& A, const Vec2& B, const Vec2& C, const Vec2& D)
|
||||
{
|
||||
return (D.y - C.y) * (B.x - A.x) - (D.x - C.x) * (B.y - A.y);
|
||||
}
|
||||
|
||||
float Vec2::angle(const Vec2& v1, const Vec2& v2)
|
||||
{
|
||||
float dz = v1.x * v2.y - v1.y * v2.x;
|
||||
return atan2f(fabsf(dz) + MATH_FLOAT_SMALL, dot(v1, v2));
|
||||
}
|
||||
|
||||
void Vec2::add(const Vec2& v1, const Vec2& v2, Vec2* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
dst->x = v1.x + v2.x;
|
||||
dst->y = v1.y + v2.y;
|
||||
}
|
||||
|
||||
void Vec2::clamp(const Vec2& min, const Vec2& max)
|
||||
{
|
||||
GP_ASSERT(!(min.x > max.x || min.y > max.y ));
|
||||
|
||||
// Clamp the x value.
|
||||
if (x < min.x)
|
||||
x = min.x;
|
||||
if (x > max.x)
|
||||
x = max.x;
|
||||
|
||||
// Clamp the y value.
|
||||
if (y < min.y)
|
||||
y = min.y;
|
||||
if (y > max.y)
|
||||
y = max.y;
|
||||
}
|
||||
|
||||
void Vec2::clamp(const Vec2& v, const Vec2& min, const Vec2& max, Vec2* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
GP_ASSERT(!(min.x > max.x || min.y > max.y ));
|
||||
|
||||
// Clamp the x value.
|
||||
dst->x = v.x;
|
||||
if (dst->x < min.x)
|
||||
dst->x = min.x;
|
||||
if (dst->x > max.x)
|
||||
dst->x = max.x;
|
||||
|
||||
// Clamp the y value.
|
||||
dst->y = v.y;
|
||||
if (dst->y < min.y)
|
||||
dst->y = min.y;
|
||||
if (dst->y > max.y)
|
||||
dst->y = max.y;
|
||||
}
|
||||
|
||||
float Vec2::distance(const Vec2& v) const
|
||||
{
|
||||
float dx = v.x - x;
|
||||
float dy = v.y - y;
|
||||
|
||||
return std::sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
float Vec2::dot(const Vec2& v1, const Vec2& v2)
|
||||
{
|
||||
return (v1.x * v2.x + v1.y * v2.y);
|
||||
}
|
||||
|
||||
float Vec2::length() const
|
||||
{
|
||||
return std::sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
void Vec2::normalize()
|
||||
{
|
||||
float n = x * x + y * y;
|
||||
// Already normalized.
|
||||
if (n == 1.0f)
|
||||
return;
|
||||
|
||||
n = std::sqrt(n);
|
||||
// Too close to zero.
|
||||
if (n < MATH_TOLERANCE)
|
||||
return;
|
||||
|
||||
n = 1.0f / n;
|
||||
x *= n;
|
||||
y *= n;
|
||||
}
|
||||
|
||||
Vec2 Vec2::getNormalized() const
|
||||
{
|
||||
Vec2 v(*this);
|
||||
v.normalize();
|
||||
return v;
|
||||
}
|
||||
|
||||
void Vec2::rotate(const Vec2& point, float angle)
|
||||
{
|
||||
float sinAngle = std::sin(angle);
|
||||
float cosAngle = std::cos(angle);
|
||||
|
||||
if (point.isZero())
|
||||
{
|
||||
float tempX = x * cosAngle - y * sinAngle;
|
||||
y = y * cosAngle + x * sinAngle;
|
||||
x = tempX;
|
||||
}
|
||||
else
|
||||
{
|
||||
float tempX = x - point.x;
|
||||
float tempY = y - point.y;
|
||||
|
||||
x = tempX * cosAngle - tempY * sinAngle + point.x;
|
||||
y = tempY * cosAngle + tempX * sinAngle + point.y;
|
||||
}
|
||||
}
|
||||
|
||||
void Vec2::set(const float* array)
|
||||
{
|
||||
GP_ASSERT(array);
|
||||
|
||||
x = array[0];
|
||||
y = array[1];
|
||||
}
|
||||
|
||||
void Vec2::subtract(const Vec2& v1, const Vec2& v2, Vec2* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
dst->x = v1.x - v2.x;
|
||||
dst->y = v1.y - v2.y;
|
||||
}
|
||||
|
||||
bool Vec2::equals(const Vec2& target) const
|
||||
{
|
||||
return (std::abs(this->x - target.x) < FLT_EPSILON)
|
||||
&& (std::abs(this->y - target.y) < FLT_EPSILON);
|
||||
}
|
||||
|
||||
bool Vec2::fuzzyEquals(const Vec2& b, float var) const
|
||||
{
|
||||
if(x - var <= b.x && b.x <= x + var)
|
||||
if(y - var <= b.y && b.y <= y + var)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
float Vec2::getAngle(const Vec2& other) const
|
||||
{
|
||||
Vec2 a2 = getNormalized();
|
||||
Vec2 b2 = other.getNormalized();
|
||||
float angle = atan2f(a2.cross(b2), a2.dot(b2));
|
||||
if (std::abs(angle) < FLT_EPSILON) return 0.f;
|
||||
return angle;
|
||||
}
|
||||
|
||||
Vec2 Vec2::rotateByAngle(const Vec2& pivot, float angle) const
|
||||
{
|
||||
return pivot + (*this - pivot).rotate(Vec2::forAngle(angle));
|
||||
}
|
||||
|
||||
bool Vec2::isLineIntersect(const Vec2& A, const Vec2& B,
|
||||
const Vec2& C, const Vec2& D,
|
||||
float *S, float *T)
|
||||
{
|
||||
// FAIL: Line undefined
|
||||
if ( (A.x==B.x && A.y==B.y) || (C.x==D.x && C.y==D.y) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const float denom = crossProduct2Vector(A, B, C, D);
|
||||
|
||||
if (denom == 0)
|
||||
{
|
||||
// Lines parallel or overlap
|
||||
return false;
|
||||
}
|
||||
|
||||
if (S != nullptr) *S = crossProduct2Vector(C, D, C, A) / denom;
|
||||
if (T != nullptr) *T = crossProduct2Vector(A, B, C, A) / denom;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Vec2::isLineParallel(const Vec2& A, const Vec2& B,
|
||||
const Vec2& C, const Vec2& D)
|
||||
{
|
||||
// FAIL: Line undefined
|
||||
if ( (A.x==B.x && A.y==B.y) || (C.x==D.x && C.y==D.y) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (crossProduct2Vector(A, B, C, D) == 0)
|
||||
{
|
||||
// line overlap
|
||||
if (crossProduct2Vector(C, D, C, A) == 0 || crossProduct2Vector(A, B, C, A) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Vec2::isLineOverlap(const Vec2& A, const Vec2& B,
|
||||
const Vec2& C, const Vec2& D)
|
||||
{
|
||||
// FAIL: Line undefined
|
||||
if ( (A.x==B.x && A.y==B.y) || (C.x==D.x && C.y==D.y) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (crossProduct2Vector(A, B, C, D) == 0 &&
|
||||
(crossProduct2Vector(C, D, C, A) == 0 || crossProduct2Vector(A, B, C, A) == 0))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Vec2::isSegmentOverlap(const Vec2& A, const Vec2& B, const Vec2& C, const Vec2& D, Vec2* S, Vec2* E)
|
||||
{
|
||||
|
||||
if (isLineOverlap(A, B, C, D))
|
||||
{
|
||||
return isOneDimensionSegmentOverlap(A.x, B.x, C.x, D.x, &S->x, &E->x) &&
|
||||
isOneDimensionSegmentOverlap(A.y, B.y, C.y, D.y, &S->y, &E->y);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Vec2::isSegmentIntersect(const Vec2& A, const Vec2& B, const Vec2& C, const Vec2& D)
|
||||
{
|
||||
float S, T;
|
||||
|
||||
if (isLineIntersect(A, B, C, D, &S, &T )&&
|
||||
(S >= 0.0f && S <= 1.0f && T >= 0.0f && T <= 1.0f))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Vec2 Vec2::getIntersectPoint(const Vec2& A, const Vec2& B, const Vec2& C, const Vec2& D)
|
||||
{
|
||||
float S, T;
|
||||
|
||||
if (isLineIntersect(A, B, C, D, &S, &T))
|
||||
{
|
||||
// Vec2 of intersection
|
||||
Vec2 P;
|
||||
P.x = A.x + S * (B.x - A.x);
|
||||
P.y = A.y + S * (B.y - A.y);
|
||||
return P;
|
||||
}
|
||||
|
||||
return Vec2::ZERO;
|
||||
}
|
||||
|
||||
const Vec2 Vec2::ZERO(0.0f, 0.0f);
|
||||
const Vec2 Vec2::ONE(1.0f, 1.0f);
|
||||
const Vec2 Vec2::UNIT_X(1.0f, 0.0f);
|
||||
const Vec2 Vec2::UNIT_Y(0.0f, 1.0f);
|
||||
const Vec2 Vec2::ANCHOR_MIDDLE(0.5f, 0.5f);
|
||||
const Vec2 Vec2::ANCHOR_BOTTOM_LEFT(0.0f, 0.0f);
|
||||
const Vec2 Vec2::ANCHOR_TOP_LEFT(0.0f, 1.0f);
|
||||
const Vec2 Vec2::ANCHOR_BOTTOM_RIGHT(1.0f, 0.0f);
|
||||
const Vec2 Vec2::ANCHOR_TOP_RIGHT(1.0f, 1.0f);
|
||||
const Vec2 Vec2::ANCHOR_MIDDLE_RIGHT(1.0f, 0.5f);
|
||||
const Vec2 Vec2::ANCHOR_MIDDLE_LEFT(0.0f, 0.5f);
|
||||
const Vec2 Vec2::ANCHOR_MIDDLE_TOP(0.5f, 1.0f);
|
||||
const Vec2 Vec2::ANCHOR_MIDDLE_BOTTOM(0.5f, 0.0f);
|
||||
|
||||
NS_CC_MATH_END
|
||||
772
cocos2d-x/cocos/math/Vec2.h
Normal file
772
cocos2d-x/cocos/math/Vec2.h
Normal file
@@ -0,0 +1,772 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
|
||||
#ifndef MATH_VEC2_H
|
||||
#define MATH_VEC2_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <cmath>
|
||||
#include "math/CCMathBase.h"
|
||||
|
||||
/**
|
||||
* @addtogroup base
|
||||
* @{
|
||||
*/
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
/** Clamp a value between from and to.
|
||||
*/
|
||||
|
||||
inline float clampf(float value, float min_inclusive, float max_inclusive)
|
||||
{
|
||||
if (min_inclusive > max_inclusive) {
|
||||
std::swap(min_inclusive, max_inclusive);
|
||||
}
|
||||
return value < min_inclusive ? min_inclusive : value < max_inclusive? value : max_inclusive;
|
||||
}
|
||||
|
||||
class Mat4;
|
||||
|
||||
/**
|
||||
* Defines a 2-element floating point vector.
|
||||
*/
|
||||
class CC_DLL Vec2
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* The x coordinate.
|
||||
*/
|
||||
float x;
|
||||
|
||||
/**
|
||||
* The y coordinate.
|
||||
*/
|
||||
float y;
|
||||
|
||||
/**
|
||||
* Constructs a new vector initialized to all zeros.
|
||||
*/
|
||||
Vec2();
|
||||
|
||||
/**
|
||||
* Constructs a new vector initialized to the specified values.
|
||||
*
|
||||
* @param xx The x coordinate.
|
||||
* @param yy The y coordinate.
|
||||
*/
|
||||
Vec2(float xx, float yy);
|
||||
|
||||
/**
|
||||
* Constructs a new vector from the values in the specified array.
|
||||
*
|
||||
* @param array An array containing the elements of the vector in the order x, y.
|
||||
*/
|
||||
Vec2(const float* array);
|
||||
|
||||
/**
|
||||
* Constructs a vector that describes the direction between the specified points.
|
||||
*
|
||||
* @param p1 The first point.
|
||||
* @param p2 The second point.
|
||||
*/
|
||||
Vec2(const Vec2& p1, const Vec2& p2);
|
||||
|
||||
/**
|
||||
* Constructs a new vector that is a copy of the specified vector.
|
||||
*
|
||||
* @param copy The vector to copy.
|
||||
*/
|
||||
Vec2(const Vec2& copy);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~Vec2();
|
||||
|
||||
/**
|
||||
* Indicates whether this vector contains all zeros.
|
||||
*
|
||||
* @return true if this vector contains all zeros, false otherwise.
|
||||
*/
|
||||
inline bool isZero() const;
|
||||
|
||||
/**
|
||||
* Indicates whether this vector contains all ones.
|
||||
*
|
||||
* @return true if this vector contains all ones, false otherwise.
|
||||
*/
|
||||
inline bool isOne() const;
|
||||
|
||||
/**
|
||||
* Returns the angle (in radians) between the specified vectors.
|
||||
*
|
||||
* @param v1 The first vector.
|
||||
* @param v2 The second vector.
|
||||
*
|
||||
* @return The angle between the two vectors (in radians).
|
||||
*/
|
||||
static float angle(const Vec2& v1, const Vec2& v2);
|
||||
|
||||
/**
|
||||
* Adds the elements of the specified vector to this one.
|
||||
*
|
||||
* @param v The vector to add.
|
||||
*/
|
||||
inline void add(const Vec2& v);
|
||||
|
||||
/**
|
||||
* Adds the specified vectors and stores the result in dst.
|
||||
*
|
||||
* @param v1 The first vector.
|
||||
* @param v2 The second vector.
|
||||
* @param dst A vector to store the result in.
|
||||
*/
|
||||
static void add(const Vec2& v1, const Vec2& v2, Vec2* dst);
|
||||
|
||||
/**
|
||||
* Clamps this vector within the specified range.
|
||||
*
|
||||
* @param min The minimum value.
|
||||
* @param max The maximum value.
|
||||
*/
|
||||
void clamp(const Vec2& min, const Vec2& max);
|
||||
|
||||
/**
|
||||
* Clamps the specified vector within the specified range and returns it in dst.
|
||||
*
|
||||
* @param v The vector to clamp.
|
||||
* @param min The minimum value.
|
||||
* @param max The maximum value.
|
||||
* @param dst A vector to store the result in.
|
||||
*/
|
||||
static void clamp(const Vec2& v, const Vec2& min, const Vec2& max, Vec2* dst);
|
||||
|
||||
/**
|
||||
* Returns the distance between this vector and v.
|
||||
*
|
||||
* @param v The other vector.
|
||||
*
|
||||
* @return The distance between this vector and v.
|
||||
*
|
||||
* @see distanceSquared
|
||||
*/
|
||||
float distance(const Vec2& v) const;
|
||||
|
||||
/**
|
||||
* Returns the squared distance between this vector and v.
|
||||
*
|
||||
* When it is not necessary to get the exact distance between
|
||||
* two vectors (for example, when simply comparing the
|
||||
* distance between different vectors), it is advised to use
|
||||
* this method instead of distance.
|
||||
*
|
||||
* @param v The other vector.
|
||||
*
|
||||
* @return The squared distance between this vector and v.
|
||||
*
|
||||
* @see distance
|
||||
*/
|
||||
inline float distanceSquared(const Vec2& v) const;
|
||||
|
||||
/**
|
||||
* Returns the dot product of this vector and the specified vector.
|
||||
*
|
||||
* @param v The vector to compute the dot product with.
|
||||
*
|
||||
* @return The dot product.
|
||||
*/
|
||||
inline float dot(const Vec2& v) const;
|
||||
|
||||
/**
|
||||
* Returns the dot product between the specified vectors.
|
||||
*
|
||||
* @param v1 The first vector.
|
||||
* @param v2 The second vector.
|
||||
*
|
||||
* @return The dot product between the vectors.
|
||||
*/
|
||||
static float dot(const Vec2& v1, const Vec2& v2);
|
||||
|
||||
/**
|
||||
* Computes the length of this vector.
|
||||
*
|
||||
* @return The length of the vector.
|
||||
*
|
||||
* @see lengthSquared
|
||||
*/
|
||||
float length() const;
|
||||
|
||||
/**
|
||||
* Returns the squared length of this vector.
|
||||
*
|
||||
* When it is not necessary to get the exact length of a
|
||||
* vector (for example, when simply comparing the lengths of
|
||||
* different vectors), it is advised to use this method
|
||||
* instead of length.
|
||||
*
|
||||
* @return The squared length of the vector.
|
||||
*
|
||||
* @see length
|
||||
*/
|
||||
inline float lengthSquared() const;
|
||||
|
||||
/**
|
||||
* Negates this vector.
|
||||
*/
|
||||
inline void negate();
|
||||
|
||||
/**
|
||||
* Normalizes this vector.
|
||||
*
|
||||
* This method normalizes this Vec2 so that it is of
|
||||
* unit length (in other words, the length of the vector
|
||||
* after calling this method will be 1.0f). If the vector
|
||||
* already has unit length or if the length of the vector
|
||||
* is zero, this method does nothing.
|
||||
*
|
||||
* @return This vector, after the normalization occurs.
|
||||
*/
|
||||
void normalize();
|
||||
|
||||
/**
|
||||
Get the normalized vector.
|
||||
*/
|
||||
Vec2 getNormalized() const;
|
||||
|
||||
/**
|
||||
* Scales all elements of this vector by the specified value.
|
||||
*
|
||||
* @param scalar The scalar value.
|
||||
*/
|
||||
inline void scale(float scalar);
|
||||
|
||||
/**
|
||||
* Scales each element of this vector by the matching component of scale.
|
||||
*
|
||||
* @param scale The vector to scale by.
|
||||
*/
|
||||
inline void scale(const Vec2& scale);
|
||||
|
||||
/**
|
||||
* Rotates this vector by angle (specified in radians) around the given point.
|
||||
*
|
||||
* @param point The point to rotate around.
|
||||
* @param angle The angle to rotate by (in radians).
|
||||
*/
|
||||
void rotate(const Vec2& point, float angle);
|
||||
|
||||
/**
|
||||
* Sets the elements of this vector to the specified values.
|
||||
*
|
||||
* @param xx The new x coordinate.
|
||||
* @param yy The new y coordinate.
|
||||
*/
|
||||
inline void set(float xx, float yy);
|
||||
|
||||
/**
|
||||
* Sets the elements of this vector from the values in the specified array.
|
||||
*
|
||||
* @param array An array containing the elements of the vector in the order x, y.
|
||||
*/
|
||||
void set(const float* array);
|
||||
|
||||
/**
|
||||
* Sets the elements of this vector to those in the specified vector.
|
||||
*
|
||||
* @param v The vector to copy.
|
||||
*/
|
||||
inline void set(const Vec2& v);
|
||||
|
||||
/**
|
||||
* Sets this vector to the directional vector between the specified points.
|
||||
*
|
||||
* @param p1 The first point.
|
||||
* @param p2 The second point.
|
||||
*/
|
||||
inline void set(const Vec2& p1, const Vec2& p2);
|
||||
|
||||
/**
|
||||
* Sets the elements of this vector to zero.
|
||||
*/
|
||||
inline void setZero();
|
||||
|
||||
/**
|
||||
* Subtracts this vector and the specified vector as (this - v)
|
||||
* and stores the result in this vector.
|
||||
*
|
||||
* @param v The vector to subtract.
|
||||
*/
|
||||
inline void subtract(const Vec2& v);
|
||||
|
||||
/**
|
||||
* Subtracts the specified vectors and stores the result in dst.
|
||||
* The resulting vector is computed as (v1 - v2).
|
||||
*
|
||||
* @param v1 The first vector.
|
||||
* @param v2 The second vector.
|
||||
* @param dst The destination vector.
|
||||
*/
|
||||
static void subtract(const Vec2& v1, const Vec2& v2, Vec2* dst);
|
||||
|
||||
/**
|
||||
* Updates this vector towards the given target using a smoothing function.
|
||||
* The given response time determines the amount of smoothing (lag). A longer
|
||||
* response time yields a smoother result and more lag. To force this vector to
|
||||
* follow the target closely, provide a response time that is very small relative
|
||||
* to the given elapsed time.
|
||||
*
|
||||
* @param target target value.
|
||||
* @param elapsedTime elapsed time between calls.
|
||||
* @param responseTime response time (in the same units as elapsedTime).
|
||||
*/
|
||||
inline void smooth(const Vec2& target, float elapsedTime, float responseTime);
|
||||
|
||||
/**
|
||||
* Calculates the sum of this vector with the given vector.
|
||||
*
|
||||
* Note: this does not modify this vector.
|
||||
*
|
||||
* @param v The vector to add.
|
||||
* @return The vector sum.
|
||||
*/
|
||||
inline const Vec2 operator+(const Vec2& v) const;
|
||||
|
||||
/**
|
||||
* Adds the given vector to this vector.
|
||||
*
|
||||
* @param v The vector to add.
|
||||
* @return This vector, after the addition occurs.
|
||||
*/
|
||||
inline Vec2& operator+=(const Vec2& v);
|
||||
|
||||
/**
|
||||
* Calculates the sum of this vector with the given vector.
|
||||
*
|
||||
* Note: this does not modify this vector.
|
||||
*
|
||||
* @param v The vector to add.
|
||||
* @return The vector sum.
|
||||
*/
|
||||
inline const Vec2 operator-(const Vec2& v) const;
|
||||
|
||||
/**
|
||||
* Subtracts the given vector from this vector.
|
||||
*
|
||||
* @param v The vector to subtract.
|
||||
* @return This vector, after the subtraction occurs.
|
||||
*/
|
||||
inline Vec2& operator-=(const Vec2& v);
|
||||
|
||||
/**
|
||||
* Calculates the negation of this vector.
|
||||
*
|
||||
* Note: this does not modify this vector.
|
||||
*
|
||||
* @return The negation of this vector.
|
||||
*/
|
||||
inline const Vec2 operator-() const;
|
||||
|
||||
/**
|
||||
* Calculates the scalar product of this vector with the given value.
|
||||
*
|
||||
* Note: this does not modify this vector.
|
||||
*
|
||||
* @param s The value to scale by.
|
||||
* @return The scaled vector.
|
||||
*/
|
||||
inline const Vec2 operator*(float s) const;
|
||||
|
||||
/**
|
||||
* Scales this vector by the given value.
|
||||
*
|
||||
* @param s The value to scale by.
|
||||
* @return This vector, after the scale occurs.
|
||||
*/
|
||||
inline Vec2& operator*=(float s);
|
||||
|
||||
/**
|
||||
* Returns the components of this vector divided by the given constant
|
||||
*
|
||||
* Note: this does not modify this vector.
|
||||
*
|
||||
* @param s the constant to divide this vector with
|
||||
* @return a smaller vector
|
||||
*/
|
||||
inline const Vec2 operator/(float s) const;
|
||||
|
||||
/**
|
||||
* Determines if this vector is less than the given vector.
|
||||
*
|
||||
* @param v The vector to compare against.
|
||||
*
|
||||
* @return True if this vector is less than the given vector, false otherwise.
|
||||
*/
|
||||
inline bool operator<(const Vec2& v) const;
|
||||
|
||||
/**
|
||||
* Determines if this vector is greater than the given vector.
|
||||
*
|
||||
* @param v The vector to compare against.
|
||||
*
|
||||
* @return True if this vector is greater than the given vector, false otherwise.
|
||||
*/
|
||||
inline bool operator>(const Vec2& v) const;
|
||||
|
||||
/**
|
||||
* Determines if this vector is equal to the given vector.
|
||||
*
|
||||
* @param v The vector to compare against.
|
||||
*
|
||||
* @return True if this vector is equal to the given vector, false otherwise.
|
||||
*/
|
||||
inline bool operator==(const Vec2& v) const;
|
||||
|
||||
/**
|
||||
* Determines if this vector is not equal to the given vector.
|
||||
*
|
||||
* @param v The vector to compare against.
|
||||
*
|
||||
* @return True if this vector is not equal to the given vector, false otherwise.
|
||||
*/
|
||||
inline bool operator!=(const Vec2& v) const;
|
||||
|
||||
//code added compatible for Point
|
||||
public:
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
inline void setPoint(float xx, float yy);
|
||||
/**
|
||||
* @js NA
|
||||
*/
|
||||
bool equals(const Vec2& target) const;
|
||||
|
||||
/** @returns if points have fuzzy equality which means equal with some degree of variance.
|
||||
@since v2.1.4
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
bool fuzzyEquals(const Vec2& target, float variance) const;
|
||||
|
||||
/** Calculates distance between point an origin
|
||||
@return float
|
||||
@since v2.1.4
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
inline float getLength() const {
|
||||
return sqrtf(x*x + y*y);
|
||||
};
|
||||
|
||||
/** Calculates the square length of a Vec2 (not calling sqrt() )
|
||||
@return float
|
||||
@since v2.1.4
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
inline float getLengthSq() const {
|
||||
return dot(*this); //x*x + y*y;
|
||||
};
|
||||
|
||||
/** Calculates the square distance between two points (not calling sqrt() )
|
||||
@return float
|
||||
@since v2.1.4
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
inline float getDistanceSq(const Vec2& other) const {
|
||||
return (*this - other).getLengthSq();
|
||||
};
|
||||
|
||||
/** Calculates the distance between two points
|
||||
@return float
|
||||
@since v2.1.4
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
inline float getDistance(const Vec2& other) const {
|
||||
return (*this - other).getLength();
|
||||
};
|
||||
|
||||
/** @returns the angle in radians between this vector and the x axis
|
||||
@since v2.1.4
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
inline float getAngle() const {
|
||||
return atan2f(y, x);
|
||||
};
|
||||
|
||||
/** @returns the angle in radians between two vector directions
|
||||
@since v2.1.4
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
float getAngle(const Vec2& other) const;
|
||||
|
||||
/** Calculates cross product of two points.
|
||||
@return float
|
||||
@since v2.1.4
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
inline float cross(const Vec2& other) const {
|
||||
return x*other.y - y*other.x;
|
||||
};
|
||||
|
||||
/** Calculates perpendicular of v, rotated 90 degrees counter-clockwise -- cross(v, perp(v)) >= 0
|
||||
@return Vec2
|
||||
@since v2.1.4
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
inline Vec2 getPerp() const {
|
||||
return Vec2(-y, x);
|
||||
};
|
||||
|
||||
/** Calculates midpoint between two points.
|
||||
@return Vec2
|
||||
@since v3.0
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
inline Vec2 getMidpoint(const Vec2& other) const
|
||||
{
|
||||
return Vec2((x + other.x) / 2.0f, (y + other.y) / 2.0f);
|
||||
}
|
||||
|
||||
/** Clamp a point between from and to.
|
||||
@since v3.0
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
inline Vec2 getClampPoint(const Vec2& min_inclusive, const Vec2& max_inclusive) const
|
||||
{
|
||||
return Vec2(clampf(x,min_inclusive.x,max_inclusive.x), clampf(y, min_inclusive.y, max_inclusive.y));
|
||||
}
|
||||
|
||||
/** Run a math operation function on each point component
|
||||
* absf, floorf, ceilf, roundf
|
||||
* any function that has the signature: float func(float);
|
||||
* For example: let's try to take the floor of x,y
|
||||
* p.compOp(floorf);
|
||||
@since v3.0
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
inline Vec2 compOp(std::function<float(float)> function) const
|
||||
{
|
||||
return Vec2(function(x), function(y));
|
||||
}
|
||||
|
||||
/** Calculates perpendicular of v, rotated 90 degrees clockwise -- cross(v, rperp(v)) <= 0
|
||||
@return Vec2
|
||||
@since v2.1.4
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
inline Vec2 getRPerp() const {
|
||||
return Vec2(y, -x);
|
||||
};
|
||||
|
||||
/** Calculates the projection of this over other.
|
||||
@return Vec2
|
||||
@since v2.1.4
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
inline Vec2 project(const Vec2& other) const {
|
||||
return other * (dot(other)/other.dot(other));
|
||||
};
|
||||
|
||||
/** Complex multiplication of two points ("rotates" two points).
|
||||
@return Vec2 vector with an angle of this.getAngle() + other.getAngle(),
|
||||
and a length of this.getLength() * other.getLength().
|
||||
@since v2.1.4
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
inline Vec2 rotate(const Vec2& other) const {
|
||||
return Vec2(x*other.x - y*other.y, x*other.y + y*other.x);
|
||||
};
|
||||
|
||||
/** Unrotates two points.
|
||||
@return Vec2 vector with an angle of this.getAngle() - other.getAngle(),
|
||||
and a length of this.getLength() * other.getLength().
|
||||
@since v2.1.4
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
inline Vec2 unrotate(const Vec2& other) const {
|
||||
return Vec2(x*other.x + y*other.y, y*other.x - x*other.y);
|
||||
};
|
||||
|
||||
/** Linear Interpolation between two points a and b
|
||||
@returns
|
||||
alpha == 0 ? a
|
||||
alpha == 1 ? b
|
||||
otherwise a value between a..b
|
||||
@since v2.1.4
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
inline Vec2 lerp(const Vec2& other, float alpha) const {
|
||||
return *this * (1.f - alpha) + other * alpha;
|
||||
};
|
||||
|
||||
/** Rotates a point counter clockwise by the angle around a pivot
|
||||
@param pivot is the pivot, naturally
|
||||
@param angle is the angle of rotation ccw in radians
|
||||
@returns the rotated point
|
||||
@since v2.1.4
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
Vec2 rotateByAngle(const Vec2& pivot, float angle) const;
|
||||
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
static inline Vec2 forAngle(const float a)
|
||||
{
|
||||
return Vec2(cosf(a), sinf(a));
|
||||
}
|
||||
|
||||
/** A general line-line intersection test
|
||||
@param A the startpoint for the first line L1 = (A - B)
|
||||
@param B the endpoint for the first line L1 = (A - B)
|
||||
@param C the startpoint for the second line L2 = (C - D)
|
||||
@param D the endpoint for the second line L2 = (C - D)
|
||||
@param S the range for a hitpoint in L1 (p = A + S*(B - A))
|
||||
@param T the range for a hitpoint in L2 (p = C + T*(D - C))
|
||||
@return whether these two lines intersects.
|
||||
|
||||
Note that to truly test intersection for segments we have to make
|
||||
sure that S & T lie within [0..1] and for rays, make sure S & T > 0
|
||||
the hit point is C + T * (D - C);
|
||||
the hit point also is A + S * (B - A);
|
||||
@since 3.0
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
static bool isLineIntersect(const Vec2& A, const Vec2& B,
|
||||
const Vec2& C, const Vec2& D,
|
||||
float *S = nullptr, float *T = nullptr);
|
||||
|
||||
/**
|
||||
returns true if Line A-B overlap with segment C-D
|
||||
@since v3.0
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
static bool isLineOverlap(const Vec2& A, const Vec2& B,
|
||||
const Vec2& C, const Vec2& D);
|
||||
|
||||
/**
|
||||
returns true if Line A-B parallel with segment C-D
|
||||
@since v3.0
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
static bool isLineParallel(const Vec2& A, const Vec2& B,
|
||||
const Vec2& C, const Vec2& D);
|
||||
|
||||
/**
|
||||
returns true if Segment A-B overlap with segment C-D
|
||||
@since v3.0
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
static bool isSegmentOverlap(const Vec2& A, const Vec2& B,
|
||||
const Vec2& C, const Vec2& D,
|
||||
Vec2* S = nullptr, Vec2* E = nullptr);
|
||||
|
||||
/**
|
||||
returns true if Segment A-B intersects with segment C-D
|
||||
@since v3.0
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
static bool isSegmentIntersect(const Vec2& A, const Vec2& B, const Vec2& C, const Vec2& D);
|
||||
|
||||
/**
|
||||
returns the intersection point of line A-B, C-D
|
||||
@since v3.0
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
static Vec2 getIntersectPoint(const Vec2& A, const Vec2& B, const Vec2& C, const Vec2& D);
|
||||
|
||||
/** equals to Vec2(0,0) */
|
||||
static const Vec2 ZERO;
|
||||
/** equals to Vec2(1,1) */
|
||||
static const Vec2 ONE;
|
||||
/** equals to Vec2(1,0) */
|
||||
static const Vec2 UNIT_X;
|
||||
/** equals to Vec2(0,1) */
|
||||
static const Vec2 UNIT_Y;
|
||||
/** equals to Vec2(0.5, 0.5) */
|
||||
static const Vec2 ANCHOR_MIDDLE;
|
||||
/** equals to Vec2(0, 0) */
|
||||
static const Vec2 ANCHOR_BOTTOM_LEFT;
|
||||
/** equals to Vec2(0, 1) */
|
||||
static const Vec2 ANCHOR_TOP_LEFT;
|
||||
/** equals to Vec2(1, 0) */
|
||||
static const Vec2 ANCHOR_BOTTOM_RIGHT;
|
||||
/** equals to Vec2(1, 1) */
|
||||
static const Vec2 ANCHOR_TOP_RIGHT;
|
||||
/** equals to Vec2(1, 0.5) */
|
||||
static const Vec2 ANCHOR_MIDDLE_RIGHT;
|
||||
/** equals to Vec2(0, 0.5) */
|
||||
static const Vec2 ANCHOR_MIDDLE_LEFT;
|
||||
/** equals to Vec2(0.5, 1) */
|
||||
static const Vec2 ANCHOR_MIDDLE_TOP;
|
||||
/** equals to Vec2(0.5, 0) */
|
||||
static const Vec2 ANCHOR_MIDDLE_BOTTOM;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates the scalar product of the given vector with the given value.
|
||||
*
|
||||
* @param x The value to scale by.
|
||||
* @param v The vector to scale.
|
||||
* @return The scaled vector.
|
||||
*/
|
||||
inline const Vec2 operator*(float x, const Vec2& v);
|
||||
|
||||
typedef Vec2 Point;
|
||||
|
||||
NS_CC_MATH_END
|
||||
|
||||
/**
|
||||
end of base group
|
||||
@}
|
||||
*/
|
||||
|
||||
#include "math/Vec2.inl"
|
||||
|
||||
#endif // MATH_VEC2_H
|
||||
234
cocos2d-x/cocos/math/Vec2.inl
Normal file
234
cocos2d-x/cocos/math/Vec2.inl
Normal file
@@ -0,0 +1,234 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
|
||||
#include "math/Vec2.h"
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
inline Vec2::Vec2()
|
||||
: x(0.0f), y(0.0f)
|
||||
{
|
||||
}
|
||||
|
||||
inline Vec2::Vec2(float xx, float yy)
|
||||
: x(xx), y(yy)
|
||||
{
|
||||
}
|
||||
|
||||
inline Vec2::Vec2(const float* array)
|
||||
{
|
||||
set(array);
|
||||
}
|
||||
|
||||
inline Vec2::Vec2(const Vec2& p1, const Vec2& p2)
|
||||
{
|
||||
set(p1, p2);
|
||||
}
|
||||
|
||||
inline Vec2::Vec2(const Vec2& copy)
|
||||
{
|
||||
set(copy);
|
||||
}
|
||||
|
||||
inline Vec2::~Vec2()
|
||||
{
|
||||
}
|
||||
|
||||
inline bool Vec2::isZero() const
|
||||
{
|
||||
return x == 0.0f && y == 0.0f;
|
||||
}
|
||||
|
||||
bool Vec2::isOne() const
|
||||
{
|
||||
return x == 1.0f && y == 1.0f;
|
||||
}
|
||||
|
||||
inline void Vec2::add(const Vec2& v)
|
||||
{
|
||||
x += v.x;
|
||||
y += v.y;
|
||||
}
|
||||
|
||||
inline float Vec2::distanceSquared(const Vec2& v) const
|
||||
{
|
||||
float dx = v.x - x;
|
||||
float dy = v.y - y;
|
||||
return (dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
inline float Vec2::dot(const Vec2& v) const
|
||||
{
|
||||
return (x * v.x + y * v.y);
|
||||
}
|
||||
|
||||
inline float Vec2::lengthSquared() const
|
||||
{
|
||||
return (x * x + y * y);
|
||||
}
|
||||
|
||||
inline void Vec2::negate()
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
}
|
||||
|
||||
inline void Vec2::scale(float scalar)
|
||||
{
|
||||
x *= scalar;
|
||||
y *= scalar;
|
||||
}
|
||||
|
||||
inline void Vec2::scale(const Vec2& scale)
|
||||
{
|
||||
x *= scale.x;
|
||||
y *= scale.y;
|
||||
}
|
||||
|
||||
inline void Vec2::set(float xx, float yy)
|
||||
{
|
||||
this->x = xx;
|
||||
this->y = yy;
|
||||
}
|
||||
|
||||
inline void Vec2::set(const Vec2& v)
|
||||
{
|
||||
this->x = v.x;
|
||||
this->y = v.y;
|
||||
}
|
||||
|
||||
inline void Vec2::set(const Vec2& p1, const Vec2& p2)
|
||||
{
|
||||
x = p2.x - p1.x;
|
||||
y = p2.y - p1.y;
|
||||
}
|
||||
|
||||
void Vec2::setZero()
|
||||
{
|
||||
x = y = 0.0f;
|
||||
}
|
||||
|
||||
inline void Vec2::subtract(const Vec2& v)
|
||||
{
|
||||
x -= v.x;
|
||||
y -= v.y;
|
||||
}
|
||||
|
||||
inline void Vec2::smooth(const Vec2& target, float elapsedTime, float responseTime)
|
||||
{
|
||||
if (elapsedTime > 0)
|
||||
{
|
||||
*this += (target - *this) * (elapsedTime / (elapsedTime + responseTime));
|
||||
}
|
||||
}
|
||||
|
||||
inline const Vec2 Vec2::operator+(const Vec2& v) const
|
||||
{
|
||||
Vec2 result(*this);
|
||||
result.add(v);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline Vec2& Vec2::operator+=(const Vec2& v)
|
||||
{
|
||||
add(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const Vec2 Vec2::operator-(const Vec2& v) const
|
||||
{
|
||||
Vec2 result(*this);
|
||||
result.subtract(v);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline Vec2& Vec2::operator-=(const Vec2& v)
|
||||
{
|
||||
subtract(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const Vec2 Vec2::operator-() const
|
||||
{
|
||||
Vec2 result(*this);
|
||||
result.negate();
|
||||
return result;
|
||||
}
|
||||
|
||||
inline const Vec2 Vec2::operator*(float s) const
|
||||
{
|
||||
Vec2 result(*this);
|
||||
result.scale(s);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline Vec2& Vec2::operator*=(float s)
|
||||
{
|
||||
scale(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const Vec2 Vec2::operator/(const float s) const
|
||||
{
|
||||
return Vec2(this->x / s, this->y / s);
|
||||
}
|
||||
|
||||
inline bool Vec2::operator<(const Vec2& v) const
|
||||
{
|
||||
if (x == v.x)
|
||||
{
|
||||
return y < v.y;
|
||||
}
|
||||
return x < v.x;
|
||||
}
|
||||
|
||||
inline bool Vec2::operator>(const Vec2& v) const
|
||||
{
|
||||
if (x == v.x)
|
||||
{
|
||||
return y > v.y;
|
||||
}
|
||||
return x > v.x;
|
||||
}
|
||||
|
||||
inline bool Vec2::operator==(const Vec2& v) const
|
||||
{
|
||||
return x==v.x && y==v.y;
|
||||
}
|
||||
|
||||
inline bool Vec2::operator!=(const Vec2& v) const
|
||||
{
|
||||
return x!=v.x || y!=v.y;
|
||||
}
|
||||
|
||||
inline const Vec2 operator*(float x, const Vec2& v)
|
||||
{
|
||||
Vec2 result(v);
|
||||
result.scale(x);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Vec2::setPoint(float xx, float yy)
|
||||
{
|
||||
this->x = xx;
|
||||
this->y = yy;
|
||||
}
|
||||
|
||||
NS_CC_MATH_END
|
||||
283
cocos2d-x/cocos/math/Vec3.cpp
Normal file
283
cocos2d-x/cocos/math/Vec3.cpp
Normal file
@@ -0,0 +1,283 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
|
||||
#include "math/Vec3.h"
|
||||
#include "math/Mat3.hpp"
|
||||
#include "math/MathUtil.h"
|
||||
#include "base/ccMacros.h"
|
||||
#include "math/Quaternion.h"
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
Vec3::Vec3()
|
||||
: x(0.0f), y(0.0f), z(0.0f)
|
||||
{
|
||||
}
|
||||
|
||||
Vec3::Vec3(float xx, float yy, float zz)
|
||||
: x(xx), y(yy), z(zz)
|
||||
{
|
||||
}
|
||||
|
||||
Vec3::Vec3(const float* array)
|
||||
{
|
||||
set(array);
|
||||
}
|
||||
|
||||
Vec3::Vec3(const Vec3& p1, const Vec3& p2)
|
||||
{
|
||||
set(p1, p2);
|
||||
}
|
||||
|
||||
Vec3::Vec3(const Vec3& copy)
|
||||
{
|
||||
set(copy);
|
||||
}
|
||||
|
||||
Vec3 Vec3::fromColor(unsigned int color)
|
||||
{
|
||||
float components[3];
|
||||
int componentIndex = 0;
|
||||
for (int i = 2; i >= 0; --i)
|
||||
{
|
||||
int component = (color >> i*8) & 0x0000ff;
|
||||
|
||||
components[componentIndex++] = static_cast<float>(component) / 255.0f;
|
||||
}
|
||||
|
||||
Vec3 value(components);
|
||||
return value;
|
||||
}
|
||||
|
||||
Vec3::~Vec3()
|
||||
{
|
||||
}
|
||||
|
||||
float Vec3::angle(const Vec3& v1, const Vec3& v2)
|
||||
{
|
||||
float dx = v1.y * v2.z - v1.z * v2.y;
|
||||
float dy = v1.z * v2.x - v1.x * v2.z;
|
||||
float dz = v1.x * v2.y - v1.y * v2.x;
|
||||
|
||||
return std::atan2(std::sqrt(dx * dx + dy * dy + dz * dz) + MATH_FLOAT_SMALL, dot(v1, v2));
|
||||
}
|
||||
|
||||
void Vec3::add(const Vec3& v1, const Vec3& v2, Vec3* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
dst->x = v1.x + v2.x;
|
||||
dst->y = v1.y + v2.y;
|
||||
dst->z = v1.z + v2.z;
|
||||
}
|
||||
|
||||
void Vec3::clamp(const Vec3& min, const Vec3& max)
|
||||
{
|
||||
GP_ASSERT(!(min.x > max.x || min.y > max.y || min.z > max.z));
|
||||
|
||||
// Clamp the x value.
|
||||
if (x < min.x)
|
||||
x = min.x;
|
||||
if (x > max.x)
|
||||
x = max.x;
|
||||
|
||||
// Clamp the y value.
|
||||
if (y < min.y)
|
||||
y = min.y;
|
||||
if (y > max.y)
|
||||
y = max.y;
|
||||
|
||||
// Clamp the z value.
|
||||
if (z < min.z)
|
||||
z = min.z;
|
||||
if (z > max.z)
|
||||
z = max.z;
|
||||
}
|
||||
|
||||
void Vec3::clamp(const Vec3& v, const Vec3& min, const Vec3& max, Vec3* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
GP_ASSERT(!(min.x > max.x || min.y > max.y || min.z > max.z));
|
||||
|
||||
// Clamp the x value.
|
||||
dst->x = v.x;
|
||||
if (dst->x < min.x)
|
||||
dst->x = min.x;
|
||||
if (dst->x > max.x)
|
||||
dst->x = max.x;
|
||||
|
||||
// Clamp the y value.
|
||||
dst->y = v.y;
|
||||
if (dst->y < min.y)
|
||||
dst->y = min.y;
|
||||
if (dst->y > max.y)
|
||||
dst->y = max.y;
|
||||
|
||||
// Clamp the z value.
|
||||
dst->z = v.z;
|
||||
if (dst->z < min.z)
|
||||
dst->z = min.z;
|
||||
if (dst->z > max.z)
|
||||
dst->z = max.z;
|
||||
}
|
||||
|
||||
void Vec3::cross(const Vec3& v)
|
||||
{
|
||||
cross(*this, v, this);
|
||||
}
|
||||
|
||||
void Vec3::cross(const Vec3& v1, const Vec3& v2, Vec3* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
// NOTE: This code assumes Vec3 struct members are contiguous floats in memory.
|
||||
// We might want to revisit this (and other areas of code that make this assumption)
|
||||
// later to guarantee 100% safety/compatibility.
|
||||
MathUtil::crossVec3(&v1.x, &v2.x, &dst->x);
|
||||
}
|
||||
|
||||
void Vec3::multiply(const Vec3& v)
|
||||
{
|
||||
x *= v.x;
|
||||
y *= v.y;
|
||||
z *= v.z;
|
||||
}
|
||||
|
||||
void Vec3::multiply(const Vec3& v1, const Vec3& v2, Vec3* dst)
|
||||
{
|
||||
dst->x = v1.x * v2.x;
|
||||
dst->y = v1.y * v2.y;
|
||||
dst->z = v1.z * v2.z;
|
||||
}
|
||||
|
||||
void Vec3::transformMat3(const Vec3& v, const Mat3 &m)
|
||||
{
|
||||
float ix = v.x, iy = v.y, iz = v.z;
|
||||
x = ix * m.m[0] + iy * m.m[3] + iz * m.m[6];
|
||||
y = ix * m.m[1] + iy * m.m[4] + iz * m.m[7];
|
||||
z = ix * m.m[2] + iy * m.m[5] + iz * m.m[8];
|
||||
}
|
||||
|
||||
void Vec3::transformMat4(const Vec3& v, const Mat4 &m)
|
||||
{
|
||||
float ix = v.x, iy = v.y, iz = v.z;
|
||||
float rhw = m.m[3] * ix + m.m[7] * iy + m.m[11] * iz + m.m[15];
|
||||
rhw = rhw ? 1 / rhw : 1;
|
||||
|
||||
x = (m.m[0] * ix + m.m[4] * iy + m.m[8] * iz + m.m[12]) * rhw;
|
||||
y = (m.m[1] * ix + m.m[5] * iy + m.m[9] * iz + m.m[13]) * rhw;
|
||||
z = (m.m[2] * ix + m.m[6] * iy + m.m[10] * iz + m.m[14]) * rhw;
|
||||
}
|
||||
|
||||
void Vec3::transformQuat(const Quaternion& q)
|
||||
{
|
||||
float qx = q.x, qy = q.y, qz = q.z, qw = q.w;
|
||||
|
||||
// calculate quat * vec
|
||||
float ix = qw * x + qy * z - qz * y;
|
||||
float iy = qw * y + qz * x - qx * z;
|
||||
float iz = qw * z + qx * y - qy * x;
|
||||
float iw = -qx * x - qy * y - qz * z;
|
||||
|
||||
// calculate result * inverse quat
|
||||
x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
|
||||
y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
|
||||
z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
|
||||
}
|
||||
|
||||
float Vec3::distance(const Vec3& v) const
|
||||
{
|
||||
float dx = v.x - x;
|
||||
float dy = v.y - y;
|
||||
float dz = v.z - z;
|
||||
|
||||
return std::sqrt(dx * dx + dy * dy + dz * dz);
|
||||
}
|
||||
|
||||
float Vec3::distanceSquared(const Vec3& v) const
|
||||
{
|
||||
float dx = v.x - x;
|
||||
float dy = v.y - y;
|
||||
float dz = v.z - z;
|
||||
|
||||
return (dx * dx + dy * dy + dz * dz);
|
||||
}
|
||||
|
||||
float Vec3::dot(const Vec3& v) const
|
||||
{
|
||||
return (x * v.x + y * v.y + z * v.z);
|
||||
}
|
||||
|
||||
float Vec3::dot(const Vec3& v1, const Vec3& v2)
|
||||
{
|
||||
return (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z);
|
||||
}
|
||||
|
||||
void Vec3::normalize()
|
||||
{
|
||||
float n = x * x + y * y + z * z;
|
||||
// Already normalized.
|
||||
if (n == 1.0f)
|
||||
return;
|
||||
|
||||
n = std::sqrt(n);
|
||||
// Too close to zero.
|
||||
if (n < MATH_TOLERANCE)
|
||||
return;
|
||||
|
||||
n = 1.0f / n;
|
||||
x *= n;
|
||||
y *= n;
|
||||
z *= n;
|
||||
}
|
||||
|
||||
Vec3 Vec3::getNormalized() const
|
||||
{
|
||||
Vec3 v(*this);
|
||||
v.normalize();
|
||||
return v;
|
||||
}
|
||||
|
||||
void Vec3::subtract(const Vec3& v1, const Vec3& v2, Vec3* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
dst->x = v1.x - v2.x;
|
||||
dst->y = v1.y - v2.y;
|
||||
dst->z = v1.z - v2.z;
|
||||
}
|
||||
|
||||
void Vec3::smooth(const Vec3& target, float elapsedTime, float responseTime)
|
||||
{
|
||||
if (elapsedTime > 0)
|
||||
{
|
||||
*this += (target - *this) * (elapsedTime / (elapsedTime + responseTime));
|
||||
}
|
||||
}
|
||||
|
||||
const Vec3 Vec3::ZERO(0.0f, 0.0f, 0.0f);
|
||||
const Vec3 Vec3::ONE(1.0f, 1.0f, 1.0f);
|
||||
const Vec3 Vec3::UNIT_X(1.0f, 0.0f, 0.0f);
|
||||
const Vec3 Vec3::UNIT_Y(0.0f, 1.0f, 0.0f);
|
||||
const Vec3 Vec3::UNIT_Z(0.0f, 0.0f, 1.0f);
|
||||
|
||||
NS_CC_MATH_END
|
||||
553
cocos2d-x/cocos/math/Vec3.h
Normal file
553
cocos2d-x/cocos/math/Vec3.h
Normal file
@@ -0,0 +1,553 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
|
||||
#ifndef MATH_VEC3_H
|
||||
#define MATH_VEC3_H
|
||||
|
||||
#include <cmath>
|
||||
#include "math/CCMathBase.h"
|
||||
|
||||
/**
|
||||
* @addtogroup base
|
||||
* @{
|
||||
*/
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
class Mat4;
|
||||
class Quaternion;
|
||||
class Mat3;
|
||||
|
||||
/**
|
||||
* Defines a 3-element floating point vector.
|
||||
*
|
||||
* When using a vector to represent a surface normal,
|
||||
* the vector should typically be normalized.
|
||||
* Other uses of directional vectors may wish to leave
|
||||
* the magnitude of the vector intact. When used as a point,
|
||||
* the elements of the vector represent a position in 3D space.
|
||||
*/
|
||||
class CC_DLL Vec3
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* The x-coordinate.
|
||||
*/
|
||||
float x;
|
||||
|
||||
/**
|
||||
* The y-coordinate.
|
||||
*/
|
||||
float y;
|
||||
|
||||
/**
|
||||
* The z-coordinate.
|
||||
*/
|
||||
float z;
|
||||
|
||||
/**
|
||||
* Constructs a new vector initialized to all zeros.
|
||||
*/
|
||||
Vec3();
|
||||
|
||||
/**
|
||||
* Constructs a new vector initialized to the specified values.
|
||||
*
|
||||
* @param xx The x coordinate.
|
||||
* @param yy The y coordinate.
|
||||
* @param zz The z coordinate.
|
||||
*/
|
||||
Vec3(float xx, float yy, float zz);
|
||||
|
||||
/**
|
||||
* Constructs a new vector from the values in the specified array.
|
||||
*
|
||||
* @param array An array containing the elements of the vector in the order x, y, z.
|
||||
*/
|
||||
Vec3(const float* array);
|
||||
|
||||
/**
|
||||
* Constructs a vector that describes the direction between the specified points.
|
||||
*
|
||||
* @param p1 The first point.
|
||||
* @param p2 The second point.
|
||||
*/
|
||||
Vec3(const Vec3& p1, const Vec3& p2);
|
||||
|
||||
/**
|
||||
* Constructs a new vector that is a copy of the specified vector.
|
||||
*
|
||||
* @param copy The vector to copy.
|
||||
*/
|
||||
Vec3(const Vec3& copy);
|
||||
|
||||
/**
|
||||
* Creates a new vector from an integer interpreted as an RGB value.
|
||||
* E.g. 0xff0000 represents red or the vector (1, 0, 0).
|
||||
*
|
||||
* @param color The integer to interpret as an RGB value.
|
||||
*
|
||||
* @return A vector corresponding to the interpreted RGB color.
|
||||
*/
|
||||
static Vec3 fromColor(unsigned int color);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~Vec3();
|
||||
|
||||
/**
|
||||
* Indicates whether this vector contains all zeros.
|
||||
*
|
||||
* @return true if this vector contains all zeros, false otherwise.
|
||||
*/
|
||||
inline bool isZero() const;
|
||||
|
||||
/**
|
||||
* Indicates whether this vector contains all ones.
|
||||
*
|
||||
* @return true if this vector contains all ones, false otherwise.
|
||||
*/
|
||||
inline bool isOne() const;
|
||||
|
||||
/**
|
||||
* Returns the angle (in radians) between the specified vectors.
|
||||
*
|
||||
* @param v1 The first vector.
|
||||
* @param v2 The second vector.
|
||||
*
|
||||
* @return The angle between the two vectors (in radians).
|
||||
*/
|
||||
static float angle(const Vec3& v1, const Vec3& v2);
|
||||
|
||||
|
||||
/**
|
||||
* Adds the elements of the specified vector to this one.
|
||||
*
|
||||
* @param v The vector to add.
|
||||
*/
|
||||
inline void add(const Vec3& v);
|
||||
|
||||
|
||||
/**
|
||||
* Adds the elements of this vector to the specified values.
|
||||
*
|
||||
* @param xx The add x coordinate.
|
||||
* @param yy The add y coordinate.
|
||||
* @param zz The add z coordinate.
|
||||
*/
|
||||
inline void add(float xx, float yy, float zz);
|
||||
|
||||
/**
|
||||
* Adds the specified vectors and stores the result in dst.
|
||||
*
|
||||
* @param v1 The first vector.
|
||||
* @param v2 The second vector.
|
||||
* @param dst A vector to store the result in.
|
||||
*/
|
||||
static void add(const Vec3& v1, const Vec3& v2, Vec3* dst);
|
||||
|
||||
/**
|
||||
* Clamps this vector within the specified range.
|
||||
*
|
||||
* @param min The minimum value.
|
||||
* @param max The maximum value.
|
||||
*/
|
||||
void clamp(const Vec3& min, const Vec3& max);
|
||||
|
||||
/**
|
||||
* Clamps the specified vector within the specified range and returns it in dst.
|
||||
*
|
||||
* @param v The vector to clamp.
|
||||
* @param min The minimum value.
|
||||
* @param max The maximum value.
|
||||
* @param dst A vector to store the result in.
|
||||
*/
|
||||
static void clamp(const Vec3& v, const Vec3& min, const Vec3& max, Vec3* dst);
|
||||
|
||||
/**
|
||||
* Sets this vector to the cross product between itself and the specified vector.
|
||||
*
|
||||
* @param v The vector to compute the cross product with.
|
||||
*/
|
||||
void cross(const Vec3& v);
|
||||
|
||||
/**
|
||||
* Computes the cross product of the specified vectors and stores the result in dst.
|
||||
*
|
||||
* @param v1 The first vector.
|
||||
* @param v2 The second vector.
|
||||
* @param dst A vector to store the result in.
|
||||
*/
|
||||
static void cross(const Vec3& v1, const Vec3& v2, Vec3* dst);
|
||||
|
||||
/**
|
||||
* Multiply the elements of the specified vector to this one.
|
||||
*
|
||||
* @param v The vector to multiply.
|
||||
*/
|
||||
void multiply(const Vec3& v);
|
||||
|
||||
/**
|
||||
* Multiply the specified vectors and stores the result in dst.
|
||||
*
|
||||
* @param v1 The first vector.
|
||||
* @param v2 The second vector.
|
||||
* @param dst A vector to store the result in.
|
||||
*/
|
||||
static void multiply(const Vec3& v1, const Vec3& v2, Vec3* dst);
|
||||
|
||||
/**
|
||||
* Transforms this vector by the specified Mat3 and stores the result in this vector.
|
||||
*
|
||||
* @param v The Vec3 to transform.
|
||||
* @param m The matrix.
|
||||
*/
|
||||
void transformMat3(const Vec3& v, const Mat3& m);
|
||||
|
||||
/**
|
||||
* Transforms this vector by the specified Mat4 and stores the result in this vector.
|
||||
*
|
||||
* @param v The Vec3 to transform.
|
||||
* @param m The matrix.
|
||||
*/
|
||||
void transformMat4(const Vec3& v, const Mat4& m);
|
||||
|
||||
/**
|
||||
* Transforms this vector by the specified quaternion and stores the result in this vector.
|
||||
*
|
||||
* @param q The quaternion to multiply.
|
||||
*/
|
||||
void transformQuat(const Quaternion& q);
|
||||
|
||||
/**
|
||||
* Returns the distance between this vector and v.
|
||||
*
|
||||
* @param v The other vector.
|
||||
*
|
||||
* @return The distance between this vector and v.
|
||||
*
|
||||
* @see distanceSquared
|
||||
*/
|
||||
float distance(const Vec3& v) const;
|
||||
|
||||
/**
|
||||
* Returns the squared distance between this vector and v.
|
||||
*
|
||||
* When it is not necessary to get the exact distance between
|
||||
* two vectors (for example, when simply comparing the
|
||||
* distance between different vectors), it is advised to use
|
||||
* this method instead of distance.
|
||||
*
|
||||
* @param v The other vector.
|
||||
*
|
||||
* @return The squared distance between this vector and v.
|
||||
*
|
||||
* @see distance
|
||||
*/
|
||||
float distanceSquared(const Vec3& v) const;
|
||||
|
||||
/**
|
||||
* Returns the dot product of this vector and the specified vector.
|
||||
*
|
||||
* @param v The vector to compute the dot product with.
|
||||
*
|
||||
* @return The dot product.
|
||||
*/
|
||||
float dot(const Vec3& v) const;
|
||||
|
||||
/**
|
||||
* Returns the dot product between the specified vectors.
|
||||
*
|
||||
* @param v1 The first vector.
|
||||
* @param v2 The second vector.
|
||||
*
|
||||
* @return The dot product between the vectors.
|
||||
*/
|
||||
static float dot(const Vec3& v1, const Vec3& v2);
|
||||
|
||||
/**
|
||||
* Computes the length of this vector.
|
||||
*
|
||||
* @return The length of the vector.
|
||||
*
|
||||
* @see lengthSquared
|
||||
*/
|
||||
inline float length() const;
|
||||
|
||||
/**
|
||||
* Returns the squared length of this vector.
|
||||
*
|
||||
* When it is not necessary to get the exact length of a
|
||||
* vector (for example, when simply comparing the lengths of
|
||||
* different vectors), it is advised to use this method
|
||||
* instead of length.
|
||||
*
|
||||
* @return The squared length of the vector.
|
||||
*
|
||||
* @see length
|
||||
*/
|
||||
inline float lengthSquared() const;
|
||||
|
||||
/**
|
||||
* Negates this vector.
|
||||
*/
|
||||
inline void negate();
|
||||
|
||||
/**
|
||||
* Normalizes this vector.
|
||||
*
|
||||
* This method normalizes this Vec3 so that it is of
|
||||
* unit length (in other words, the length of the vector
|
||||
* after calling this method will be 1.0f). If the vector
|
||||
* already has unit length or if the length of the vector
|
||||
* is zero, this method does nothing.
|
||||
*
|
||||
* @return This vector, after the normalization occurs.
|
||||
*/
|
||||
void normalize();
|
||||
|
||||
/**
|
||||
* Get the normalized vector.
|
||||
*/
|
||||
Vec3 getNormalized() const;
|
||||
|
||||
/**
|
||||
* Scales all elements of this vector by the specified value.
|
||||
*
|
||||
* @param scalar The scalar value.
|
||||
*/
|
||||
inline void scale(float scalar);
|
||||
|
||||
/**
|
||||
* Sets the elements of this vector to the specified values.
|
||||
*
|
||||
* @param xx The new x coordinate.
|
||||
* @param yy The new y coordinate.
|
||||
* @param zz The new z coordinate.
|
||||
*/
|
||||
inline void set(float xx, float yy, float zz);
|
||||
|
||||
/**
|
||||
* Sets the elements of this vector from the values in the specified array.
|
||||
*
|
||||
* @param array An array containing the elements of the vector in the order x, y, z.
|
||||
*/
|
||||
inline void set(const float* array);
|
||||
|
||||
/**
|
||||
* Sets the elements of this vector to those in the specified vector.
|
||||
*
|
||||
* @param v The vector to copy.
|
||||
*/
|
||||
inline void set(const Vec3& v);
|
||||
|
||||
/**
|
||||
* Sets this vector to the directional vector between the specified points.
|
||||
*/
|
||||
inline void set(const Vec3& p1, const Vec3& p2);
|
||||
|
||||
/**
|
||||
* Sets the elements of this vector to zero.
|
||||
*/
|
||||
inline void setZero();
|
||||
|
||||
/**
|
||||
* Subtracts this vector and the specified vector as (this - v)
|
||||
* and stores the result in this vector.
|
||||
*
|
||||
* @param v The vector to subtract.
|
||||
*/
|
||||
inline void subtract(const Vec3& v);
|
||||
|
||||
/**
|
||||
* Subtracts the specified vectors and stores the result in dst.
|
||||
* The resulting vector is computed as (v1 - v2).
|
||||
*
|
||||
* @param v1 The first vector.
|
||||
* @param v2 The second vector.
|
||||
* @param dst The destination vector.
|
||||
*/
|
||||
static void subtract(const Vec3& v1, const Vec3& v2, Vec3* dst);
|
||||
|
||||
/**
|
||||
* Updates this vector towards the given target using a smoothing function.
|
||||
* The given response time determines the amount of smoothing (lag). A longer
|
||||
* response time yields a smoother result and more lag. To force this vector to
|
||||
* follow the target closely, provide a response time that is very small relative
|
||||
* to the given elapsed time.
|
||||
*
|
||||
* @param target target value.
|
||||
* @param elapsedTime elapsed time between calls.
|
||||
* @param responseTime response time (in the same units as elapsedTime).
|
||||
*/
|
||||
void smooth(const Vec3& target, float elapsedTime, float responseTime);
|
||||
|
||||
/**
|
||||
* Linear interpolation between two vectors A and B by alpha which
|
||||
* is in the range [0,1]
|
||||
*/
|
||||
inline Vec3 lerp(const Vec3& target, float alpha) const;
|
||||
|
||||
/**
|
||||
* Calculates the sum of this vector with the given vector.
|
||||
*
|
||||
* Note: this does not modify this vector.
|
||||
*
|
||||
* @param v The vector to add.
|
||||
* @return The vector sum.
|
||||
*/
|
||||
inline const Vec3 operator+(const Vec3& v) const;
|
||||
|
||||
/**
|
||||
* Adds the given vector to this vector.
|
||||
*
|
||||
* @param v The vector to add.
|
||||
* @return This vector, after the addition occurs.
|
||||
*/
|
||||
inline Vec3& operator+=(const Vec3& v);
|
||||
|
||||
/**
|
||||
* Calculates the difference of this vector with the given vector.
|
||||
*
|
||||
* Note: this does not modify this vector.
|
||||
*
|
||||
* @param v The vector to subtract.
|
||||
* @return The vector difference.
|
||||
*/
|
||||
inline const Vec3 operator-(const Vec3& v) const;
|
||||
|
||||
/**
|
||||
* Subtracts the given vector from this vector.
|
||||
*
|
||||
* @param v The vector to subtract.
|
||||
* @return This vector, after the subtraction occurs.
|
||||
*/
|
||||
inline Vec3& operator-=(const Vec3& v);
|
||||
|
||||
/**
|
||||
* Calculates the negation of this vector.
|
||||
*
|
||||
* Note: this does not modify this vector.
|
||||
*
|
||||
* @return The negation of this vector.
|
||||
*/
|
||||
inline const Vec3 operator-() const;
|
||||
|
||||
/**
|
||||
* Calculates the scalar product of this vector with the given value.
|
||||
*
|
||||
* Note: this does not modify this vector.
|
||||
*
|
||||
* @param s The value to scale by.
|
||||
* @return The scaled vector.
|
||||
*/
|
||||
inline const Vec3 operator*(float s) const;
|
||||
|
||||
/**
|
||||
* Scales this vector by the given value.
|
||||
*
|
||||
* @param s The value to scale by.
|
||||
* @return This vector, after the scale occurs.
|
||||
*/
|
||||
inline Vec3& operator*=(float s);
|
||||
|
||||
/**
|
||||
* Returns the components of this vector divided by the given constant
|
||||
*
|
||||
* Note: this does not modify this vector.
|
||||
*
|
||||
* @param s the constant to divide this vector with
|
||||
* @return a smaller vector
|
||||
*/
|
||||
inline const Vec3 operator/(float s) const;
|
||||
|
||||
/** Returns true if the vector's scalar components are all greater
|
||||
that the ones of the vector it is compared against.
|
||||
*/
|
||||
inline bool operator < (const Vec3& rhs) const
|
||||
{
|
||||
if (x < rhs.x && y < rhs.y && z < rhs.z)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Returns true if the vector's scalar components are all smaller
|
||||
that the ones of the vector it is compared against.
|
||||
*/
|
||||
inline bool operator >(const Vec3& rhs) const
|
||||
{
|
||||
if (x > rhs.x && y > rhs.y && z > rhs.z)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this vector is equal to the given vector.
|
||||
*
|
||||
* @param v The vector to compare against.
|
||||
*
|
||||
* @return True if this vector is equal to the given vector, false otherwise.
|
||||
*/
|
||||
inline bool operator==(const Vec3& v) const;
|
||||
|
||||
/**
|
||||
* Determines if this vector is not equal to the given vector.
|
||||
*
|
||||
* @param v The vector to compare against.
|
||||
*
|
||||
* @return True if this vector is not equal to the given vector, false otherwise.
|
||||
*/
|
||||
inline bool operator!=(const Vec3& v) const;
|
||||
|
||||
/** equals to Vec3(0,0,0) */
|
||||
static const Vec3 ZERO;
|
||||
/** equals to Vec3(1,1,1) */
|
||||
static const Vec3 ONE;
|
||||
/** equals to Vec3(1,0,0) */
|
||||
static const Vec3 UNIT_X;
|
||||
/** equals to Vec3(0,1,0) */
|
||||
static const Vec3 UNIT_Y;
|
||||
/** equals to Vec3(0,0,1) */
|
||||
static const Vec3 UNIT_Z;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates the scalar product of the given vector with the given value.
|
||||
*
|
||||
* @param x The value to scale by.
|
||||
* @param v The vector to scale.
|
||||
* @return The scaled vector.
|
||||
*/
|
||||
inline const Vec3 operator*(float x, const Vec3& v);
|
||||
|
||||
//typedef Vec3 Point3;
|
||||
|
||||
NS_CC_MATH_END
|
||||
/**
|
||||
end of base group
|
||||
@}
|
||||
*/
|
||||
#include "math/Vec3.inl"
|
||||
|
||||
#endif // MATH_VEC3_H
|
||||
190
cocos2d-x/cocos/math/Vec3.inl
Normal file
190
cocos2d-x/cocos/math/Vec3.inl
Normal file
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
|
||||
#include "math/Vec3.h"
|
||||
#include "math/Mat4.h"
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
|
||||
inline bool Vec3::isZero() const
|
||||
{
|
||||
return x == 0.0f && y == 0.0f && z == 0.0f;
|
||||
}
|
||||
|
||||
inline bool Vec3::isOne() const
|
||||
{
|
||||
return x == 1.0f && y == 1.0f && z == 1.0f;
|
||||
}
|
||||
|
||||
inline void Vec3::add(const Vec3& v)
|
||||
{
|
||||
x += v.x;
|
||||
y += v.y;
|
||||
z += v.z;
|
||||
}
|
||||
|
||||
inline void Vec3::add(float xx, float yy, float zz)
|
||||
{
|
||||
x += xx;
|
||||
y += yy;
|
||||
z += zz;
|
||||
}
|
||||
|
||||
inline float Vec3::length() const
|
||||
{
|
||||
return std::sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
inline float Vec3::lengthSquared() const
|
||||
{
|
||||
return (x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
inline void Vec3::negate()
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
z = -z;
|
||||
}
|
||||
|
||||
inline void Vec3::scale(float scalar)
|
||||
{
|
||||
x *= scalar;
|
||||
y *= scalar;
|
||||
z *= scalar;
|
||||
}
|
||||
|
||||
inline Vec3 Vec3::lerp(const Vec3 &target, float alpha) const
|
||||
{
|
||||
return *this * (1.f - alpha) + target * alpha;
|
||||
}
|
||||
|
||||
inline void Vec3::set(float xx, float yy, float zz)
|
||||
{
|
||||
this->x = xx;
|
||||
this->y = yy;
|
||||
this->z = zz;
|
||||
}
|
||||
|
||||
inline void Vec3::set(const float* array)
|
||||
{
|
||||
GP_ASSERT(array);
|
||||
|
||||
x = array[0];
|
||||
y = array[1];
|
||||
z = array[2];
|
||||
}
|
||||
|
||||
inline void Vec3::set(const Vec3& v)
|
||||
{
|
||||
this->x = v.x;
|
||||
this->y = v.y;
|
||||
this->z = v.z;
|
||||
}
|
||||
|
||||
inline void Vec3::set(const Vec3& p1, const Vec3& p2)
|
||||
{
|
||||
x = p2.x - p1.x;
|
||||
y = p2.y - p1.y;
|
||||
z = p2.z - p1.z;
|
||||
}
|
||||
|
||||
inline void Vec3::setZero()
|
||||
{
|
||||
x = y = z = 0.0f;
|
||||
}
|
||||
|
||||
inline void Vec3::subtract(const Vec3& v)
|
||||
{
|
||||
x -= v.x;
|
||||
y -= v.y;
|
||||
z -= v.z;
|
||||
}
|
||||
|
||||
inline const Vec3 Vec3::operator+(const Vec3& v) const
|
||||
{
|
||||
Vec3 result(*this);
|
||||
result.add(v);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline Vec3& Vec3::operator+=(const Vec3& v)
|
||||
{
|
||||
add(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const Vec3 Vec3::operator-(const Vec3& v) const
|
||||
{
|
||||
Vec3 result(*this);
|
||||
result.subtract(v);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline Vec3& Vec3::operator-=(const Vec3& v)
|
||||
{
|
||||
subtract(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const Vec3 Vec3::operator-() const
|
||||
{
|
||||
Vec3 result(*this);
|
||||
result.negate();
|
||||
return result;
|
||||
}
|
||||
|
||||
inline const Vec3 Vec3::operator*(float s) const
|
||||
{
|
||||
Vec3 result(*this);
|
||||
result.scale(s);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline Vec3& Vec3::operator*=(float s)
|
||||
{
|
||||
scale(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const Vec3 Vec3::operator/(const float s) const
|
||||
{
|
||||
return Vec3(this->x / s, this->y / s, this->z / s);
|
||||
}
|
||||
|
||||
inline bool Vec3::operator==(const Vec3& v) const
|
||||
{
|
||||
return x==v.x && y==v.y && z==v.z;
|
||||
}
|
||||
|
||||
inline bool Vec3::operator!=(const Vec3& v) const
|
||||
{
|
||||
return x!=v.x || y!=v.y || z!=v.z;
|
||||
}
|
||||
|
||||
inline const Vec3 operator*(float x, const Vec3& v)
|
||||
{
|
||||
Vec3 result(v);
|
||||
result.scale(x);
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_CC_MATH_END
|
||||
317
cocos2d-x/cocos/math/Vec4.cpp
Normal file
317
cocos2d-x/cocos/math/Vec4.cpp
Normal file
@@ -0,0 +1,317 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
|
||||
#include "math/Vec4.h"
|
||||
|
||||
#include <cmath>
|
||||
#include "math/MathUtil.h"
|
||||
#include "base/ccMacros.h"
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
Vec4::Vec4()
|
||||
: x(0.0f), y(0.0f), z(0.0f), w(0.0f)
|
||||
{
|
||||
}
|
||||
|
||||
Vec4::Vec4(float xx, float yy, float zz, float ww)
|
||||
: x(xx), y(yy), z(zz), w(ww)
|
||||
{
|
||||
}
|
||||
|
||||
Vec4::Vec4(const float* src)
|
||||
{
|
||||
set(src);
|
||||
}
|
||||
|
||||
Vec4::Vec4(const Vec4& p1, const Vec4& p2)
|
||||
{
|
||||
set(p1, p2);
|
||||
}
|
||||
|
||||
Vec4::Vec4(const Vec4& copy)
|
||||
{
|
||||
set(copy);
|
||||
}
|
||||
|
||||
Vec4 Vec4::fromColor(unsigned int color)
|
||||
{
|
||||
float components[4];
|
||||
int componentIndex = 0;
|
||||
for (int i = 3; i >= 0; --i)
|
||||
{
|
||||
int component = (color >> i*8) & 0x000000ff;
|
||||
|
||||
components[componentIndex++] = static_cast<float>(component) / 255.0f;
|
||||
}
|
||||
|
||||
Vec4 value(components);
|
||||
return value;
|
||||
}
|
||||
|
||||
Vec4::~Vec4()
|
||||
{
|
||||
}
|
||||
|
||||
bool Vec4::isZero() const
|
||||
{
|
||||
return x == 0.0f && y == 0.0f && z == 0.0f && w == 0.0f;
|
||||
}
|
||||
|
||||
bool Vec4::isOne() const
|
||||
{
|
||||
return x == 1.0f && y == 1.0f && z == 1.0f && w == 1.0f;
|
||||
}
|
||||
|
||||
float Vec4::angle(const Vec4& v1, const Vec4& v2)
|
||||
{
|
||||
float dx = v1.w * v2.x - v1.x * v2.w - v1.y * v2.z + v1.z * v2.y;
|
||||
float dy = v1.w * v2.y - v1.y * v2.w - v1.z * v2.x + v1.x * v2.z;
|
||||
float dz = v1.w * v2.z - v1.z * v2.w - v1.x * v2.y + v1.y * v2.x;
|
||||
|
||||
return std::atan2(std::sqrt(dx * dx + dy * dy + dz * dz) + MATH_FLOAT_SMALL, dot(v1, v2));
|
||||
}
|
||||
|
||||
void Vec4::add(const Vec4& v)
|
||||
{
|
||||
x += v.x;
|
||||
y += v.y;
|
||||
z += v.z;
|
||||
w += v.w;
|
||||
}
|
||||
|
||||
void Vec4::add(const Vec4& v1, const Vec4& v2, Vec4* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
dst->x = v1.x + v2.x;
|
||||
dst->y = v1.y + v2.y;
|
||||
dst->z = v1.z + v2.z;
|
||||
dst->w = v1.w + v2.w;
|
||||
}
|
||||
|
||||
void Vec4::clamp(const Vec4& min, const Vec4& max)
|
||||
{
|
||||
GP_ASSERT(!(min.x > max.x || min.y > max.y || min.z > max.z || min.w > max.w));
|
||||
|
||||
// Clamp the x value.
|
||||
if (x < min.x)
|
||||
x = min.x;
|
||||
if (x > max.x)
|
||||
x = max.x;
|
||||
|
||||
// Clamp the y value.
|
||||
if (y < min.y)
|
||||
y = min.y;
|
||||
if (y > max.y)
|
||||
y = max.y;
|
||||
|
||||
// Clamp the z value.
|
||||
if (z < min.z)
|
||||
z = min.z;
|
||||
if (z > max.z)
|
||||
z = max.z;
|
||||
|
||||
// Clamp the z value.
|
||||
if (w < min.w)
|
||||
w = min.w;
|
||||
if (w > max.w)
|
||||
w = max.w;
|
||||
}
|
||||
|
||||
void Vec4::clamp(const Vec4& v, const Vec4& min, const Vec4& max, Vec4* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
GP_ASSERT(!(min.x > max.x || min.y > max.y || min.z > max.z || min.w > max.w));
|
||||
|
||||
// Clamp the x value.
|
||||
dst->x = v.x;
|
||||
if (dst->x < min.x)
|
||||
dst->x = min.x;
|
||||
if (dst->x > max.x)
|
||||
dst->x = max.x;
|
||||
|
||||
// Clamp the y value.
|
||||
dst->y = v.y;
|
||||
if (dst->y < min.y)
|
||||
dst->y = min.y;
|
||||
if (dst->y > max.y)
|
||||
dst->y = max.y;
|
||||
|
||||
// Clamp the z value.
|
||||
dst->z = v.z;
|
||||
if (dst->z < min.z)
|
||||
dst->z = min.z;
|
||||
if (dst->z > max.z)
|
||||
dst->z = max.z;
|
||||
|
||||
// Clamp the w value.
|
||||
dst->w = v.w;
|
||||
if (dst->w < min.w)
|
||||
dst->w = min.w;
|
||||
if (dst->w > max.w)
|
||||
dst->w = max.w;
|
||||
}
|
||||
|
||||
float Vec4::distance(const Vec4& v) const
|
||||
{
|
||||
float dx = v.x - x;
|
||||
float dy = v.y - y;
|
||||
float dz = v.z - z;
|
||||
float dw = v.w - w;
|
||||
|
||||
return std::sqrt(dx * dx + dy * dy + dz * dz + dw * dw);
|
||||
}
|
||||
|
||||
float Vec4::distanceSquared(const Vec4& v) const
|
||||
{
|
||||
float dx = v.x - x;
|
||||
float dy = v.y - y;
|
||||
float dz = v.z - z;
|
||||
float dw = v.w - w;
|
||||
|
||||
return (dx * dx + dy * dy + dz * dz + dw * dw);
|
||||
}
|
||||
|
||||
float Vec4::dot(const Vec4& v) const
|
||||
{
|
||||
return (x * v.x + y * v.y + z * v.z + w * v.w);
|
||||
}
|
||||
|
||||
float Vec4::dot(const Vec4& v1, const Vec4& v2)
|
||||
{
|
||||
return (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w);
|
||||
}
|
||||
|
||||
float Vec4::length() const
|
||||
{
|
||||
return std::sqrt(x * x + y * y + z * z + w * w);
|
||||
}
|
||||
|
||||
|
||||
float Vec4::lengthSquared() const
|
||||
{
|
||||
return (x * x + y * y + z * z + w * w);
|
||||
}
|
||||
|
||||
void Vec4::negate()
|
||||
{
|
||||
x = -x;
|
||||
y = -y;
|
||||
z = -z;
|
||||
w = -w;
|
||||
}
|
||||
|
||||
void Vec4::normalize()
|
||||
{
|
||||
float n = x * x + y * y + z * z + w * w;
|
||||
// Already normalized.
|
||||
if (n == 1.0f)
|
||||
return;
|
||||
|
||||
n = std::sqrt(n);
|
||||
// Too close to zero.
|
||||
if (n < MATH_TOLERANCE)
|
||||
return;
|
||||
|
||||
n = 1.0f / n;
|
||||
x *= n;
|
||||
y *= n;
|
||||
z *= n;
|
||||
w *= n;
|
||||
}
|
||||
|
||||
Vec4 Vec4::getNormalized() const
|
||||
{
|
||||
Vec4 v(*this);
|
||||
v.normalize();
|
||||
return v;
|
||||
}
|
||||
|
||||
void Vec4::scale(float scalar)
|
||||
{
|
||||
x *= scalar;
|
||||
y *= scalar;
|
||||
z *= scalar;
|
||||
w *= scalar;
|
||||
}
|
||||
|
||||
void Vec4::set(float xx, float yy, float zz, float ww)
|
||||
{
|
||||
this->x = xx;
|
||||
this->y = yy;
|
||||
this->z = zz;
|
||||
this->w = ww;
|
||||
}
|
||||
|
||||
void Vec4::set(const float* array)
|
||||
{
|
||||
GP_ASSERT(array);
|
||||
|
||||
x = array[0];
|
||||
y = array[1];
|
||||
z = array[2];
|
||||
w = array[3];
|
||||
}
|
||||
|
||||
void Vec4::set(const Vec4& v)
|
||||
{
|
||||
this->x = v.x;
|
||||
this->y = v.y;
|
||||
this->z = v.z;
|
||||
this->w = v.w;
|
||||
}
|
||||
|
||||
void Vec4::set(const Vec4& p1, const Vec4& p2)
|
||||
{
|
||||
x = p2.x - p1.x;
|
||||
y = p2.y - p1.y;
|
||||
z = p2.z - p1.z;
|
||||
w = p2.w - p1.w;
|
||||
}
|
||||
|
||||
void Vec4::subtract(const Vec4& v)
|
||||
{
|
||||
x -= v.x;
|
||||
y -= v.y;
|
||||
z -= v.z;
|
||||
w -= v.w;
|
||||
}
|
||||
|
||||
void Vec4::subtract(const Vec4& v1, const Vec4& v2, Vec4* dst)
|
||||
{
|
||||
GP_ASSERT(dst);
|
||||
|
||||
dst->x = v1.x - v2.x;
|
||||
dst->y = v1.y - v2.y;
|
||||
dst->z = v1.z - v2.z;
|
||||
dst->w = v1.w - v2.w;
|
||||
}
|
||||
|
||||
const Vec4 Vec4::ZERO = Vec4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
const Vec4 Vec4::ONE = Vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
const Vec4 Vec4::UNIT_X = Vec4(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
const Vec4 Vec4::UNIT_Y = Vec4(0.0f, 1.0f, 0.0f, 0.0f);
|
||||
const Vec4 Vec4::UNIT_Z = Vec4(0.0f, 0.0f, 1.0f, 0.0f);
|
||||
const Vec4 Vec4::UNIT_W = Vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
NS_CC_MATH_END
|
||||
470
cocos2d-x/cocos/math/Vec4.h
Normal file
470
cocos2d-x/cocos/math/Vec4.h
Normal file
@@ -0,0 +1,470 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
|
||||
#ifndef MATH_VEC4_H
|
||||
#define MATH_VEC4_H
|
||||
|
||||
#ifdef __SSE__
|
||||
#include <xmmintrin.h>
|
||||
#endif
|
||||
|
||||
#include "math/CCMathBase.h"
|
||||
|
||||
/**
|
||||
* @addtogroup base
|
||||
* @{
|
||||
*/
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
class Mat4;
|
||||
|
||||
/**
|
||||
* Defines 4-element floating point vector.
|
||||
*/
|
||||
class CC_DLL Vec4
|
||||
{
|
||||
public:
|
||||
#ifdef __SSE__
|
||||
union {
|
||||
struct {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float w;
|
||||
};
|
||||
__m128 v;
|
||||
};
|
||||
#else
|
||||
/**
|
||||
* The x-coordinate.
|
||||
*/
|
||||
float x;
|
||||
|
||||
/**
|
||||
* The y-coordinate.
|
||||
*/
|
||||
float y;
|
||||
|
||||
/**
|
||||
* The z-coordinate.
|
||||
*/
|
||||
float z;
|
||||
|
||||
/**
|
||||
* The w-coordinate.
|
||||
*/
|
||||
float w;
|
||||
#endif
|
||||
/**
|
||||
* Constructs a new vector initialized to all zeros.
|
||||
*/
|
||||
Vec4();
|
||||
|
||||
/**
|
||||
* Constructs a new vector initialized to the specified values.
|
||||
*
|
||||
* @param xx The x coordinate.
|
||||
* @param yy The y coordinate.
|
||||
* @param zz The z coordinate.
|
||||
* @param ww The w coordinate.
|
||||
*/
|
||||
Vec4(float xx, float yy, float zz, float ww);
|
||||
|
||||
/**
|
||||
* Constructs a new vector from the values in the specified array.
|
||||
*
|
||||
* @param array An array containing the elements of the vector in the order x, y, z, w.
|
||||
*/
|
||||
Vec4(const float* array);
|
||||
|
||||
/**
|
||||
* Constructs a vector that describes the direction between the specified points.
|
||||
*
|
||||
* @param p1 The first point.
|
||||
* @param p2 The second point.
|
||||
*/
|
||||
Vec4(const Vec4& p1, const Vec4& p2);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Creates a new vector that is a copy of the specified vector.
|
||||
*
|
||||
* @param copy The vector to copy.
|
||||
*/
|
||||
Vec4(const Vec4& copy);
|
||||
|
||||
/**
|
||||
* Creates a new vector from an integer interpreted as an RGBA value.
|
||||
* E.g. 0xff0000ff represents opaque red or the vector (1, 0, 0, 1).
|
||||
*
|
||||
* @param color The integer to interpret as an RGBA value.
|
||||
*
|
||||
* @return A vector corresponding to the interpreted RGBA color.
|
||||
*/
|
||||
static Vec4 fromColor(unsigned int color);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~Vec4();
|
||||
|
||||
/**
|
||||
* Indicates whether this vector contains all zeros.
|
||||
*
|
||||
* @return true if this vector contains all zeros, false otherwise.
|
||||
*/
|
||||
bool isZero() const;
|
||||
|
||||
/**
|
||||
* Indicates whether this vector contains all ones.
|
||||
*
|
||||
* @return true if this vector contains all ones, false otherwise.
|
||||
*/
|
||||
bool isOne() const;
|
||||
|
||||
/**
|
||||
* Returns the angle (in radians) between the specified vectors.
|
||||
*
|
||||
* @param v1 The first vector.
|
||||
* @param v2 The second vector.
|
||||
*
|
||||
* @return The angle between the two vectors (in radians).
|
||||
*/
|
||||
static float angle(const Vec4& v1, const Vec4& v2);
|
||||
|
||||
/**
|
||||
* Adds the elements of the specified vector to this one.
|
||||
*
|
||||
* @param v The vector to add.
|
||||
*/
|
||||
void add(const Vec4& v);
|
||||
|
||||
/**
|
||||
* Adds the specified vectors and stores the result in dst.
|
||||
*
|
||||
* @param v1 The first vector.
|
||||
* @param v2 The second vector.
|
||||
* @param dst A vector to store the result in.
|
||||
*/
|
||||
static void add(const Vec4& v1, const Vec4& v2, Vec4* dst);
|
||||
|
||||
/**
|
||||
* Clamps this vector within the specified range.
|
||||
*
|
||||
* @param min The minimum value.
|
||||
* @param max The maximum value.
|
||||
*/
|
||||
void clamp(const Vec4& min, const Vec4& max);
|
||||
|
||||
/**
|
||||
* Clamps the specified vector within the specified range and returns it in dst.
|
||||
*
|
||||
* @param v The vector to clamp.
|
||||
* @param min The minimum value.
|
||||
* @param max The maximum value.
|
||||
* @param dst A vector to store the result in.
|
||||
*/
|
||||
static void clamp(const Vec4& v, const Vec4& min, const Vec4& max, Vec4* dst);
|
||||
|
||||
/**
|
||||
* Returns the distance between this vector and v.
|
||||
*
|
||||
* @param v The other vector.
|
||||
*
|
||||
* @return The distance between this vector and v.
|
||||
*
|
||||
* @see distanceSquared
|
||||
*/
|
||||
float distance(const Vec4& v) const;
|
||||
|
||||
/**
|
||||
* Returns the squared distance between this vector and v.
|
||||
*
|
||||
* When it is not necessary to get the exact distance between
|
||||
* two vectors (for example, when simply comparing the
|
||||
* distance between different vectors), it is advised to use
|
||||
* this method instead of distance.
|
||||
*
|
||||
* @param v The other vector.
|
||||
*
|
||||
* @return The squared distance between this vector and v.
|
||||
*
|
||||
* @see distance
|
||||
*/
|
||||
float distanceSquared(const Vec4& v) const;
|
||||
|
||||
/**
|
||||
* Returns the dot product of this vector and the specified vector.
|
||||
*
|
||||
* @param v The vector to compute the dot product with.
|
||||
*
|
||||
* @return The dot product.
|
||||
*/
|
||||
float dot(const Vec4& v) const;
|
||||
|
||||
/**
|
||||
* Returns the dot product between the specified vectors.
|
||||
*
|
||||
* @param v1 The first vector.
|
||||
* @param v2 The second vector.
|
||||
*
|
||||
* @return The dot product between the vectors.
|
||||
*/
|
||||
static float dot(const Vec4& v1, const Vec4& v2);
|
||||
|
||||
/**
|
||||
* Computes the length of this vector.
|
||||
*
|
||||
* @return The length of the vector.
|
||||
*
|
||||
* @see lengthSquared
|
||||
*/
|
||||
float length() const;
|
||||
|
||||
/**
|
||||
* Returns the squared length of this vector.
|
||||
*
|
||||
* When it is not necessary to get the exact length of a
|
||||
* vector (for example, when simply comparing the lengths of
|
||||
* different vectors), it is advised to use this method
|
||||
* instead of length.
|
||||
*
|
||||
* @return The squared length of the vector.
|
||||
*
|
||||
* @see length
|
||||
*/
|
||||
float lengthSquared() const;
|
||||
|
||||
/**
|
||||
* Negates this vector.
|
||||
*/
|
||||
void negate();
|
||||
|
||||
/**
|
||||
* Normalizes this vector.
|
||||
*
|
||||
* This method normalizes this Vec4 so that it is of
|
||||
* unit length (in other words, the length of the vector
|
||||
* after calling this method will be 1.0f). If the vector
|
||||
* already has unit length or if the length of the vector
|
||||
* is zero, this method does nothing.
|
||||
*
|
||||
* @return This vector, after the normalization occurs.
|
||||
*/
|
||||
void normalize();
|
||||
|
||||
/**
|
||||
* Get the normalized vector.
|
||||
*/
|
||||
Vec4 getNormalized() const;
|
||||
|
||||
/**
|
||||
* Scales all elements of this vector by the specified value.
|
||||
*
|
||||
* @param scalar The scalar value.
|
||||
*/
|
||||
void scale(float scalar);
|
||||
|
||||
/**
|
||||
* Sets the elements of this vector to the specified values.
|
||||
*
|
||||
* @param xx The new x coordinate.
|
||||
* @param yy The new y coordinate.
|
||||
* @param zz The new z coordinate.
|
||||
* @param ww The new w coordinate.
|
||||
*/
|
||||
void set(float xx, float yy, float zz, float ww);
|
||||
|
||||
/**
|
||||
* Sets the elements of this vector from the values in the specified array.
|
||||
*
|
||||
* @param array An array containing the elements of the vector in the order x, y, z, w.
|
||||
*/
|
||||
void set(const float* array);
|
||||
|
||||
/**
|
||||
* Sets the elements of this vector to those in the specified vector.
|
||||
*
|
||||
* @param v The vector to copy.
|
||||
*/
|
||||
void set(const Vec4& v);
|
||||
|
||||
/**
|
||||
* Sets this vector to the directional vector between the specified points.
|
||||
*
|
||||
* @param p1 The first point.
|
||||
* @param p2 The second point.
|
||||
*/
|
||||
void set(const Vec4& p1, const Vec4& p2);
|
||||
|
||||
/**
|
||||
* Subtracts this vector and the specified vector as (this - v)
|
||||
* and stores the result in this vector.
|
||||
*
|
||||
* @param v The vector to subtract.
|
||||
*/
|
||||
void subtract(const Vec4& v);
|
||||
|
||||
/**
|
||||
* Subtracts the specified vectors and stores the result in dst.
|
||||
* The resulting vector is computed as (v1 - v2).
|
||||
*
|
||||
* @param v1 The first vector.
|
||||
* @param v2 The second vector.
|
||||
* @param dst The destination vector.
|
||||
*/
|
||||
static void subtract(const Vec4& v1, const Vec4& v2, Vec4* dst);
|
||||
|
||||
/**
|
||||
* Calculates the sum of this vector with the given vector.
|
||||
*
|
||||
* Note: this does not modify this vector.
|
||||
*
|
||||
* @param v The vector to add.
|
||||
* @return The vector sum.
|
||||
*/
|
||||
inline const Vec4 operator+(const Vec4& v) const;
|
||||
|
||||
/**
|
||||
* Adds the given vector to this vector.
|
||||
*
|
||||
* @param v The vector to add.
|
||||
* @return This vector, after the addition occurs.
|
||||
*/
|
||||
inline Vec4& operator+=(const Vec4& v);
|
||||
|
||||
/**
|
||||
* Calculates the sum of this vector with the given vector.
|
||||
*
|
||||
* Note: this does not modify this vector.
|
||||
*
|
||||
* @param v The vector to add.
|
||||
* @return The vector sum.
|
||||
*/
|
||||
inline const Vec4 operator-(const Vec4& v) const;
|
||||
|
||||
/**
|
||||
* Subtracts the given vector from this vector.
|
||||
*
|
||||
* @param v The vector to subtract.
|
||||
* @return This vector, after the subtraction occurs.
|
||||
*/
|
||||
inline Vec4& operator-=(const Vec4& v);
|
||||
|
||||
/**
|
||||
* Calculates the negation of this vector.
|
||||
*
|
||||
* Note: this does not modify this vector.
|
||||
*
|
||||
* @return The negation of this vector.
|
||||
*/
|
||||
inline const Vec4 operator-() const;
|
||||
|
||||
/**
|
||||
* Calculates the scalar product of this vector with the given value.
|
||||
*
|
||||
* Note: this does not modify this vector.
|
||||
*
|
||||
* @param s The value to scale by.
|
||||
* @return The scaled vector.
|
||||
*/
|
||||
inline const Vec4 operator*(float s) const;
|
||||
|
||||
/**
|
||||
* Scales this vector by the given value.
|
||||
*
|
||||
* @param s The value to scale by.
|
||||
* @return This vector, after the scale occurs.
|
||||
*/
|
||||
inline Vec4& operator*=(float s);
|
||||
|
||||
/**
|
||||
* Returns the components of this vector divided by the given constant
|
||||
*
|
||||
* Note: this does not modify this vector.
|
||||
*
|
||||
* @param s the constant to divide this vector with
|
||||
* @return a smaller vector
|
||||
*/
|
||||
inline const Vec4 operator/(float s) const;
|
||||
|
||||
/**
|
||||
* Determines if this vector is less than the given vector.
|
||||
*
|
||||
* @param v The vector to compare against.
|
||||
*
|
||||
* @return True if this vector is less than the given vector, false otherwise.
|
||||
*/
|
||||
inline bool operator<(const Vec4& v) const;
|
||||
|
||||
/**
|
||||
* Determines if this vector is equal to the given vector.
|
||||
*
|
||||
* @param v The vector to compare against.
|
||||
*
|
||||
* @return True if this vector is equal to the given vector, false otherwise.
|
||||
*/
|
||||
inline bool operator==(const Vec4& v) const;
|
||||
|
||||
/**
|
||||
* Determines if this vector is not equal to the given vector.
|
||||
*
|
||||
* @param v The vector to compare against.
|
||||
*
|
||||
* @return True if this vector is not equal to the given vector, false otherwise.
|
||||
*/
|
||||
inline bool operator!=(const Vec4& v) const;
|
||||
|
||||
/** equals to Vec4(0,0,0,0) */
|
||||
static const Vec4 ZERO;
|
||||
/** equals to Vec4(1,1,1,1) */
|
||||
static const Vec4 ONE;
|
||||
/** equals to Vec4(1,0,0,0) */
|
||||
static const Vec4 UNIT_X;
|
||||
/** equals to Vec4(0,1,0,0) */
|
||||
static const Vec4 UNIT_Y;
|
||||
/** equals to Vec4(0,0,1,0) */
|
||||
static const Vec4 UNIT_Z;
|
||||
/** equals to Vec4(0,0,0,1) */
|
||||
static const Vec4 UNIT_W;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates the scalar product of the given vector with the given value.
|
||||
*
|
||||
* @param x The value to scale by.
|
||||
* @param v The vector to scale.
|
||||
* @return The scaled vector.
|
||||
*/
|
||||
inline const Vec4 operator*(float x, const Vec4& v);
|
||||
|
||||
NS_CC_MATH_END
|
||||
/**
|
||||
end of base group
|
||||
@}
|
||||
*/
|
||||
#include "math/Vec4.inl"
|
||||
|
||||
#endif // MATH_VEC4_H
|
||||
|
||||
114
cocos2d-x/cocos/math/Vec4.inl
Normal file
114
cocos2d-x/cocos/math/Vec4.inl
Normal file
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Original file from GamePlay3D: http://gameplay3d.org
|
||||
|
||||
This file was modified to fit the cocos2d-x project
|
||||
*/
|
||||
|
||||
#include "math/Mat4.h"
|
||||
#include "math/Vec4.h"
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
inline const Vec4 Vec4::operator+(const Vec4& v) const
|
||||
{
|
||||
Vec4 result(*this);
|
||||
result.add(v);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline Vec4& Vec4::operator+=(const Vec4& v)
|
||||
{
|
||||
add(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const Vec4 Vec4::operator-(const Vec4& v) const
|
||||
{
|
||||
Vec4 result(*this);
|
||||
result.subtract(v);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline Vec4& Vec4::operator-=(const Vec4& v)
|
||||
{
|
||||
subtract(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const Vec4 Vec4::operator-() const
|
||||
{
|
||||
Vec4 result(*this);
|
||||
result.negate();
|
||||
return result;
|
||||
}
|
||||
|
||||
inline const Vec4 Vec4::operator*(float s) const
|
||||
{
|
||||
Vec4 result(*this);
|
||||
result.scale(s);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline Vec4& Vec4::operator*=(float s)
|
||||
{
|
||||
scale(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const Vec4 Vec4::operator/(const float s) const
|
||||
{
|
||||
return Vec4(this->x / s, this->y / s, this->z / s, this->w / s);
|
||||
}
|
||||
|
||||
inline bool Vec4::operator<(const Vec4& v) const
|
||||
{
|
||||
if (x == v.x)
|
||||
{
|
||||
if (y == v.y)
|
||||
{
|
||||
if (z < v.z)
|
||||
{
|
||||
if (w < v.w)
|
||||
{
|
||||
return w < v.w;
|
||||
}
|
||||
}
|
||||
return z < v.z;
|
||||
}
|
||||
return y < v.y;
|
||||
}
|
||||
return x < v.x;
|
||||
}
|
||||
|
||||
inline bool Vec4::operator==(const Vec4& v) const
|
||||
{
|
||||
return x==v.x && y==v.y && z==v.z && w==v.w;
|
||||
}
|
||||
|
||||
inline bool Vec4::operator!=(const Vec4& v) const
|
||||
{
|
||||
return x!=v.x || y!=v.y || z!=v.z || w!=v.w;
|
||||
}
|
||||
|
||||
inline const Vec4 operator*(float x, const Vec4& v)
|
||||
{
|
||||
Vec4 result(v);
|
||||
result.scale(x);
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_CC_MATH_END
|
||||
Reference in New Issue
Block a user