no message
This commit is contained in:
100
cocos/math/Color.cpp
Normal file
100
cocos/math/Color.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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 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 "Color.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
Color::Color()
|
||||
: r(0),
|
||||
g(0),
|
||||
b(0),
|
||||
a(0) {
|
||||
}
|
||||
|
||||
Color::Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||
: r(r),
|
||||
g(g),
|
||||
b(b),
|
||||
a(a) {
|
||||
}
|
||||
|
||||
Color::Color(const uint8_t *src) {
|
||||
set(src);
|
||||
}
|
||||
|
||||
Color::Color(uint32_t val) {
|
||||
set(val);
|
||||
}
|
||||
|
||||
Color::Color(const Color &p1, const Color &p2) {
|
||||
set(p1, p2);
|
||||
}
|
||||
|
||||
Color::Color(const Color ©) {
|
||||
set(copy);
|
||||
}
|
||||
|
||||
void Color::set(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
|
||||
this->r = r;
|
||||
this->g = g;
|
||||
this->b = b;
|
||||
this->a = a;
|
||||
}
|
||||
|
||||
void Color::set(const uint8_t *array) {
|
||||
r = array[0];
|
||||
g = array[1];
|
||||
b = array[2];
|
||||
a = array[3];
|
||||
}
|
||||
|
||||
void Color::set(uint32_t val) {
|
||||
r = val & 0x000000FF;
|
||||
g = (val & 0x0000FF00) >> 8;
|
||||
b = (val & 0x00FF0000) >> 16;
|
||||
a = (val & 0xFF000000) >> 24;
|
||||
}
|
||||
|
||||
void Color::set(const Color &c) {
|
||||
this->r = c.r;
|
||||
this->g = c.g;
|
||||
this->b = c.b;
|
||||
this->a = c.a;
|
||||
}
|
||||
|
||||
void Color::set(const Color &p1, const Color &p2) {
|
||||
r = p2.r - p1.r;
|
||||
g = p2.g - p1.g;
|
||||
b = p2.b - p1.b;
|
||||
a = p2.a - p1.a;
|
||||
}
|
||||
|
||||
Vec4 Color::toVec4() const {
|
||||
return {static_cast<float>(r) / 255.F, static_cast<float>(g) / 255.F, static_cast<float>(b) / 255.F, static_cast<float>(a) / 255.F};
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
118
cocos/math/Color.h
Normal file
118
cocos/math/Color.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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 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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "math/Vec4.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
class Color {
|
||||
public:
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
uint8_t a;
|
||||
/**
|
||||
* Constructs a new color initialized to all zeros.
|
||||
*/
|
||||
Color();
|
||||
|
||||
/**
|
||||
* Constructs a new color 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.
|
||||
*/
|
||||
explicit Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
|
||||
|
||||
/**
|
||||
* Constructs a new color from the values in the specified array.
|
||||
*
|
||||
* @param array An array containing the elements of the color in the order r, g, b, a.
|
||||
*/
|
||||
explicit Color(const uint8_t *src);
|
||||
|
||||
explicit Color(uint32_t val);
|
||||
|
||||
/**
|
||||
* Constructs a color that describes the direction between the specified points.
|
||||
*
|
||||
* @param p1 The first point.
|
||||
* @param p2 The second point.
|
||||
*/
|
||||
Color(const Color &p1, const Color &p2);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Creates a new color that is a copy of the specified color.
|
||||
*
|
||||
* @param copy The color to copy.
|
||||
*/
|
||||
Color(const Color ©);
|
||||
/**
|
||||
* Sets the elements of this color 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(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
|
||||
|
||||
/**
|
||||
* Sets the elements of this color from the values in the specified array.
|
||||
*
|
||||
* @param array An array containing the elements of the color in the order r, g, b, a.
|
||||
*/
|
||||
void set(const uint8_t *array);
|
||||
|
||||
void set(uint32_t val);
|
||||
|
||||
/**
|
||||
* Sets the elements of this color to those in the specified color.
|
||||
*
|
||||
* @param v The color to copy.
|
||||
*/
|
||||
void set(const Color &c);
|
||||
|
||||
/**
|
||||
* Sets this color to the directional color between the specified points.
|
||||
*
|
||||
* @param p1 The first point.
|
||||
* @param p2 The second point.
|
||||
*/
|
||||
void set(const Color &p1, const Color &p2);
|
||||
|
||||
Vec4 toVec4() const;
|
||||
};
|
||||
|
||||
} // namespace cc
|
||||
241
cocos/math/Geometry.cpp
Normal file
241
cocos/math/Geometry.cpp
Normal file
@@ -0,0 +1,241 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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/Geometry.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include "base/Macros.h"
|
||||
|
||||
// implementation of Vec2
|
||||
namespace cc {
|
||||
|
||||
// implementation of Size
|
||||
|
||||
Size::Size() = default;
|
||||
|
||||
Size::Size(float w, float h) : width(w),
|
||||
height(h) {
|
||||
}
|
||||
|
||||
Size::Size(const Size &other) = default;
|
||||
|
||||
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 {
|
||||
CC_ASSERT_NE(a, 0);
|
||||
float inv = 1.0F / a;
|
||||
return Size(this->width * inv, this->height * inv);
|
||||
}
|
||||
|
||||
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() {
|
||||
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.x, other.y, other.width, other.height);
|
||||
}
|
||||
|
||||
Rect &Rect::operator=(const Rect &other) {
|
||||
setRect(other.x, other.y, other.width, other.height);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Rect::setRect(float x, float y, float width, float height) {
|
||||
// CGRect can support width<0 or height<0
|
||||
// CC_ASSERT(width >= 0.0f && height >= 0.0f);
|
||||
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
}
|
||||
|
||||
bool Rect::equals(const Rect &rect) const {
|
||||
return (std::abs(this->x - rect.x) < FLT_EPSILON) && (std::abs(this->y - rect.y) < FLT_EPSILON) && (std::abs(this->width - rect.width) < FLT_EPSILON) && (std::abs(this->height - rect.height) < FLT_EPSILON);
|
||||
}
|
||||
|
||||
float Rect::getMaxX() const {
|
||||
return this->x + this->width;
|
||||
}
|
||||
|
||||
float Rect::getMidX() const {
|
||||
return this->x + this->width / 2.0F;
|
||||
}
|
||||
|
||||
float Rect::getMinX() const {
|
||||
return this->x;
|
||||
}
|
||||
|
||||
float Rect::getMaxY() const {
|
||||
return this->y + this->height;
|
||||
}
|
||||
|
||||
float Rect::getMidY() const {
|
||||
return this->y + this->height / 2.0F;
|
||||
}
|
||||
|
||||
float Rect::getMinY() const {
|
||||
return this->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 Vec2 ¢er, float radius) const {
|
||||
Vec2 rectangleCenter((this->x + this->width / 2),
|
||||
(this->y + this->height / 2));
|
||||
|
||||
float w = this->width / 2;
|
||||
float h = this->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 - this->x - w),
|
||||
std::abs(center.y - this->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 = this->x;
|
||||
float thisRightX = this->x + this->width;
|
||||
float thisTopY = this->y + this->height;
|
||||
float thisBottomY = this->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.x;
|
||||
float otherRightX = rect.x + rect.width;
|
||||
float otherTopY = rect.y + rect.height;
|
||||
float otherBottomY = rect.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);
|
||||
|
||||
} // namespace cc
|
||||
140
cocos/math/Geometry.h
Normal file
140
cocos/math/Geometry.h
Normal file
@@ -0,0 +1,140 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "base/Macros.h"
|
||||
#include "math/Vec2.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
class CC_DLL Size {
|
||||
public:
|
||||
/**Width of the Size.*/
|
||||
float width{0.F};
|
||||
/**Height of the Size.*/
|
||||
float height{0.F};
|
||||
|
||||
/**Conversion from Vec2 to Size.*/
|
||||
operator Vec2() const { // NOLINT
|
||||
return Vec2(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
@{
|
||||
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);
|
||||
/**@}*/
|
||||
|
||||
Size &operator=(const Size &other);
|
||||
Size &operator=(const Vec2 &point);
|
||||
Size operator+(const Size &right) const;
|
||||
Size operator-(const Size &right) const;
|
||||
Size operator*(float a) const;
|
||||
Size operator/(float a) const;
|
||||
/**
|
||||
Set the width and height of Size.
|
||||
*/
|
||||
void setSize(float width, float height);
|
||||
/**
|
||||
Check if two size is the same.
|
||||
*/
|
||||
bool equals(const Size &target) const;
|
||||
/**Size(0,0).*/
|
||||
static const Size ZERO;
|
||||
};
|
||||
|
||||
/**Rectangle area.*/
|
||||
class CC_DLL Rect {
|
||||
public:
|
||||
float x{0.F};
|
||||
float y{0.F};
|
||||
float width{0.F};
|
||||
float height{0.F};
|
||||
|
||||
Rect();
|
||||
Rect(float x, float y, float width, float height);
|
||||
Rect(const Vec2 &pos, const Size &dimension);
|
||||
Rect(const Rect &other);
|
||||
Rect &operator=(const Rect &other);
|
||||
void setRect(float x, float y, float width, float height);
|
||||
/**
|
||||
Get the left of the rect.
|
||||
*/
|
||||
float getMinX() const; /// return the leftmost x-value of current rect
|
||||
/**
|
||||
Get the X coordinate of center point.
|
||||
*/
|
||||
float getMidX() const; /// return the midpoint x-value of current rect
|
||||
/**
|
||||
Get the right of rect.
|
||||
*/
|
||||
float getMaxX() const; /// return the rightmost x-value of current rect
|
||||
/**
|
||||
Get the bottom of rect.
|
||||
*/
|
||||
float getMinY() const; /// return the bottommost y-value of current rect
|
||||
/**
|
||||
Get the Y coordinate of center point.
|
||||
*/
|
||||
float getMidY() const; /// return the midpoint y-value of current rect
|
||||
/**
|
||||
Get top of rect.
|
||||
*/
|
||||
float getMaxY() const; /// return the topmost y-value of current rect
|
||||
|
||||
bool equals(const Rect &rect) const;
|
||||
/**
|
||||
Check if the points is contained in the rect.
|
||||
*/
|
||||
bool containsPoint(const Vec2 &point) const;
|
||||
/**
|
||||
Check the intersect status of two rects.
|
||||
*/
|
||||
bool intersectsRect(const Rect &rect) const;
|
||||
/**
|
||||
Check the intersect status of the rect and a circle.
|
||||
*/
|
||||
bool intersectsCircle(const Vec2 ¢er, float radius) const;
|
||||
/**
|
||||
Get the min rect which can contain this and rect.
|
||||
*/
|
||||
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;
|
||||
};
|
||||
|
||||
} // namespace cc
|
||||
448
cocos/math/Mat3.cpp
Normal file
448
cocos/math/Mat3.cpp
Normal file
@@ -0,0 +1,448 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018-2023 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 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.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include "base/Macros.h"
|
||||
#include "math/Math.h"
|
||||
#include "math/MathUtil.h"
|
||||
#include "math/Quaternion.h"
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
Mat3::Mat3() {
|
||||
*this = IDENTITY;
|
||||
}
|
||||
|
||||
Mat3::Mat3(float m00, float m01, float m02,
|
||||
float m03, float m04, float m05,
|
||||
float m06, float m07, float m08) {
|
||||
set(m00, m01, m02, m03, m04, m05, m06, m07, m08);
|
||||
}
|
||||
|
||||
Mat3::Mat3(const float *mat) {
|
||||
set(mat);
|
||||
}
|
||||
|
||||
Mat3::Mat3(const Mat3 ©) {
|
||||
memcpy(m, copy.m, MATRIX3_SIZE);
|
||||
}
|
||||
|
||||
void Mat3::set(float m00, float m01, float m02,
|
||||
float m03, float m04, float m05,
|
||||
float m06, float m07, float m08) {
|
||||
m[0] = m00;
|
||||
m[1] = m01;
|
||||
m[2] = m02;
|
||||
m[3] = m03;
|
||||
m[4] = m04;
|
||||
m[5] = m05;
|
||||
m[6] = m06;
|
||||
m[7] = m07;
|
||||
m[8] = m08;
|
||||
}
|
||||
|
||||
void Mat3::set(const float *mat) {
|
||||
CC_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::fromViewUp(const Vec3 &view, Mat3 *out) {
|
||||
CC_ASSERT(out);
|
||||
fromViewUp(view, Vec3(0, 1, 0), out);
|
||||
}
|
||||
void Mat3::fromViewUp(const Vec3 &view, const Vec3 &up, Mat3 *out) {
|
||||
CC_ASSERT(out);
|
||||
if (view.lengthSquared() < math::EPSILON * math::EPSILON) {
|
||||
Mat3::identity(*out);
|
||||
return;
|
||||
}
|
||||
Vec3 vTempA{Vec3::ZERO};
|
||||
Vec3 vTempB{Vec3::ZERO};
|
||||
|
||||
Vec3::cross(up, view, &vTempA);
|
||||
vTempA.normalize();
|
||||
if (vTempA.lengthSquared() < math::EPSILON * math::EPSILON) {
|
||||
Mat3::identity(*out);
|
||||
return;
|
||||
}
|
||||
Vec3::cross(view, vTempA, &vTempB);
|
||||
out->set(vTempA.x, vTempA.y, vTempA.z,
|
||||
vTempB.x, vTempB.y, vTempB.z,
|
||||
view.x, view.y, view.z);
|
||||
}
|
||||
|
||||
void Mat3::transpose() {
|
||||
float a01 = m[1];
|
||||
float a02 = m[2];
|
||||
float 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(const Mat3 &mat, Mat3 *out) {
|
||||
CC_ASSERT(out);
|
||||
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];
|
||||
float a01 = m[1];
|
||||
float a02 = m[2];
|
||||
float a10 = m[3];
|
||||
float a11 = m[4];
|
||||
float a12 = m[5];
|
||||
float a20 = m[6];
|
||||
float a21 = m[7];
|
||||
float 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;
|
||||
if (det == 0.F) {
|
||||
set(0.F, 0.F, 0.F, 0.F, 0.F, 0.F, 0.F, 0.F, 0.F);
|
||||
return;
|
||||
}
|
||||
|
||||
det = 1.0F / 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(const Mat3 &mat, Mat3 *out) {
|
||||
CC_ASSERT(out);
|
||||
float a00 = mat.m[0];
|
||||
float a01 = mat.m[1];
|
||||
float a02 = mat.m[2];
|
||||
float a10 = mat.m[3];
|
||||
float a11 = mat.m[4];
|
||||
float a12 = mat.m[5];
|
||||
float a20 = mat.m[6];
|
||||
float a21 = mat.m[7];
|
||||
float 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(const Mat3 &a, const Mat3 &b, Mat3 *out) {
|
||||
CC_ASSERT(out);
|
||||
float a00 = a.m[0];
|
||||
float a01 = a.m[1];
|
||||
float a02 = a.m[2];
|
||||
float a10 = a.m[3];
|
||||
float a11 = a.m[4];
|
||||
float a12 = a.m[5];
|
||||
float a20 = a.m[6];
|
||||
float a21 = a.m[7];
|
||||
float a22 = a.m[8];
|
||||
|
||||
float b00 = b.m[0];
|
||||
float b01 = b.m[1];
|
||||
float b02 = b.m[2];
|
||||
float b10 = b.m[3];
|
||||
float b11 = b.m[4];
|
||||
float b12 = b.m[5];
|
||||
float b20 = b.m[6];
|
||||
float b21 = b.m[7];
|
||||
float 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(const Mat3 &mat, const Vec2 &vec, Mat3 *out) {
|
||||
CC_ASSERT(out);
|
||||
float a00 = mat.m[0];
|
||||
float a01 = mat.m[1];
|
||||
float a02 = mat.m[2];
|
||||
float a10 = mat.m[3];
|
||||
float a11 = mat.m[4];
|
||||
float a12 = mat.m[5];
|
||||
float a20 = mat.m[6];
|
||||
float a21 = mat.m[7];
|
||||
float a22 = mat.m[8];
|
||||
float x = vec.x;
|
||||
float 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(const Mat3 &mat, float rad, Mat3 *out) {
|
||||
CC_ASSERT(out);
|
||||
float a00 = mat.m[0];
|
||||
float a01 = mat.m[1];
|
||||
float a02 = mat.m[2];
|
||||
float a10 = mat.m[3];
|
||||
float a11 = mat.m[4];
|
||||
float a12 = mat.m[5];
|
||||
float a20 = mat.m[6];
|
||||
float a21 = mat.m[7];
|
||||
float 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(const Mat3 &mat, const Vec2 &vec, Mat3 *out) {
|
||||
CC_ASSERT(out);
|
||||
float x = vec.x;
|
||||
float 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(const Mat4 &mat, Mat3 *out) {
|
||||
CC_ASSERT(out);
|
||||
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(const Vec2 &vec, Mat3 *out) {
|
||||
CC_ASSERT(out);
|
||||
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(float rad, Mat3 *out) {
|
||||
CC_ASSERT(out);
|
||||
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(const Vec2 &vec, Mat3 *out) {
|
||||
CC_ASSERT(out);
|
||||
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(const Quaternion &quat, Mat3 *out) {
|
||||
CC_ASSERT(out);
|
||||
float x = quat.x;
|
||||
float y = quat.y;
|
||||
float z = quat.z;
|
||||
float 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(const Mat3 &a, const Mat3 &b, Mat3 *out) {
|
||||
CC_ASSERT(out);
|
||||
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(const Mat3 &a, const Mat3 &b, Mat3 *out) {
|
||||
CC_ASSERT(out);
|
||||
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];
|
||||
}
|
||||
|
||||
bool Mat3::approxEquals(const Mat3 &v, float precision /* = CC_FLOAT_CMP_PRECISION */) const {
|
||||
return math::isEqualF(m[0], v.m[0], precision) &&
|
||||
math::isEqualF(m[1], v.m[1], precision) &&
|
||||
math::isEqualF(m[2], v.m[2], precision) &&
|
||||
math::isEqualF(m[3], v.m[3], precision) &&
|
||||
math::isEqualF(m[4], v.m[4], precision) &&
|
||||
math::isEqualF(m[5], v.m[5], precision) &&
|
||||
math::isEqualF(m[6], v.m[6], precision) &&
|
||||
math::isEqualF(m[7], v.m[7], precision) &&
|
||||
math::isEqualF(m[8], v.m[8], precision);
|
||||
}
|
||||
|
||||
const Mat3 Mat3::IDENTITY = Mat3(
|
||||
1.F, 0.F, 0.F,
|
||||
0.F, 1.F, 0.F,
|
||||
0.F, 0.F, 1.F);
|
||||
|
||||
const Mat3 Mat3::ZERO = Mat3(
|
||||
0, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 0);
|
||||
|
||||
NS_CC_MATH_END
|
||||
244
cocos/math/Mat3.h
Normal file
244
cocos/math/Mat3.h
Normal file
@@ -0,0 +1,244 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018-2023 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 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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define MATRIX3_SIZE (sizeof(float) * 9)
|
||||
|
||||
#include "base/Macros.h"
|
||||
|
||||
#include "math/Mat4.h"
|
||||
#include "math/Vec2.h"
|
||||
#include "math/Vec3.h"
|
||||
#include "math/Vec4.h"
|
||||
|
||||
/**
|
||||
* @addtogroup base
|
||||
* @{
|
||||
*/
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
class CC_DLL Mat3 {
|
||||
public:
|
||||
/**
|
||||
* Stores the columns of this 3x3 matrix.
|
||||
* matrix layout
|
||||
* |m[0] m[3] m[6]|
|
||||
* |m[1] m[4] m[7]|
|
||||
* |m[2] m[5] m[8]|
|
||||
*/
|
||||
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 values which are column-major order.
|
||||
*/
|
||||
Mat3(float m00, float m01, float m02,
|
||||
float m03, float m04, float m05,
|
||||
float m06, float m07, float m08);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
explicit 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 ©);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Construct a new Mat 3 object with a Mat4.
|
||||
* Copies the upper-left 3x3 values of a 4x4 matrix into a 3x3 matrix.
|
||||
* @param m4
|
||||
*/
|
||||
explicit Mat3(const Mat4 &m4) {
|
||||
fromMat4(m4, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new Mat 3 object with a Quaternion
|
||||
* Calculates a 3x3 matrix from the given quaternion.
|
||||
* @param quat
|
||||
*/
|
||||
explicit Mat3(const Quaternion &quat) {
|
||||
fromQuat(quat, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~Mat3() = default;
|
||||
|
||||
/**
|
||||
* Sets the values of this matrix which are column-major order.
|
||||
*/
|
||||
void set(float m00, float m01, float m02,
|
||||
float m03, float m04, float m05,
|
||||
float m06, float m07, float m08);
|
||||
|
||||
/**
|
||||
* 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(const Mat3 &mat, Mat3 *out);
|
||||
|
||||
/**
|
||||
* Inverts a matrix.
|
||||
*/
|
||||
void inverse();
|
||||
|
||||
/**
|
||||
* Calculates the adjoint matrix.
|
||||
*/
|
||||
static void adjoint(const Mat3 &mat, Mat3 *out);
|
||||
|
||||
/**
|
||||
* Calculates the determinant of a matrix.
|
||||
*/
|
||||
float determinant();
|
||||
|
||||
/**
|
||||
* Multiply two matrices explicitly.
|
||||
*/
|
||||
static void multiply(const Mat3 &a, const Mat3 &b, Mat3 *out);
|
||||
|
||||
/**
|
||||
* Multiply a matrix with a translation matrix given by a translation offset.
|
||||
*/
|
||||
static void translate(const Mat3 &mat, const Vec2 &vec, Mat3 *out);
|
||||
|
||||
/**
|
||||
* Rotates a matrix by the given angle.
|
||||
*/
|
||||
static void rotate(const Mat3 &mat, float rad, Mat3 *out);
|
||||
|
||||
/**
|
||||
* Multiply a matrix with a scale matrix given by a scale vector.
|
||||
*/
|
||||
static void scale(const Mat3 &mat, const Vec2 &vec, Mat3 *out);
|
||||
|
||||
/**
|
||||
* Copies the upper-left 3x3 values of a 4x4 matrix into a 3x3 matrix.
|
||||
*/
|
||||
static void fromMat4(const Mat4 &mat, Mat3 *out);
|
||||
|
||||
/**
|
||||
* Creates a matrix from a translation offset.
|
||||
*/
|
||||
static void fromTranslation(const Vec2 &vec, Mat3 *out);
|
||||
|
||||
/**
|
||||
* Creates a matrix from a given angle.
|
||||
*/
|
||||
static void fromRotation(float rad, Mat3 *out);
|
||||
|
||||
/**
|
||||
* Creates a matrix from a scale vector.
|
||||
*/
|
||||
static void fromScaling(const Vec2 &vec, Mat3 *out);
|
||||
|
||||
/**
|
||||
* Sets a third order matrix with view direction and up direction. Then save the results to out matrix
|
||||
*/
|
||||
static void fromViewUp(const Vec3 &view, Mat3 *out);
|
||||
static void fromViewUp(const Vec3 &view, const Vec3 &up, Mat3 *out);
|
||||
|
||||
/**
|
||||
* Calculates a 3x3 matrix from the given quaternion.
|
||||
*/
|
||||
|
||||
static void fromQuat(const Quaternion &quat, Mat3 *out);
|
||||
|
||||
/**
|
||||
* Adds two matrices.
|
||||
*/
|
||||
static void add(const Mat3 &a, const Mat3 &b, Mat3 *out);
|
||||
|
||||
/**
|
||||
* Subtracts matrix b from matrix a.
|
||||
*/
|
||||
static void subtract(const Mat3 &a, const Mat3 &b, Mat3 *out);
|
||||
|
||||
/**
|
||||
* Determines if this matrix is approximately equal to the given matrix.
|
||||
*/
|
||||
bool approxEquals(const Mat3 &v, float precision = CC_FLOAT_CMP_PRECISION) const;
|
||||
|
||||
/** 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
|
||||
@}
|
||||
*/
|
||||
1061
cocos/math/Mat4.cpp
Normal file
1061
cocos/math/Mat4.cpp
Normal file
File diff suppressed because it is too large
Load Diff
964
cocos/math/Mat4.h
Normal file
964
cocos/math/Mat4.h
Normal file
@@ -0,0 +1,964 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "base/Macros.h"
|
||||
|
||||
#include "math/Vec3.h"
|
||||
#include "math/Vec4.h"
|
||||
|
||||
#undef __SSE__
|
||||
#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.
|
||||
* matrix layout
|
||||
* |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]|
|
||||
*/
|
||||
#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 m00 Component in column 0, row 0 position (index 0)
|
||||
* @param m01 Component in column 0, row 1 position (index 1)
|
||||
* @param m02 Component in column 0, row 2 position (index 2)
|
||||
* @param m03 Component in column 0, row 3 position (index 3)
|
||||
* @param m10 Component in column 1, row 0 position (index 4)
|
||||
* @param m11 Component in column 1, row 1 position (index 5)
|
||||
* @param m12 Component in column 1, row 2 position (index 6)
|
||||
* @param m13 Component in column 1, row 3 position (index 7)
|
||||
* @param m20 Component in column 2, row 0 position (index 8)
|
||||
* @param m21 Component in column 2, row 1 position (index 9)
|
||||
* @param m22 Component in column 2, row 2 position (index 10)
|
||||
* @param m23 Component in column 2, row 3 position (index 11)
|
||||
* @param m30 Component in column 3, row 0 position (index 12)
|
||||
* @param m31 Component in column 3, row 1 position (index 13)
|
||||
* @param m32 Component in column 3, row 2 position (index 14)
|
||||
* @param m33 Component in column 3, row 3 position (index 15)
|
||||
*/
|
||||
Mat4(float m00, float m01, float m02, float m03,
|
||||
float m10, float m11, float m12, float m13,
|
||||
float m20, float m21, float m22, float m23,
|
||||
float m30, 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 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.
|
||||
*/
|
||||
explicit 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 ©);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~Mat4() = default;
|
||||
|
||||
/**
|
||||
* 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 targetPositionX, float targetPositionY, float targetPositionZ,
|
||||
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 = nullptr) {
|
||||
Mat4::createPerspective(fieldOfView, aspectRatio, zNearPlane, zFarPlane, true, -1.0F, 1.0F, 0, dst);
|
||||
}
|
||||
|
||||
static void createPerspective(float fieldOfView, float aspectRatio, float zNearPlane, float zFarPlane,
|
||||
bool isFieldOfViewY = false, float minClipZ = -1, float projectionSignY = 1,
|
||||
int orientation = 0, Mat4 *dst = nullptr);
|
||||
|
||||
/**
|
||||
* 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 createOrthographic(float left, float right, float bottom, float top, float zNearPlane, float zFarPlane, Mat4 *dst);
|
||||
|
||||
static void createOrthographicOffCenter(float left, float right, float bottom, float top,
|
||||
float zNearPlane, float zFarPlane, Mat4 *dst);
|
||||
|
||||
static void createOrthographicOffCenter(float left, float right, float bottom, float top,
|
||||
float zNearPlane, float zFarPlane, float minClipZ,
|
||||
float projectionSignY, int orientation, 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);
|
||||
|
||||
/**
|
||||
* Calculate the matrix according to the ratation and translation
|
||||
*/
|
||||
static void fromRT(const Quaternion &rotation, const Vec3 &translation, Mat4 *dst);
|
||||
|
||||
/**
|
||||
* Compose a matrix from scale, rotation and translation, applied in order.
|
||||
*/
|
||||
static void fromRTS(const Quaternion &rotation, const Vec3 &translation, const Vec3 &scale, Mat4 *dst);
|
||||
|
||||
/**
|
||||
* Decomposes the scale, rotation and translation components of this matrix.
|
||||
*/
|
||||
static void toRTS(const Mat4 &src, Quaternion *rotation, Vec3 *translation, Vec3 *scale);
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
/**
|
||||
* Clone this matrix.
|
||||
*
|
||||
* @return a new clone matrix.
|
||||
*/
|
||||
Mat4 clone() const;
|
||||
|
||||
/**
|
||||
* 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 m00 Component in column 0, row 0 position (index 0)
|
||||
* @param m01 Component in column 0, row 1 position (index 1)
|
||||
* @param m02 Component in column 0, row 2 position (index 2)
|
||||
* @param m03 Component in column 0, row 3 position (index 3)
|
||||
* @param m10 Component in column 1, row 0 position (index 4)
|
||||
* @param m11 Component in column 1, row 1 position (index 5)
|
||||
* @param m12 Component in column 1, row 2 position (index 6)
|
||||
* @param m13 Component in column 1, row 3 position (index 7)
|
||||
* @param m20 Component in column 2, row 0 position (index 8)
|
||||
* @param m21 Component in column 2, row 1 position (index 9)
|
||||
* @param m22 Component in column 2, row 2 position (index 10)
|
||||
* @param m23 Component in column 2, row 3 position (index 11)
|
||||
* @param m30 Component in column 3, row 0 position (index 12)
|
||||
* @param m31 Component in column 3, row 1 position (index 13)
|
||||
* @param m32 Component in column 3, row 2 position (index 14)
|
||||
* @param m33 Component in column 3, row 3 position (index 15)
|
||||
*/
|
||||
void set(float m00, float m01, float m02, float m03,
|
||||
float m10, float m11, float m12, float m13,
|
||||
float m20, float m21, float m22, float m23,
|
||||
float m30, 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 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 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 inverse transpose of a matrix and save the results to out matrix
|
||||
*/
|
||||
static void inverseTranspose(const Mat4 &mat, Mat4 *dst);
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Determines if this matrix is approximately equal to the given matrix.
|
||||
*/
|
||||
bool approxEquals(const Mat4 &v, float precision = CC_FLOAT_CMP_PRECISION) const;
|
||||
|
||||
/** 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 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"
|
||||
86
cocos/math/Mat4.inl
Normal file
86
cocos/math/Mat4.inl
Normal file
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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"
|
||||
|
||||
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 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
|
||||
60
cocos/math/Math.cpp
Normal file
60
cocos/math/Math.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
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/Math.h"
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
namespace cc {
|
||||
namespace math {
|
||||
|
||||
const float PI = static_cast<float>(3.14159265358979323846264338327950288419716939937511);
|
||||
|
||||
const float PI_2 = math::PI * 2.0F;
|
||||
const float PI_DIV2 = math::PI * 0.5F;
|
||||
const float PI_DIV3 = math::PI / 3.0F;
|
||||
const float PI_DIV4 = math::PI / 4.0F;
|
||||
const float PI_DIV5 = math::PI / 5.0F;
|
||||
const float PI_DIV6 = math::PI / 6.0F;
|
||||
const float PI_DIV8 = math::PI / 8.0F;
|
||||
const float PI_SQR = static_cast<float>(9.86960440108935861883449099987615113531369940724079);
|
||||
const float PI_INV = static_cast<float>(0.31830988618379067153776752674502872406891929148091);
|
||||
const float EPSILON = std::numeric_limits<float>::epsilon();
|
||||
const float LOW_EPSILON = static_cast<float>(1e-04);
|
||||
const float POS_INFINITY = std::numeric_limits<float>::infinity();
|
||||
const float NEG_INFINITY = -std::numeric_limits<float>::infinity();
|
||||
|
||||
const float LN2 = std::log(2.0F);
|
||||
const float LN10 = std::log(10.0F);
|
||||
const float LN2_INV = 1.0F / LN2;
|
||||
const float LN10_INV = 1.0F / LN10;
|
||||
const float DEG_TO_RAD = static_cast<float>(0.01745329);
|
||||
const float RAD_TO_DEG = static_cast<float>(57.29577);
|
||||
const float MIN_FLOAT = 1.175494351e-38F;
|
||||
const float MAX_FLOAT = 3.402823466e+38F;
|
||||
|
||||
} // namespace math
|
||||
} // namespace cc
|
||||
83
cocos/math/Math.h
Normal file
83
cocos/math/Math.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2017-2023 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 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.
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include "base/Macros.h"
|
||||
|
||||
namespace cc {
|
||||
namespace math {
|
||||
|
||||
extern CC_DLL const float PI;
|
||||
extern CC_DLL const float PI_2;
|
||||
extern CC_DLL const float PI_DIV2;
|
||||
extern CC_DLL const float PI_DIV3;
|
||||
extern CC_DLL const float PI_DIV4;
|
||||
extern CC_DLL const float PI_DIV5;
|
||||
extern CC_DLL const float PI_DIV6;
|
||||
extern CC_DLL const float PI_DIV8;
|
||||
extern CC_DLL const float PI_SQR;
|
||||
extern CC_DLL const float PI_INV;
|
||||
extern CC_DLL const float EPSILON;
|
||||
extern CC_DLL const float LOW_EPSILON;
|
||||
extern CC_DLL const float POS_INFINITY;
|
||||
extern CC_DLL const float NEG_INFINITY;
|
||||
extern CC_DLL const float LN2;
|
||||
extern CC_DLL const float LN10;
|
||||
extern CC_DLL const float LN2_INV;
|
||||
extern CC_DLL const float LN10_INV;
|
||||
extern CC_DLL const float DEG_TO_RAD;
|
||||
extern CC_DLL const float RAD_TO_DEG;
|
||||
extern CC_DLL const float MIN_FLOAT;
|
||||
extern CC_DLL const float MAX_FLOAT;
|
||||
|
||||
#define CC_FLOAT_CMP_PRECISION (0.00001F)
|
||||
|
||||
template <typename T>
|
||||
inline T sgn(T x) {
|
||||
return (x < T(0) ? T(-1) : (x > T(0) ? T(1) : T(0)));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool isPowerOfTwo(T n) {
|
||||
return (n & (n - 1)) == 0;
|
||||
}
|
||||
|
||||
inline bool isEqualF(float lhs, float rhs, float precision = 0.000001F) {
|
||||
const bool hasInf = std::isinf(lhs) || std::isinf(rhs);
|
||||
return !hasInf && (std::fabs(lhs - rhs) <= (std::fmax(std::fmax(std::fabs(lhs), std::fabs(rhs)), 1.0F) * precision));
|
||||
}
|
||||
|
||||
inline bool isNotEqualF(float lhs, float rhs, float precision = 0.000001F) { // same as !isEqualF
|
||||
const bool hasInf = std::isinf(lhs) || std::isinf(rhs);
|
||||
return hasInf || (std::fabs(lhs - rhs) > (std::fmax(std::fmax(std::fabs(lhs), std::fabs(rhs)), 1.0F) * precision));
|
||||
}
|
||||
|
||||
inline bool isNotZeroF(float v, float precision = 0.000001F) { // same as isNotEqualF(v, 0.0F)
|
||||
return std::isinf(v) || (std::fabs(v) > (std::fmax(std::fabs(v), 1.0F) * precision));
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace cc
|
||||
102
cocos/math/MathBase.h
Normal file
102
cocos/math/MathBase.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2017-2023 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 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 __CCMATHBASE_H__
|
||||
#define __CCMATHBASE_H__
|
||||
|
||||
#include <memory>
|
||||
#include "base/Macros.h"
|
||||
|
||||
#if CC_PLATFORM != CC_PLATFORM_EMSCRIPTEN
|
||||
#include "base/std/hash/hash.h"
|
||||
#endif
|
||||
/**
|
||||
* @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 cc {
|
||||
#define NS_CC_MATH_END }
|
||||
#define USING_NS_CC_MATH using namespace cc
|
||||
#else
|
||||
#define NS_CC_MATH_BEGIN
|
||||
#define NS_CC_MATH_END
|
||||
#define USING_NS_CC_MATH
|
||||
#endif
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
#if CC_PLATFORM != CC_PLATFORM_EMSCRIPTEN
|
||||
|
||||
template <typename T, typename Enable = std::enable_if_t<std::is_class<T>::value>>
|
||||
struct Hasher final {
|
||||
// NOTE: ccstd::hash_t is a typedef of uint32_t now, sizeof(ccstd::hash_t) == sizeof(size_t) on 32 bits architecture device,
|
||||
// sizeof(ccstd::hash_t) < sizeof(size_t) on 64 bits architecture device.
|
||||
// STL containers like ccstd::unordered_map<K, V, Hasher> expects the custom Hasher function to return size_t.
|
||||
// So it's safe to return ccstd::hash_t for operator() function now.
|
||||
// If we need to define ccstd::hash_t to uint64_t someday, we must take care of the return value of operator(),
|
||||
// it should be size_t and we need to convert hash value from uint64_t to uint32_t for 32 bit architecture device.
|
||||
ccstd::hash_t operator()(const T &info) const;
|
||||
};
|
||||
|
||||
// make this ccstd::hash compatible
|
||||
template <typename T, typename Enable = std::enable_if_t<std::is_class<T>::value>>
|
||||
ccstd::hash_t hash_value(const T &info) { return Hasher<T>()(info); } // NOLINT(readability-identifier-naming)
|
||||
|
||||
#endif // CC_PLATFORM != CC_PLATFORM_EMSCRIPTEN
|
||||
|
||||
NS_CC_MATH_END
|
||||
|
||||
/**
|
||||
* end of base group
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif // __CCMATHBASE_H__
|
||||
286
cocos/math/MathUtil.cpp
Normal file
286
cocos/math/MathUtil.cpp
Normal file
@@ -0,0 +1,286 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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/Macros.h"
|
||||
|
||||
#if (CC_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_PLATFORM == CC_PLATFORM_IOS)
|
||||
#if defined(__arm64__)
|
||||
#define USE_NEON64
|
||||
#define INCLUDE_NEON64
|
||||
#endif
|
||||
#elif (CC_PLATFORM == CC_PLATFORM_ANDROID)
|
||||
#if defined(__arm64__) || defined(__aarch64__)
|
||||
#define USE_NEON64
|
||||
#define INCLUDE_NEON64
|
||||
#elif defined(__ARM_NEON__)
|
||||
#define INCLUDE_NEON32
|
||||
#endif
|
||||
#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 <cstring>
|
||||
#include "math/MathUtil.inl"
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
void MathUtil::smooth(float *x, float target, float elapsedTime, float responseTime) {
|
||||
CC_ASSERT(x);
|
||||
|
||||
if (elapsedTime > 0) {
|
||||
*x += (target - *x) * elapsedTime / (elapsedTime + responseTime);
|
||||
}
|
||||
}
|
||||
|
||||
void MathUtil::smooth(float *x, float target, float elapsedTime, float riseTime, float fallTime) {
|
||||
CC_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_PLATFORM == CC_PLATFORM_ANDROID))
|
||||
class AndroidNeonChecker {
|
||||
public:
|
||||
AndroidNeonChecker() {
|
||||
_isNeonEnabled = (android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM && (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0);
|
||||
}
|
||||
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
cocos/math/MathUtil.h
Normal file
149
cocos/math/MathUtil.h
Normal file
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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/MathBase.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
|
||||
220
cocos/math/MathUtil.inl
Normal file
220
cocos/math/MathUtil.inl
Normal file
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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
|
||||
*/
|
||||
|
||||
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];
|
||||
dst[3] = x * m[3] + y * m[7] + z * m[11] + w * m[15];
|
||||
}
|
||||
|
||||
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
|
||||
273
cocos/math/MathUtilNeon.inl
Normal file
273
cocos/math/MathUtilNeon.inl
Normal file
@@ -0,0 +1,273 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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
|
||||
*/
|
||||
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
cocos/math/MathUtilNeon64.inl
Normal file
265
cocos/math/MathUtilNeon64.inl
Normal file
@@ -0,0 +1,265 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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
|
||||
*/
|
||||
|
||||
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
|
||||
:
|
||||
: "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
|
||||
179
cocos/math/MathUtilSSE.inl
Normal file
179
cocos/math/MathUtilSSE.inl
Normal file
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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
|
||||
*/
|
||||
|
||||
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
|
||||
585
cocos/math/Quaternion.cpp
Normal file
585
cocos/math/Quaternion.cpp
Normal file
@@ -0,0 +1,585 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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 <cstring>
|
||||
#include "base/Macros.h"
|
||||
#include "math/Mat3.h"
|
||||
#include "math/Math.h"
|
||||
#include "math/Utils.h"
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
const Quaternion Quaternion::ZERO(0.F, 0.F, 0.F, 0.F);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
const Quaternion &Quaternion::identity() {
|
||||
static Quaternion value(0.F, 0.F, 0.F, 1.F);
|
||||
return value;
|
||||
}
|
||||
|
||||
const Quaternion &Quaternion::zero() {
|
||||
static Quaternion value(0.F, 0.F, 0.F, 0.F);
|
||||
return value;
|
||||
}
|
||||
|
||||
bool Quaternion::isIdentity() const {
|
||||
return x == 0.F && y == 0.F && z == 0.F && w == 1.F;
|
||||
}
|
||||
|
||||
bool Quaternion::isZero() const {
|
||||
return x == 0.F && y == 0.F && z == 0.F && w == 0.F;
|
||||
}
|
||||
|
||||
void Quaternion::createFromRotationMatrix(const Mat4 &m, Quaternion *dst) {
|
||||
m.getRotation(dst);
|
||||
}
|
||||
|
||||
void Quaternion::createFromAxisAngle(const Vec3 &axis, float angle, Quaternion *dst) {
|
||||
CC_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::createFromAngleZ(float z, Quaternion *dst) {
|
||||
CC_ASSERT(dst);
|
||||
|
||||
z *= mathutils::HALF_TO_RAD;
|
||||
dst->x = dst->y = 0.F;
|
||||
dst->z = sinf(z);
|
||||
dst->w = cosf(z);
|
||||
}
|
||||
|
||||
void Quaternion::conjugate() {
|
||||
x = -x;
|
||||
y = -y;
|
||||
z = -z;
|
||||
}
|
||||
|
||||
Quaternion Quaternion::getConjugated() const {
|
||||
Quaternion q(*this);
|
||||
q.conjugate();
|
||||
return q;
|
||||
}
|
||||
|
||||
void Quaternion::inverse() {
|
||||
float dot = x * x + y * y + z * z + w * w;
|
||||
float invDot = dot > 0.F ? 1.F / dot : 0.F;
|
||||
|
||||
x = -x * invDot;
|
||||
y = -y * invDot;
|
||||
z = -z * invDot;
|
||||
w = w * invDot;
|
||||
}
|
||||
|
||||
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) {
|
||||
CC_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 len = x * x + y * y + z * z + w * w;
|
||||
if (len > 0.F) {
|
||||
len = 1.F / sqrt(len);
|
||||
x *= len;
|
||||
y *= len;
|
||||
z *= len;
|
||||
w *= len;
|
||||
} else {
|
||||
x = 0.F;
|
||||
y = 0.F;
|
||||
z = 0.F;
|
||||
w = 0.F;
|
||||
}
|
||||
}
|
||||
|
||||
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(const float *array) {
|
||||
CC_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.F;
|
||||
y = 0.F;
|
||||
z = 0.F;
|
||||
w = 1.F;
|
||||
}
|
||||
|
||||
float Quaternion::toAxisAngle(Vec3 *axis) const {
|
||||
CC_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.F * std::acos(q.w));
|
||||
}
|
||||
|
||||
void Quaternion::lerp(const Quaternion &q1, const Quaternion &q2, float t, Quaternion *dst) {
|
||||
CC_ASSERT(dst);
|
||||
CC_ASSERT(!(t < 0.F || t > 1.F));
|
||||
|
||||
float t1 = 1.F - 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 &a, const Quaternion &b, float t, Quaternion *dst) {
|
||||
// benchmarks: http://jsperf.com/quaternion-slerp-implementations
|
||||
|
||||
float scale0 = 0;
|
||||
float scale1 = 0;
|
||||
float bx = b.x;
|
||||
float by = b.y;
|
||||
float bz = b.z;
|
||||
float bw = b.w;
|
||||
|
||||
// calc cosine
|
||||
float cosom = a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
|
||||
// adjust signs (if necessary)
|
||||
if (cosom < 0.F) {
|
||||
cosom = -cosom;
|
||||
bx = -bx;
|
||||
by = -by;
|
||||
bz = -bz;
|
||||
bw = -bw;
|
||||
}
|
||||
// calculate coefficients
|
||||
if ((1.F - cosom) > 0.000001F) {
|
||||
// standard case (slerp)
|
||||
const float omega = acos(cosom);
|
||||
const float sinom = sinf(omega);
|
||||
scale0 = sinf((1.0F - t) * omega) / sinom;
|
||||
scale1 = sinf(t * omega) / sinom;
|
||||
} else {
|
||||
// "from" and "to" quaternions are very close
|
||||
// ... so we can do a linear interpolation
|
||||
scale0 = 1.0F - t;
|
||||
scale1 = t;
|
||||
}
|
||||
// calculate final values
|
||||
dst->x = scale0 * a.x + scale1 * bx;
|
||||
dst->y = scale0 * a.y + scale1 * by;
|
||||
dst->z = scale0 * a.z + scale1 * bz;
|
||||
dst->w = scale0 * a.w + scale1 * bw;
|
||||
}
|
||||
|
||||
void Quaternion::sqlerp(const Quaternion &a, const Quaternion &b, const Quaternion &c, const Quaternion &d, float t, Quaternion *dst) {
|
||||
Quaternion q1(0.F, 0.F, 0.F, 1.F);
|
||||
Quaternion q2(0.F, 0.F, 0.F, 1.F);
|
||||
|
||||
slerp(a, d, t, &q1);
|
||||
slerp(b, c, t, &q2);
|
||||
slerp(q1, q2, 2.F * t * (1.F - t), dst);
|
||||
}
|
||||
|
||||
void Quaternion::squad(const Quaternion &q1, const Quaternion &q2, const Quaternion &s1, const Quaternion &s2, float t, Quaternion *dst) {
|
||||
CC_ASSERT(!(t < 0.F || t > 1.F));
|
||||
|
||||
Quaternion dstQ(0.F, 0.F, 0.F, 1.F);
|
||||
Quaternion dstS(0.F, 0.F, 0.F, 1.F);
|
||||
|
||||
slerpForSquad(q1, q2, t, &dstQ);
|
||||
slerpForSquad(s1, s2, t, &dstS);
|
||||
slerpForSquad(dstQ, dstS, 2.F * t * (1.F - t), dst);
|
||||
}
|
||||
|
||||
float Quaternion::angle(const Quaternion &a, const Quaternion &b) {
|
||||
const auto dot = std::min(std::abs(Quaternion::dot(a, b)), 1.0F);
|
||||
return std::acos(dot) * 2.0F;
|
||||
}
|
||||
|
||||
void Quaternion::rotateTowards(const Quaternion &from, const Quaternion &to, float maxStep, Quaternion *dst) {
|
||||
const auto angle = Quaternion::angle(from, to);
|
||||
if (angle == 0.0F) {
|
||||
dst->set(to);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto t = std::min(maxStep / (angle * 180.F / math::PI), 1.0F);
|
||||
Quaternion::slerp(from, to, t, dst);
|
||||
}
|
||||
|
||||
void Quaternion::fromViewUp(const Vec3 &view, Quaternion *out) {
|
||||
CC_ASSERT(out);
|
||||
fromViewUp(view, Vec3(0, 1, 0), out);
|
||||
}
|
||||
void Quaternion::fromViewUp(const Vec3 &view, const Vec3 &up, Quaternion *out) {
|
||||
CC_ASSERT(out);
|
||||
Mat3 mTemp{Mat3::IDENTITY};
|
||||
Mat3::fromViewUp(view, up, &mTemp);
|
||||
Quaternion::fromMat3(mTemp, out);
|
||||
out->normalize();
|
||||
}
|
||||
|
||||
void Quaternion::fromEuler(float x, float y, float z, Quaternion *dst) {
|
||||
CC_ASSERT(dst);
|
||||
float halfToRad = 0.5F * cc::math::PI / 180.F;
|
||||
x *= halfToRad;
|
||||
y *= halfToRad;
|
||||
z *= halfToRad;
|
||||
float sx = std::sin(x);
|
||||
float cx = std::cos(x);
|
||||
float sy = std::sin(y);
|
||||
float cy = std::cos(y);
|
||||
float sz = std::sin(z);
|
||||
float cz = std::cos(z);
|
||||
|
||||
dst->x = sx * cy * cz + cx * sy * sz;
|
||||
dst->y = cx * sy * cz + sx * cy * sz;
|
||||
dst->z = cx * cy * sz - sx * sy * cz;
|
||||
dst->w = cx * cy * cz - sx * sy * sz;
|
||||
}
|
||||
|
||||
void Quaternion::toEuler(const Quaternion &q, bool outerZ, Vec3 *out) {
|
||||
CC_ASSERT(out);
|
||||
float x{q.x};
|
||||
float y{q.y};
|
||||
float z{q.z};
|
||||
float w{q.w};
|
||||
float bank{0};
|
||||
float heading{0};
|
||||
float attitude{0};
|
||||
float test = x * y + z * w;
|
||||
float r2d = 180.F / math::PI;
|
||||
if (test > 0.499999) {
|
||||
bank = 0;
|
||||
heading = 2 * atan2(x, w) * r2d;
|
||||
attitude = 90;
|
||||
} else if (test < -0.499999) {
|
||||
bank = 0;
|
||||
heading = -2 * atan2(x, w) * r2d;
|
||||
attitude = -90;
|
||||
} else {
|
||||
float sqx = x * x;
|
||||
float sqy = y * y;
|
||||
float sqz = z * z;
|
||||
bank = atan2(2 * x * w - 2 * y * z, 1 - 2 * sqx - 2 * sqz) * r2d;
|
||||
heading = atan2(2 * y * w - 2 * x * z, 1 - 2 * sqy - 2 * sqz) * r2d;
|
||||
attitude = asin(2 * test) * r2d;
|
||||
if (outerZ) {
|
||||
bank = static_cast<float>(-180.F * math::sgn(bank + 1e-6) + bank);
|
||||
heading = static_cast<float>(-180.F * math::sgn(heading + 1e-6) + heading);
|
||||
attitude = static_cast<float>(180.F * math::sgn(attitude + 1e-6) - attitude);
|
||||
}
|
||||
}
|
||||
out->x = bank;
|
||||
out->y = heading;
|
||||
out->z = attitude;
|
||||
}
|
||||
|
||||
void Quaternion::fromMat3(const Mat3 &m, Quaternion *out) {
|
||||
CC_ASSERT(out);
|
||||
float m00 = m.m[0];
|
||||
float m01 = m.m[1];
|
||||
float m02 = m.m[2];
|
||||
float m10 = m.m[3];
|
||||
float m11 = m.m[4];
|
||||
float m12 = m.m[5];
|
||||
float m20 = m.m[6];
|
||||
float m21 = m.m[7];
|
||||
float m22 = m.m[8];
|
||||
|
||||
float fourXSquaredMinus1 = m00 - m11 - m22;
|
||||
float fourYSquaredMinus1 = m11 - m00 - m22;
|
||||
float fourZSquaredMinus1 = m22 - m00 - m11;
|
||||
float fourWSquaredMinus1 = m00 + m11 + m22;
|
||||
|
||||
int biggestIndex = 0;
|
||||
float fourBiggestSquaredMinus1 = fourWSquaredMinus1;
|
||||
if (fourXSquaredMinus1 > fourBiggestSquaredMinus1) {
|
||||
fourBiggestSquaredMinus1 = fourXSquaredMinus1;
|
||||
biggestIndex = 1;
|
||||
}
|
||||
if (fourYSquaredMinus1 > fourBiggestSquaredMinus1) {
|
||||
fourBiggestSquaredMinus1 = fourYSquaredMinus1;
|
||||
biggestIndex = 2;
|
||||
}
|
||||
if (fourZSquaredMinus1 > fourBiggestSquaredMinus1) {
|
||||
fourBiggestSquaredMinus1 = fourZSquaredMinus1;
|
||||
biggestIndex = 3;
|
||||
}
|
||||
|
||||
float biggestVal = std::sqrt(fourBiggestSquaredMinus1 + 1) * 0.5F;
|
||||
float mult = 0.25F / biggestVal;
|
||||
switch (biggestIndex) {
|
||||
case 0:
|
||||
out->w = biggestVal;
|
||||
out->x = (m12 - m21) * mult;
|
||||
out->y = (m20 - m02) * mult;
|
||||
out->z = (m01 - m10) * mult;
|
||||
break;
|
||||
case 1:
|
||||
out->w = (m12 - m21) * mult;
|
||||
out->x = biggestVal;
|
||||
out->y = (m01 + m10) * mult;
|
||||
out->z = (m20 + m02) * mult;
|
||||
break;
|
||||
case 2:
|
||||
out->w = (m20 - m02) * mult;
|
||||
out->x = (m01 + m10) * mult;
|
||||
out->y = biggestVal;
|
||||
out->z = (m12 + m21) * mult;
|
||||
break;
|
||||
case 3:
|
||||
out->w = (m01 - m10) * mult;
|
||||
out->x = (m20 + m02) * mult;
|
||||
out->y = (m12 + m21) * mult;
|
||||
out->z = biggestVal;
|
||||
break;
|
||||
default: // Silence a -Wswitch-default warning in GCC. Should never actually get here. Assert is just for sanity.
|
||||
CC_ASSERT(false);
|
||||
out->w = 1.F;
|
||||
out->x = 0.F;
|
||||
out->y = 0.F;
|
||||
out->z = 0.F;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
CC_ASSERT(dstx && dsty && dstz && dstw);
|
||||
CC_ASSERT(!(t < 0.F || t > 1.F));
|
||||
|
||||
if (t == 0.F) {
|
||||
*dstx = q1x;
|
||||
*dsty = q1y;
|
||||
*dstz = q1z;
|
||||
*dstw = q1w;
|
||||
return;
|
||||
}
|
||||
|
||||
if (t == 1.F) {
|
||||
*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;
|
||||
float alpha;
|
||||
float beta;
|
||||
|
||||
float u;
|
||||
float f1;
|
||||
float f2a;
|
||||
float f2b;
|
||||
|
||||
float ratio1;
|
||||
float ratio2;
|
||||
|
||||
float halfSecHalfTheta;
|
||||
float versHalfTheta;
|
||||
|
||||
float sqNotU;
|
||||
float sqU;
|
||||
|
||||
float cosTheta = q1w * q2w + q1x * q2x + q1y * q2y + q1z * q2z;
|
||||
|
||||
// As usual in all slerp implementations, we fold theta.
|
||||
alpha = cosTheta >= 0 ? 1.F : -1.F;
|
||||
halfY = 1.F + 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.F - 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.F - halfY * halfSecHalfTheta;
|
||||
|
||||
// Evaluate series expansions of the coefficients.
|
||||
sqNotU = f1 * f1;
|
||||
ratio2 = 0.0000440917108F * versHalfTheta;
|
||||
ratio1 = -0.00158730159F + (sqNotU - 16.F) * ratio2;
|
||||
ratio1 = 0.0333333333F + ratio1 * (sqNotU - 9.F) * versHalfTheta;
|
||||
ratio1 = -0.333333333F + ratio1 * (sqNotU - 4.F) * versHalfTheta;
|
||||
ratio1 = 1.F + ratio1 * (sqNotU - 1.F) * versHalfTheta;
|
||||
|
||||
sqU = u * u;
|
||||
ratio2 = -0.00158730159F + (sqU - 16.F) * ratio2;
|
||||
ratio2 = 0.0333333333F + ratio2 * (sqU - 9.F) * versHalfTheta;
|
||||
ratio2 = -0.333333333F + ratio2 * (sqU - 4.F) * versHalfTheta;
|
||||
ratio2 = 1.F + ratio2 * (sqU - 1.F) * 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) {
|
||||
CC_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.F) {
|
||||
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.F - 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
|
||||
479
cocos/math/Quaternion.h
Normal file
479
cocos/math/Quaternion.h
Normal file
@@ -0,0 +1,479 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "math/Mat4.h"
|
||||
#include "math/Vec3.h"
|
||||
//#include "Plane.h"
|
||||
|
||||
/**
|
||||
* @addtogroup base
|
||||
* @{
|
||||
*/
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
class Mat4;
|
||||
class Mat3;
|
||||
/**
|
||||
* 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 {
|
||||
public:
|
||||
/**
|
||||
* The x-value of the quaternion's vector component.
|
||||
*/
|
||||
float x{0.0F};
|
||||
/**
|
||||
* The y-value of the quaternion's vector component.
|
||||
*/
|
||||
float y{0.0F};
|
||||
/**
|
||||
* The z-value of the quaternion's vector component.
|
||||
*/
|
||||
float z{0.0F};
|
||||
/**
|
||||
* The scalar component of the quaternion.
|
||||
*/
|
||||
float w{1.0F};
|
||||
|
||||
/**
|
||||
* Constructs a quaternion initialized to (0, 0, 0, 1).
|
||||
*/
|
||||
Quaternion() = default;
|
||||
|
||||
/**
|
||||
* Constructs a quaternion.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
explicit Quaternion(float *array);
|
||||
|
||||
/**
|
||||
* Constructs a quaternion equal to the rotational part of the specified matrix.
|
||||
*
|
||||
* @param m The matrix.
|
||||
*/
|
||||
explicit 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);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Calculates the quaternion with Euler angles, the rotation order is YZX
|
||||
*/
|
||||
static void fromEuler(float x, float y, float z, Quaternion *dst);
|
||||
|
||||
/**
|
||||
* Converts the quaternion to angles, result angle x, y in the range of [-180, 180], z in the range of [-90, 90] interval, the rotation order is YZX
|
||||
*/
|
||||
static void toEuler(const Quaternion &q, bool outerZ, Vec3 *out);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* @en Calculates the quaternion with given 2D angle (0, 0, z).
|
||||
* @zh 根据 2D 角度(0, 0, z)计算四元数
|
||||
*
|
||||
* @param out Output quaternion
|
||||
* @param z Angle to rotate around Z axis in degrees.
|
||||
*/
|
||||
static void createFromAngleZ(float z, 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.
|
||||
*/
|
||||
void 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(const 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 *axis) const;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Calculates the quaternion with the three-dimensional transform matrix, considering no scale included in the matrix
|
||||
*/
|
||||
static void fromMat3(const Mat3 &m, Quaternion *out);
|
||||
|
||||
/**
|
||||
* Calculates the quaternion with the up direction and the direction of the viewport
|
||||
*/
|
||||
static void fromViewUp(const Vec3 &view, Quaternion *out);
|
||||
static void fromViewUp(const Vec3 &view, const Vec3 &up, Quaternion *out);
|
||||
|
||||
/**
|
||||
* 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 &a, const Quaternion &b, float t, Quaternion *dst);
|
||||
|
||||
/**
|
||||
* @en Spherical quaternion interpolation with two control points
|
||||
*
|
||||
* @param out the receiving quaternion
|
||||
* @param a the first operand
|
||||
* @param b the second operand
|
||||
* @param c the third operand
|
||||
* @param d the fourth operand
|
||||
* @param t interpolation amount, in the range [0-1], between the two inputs
|
||||
* @returns out
|
||||
*/
|
||||
static void sqlerp(const Quaternion &a, const Quaternion &b, const Quaternion &c, const Quaternion &d, 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.
|
||||
*/
|
||||
/**
|
||||
* @deprecated since v3.8.0 please use [[sqlerp]] instead
|
||||
*/
|
||||
static void squad(const Quaternion &q1, const Quaternion &q2, const Quaternion &s1, const Quaternion &s2, float t, Quaternion *dst);
|
||||
|
||||
/**
|
||||
* @en Quaternion dot product (scalar product)
|
||||
* @zh 四元数点积(数量积)
|
||||
* @param a The first unit quaternion
|
||||
* @param b The second unit quaternion
|
||||
*/
|
||||
static inline float dot(const Quaternion &a, const Quaternion &b) {
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
|
||||
}
|
||||
|
||||
/**
|
||||
* @en Gets the angular distance between two unit quaternions
|
||||
* @zh 获取两个单位四元数的夹角
|
||||
* @param a The first unit quaternion
|
||||
* @param b The second unit quaternion
|
||||
* @returns Angle between the two quaternions in radians
|
||||
*/
|
||||
static float angle(const Quaternion &a, const Quaternion &b);
|
||||
|
||||
/**
|
||||
* @en Rotate a `from` unit quaternion towards `to` unit quaternion
|
||||
* @zh 将一个起始单位四元数旋转到一个目标单位四元数
|
||||
* @param from The first unit quaternion
|
||||
* @param to The second unit quaternion
|
||||
* @param maxStep The maximum angle of rotation in degrees
|
||||
* @returns new unit quaternion generated during rotation
|
||||
*/
|
||||
static void rotateTowards(const Quaternion &from, const Quaternion &to, float maxStep, 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;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Determines if this quaternion is approximately equal to the given quaternion.
|
||||
*/
|
||||
inline bool approxEquals(const Quaternion &v, float precision = CC_FLOAT_CMP_PRECISION) const {
|
||||
return math::isEqualF(x, v.x, precision) && math::isEqualF(y, v.y, precision) && math::isEqualF(z, v.z, precision) && math::isEqualF(w, v.w, precision);
|
||||
}
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
/**
|
||||
* @deprecated since v3.8.0
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @deprecated since v3.8.0
|
||||
*/
|
||||
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"
|
||||
38
cocos/math/Quaternion.inl
Normal file
38
cocos/math/Quaternion.inl
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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"
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
NS_CC_MATH_END
|
||||
112
cocos/math/Utils.cpp
Normal file
112
cocos/math/Utils.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
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/Utils.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <random>
|
||||
#include "math/Math.h"
|
||||
|
||||
namespace {
|
||||
std::random_device rd;
|
||||
std::uniform_real_distribution<float> uniformReal{0.0F, 1.0F};
|
||||
} // namespace
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace mathutils {
|
||||
|
||||
float random() {
|
||||
return uniformReal(rd);
|
||||
}
|
||||
|
||||
float absMaxComponent(const Vec3 &v) {
|
||||
return absMax(absMax(v.x, v.y), v.z);
|
||||
}
|
||||
|
||||
float maxComponent(const Vec3 &v) {
|
||||
return std::max(std::max(v.x, v.y), v.z);
|
||||
}
|
||||
|
||||
uint16_t floatToHalf(float fval) {
|
||||
union {
|
||||
float f;
|
||||
unsigned int ui;
|
||||
} u = {fval};
|
||||
unsigned int ui = u.ui;
|
||||
|
||||
int s = (ui >> 16) & 0x8000; // NOLINT
|
||||
int em = ui & 0x7fffffff; // NOLINT
|
||||
|
||||
/* bias exponent and round to nearest; 112 is relative exponent bias (127-15) */
|
||||
int h = (em - (112 << 23) + (1 << 12)) >> 13;
|
||||
|
||||
/* underflow: flush to zero; 113 encodes exponent -14 */
|
||||
h = (em < (113 << 23)) ? 0 : h;
|
||||
|
||||
/* overflow: infinity; 143 encodes exponent 16 */
|
||||
h = (em >= (143 << 23)) ? 0x7c00 : h;
|
||||
|
||||
/* NaN; note that we convert all types of NaN to qNaN */
|
||||
h = (em > (255 << 23)) ? 0x7e00 : h;
|
||||
|
||||
return static_cast<uint16_t>(s | h);
|
||||
}
|
||||
|
||||
float halfToFloat(uint16_t hval) {
|
||||
union {
|
||||
float f;
|
||||
unsigned int ui;
|
||||
} u;
|
||||
|
||||
int s = (hval >> 15) & 0x00000001;
|
||||
int em = hval & 0x00007fff;
|
||||
int m = 0;
|
||||
|
||||
if (em > 0) {
|
||||
/* normalized */
|
||||
if (em > 30 << 10) {
|
||||
/* overflow: infinity */
|
||||
em = 255 << 23;
|
||||
} else {
|
||||
em = (em + (112 << 10)) << 13;
|
||||
}
|
||||
} else {
|
||||
/* denormalized */
|
||||
if (em > 25 << 10) {
|
||||
/* underflow: flush to zero */
|
||||
em = 0;
|
||||
} else {
|
||||
em = (em + (113 << 10)) >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
u.ui = ((s << 31)) | em | m; // NOLINT
|
||||
return u.f;
|
||||
}
|
||||
|
||||
} // namespace mathutils
|
||||
|
||||
} // namespace cc
|
||||
292
cocos/math/Utils.h
Normal file
292
cocos/math/Utils.h
Normal file
@@ -0,0 +1,292 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
https://www.cocos.com/
|
||||
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include "math/Vec3.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
namespace mathutils {
|
||||
|
||||
constexpr auto EPSILON = 0.000001;
|
||||
constexpr auto D2R = M_PI / 180.0;
|
||||
constexpr auto R2D = 180.0 / M_PI;
|
||||
constexpr auto HALF_TO_RAD = 0.5 * D2R;
|
||||
/**
|
||||
* @en Tests whether or not the arguments have approximately the same value, within an absolute<br/>
|
||||
* or relative tolerance of glMatrix.EPSILON (an absolute tolerance is used for values less<br/>
|
||||
* than or equal to 1.0, and a relative tolerance is used for larger values)
|
||||
* @zh 在glMatrix的绝对或相对容差范围内,测试参数是否具有近似相同的值。<br/>
|
||||
* EPSILON(小于等于1.0的值采用绝对公差,大于1.0的值采用相对公差)
|
||||
* @param a The first number to test.
|
||||
* @param b The second number to test.
|
||||
* @return True if the numbers are approximately equal, false otherwise.
|
||||
*/
|
||||
template <typename F>
|
||||
bool equals(F a, F b) {
|
||||
static_assert(std::is_floating_point<F>::value, "number expected");
|
||||
return std::fabs(a - b) <= EPSILON * std::max(1.0F, std::max(std::fabs(a), std::fabs(b)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @en Tests whether or not the arguments have approximately the same value by given maxDiff<br/>
|
||||
* @zh 通过给定的最大差异,测试参数是否具有近似相同的值。
|
||||
* @param a The first number to test.
|
||||
* @param b The second number to test.
|
||||
* @param maxDiff Maximum difference.
|
||||
* @return True if the numbers are approximately equal, false otherwise.
|
||||
*/
|
||||
template <typename F>
|
||||
bool approx(F a, F b, F maxDiff) {
|
||||
static_assert(std::is_floating_point<F>::value, "number expected");
|
||||
return std::fabs(a - b) <= maxDiff;
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
bool approx(F a, F b) {
|
||||
static_assert(std::is_floating_point<F>::value, "number expected");
|
||||
return std::fabs(a - b) <= EPSILON;
|
||||
}
|
||||
|
||||
/**
|
||||
* @en Clamps a value between a minimum float and maximum float value.<br/>
|
||||
* @zh 返回最小浮点数和最大浮点数之间的一个数值。可以使用 clamp 函数将不断变化的数值限制在范围内。
|
||||
* @param val
|
||||
* @param min
|
||||
* @param max
|
||||
*/
|
||||
template <typename F>
|
||||
typename std::enable_if<std::is_arithmetic<F>::value, F>::type
|
||||
clamp(F val, F min, F max) {
|
||||
if (min > max) {
|
||||
const auto temp = min;
|
||||
min = max;
|
||||
max = temp;
|
||||
}
|
||||
|
||||
return val < min ? min : val > max ? max
|
||||
: val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @en Clamps a value between 0 and 1.<br/>
|
||||
* @zh 将值限制在0和1之间。
|
||||
* @param val
|
||||
*/
|
||||
template <typename F>
|
||||
auto clamp01(F val) {
|
||||
static_assert(std::is_floating_point<F>::value, "number expected");
|
||||
return val < 0 ? 0 : val > 1 ? 1
|
||||
: val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param from
|
||||
* @param to
|
||||
* @param ratio - The interpolation coefficient.
|
||||
*/
|
||||
template <typename F>
|
||||
auto lerp(F from, F to, F ratio) {
|
||||
static_assert(std::is_floating_point<F>::value, "number expected");
|
||||
return from + (to - from) * ratio;
|
||||
}
|
||||
|
||||
/**
|
||||
* @en Convert Degree To Radian<br/>
|
||||
* @zh 把角度换算成弧度。
|
||||
* @param {Number} a Angle in Degrees
|
||||
*/
|
||||
template <typename F>
|
||||
auto toRadian(F a) {
|
||||
static_assert(std::is_floating_point<F>::value, "number expected");
|
||||
return a * D2R;
|
||||
}
|
||||
|
||||
/**
|
||||
* @en Convert Radian To Degree<br/>
|
||||
* @zh 把弧度换算成角度。
|
||||
* @param {Number} a Angle in Radian
|
||||
*/
|
||||
template <typename F>
|
||||
auto toDegree(F a) {
|
||||
return a * R2D;
|
||||
}
|
||||
|
||||
/**
|
||||
* @method random
|
||||
*/
|
||||
float random();
|
||||
|
||||
/**
|
||||
* @en Returns a floating-point random number between min (inclusive) and max (exclusive).<br/>
|
||||
* @zh 返回最小(包含)和最大(不包含)之间的浮点随机数。
|
||||
* @method randomRange
|
||||
* @param min
|
||||
* @param max
|
||||
* @return The random number.
|
||||
*/
|
||||
template <typename T>
|
||||
auto randomRange(T min, T max) {
|
||||
return random() * (max - min) + min;
|
||||
}
|
||||
|
||||
/**
|
||||
* @en Returns a random integer between min (inclusive) and max (exclusive).<br/>
|
||||
* @zh 返回最小(包含)和最大(不包含)之间的随机整数。
|
||||
* @param min
|
||||
* @param max
|
||||
* @return The random integer.
|
||||
*/
|
||||
template <typename T>
|
||||
auto randomRangeInt(T min, T max) {
|
||||
static_assert(std::is_arithmetic<T>::value, "number expected");
|
||||
return floor(randomRange(min, max));
|
||||
}
|
||||
|
||||
/**
|
||||
* Linear congruential generator using Hull-Dobell Theorem.
|
||||
*
|
||||
* @param seed The random seed.
|
||||
* @return The pseudo random.
|
||||
*/
|
||||
template <typename In>
|
||||
auto pseudoRandom(In seed) {
|
||||
static_assert(std::is_arithmetic<In>::value, "number expected");
|
||||
seed = (seed * 9301 + 49297) % 233280;
|
||||
return seed / 233280.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a floating-point pseudo-random number between min (inclusive) and max (exclusive).
|
||||
*
|
||||
* @param seed
|
||||
* @param min
|
||||
* @param max
|
||||
* @return The random number.
|
||||
*/
|
||||
template <typename In>
|
||||
auto pseudoRandomRange(In seed, In min, In max) {
|
||||
static_assert(std::is_arithmetic<In>::value, "number expected");
|
||||
return pseudoRandom(seed) * (max - min) + min;
|
||||
}
|
||||
|
||||
/**
|
||||
* @en Returns a pseudo-random integer between min (inclusive) and max (exclusive).<br/>
|
||||
* @zh 返回最小(包含)和最大(不包含)之间的浮点伪随机数。
|
||||
* @param seed
|
||||
* @param min
|
||||
* @param max
|
||||
* @return The random integer.
|
||||
*/
|
||||
template <typename In>
|
||||
auto pseudoRandomRangeInt(In seed, In min, In max) {
|
||||
return floor(pseudoRandomRange(seed, min, max));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next power of two for the value.<br/>
|
||||
*
|
||||
* @param val
|
||||
* @return The the next power of two.
|
||||
*/
|
||||
template <typename T>
|
||||
auto nextPow2(T val) {
|
||||
// ref: https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
|
||||
--val;
|
||||
val = (val >> 1) | val;
|
||||
val = (val >> 2) | val;
|
||||
val = (val >> 4) | val;
|
||||
val = (val >> 8) | val;
|
||||
val = (val >> 16) | val;
|
||||
++val;
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @en Returns float remainder for t / length.<br/>
|
||||
* @zh 返回t / length的浮点余数。
|
||||
* @param t Time start at 0.
|
||||
* @param length Time of one cycle.
|
||||
* @return The Time wrapped in the first cycle.
|
||||
*/
|
||||
template <typename T>
|
||||
auto repeat(T t, T length) {
|
||||
return t - floor(t / length) * length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns time wrapped in ping-pong mode.
|
||||
*
|
||||
* @param t Time start at 0.
|
||||
* @param length Time of one cycle.
|
||||
* @return The time wrapped in the first cycle.
|
||||
*/
|
||||
template <typename T>
|
||||
auto pingPong(T t, T length) {
|
||||
t = repeat(t, length * 2);
|
||||
t = length - std::fabs(t - length);
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* @en Returns ratio of a value within a given range.<br/>
|
||||
* @zh 返回给定范围内的值的比率。
|
||||
* @param from Start value.
|
||||
* @param to End value.
|
||||
* @param value Given value.
|
||||
* @return The ratio between [from, to].
|
||||
*/
|
||||
template <typename T>
|
||||
auto inverseLerp(T from, T to, T value) {
|
||||
return (value - from) / (to - from);
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh 对所有分量的绝对值进行比较大小,返回绝对值最大的分量。
|
||||
* @param v 类 Vec3 结构
|
||||
* @returns 绝对值最大的分量
|
||||
*/
|
||||
float absMaxComponent(const Vec3 &v);
|
||||
|
||||
float maxComponent(const Vec3 &v);
|
||||
|
||||
/**
|
||||
* @zh 对 a b 的绝对值进行比较大小,返回绝对值最大的值。
|
||||
* @param a number
|
||||
* @param b number
|
||||
*/
|
||||
template <typename F>
|
||||
auto absMax(F a, F b) {
|
||||
return std::fabs(a) > std::fabs(b) ? a : b;
|
||||
}
|
||||
|
||||
uint16_t floatToHalf(float fval);
|
||||
|
||||
float halfToFloat(uint16_t hval);
|
||||
|
||||
} // namespace mathutils
|
||||
} // namespace cc
|
||||
300
cocos/math/Vec2.cpp
Normal file
300
cocos/math/Vec2.cpp
Normal file
@@ -0,0 +1,300 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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 "base/Macros.h"
|
||||
#include "math/MathUtil.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;
|
||||
}
|
||||
|
||||
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) {
|
||||
const auto magSqr1 = v1.x * v1.x + v1.y * v1.y;
|
||||
const auto magSqr2 = v2.x * v2.x + v2.y * v2.y;
|
||||
|
||||
if (magSqr1 == 0.0F || magSqr2 == 0.0F) {
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
const auto dot = v1.x * v2.x + v1.y * v2.y;
|
||||
auto cosine = dot / (sqrt(magSqr1 * magSqr2));
|
||||
cosine = clampf(cosine, -1.0, 1.0);
|
||||
return acos(cosine);
|
||||
}
|
||||
|
||||
void Vec2::add(const Vec2 &v1, const Vec2 &v2, Vec2 *dst) {
|
||||
CC_ASSERT(dst);
|
||||
|
||||
dst->x = v1.x + v2.x;
|
||||
dst->y = v1.y + v2.y;
|
||||
}
|
||||
|
||||
void Vec2::clamp(const Vec2 &min, const Vec2 &max) {
|
||||
CC_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) {
|
||||
CC_ASSERT(dst);
|
||||
CC_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 len = x * x + y * y;
|
||||
if (len > 0.0F) {
|
||||
len = 1.0F / std::sqrt(len);
|
||||
x *= len;
|
||||
y *= len;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
CC_ASSERT(array);
|
||||
|
||||
x = array[0];
|
||||
y = array[1];
|
||||
}
|
||||
|
||||
void Vec2::subtract(const Vec2 &v1, const Vec2 &v2, Vec2 *dst) {
|
||||
CC_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 {
|
||||
return Vec2::angle(*this, other);
|
||||
}
|
||||
|
||||
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
|
||||
return !(crossProduct2Vector(c, d, c, a) == 0 || crossProduct2Vector(a, b, c, a) == 0);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return (crossProduct2Vector(a, b, c, d) == 0 && (crossProduct2Vector(c, d, c, a) == 0 || crossProduct2Vector(a, b, c, a) == 0));
|
||||
}
|
||||
|
||||
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;
|
||||
float t;
|
||||
|
||||
return (isLineIntersect(a, b, c, d, &s, &t) && (s >= 0.0F && s <= 1.0F && t >= 0.0F && t <= 1.0F));
|
||||
}
|
||||
|
||||
Vec2 Vec2::getIntersectPoint(const Vec2 &a, const Vec2 &b, const Vec2 &c, const Vec2 &d) {
|
||||
float s;
|
||||
float 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
|
||||
703
cocos/math/Vec2.h
Normal file
703
cocos/math/Vec2.h
Normal file
@@ -0,0 +1,703 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
#include "math/Math.h"
|
||||
#include "math/MathBase.h"
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
/** Clamp a value between from and to.
|
||||
*/
|
||||
|
||||
inline float clampf(float value, float minInclusive, float maxInclusive) {
|
||||
if (minInclusive > maxInclusive) {
|
||||
std::swap(minInclusive, maxInclusive);
|
||||
}
|
||||
return value < minInclusive ? minInclusive : value < maxInclusive ? value
|
||||
: maxInclusive;
|
||||
}
|
||||
|
||||
class Mat4;
|
||||
|
||||
/**
|
||||
* Defines a 2-element floating point vector.
|
||||
*/
|
||||
class CC_DLL Vec2 {
|
||||
public:
|
||||
/**
|
||||
* The x coordinate.
|
||||
*/
|
||||
float x{0.F};
|
||||
|
||||
/**
|
||||
* The y coordinate.
|
||||
*/
|
||||
float y{0.F};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
explicit 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 ©);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Determines if this vector is approximately equal to the given vector.
|
||||
*/
|
||||
inline bool approxEquals(const Vec2 &v, float precision = CC_FLOAT_CMP_PRECISION) const {
|
||||
return math::isEqualF(x, v.x, precision) && math::isEqualF(y, v.y, precision);
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
bool fuzzyEquals(const Vec2 &b, float var) const;
|
||||
|
||||
/** Calculates distance between point an origin
|
||||
@return float
|
||||
@since v2.1.4
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
inline float getDistanceSq(const Vec2 &other) const {
|
||||
return (*this - other).getLengthSq();
|
||||
};
|
||||
|
||||
/** Calculates the distance between two points
|
||||
@return float
|
||||
@since v2.1.4
|
||||
*/
|
||||
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
|
||||
*/
|
||||
inline float getAngle() const {
|
||||
return atan2f(y, x);
|
||||
};
|
||||
|
||||
/** @returns the angle in radians between two vector directions
|
||||
@since v2.1.4
|
||||
*/
|
||||
float getAngle(const Vec2 &other) const;
|
||||
|
||||
/** Calculates cross product of two points.
|
||||
@return float
|
||||
@since v2.1.4
|
||||
*/
|
||||
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
|
||||
*/
|
||||
inline Vec2 getPerp() const {
|
||||
return Vec2(-y, x);
|
||||
};
|
||||
|
||||
/** Calculates midpoint between two points.
|
||||
@return Vec2
|
||||
@since v3.0
|
||||
*/
|
||||
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
|
||||
*/
|
||||
inline Vec2 getClampPoint(const Vec2 &minInclusive, const Vec2 &maxInclusive) const {
|
||||
return Vec2(clampf(x, minInclusive.x, maxInclusive.x), clampf(y, minInclusive.y, maxInclusive.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
|
||||
*/
|
||||
inline Vec2 compOp(const 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
|
||||
*/
|
||||
inline Vec2 getRPerp() const {
|
||||
return Vec2(y, -x);
|
||||
};
|
||||
|
||||
/** Calculates the projection of this over other.
|
||||
@return Vec2
|
||||
@since v2.1.4
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
Vec2 rotateByAngle(const Vec2 &pivot, float angle) const;
|
||||
|
||||
static inline Vec2 forAngle(const float a) {
|
||||
return Vec2(cosf(a), sinf(a));
|
||||
}
|
||||
|
||||
/** A general line-line intersection test
|
||||
@param a the start point for the first line L1 = (a - b)
|
||||
@param b the end point for the first line L1 = (a - b)
|
||||
@param c the start point for the second line L2 = (c - d)
|
||||
@param d the end point 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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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);
|
||||
|
||||
using Point = Vec2;
|
||||
|
||||
NS_CC_MATH_END
|
||||
|
||||
#include "math/Vec2.inl"
|
||||
199
cocos/math/Vec2.inl
Normal file
199
cocos/math/Vec2.inl
Normal file
@@ -0,0 +1,199 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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"
|
||||
|
||||
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 {
|
||||
const float inv = 1.0f / s;
|
||||
return Vec2(this->x * inv, this->y * inv);
|
||||
}
|
||||
|
||||
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
|
||||
403
cocos/math/Vec3.cpp
Normal file
403
cocos/math/Vec3.cpp
Normal file
@@ -0,0 +1,403 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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 "base/Macros.h"
|
||||
#include "math/Mat3.h"
|
||||
#include "math/Math.h"
|
||||
#include "math/MathUtil.h"
|
||||
#include "math/Quaternion.h"
|
||||
|
||||
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
|
||||
#include <cpu-features.h>
|
||||
#endif
|
||||
|
||||
#if (CC_PLATFORM == CC_PLATFORM_IOS)
|
||||
#if defined(__arm64__)
|
||||
#define USE_NEON64
|
||||
#define INCLUDE_NEON64
|
||||
#endif
|
||||
#elif (CC_PLATFORM == CC_PLATFORM_ANDROID)
|
||||
#if defined(__arm64__) || defined(__aarch64__)
|
||||
#define USE_NEON64
|
||||
#define INCLUDE_NEON64
|
||||
#elif defined(__ARM_NEON__)
|
||||
#define INCLUDE_NEON32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(USE_NEON64) || defined(USE_NEON32) || defined(INCLUDE_NEON32)
|
||||
#include "enoki/array.h"
|
||||
#ifndef ENOKI_ARM_NEON
|
||||
#error "ENOKI_ARM_NEON isn't enabled!"
|
||||
#endif
|
||||
using SimdVec4 = enoki::Array<float, 4>;
|
||||
#endif
|
||||
|
||||
NS_CC_MATH_BEGIN
|
||||
|
||||
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 ©) {
|
||||
set(copy);
|
||||
}
|
||||
|
||||
Vec3 Vec3::fromColor(unsigned int color) {
|
||||
float components[3];
|
||||
int componentIndex = 0;
|
||||
for (int i = 2; i >= 0; --i) {
|
||||
auto component = (color >> i * 8) & 0x0000ff;
|
||||
|
||||
components[componentIndex++] = static_cast<float>(component) / 255.0F;
|
||||
}
|
||||
|
||||
Vec3 value(components);
|
||||
return value;
|
||||
}
|
||||
|
||||
void Vec3::transformInverseRTS(const Vec3 &v, const Quaternion &r, const Vec3 &t, const Vec3 &s, Vec3 *out) {
|
||||
CC_ASSERT(out);
|
||||
const float x = v.x - t.x;
|
||||
const float y = v.y - t.y;
|
||||
const float z = v.z - t.z;
|
||||
|
||||
const float ix = r.w * x - r.y * z + r.z * y;
|
||||
const float iy = r.w * y - r.z * x + r.x * z;
|
||||
const float iz = r.w * z - r.x * y + r.y * x;
|
||||
const float iw = r.x * x + r.y * y + r.z * z;
|
||||
out->x = (ix * r.w + iw * r.x + iy * r.z - iz * r.y) / s.x;
|
||||
out->y = (iy * r.w + iw * r.y + iz * r.x - ix * r.z) / s.y;
|
||||
out->z = (iz * r.w + iw * r.z + ix * r.y - iy * r.x) / s.z;
|
||||
}
|
||||
|
||||
float Vec3::angle(const Vec3 &v1, const Vec3 &v2) {
|
||||
const auto magSqr1 = v1.x * v1.x + v1.y * v1.y + v1.z * v1.z;
|
||||
const auto magSqr2 = v2.x * v2.x + v2.y * v2.y + v2.z * v2.z;
|
||||
|
||||
if (magSqr1 == 0.0F || magSqr2 == 0.0F) {
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
const auto dot = v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
|
||||
auto cosine = dot / (sqrt(magSqr1 * magSqr2));
|
||||
cosine = clampf(cosine, -1.0, 1.0);
|
||||
return acos(cosine);
|
||||
}
|
||||
|
||||
void Vec3::add(const Vec3 &v1, const Vec3 &v2, Vec3 *dst) {
|
||||
CC_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) {
|
||||
CC_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) {
|
||||
CC_ASSERT(dst);
|
||||
CC_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) {
|
||||
dst->set(
|
||||
v1.y * v2.z - v1.z * v2.y,
|
||||
v1.z * v2.x - v1.x * v2.z,
|
||||
v1.x * v2.y - v1.y * v2.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) {
|
||||
const float ix = v.x;
|
||||
const float iy = v.y;
|
||||
const float 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::transformMat4Neon(const Vec3 &v, const Mat4 &m) {
|
||||
#if defined(USE_NEON64) || defined(USE_NEON32) || defined(INCLUDE_NEON32)
|
||||
alignas(16) float tmpV0[4];
|
||||
|
||||
auto row0 = enoki::load_unaligned<SimdVec4>(&m.m[0]);
|
||||
auto row1 = enoki::load_unaligned<SimdVec4>(&m.m[4]);
|
||||
auto row2 = enoki::load_unaligned<SimdVec4>(&m.m[8]);
|
||||
auto row3 = enoki::load_unaligned<SimdVec4>(&m.m[12]);
|
||||
|
||||
row0 *= v.x;
|
||||
row1 *= v.y;
|
||||
row2 *= v.z;
|
||||
|
||||
row0 = row0 + row1 + row2 + row3;
|
||||
enoki::store(tmpV0, row0);
|
||||
float rhw;
|
||||
|
||||
if (CC_PREDICT_TRUE(math::isNotZeroF(tmpV0[3]))) {
|
||||
rhw = 1.F / tmpV0[3];
|
||||
} else {
|
||||
rhw = 1.F;
|
||||
}
|
||||
|
||||
SimdVec4 tmpV1{rhw};
|
||||
row0 *= tmpV1;
|
||||
enoki::store(tmpV0, row0);
|
||||
|
||||
x = tmpV0[0];
|
||||
y = tmpV0[1];
|
||||
z = tmpV0[2];
|
||||
#endif
|
||||
}
|
||||
|
||||
void Vec3::transformMat4C(const Vec3 &v, const Mat4 &m) {
|
||||
alignas(16) float tmp[4] = {v.x, v.y, v.z, 1.0F};
|
||||
MathUtil::transformVec4(m.m, tmp, tmp);
|
||||
float rhw = math::isNotZeroF(tmp[3]) ? 1.F / tmp[3] : 1.F;
|
||||
x = tmp[0] * rhw;
|
||||
y = tmp[1] * rhw;
|
||||
z = tmp[2] * rhw;
|
||||
}
|
||||
|
||||
void Vec3::transformMat4(const Vec3 &v, const Mat4 &m) {
|
||||
#if defined(USE_NEON64)
|
||||
transformMat4Neon(v, m);
|
||||
#elif defined(INCLUDE_NEON32)
|
||||
if (CC_PREDICT_TRUE(MathUtil::isNeon32Enabled())) {
|
||||
transformMat4Neon(v, m);
|
||||
} else {
|
||||
transformMat4C(v, m);
|
||||
}
|
||||
#else
|
||||
transformMat4C(v, m);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Vec3::transformMat4(const Vec3 &v, const Mat4 &m, Vec3 *dst) {
|
||||
dst->transformMat4(v, m);
|
||||
}
|
||||
|
||||
void Vec3::transformMat4Normal(const Vec3 &v, const Mat4 &m, Vec3 *dst) {
|
||||
float x = v.x;
|
||||
float y = v.y;
|
||||
float z = v.z;
|
||||
float rhw = m.m[3] * x + m.m[7] * y + m.m[11] * z;
|
||||
rhw = (rhw != 0.0F ? 1.0F / rhw : 1.0F);
|
||||
dst->x = (m.m[0] * x + m.m[4] * y + m.m[8] * z) * rhw;
|
||||
dst->y = (m.m[1] * x + m.m[5] * y + m.m[9] * z) * rhw;
|
||||
dst->z = (m.m[2] * x + m.m[6] * y + m.m[10] * z) * rhw;
|
||||
}
|
||||
|
||||
void Vec3::moveTowards(const Vec3 ¤t, const Vec3 &target, float maxStep, Vec3 *dst) {
|
||||
const auto deltaX = target.x - current.x;
|
||||
const auto deltaY = target.y - current.y;
|
||||
const auto deltaZ = target.z - current.z;
|
||||
|
||||
const auto distanceSqr = deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ;
|
||||
if (distanceSqr == 0.0F || (maxStep >= 0.0F && distanceSqr < maxStep * maxStep)) {
|
||||
dst->set(target);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto distance = std::sqrt(distanceSqr);
|
||||
const auto scale = maxStep / distance;
|
||||
dst->set(
|
||||
current.x + deltaX * scale,
|
||||
current.y + deltaY * scale,
|
||||
current.z + deltaZ * scale);
|
||||
}
|
||||
|
||||
void Vec3::transformQuat(const Quaternion &q) {
|
||||
const float qx = q.x;
|
||||
const float qy = q.y;
|
||||
const float qz = q.z;
|
||||
const float qw = q.w;
|
||||
|
||||
// calculate quat * vec
|
||||
const float ix = qw * x + qy * z - qz * y;
|
||||
const float iy = qw * y + qz * x - qx * z;
|
||||
const float iz = qw * z + qx * y - qy * x;
|
||||
const 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 {
|
||||
const float dx = v.x - x;
|
||||
const float dy = v.y - y;
|
||||
const float dz = v.z - z;
|
||||
|
||||
return std::sqrt(dx * dx + dy * dy + dz * dz);
|
||||
}
|
||||
|
||||
float Vec3::distanceSquared(const Vec3 &v) const {
|
||||
const float dx = v.x - x;
|
||||
const float dy = v.y - y;
|
||||
const 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 len = x * x + y * y + z * z;
|
||||
if (len > 0.0F) {
|
||||
len = 1.0F / std::sqrt(len);
|
||||
x *= len;
|
||||
y *= len;
|
||||
z *= len;
|
||||
}
|
||||
}
|
||||
|
||||
Vec3 Vec3::getNormalized() const {
|
||||
Vec3 v(*this);
|
||||
v.normalize();
|
||||
return v;
|
||||
}
|
||||
|
||||
void Vec3::subtract(const Vec3 &v1, const Vec3 &v2, Vec3 *dst) {
|
||||
CC_ASSERT(dst);
|
||||
|
||||
dst->x = v1.x - v2.x;
|
||||
dst->y = v1.y - v2.y;
|
||||
dst->z = v1.z - v2.z;
|
||||
}
|
||||
|
||||
void Vec3::max(const Vec3 &v1, const Vec3 &v2, Vec3 *dst) {
|
||||
CC_ASSERT(dst);
|
||||
|
||||
dst->x = std::fmaxf(v1.x, v2.x);
|
||||
dst->y = std::fmaxf(v1.y, v2.y);
|
||||
dst->z = std::fmaxf(v1.z, v2.z);
|
||||
}
|
||||
|
||||
void Vec3::min(const Vec3 &v1, const Vec3 &v2, Vec3 *dst) {
|
||||
CC_ASSERT(dst);
|
||||
|
||||
dst->x = std::fminf(v1.x, v2.x);
|
||||
dst->y = std::fminf(v1.y, v2.y);
|
||||
dst->z = std::fminf(v1.z, v2.z);
|
||||
}
|
||||
|
||||
void Vec3::smooth(const Vec3 &target, float elapsedTime, float responseTime) {
|
||||
if (elapsedTime > 0.0F) {
|
||||
*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);
|
||||
const Vec3 Vec3::FORWARD(0.0F, 0.0F, -1.0F);
|
||||
|
||||
NS_CC_MATH_END
|
||||
655
cocos/math/Vec3.h
Normal file
655
cocos/math/Vec3.h
Normal file
@@ -0,0 +1,655 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include "math/Math.h"
|
||||
#include "math/MathBase.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() = default;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
explicit 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 ©);
|
||||
|
||||
/**
|
||||
* 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() = default;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Transforms the current vector with given scale, rotation and translation in reverse order
|
||||
*/
|
||||
static void transformInverseRTS(const Vec3 &v, const Quaternion &r, const Vec3 &t, const Vec3 &s, Vec3 *out);
|
||||
|
||||
/**
|
||||
* 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 the input 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 Mat4 and stores the result in this vector.
|
||||
* @param m The matrix.
|
||||
*/
|
||||
inline void transformMat4(const Mat4 &m) {
|
||||
transformMat4(*this, m);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms vector v by the specified Mat4 and stores the result in dst vector.
|
||||
* @zh 向量与四维矩阵乘法,默认向量第四位为 1。
|
||||
* @param v The Vec3 to transform.
|
||||
* @param m The matrix.
|
||||
* @param dst The destination vector
|
||||
*/
|
||||
static void transformMat4(const Vec3 &v, const Mat4 &m, Vec3 *dst);
|
||||
|
||||
/**
|
||||
* @en Vector and fourth order matrix multiplication, will complete the vector with a fourth element as one
|
||||
* @zh 向量与四维矩阵乘法,默认向量第四位为 0。
|
||||
*/
|
||||
static void transformMat4Normal(const Vec3 &v, const Mat4 &m, Vec3 *dst);
|
||||
|
||||
/**
|
||||
* @en Calculates a new position from current to target no more than `maxStep` distance.
|
||||
* @zh 计算一个新位置从当前位置移动不超过 `maxStep` 距离到目标位置。
|
||||
* @param current current position
|
||||
* @param target target position
|
||||
* @param maxStep maximum moving distance
|
||||
*/
|
||||
static void moveTowards(const Vec3 ¤t, const Vec3 &target, float maxStep, Vec3 *dst);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void normalize();
|
||||
|
||||
/**
|
||||
* Get the normalized vector.
|
||||
*
|
||||
* @return 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.
|
||||
*
|
||||
* @param p1 The vector to subtract.
|
||||
* @param p2 The vector to subtracted.
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Get the maximum value in the vector
|
||||
*
|
||||
* @param v1 To be compared vector.
|
||||
* @param v2 To be compared vector.
|
||||
* @param dst The destination vector.
|
||||
*/
|
||||
static void max(const Vec3 &v1, const Vec3 &v2, Vec3 *dst);
|
||||
|
||||
/**
|
||||
* Get the minimum value in the vector
|
||||
*
|
||||
* @param v1 To be compared vector.
|
||||
* @param v2 To be compared vector.
|
||||
* @param dst The destination vector.
|
||||
*/
|
||||
static void min(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;
|
||||
|
||||
/**
|
||||
* Multiply with a vector.
|
||||
*
|
||||
* @param rhs The value to scale by.
|
||||
* @return The scaled vector.
|
||||
*/
|
||||
inline Vec3 operator*(const Vec3 &rhs) 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;
|
||||
|
||||
/**
|
||||
* Divide by a vector.
|
||||
*
|
||||
* Note: this does not modify this vector.
|
||||
*
|
||||
* @param rhs the vector to divide this vector with
|
||||
* @return a vector
|
||||
*/
|
||||
inline Vec3 operator/(const Vec3 &rhs) const;
|
||||
|
||||
/**
|
||||
* Returns true if the vector's scalar components are all greater
|
||||
* that the ones of the vector it is compared against.
|
||||
*
|
||||
* @param rhs Compare the size of two vectors
|
||||
* @return bool
|
||||
*/
|
||||
inline bool operator<(const Vec3 &rhs) const {
|
||||
return x < rhs.x && y < rhs.y && z < rhs.z;
|
||||
}
|
||||
|
||||
inline bool operator<=(const Vec3 &rhs) const {
|
||||
return x <= rhs.x && y <= rhs.y && z <= rhs.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the vector's scalar components are all smaller
|
||||
* that the ones of the vector it is compared against.
|
||||
*
|
||||
* @param rhs Compare the size of two vectors
|
||||
* @return bool
|
||||
*/
|
||||
inline bool operator>(const Vec3 &rhs) const {
|
||||
return x > rhs.x && y > rhs.y && z > rhs.z;
|
||||
}
|
||||
|
||||
inline bool operator>=(const Vec3 &rhs) const {
|
||||
return x >= rhs.x && y >= rhs.y && z >= rhs.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Assign from another vector.
|
||||
*
|
||||
* @param rhs the vector to divide this vector with
|
||||
*
|
||||
* @return a vector
|
||||
*/
|
||||
inline Vec3 &operator=(const Vec3 &rhs) noexcept = default;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Determines if this vector is approximately equal to the given vector.
|
||||
*/
|
||||
inline bool approxEquals(const Vec3 &v, float precision = CC_FLOAT_CMP_PRECISION) const {
|
||||
return math::isEqualF(x, v.x, precision) && math::isEqualF(y, v.y, precision) && math::isEqualF(z, v.z, precision);
|
||||
}
|
||||
|
||||
/** 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;
|
||||
/** equals to Vec3(0,0,-1) */
|
||||
static const Vec3 FORWARD;
|
||||
|
||||
private:
|
||||
void transformMat4C(const Vec3 &v, const Mat4 &m);
|
||||
void transformMat4Neon(const Vec3 &v, const Mat4 &m);
|
||||
};
|
||||
|
||||
/**
|
||||
* 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"
|
||||
176
cocos/math/Vec3.inl
Normal file
176
cocos/math/Vec3.inl
Normal file
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <cmath>
|
||||
#include "math/Mat4.h"
|
||||
#include "math/Vec3.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) {
|
||||
CC_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*(const Vec3& rhs) const {
|
||||
return Vec3(x * rhs.x, y * rhs.y, z * rhs.z);
|
||||
}
|
||||
|
||||
inline Vec3& Vec3::operator*=(float s) {
|
||||
scale(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const Vec3 Vec3::operator/(const float s) const {
|
||||
const float inv = 1.0F / s;
|
||||
return Vec3(this->x * inv, this->y * inv, this->z * inv);
|
||||
}
|
||||
|
||||
inline Vec3 Vec3::operator/(const Vec3& rhs) const {
|
||||
return Vec3(x / rhs.x, y / rhs.y, z / rhs.z);
|
||||
}
|
||||
|
||||
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
|
||||
342
cocos/math/Vec4.cpp
Normal file
342
cocos/math/Vec4.cpp
Normal file
@@ -0,0 +1,342 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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 "base/Macros.h"
|
||||
#include "math/MathUtil.h"
|
||||
|
||||
#if CC_PLATFORM != CC_PLATFORM_EMSCRIPTEN
|
||||
#include "base/std/hash/hash.h"
|
||||
#endif
|
||||
|
||||
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 ©) {
|
||||
set(copy);
|
||||
}
|
||||
|
||||
Vec4 Vec4::fromColor(unsigned int color) {
|
||||
float components[4];
|
||||
int componentIndex = 0;
|
||||
for (int i = 3; i >= 0; --i) {
|
||||
uint32_t component = (color >> i * 8) & 0x000000ff;
|
||||
|
||||
components[componentIndex++] = static_cast<float>(component) / 255.0F;
|
||||
}
|
||||
|
||||
Vec4 value(components);
|
||||
return value;
|
||||
}
|
||||
|
||||
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) {
|
||||
const float dx = (v1.y * v2.z - v1.z * v2.y);
|
||||
const float dy = (v1.z * v2.x - v1.x * v2.z);
|
||||
const float dz = (v1.x * v2.y - v1.y * v2.x);
|
||||
const float dotVal = (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z);
|
||||
|
||||
return std::atan2(std::sqrt(dx * dx + dy * dy + dz * dz) + MATH_FLOAT_SMALL, dotVal);
|
||||
}
|
||||
|
||||
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) {
|
||||
CC_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) {
|
||||
CC_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) {
|
||||
CC_ASSERT(dst);
|
||||
CC_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* The inverse value of this vector.
|
||||
*
|
||||
* This method set each component to its inverse value, zero
|
||||
* will become infinity.
|
||||
*/
|
||||
void Vec4::inverse(const Vec4 &v, Vec4 *dst) {
|
||||
CC_ASSERT(dst);
|
||||
|
||||
dst->x = 1.0F / v.x;
|
||||
dst->y = 1.0F / v.y;
|
||||
dst->z = 1.0F / v.z;
|
||||
dst->w = 1.0F / v.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) {
|
||||
CC_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) {
|
||||
CC_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::lerp(const Vec4 &a, const Vec4 &b, float t, Vec4 *dst) {
|
||||
CC_ASSERT(dst);
|
||||
dst->x = a.x + t * (b.x - a.x);
|
||||
dst->y = a.y + t * (b.y - a.y);
|
||||
dst->z = a.z + t * (b.z - a.z);
|
||||
dst->w = a.w + t * (b.w - a.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);
|
||||
|
||||
#if CC_PLATFORM != CC_PLATFORM_EMSCRIPTEN
|
||||
template <>
|
||||
ccstd::hash_t Hasher<Vec4>::operator()(const Vec4 &v) const {
|
||||
return ccstd::hash_range(reinterpret_cast<const uint64_t *>(&v.x),
|
||||
reinterpret_cast<const uint64_t *>(&v.x + 4));
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_CC_MATH_END
|
||||
483
cocos/math/Vec4.h
Normal file
483
cocos/math/Vec4.h
Normal file
@@ -0,0 +1,483 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#undef __SSE__
|
||||
#ifdef __SSE__
|
||||
#include <xmmintrin.h>
|
||||
#endif
|
||||
|
||||
#include "math/Math.h"
|
||||
#include "math/MathBase.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.
|
||||
*/
|
||||
explicit Vec4(const float *src);
|
||||
|
||||
/**
|
||||
* 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 ©);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
/**
|
||||
* The inverse value of this vector.
|
||||
*
|
||||
* This method set each component to its inverse value, zero
|
||||
* will become infinity.
|
||||
*/
|
||||
static void inverse(const Vec4 &v, Vec4 *dst);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* @en Calculates the linear interpolation between two vectors with a given ratio
|
||||
* @zh 逐元素向量线性插值: A + t * (B - A)
|
||||
*/
|
||||
static void lerp(const Vec4 &a, const Vec4 &b, float t, 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;
|
||||
|
||||
/**
|
||||
* Determines if this vector is approximately equal to the given vector.
|
||||
*/
|
||||
inline bool approxEquals(const Vec4 &v, float precision = CC_FLOAT_CMP_PRECISION) const {
|
||||
return math::isEqualF(x, v.x, precision) && math::isEqualF(y, v.y, precision) && math::isEqualF(z, v.z, precision) && math::isEqualF(w, v.w, precision);
|
||||
}
|
||||
|
||||
/** 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"
|
||||
116
cocos/math/Vec4.inl
Normal file
116
cocos/math/Vec4.inl
Normal file
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
Copyright 2013 BlackBerry Inc.
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2023 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 "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