no message
This commit is contained in:
181
cocos/core/geometry/AABB.cpp
Normal file
181
cocos/core/geometry/AABB.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-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 "AABB.h"
|
||||
#include "base/Macros.h"
|
||||
#include "cocos/core/geometry/Enums.h"
|
||||
#include "cocos/core/geometry/Sphere.h"
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
|
||||
Sphere *AABB::toBoundingSphere(Sphere *out, const AABB &a) {
|
||||
out->setCenter(a.getCenter());
|
||||
out->setRadius(a.getHalfExtents().length());
|
||||
return out;
|
||||
}
|
||||
|
||||
AABB *AABB::fromPoints(const Vec3 &minPos, const Vec3 &maxPos, AABB *dst) {
|
||||
Vec3 center{(minPos + maxPos) * 0.5F};
|
||||
Vec3 halfExtents{(maxPos - minPos) * 0.5F};
|
||||
dst->setCenter(center);
|
||||
dst->setHalfExtents(halfExtents);
|
||||
return dst;
|
||||
}
|
||||
|
||||
AABB *AABB::merge(AABB *out, const AABB &a, const AABB &b) {
|
||||
Vec3 minCornor;
|
||||
Vec3 maxCorner;
|
||||
Vec3::max(a.getCenter() + a.getHalfExtents(), b.getCenter() + b.getHalfExtents(), &maxCorner);
|
||||
Vec3::min(a.getCenter() - a.getHalfExtents(), b.getCenter() - b.getHalfExtents(), &minCornor);
|
||||
return AABB::fromPoints(minCornor, maxCorner, out);
|
||||
}
|
||||
|
||||
void AABB::merge(const cc::Vec3 &point) {
|
||||
cc::Vec3 minPos = getCenter() - getHalfExtents();
|
||||
cc::Vec3 maxPos = getCenter() + getHalfExtents();
|
||||
if (point.x < minPos.x) {
|
||||
minPos.x = point.x;
|
||||
}
|
||||
if (point.y < minPos.y) {
|
||||
minPos.y = point.y;
|
||||
}
|
||||
if (point.z < minPos.z) {
|
||||
minPos.z = point.z;
|
||||
}
|
||||
if (point.x > maxPos.x) {
|
||||
maxPos.x = point.x;
|
||||
}
|
||||
if (point.y > maxPos.y) {
|
||||
maxPos.y = point.y;
|
||||
}
|
||||
if (point.z > maxPos.z) {
|
||||
maxPos.z = point.z;
|
||||
}
|
||||
|
||||
const Vec3 center = (minPos + maxPos) * 0.5F;
|
||||
setCenter(center);
|
||||
setHalfExtents(maxPos.x - center.x, maxPos.y - center.y, maxPos.z - center.z);
|
||||
}
|
||||
|
||||
void AABB::merge(const ccstd::vector<cc::Vec3> &points) {
|
||||
for (const auto &p : points) {
|
||||
merge(p);
|
||||
}
|
||||
}
|
||||
|
||||
void AABB::merge(const Frustum &frustum) {
|
||||
const ccstd::array<Vec3, 8> &vertices = frustum.vertices;
|
||||
for (size_t i = 0; i < vertices.max_size(); ++i) {
|
||||
merge(vertices[i]);
|
||||
}
|
||||
}
|
||||
|
||||
bool AABB::aabbAabb(const AABB &aabb) const {
|
||||
Vec3 aMin;
|
||||
Vec3 aMax;
|
||||
Vec3 bMin;
|
||||
Vec3 bMax;
|
||||
Vec3::subtract(getCenter(), getHalfExtents(), &aMin);
|
||||
Vec3::add(getCenter(), getHalfExtents(), &aMax);
|
||||
Vec3::subtract(aabb.getCenter(), aabb.getHalfExtents(), &bMin);
|
||||
Vec3::add(aabb.getCenter(), aabb.getHalfExtents(), &bMax);
|
||||
return (aMin.x <= bMax.x && aMax.x >= bMin.x) &&
|
||||
(aMin.y <= bMax.y && aMax.y >= bMin.y) &&
|
||||
(aMin.z <= bMax.z && aMax.z >= bMin.z);
|
||||
}
|
||||
|
||||
int AABB::aabbPlane(const Plane &plane) const {
|
||||
auto r = getHalfExtents().x * std::abs(plane.n.x) +
|
||||
getHalfExtents().y * std::abs(plane.n.y) +
|
||||
getHalfExtents().z * std::abs(plane.n.z);
|
||||
auto dot = Vec3::dot(plane.n, getCenter());
|
||||
if (dot + r < plane.d) {
|
||||
return -1;
|
||||
}
|
||||
if (dot - r > plane.d) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool AABB::aabbFrustum(const Frustum &frustum) const {
|
||||
const auto &planes = frustum.planes;
|
||||
const auto *self = this;
|
||||
return std::all_of(planes.begin(),
|
||||
planes.end(),
|
||||
// frustum plane normal points to the inside
|
||||
[self](const Plane *plane) { return self->aabbPlane(*plane) != -1; });
|
||||
}
|
||||
|
||||
void AABB::getBoundary(cc::Vec3 *minPos, cc::Vec3 *maxPos) const {
|
||||
*maxPos = getCenter() + getHalfExtents();
|
||||
*minPos = getCenter() - getHalfExtents();
|
||||
}
|
||||
|
||||
void AABB::merge(const AABB &aabb) {
|
||||
AABB::merge(this, aabb, *this);
|
||||
}
|
||||
|
||||
void AABB::set(const cc::Vec3 ¢erVal, const cc::Vec3 &halfExtentVal) {
|
||||
setCenter(centerVal);
|
||||
setHalfExtents(halfExtentVal);
|
||||
}
|
||||
|
||||
void AABB::transform(const Mat4 &m, AABB *out) const {
|
||||
Vec3::transformMat4(center, m, &out->center);
|
||||
transformExtentM4(&out->halfExtents, getHalfExtents(), m);
|
||||
}
|
||||
|
||||
bool AABB::contain(const cc::Vec3 &point) const {
|
||||
cc::Vec3 minPos = getCenter() - getHalfExtents();
|
||||
cc::Vec3 maxPos = getCenter() + getHalfExtents();
|
||||
|
||||
return !(point.x > maxPos.x || point.x < minPos.x ||
|
||||
point.y > maxPos.y || point.y < minPos.y ||
|
||||
point.z > maxPos.z || point.z < minPos.z);
|
||||
}
|
||||
|
||||
// https://zeuxcg.org/2010/10/17/aabb-from-obb-with-component-wise-abs/
|
||||
void AABB::transformExtentM4(Vec3 *out, const Vec3 &extent, const Mat4 &m4) {
|
||||
Mat3 m3Tmp;
|
||||
m3Tmp.m[0] = std::abs(m4.m[0]);
|
||||
m3Tmp.m[1] = std::abs(m4.m[1]);
|
||||
m3Tmp.m[2] = std::abs(m4.m[2]);
|
||||
m3Tmp.m[3] = std::abs(m4.m[4]);
|
||||
m3Tmp.m[4] = std::abs(m4.m[5]);
|
||||
m3Tmp.m[5] = std::abs(m4.m[6]);
|
||||
m3Tmp.m[6] = std::abs(m4.m[8]);
|
||||
m3Tmp.m[7] = std::abs(m4.m[9]);
|
||||
m3Tmp.m[8] = std::abs(m4.m[10]);
|
||||
out->transformMat3(extent, m3Tmp);
|
||||
}
|
||||
|
||||
AABB::AABB(float px, float py, float pz, float hw, float hh, float hl) : AABB() {
|
||||
setCenter(px, py, pz);
|
||||
setHalfExtents(hw, hh, hl);
|
||||
}
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
164
cocos/core/geometry/AABB.h
Normal file
164
cocos/core/geometry/AABB.h
Normal file
@@ -0,0 +1,164 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-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 <algorithm>
|
||||
#include "base/memory/Memory.h"
|
||||
#include "base/std/container/vector.h"
|
||||
#include "core/geometry/Enums.h"
|
||||
#include "math/Mat3.h"
|
||||
#include "math/Quaternion.h"
|
||||
#include "math/Vec3.h"
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
|
||||
class Sphere;
|
||||
class Frustum;
|
||||
class Plane;
|
||||
|
||||
class AABB final : public ShapeBase {
|
||||
public:
|
||||
/**
|
||||
* @en
|
||||
* create a new AABB
|
||||
* @zh
|
||||
* 创建一个新的 AABB 实例。
|
||||
* @param px - AABB 的原点的 X 坐标。
|
||||
* @param py - AABB 的原点的 Y 坐标。
|
||||
* @param pz - AABB 的原点的 Z 坐标。
|
||||
* @param hw - AABB 宽度的一半。
|
||||
* @param hh - AABB 高度的一半。
|
||||
* @param hl - AABB 长度的一半。
|
||||
* @returns 返回新创建的 AABB 实例。
|
||||
*/
|
||||
static AABB *create(float px, float py, float pz, float hw, float hh, float hl) {
|
||||
return ccnew AABB(px, py, pz, hw, hh, hl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Set the components of a AABB to the given values
|
||||
* @zh
|
||||
* 将 AABB 的属性设置为给定的值。
|
||||
* @param {AABB} out 接受操作的 AABB。
|
||||
* @param px - AABB 的原点的 X 坐标。
|
||||
* @param py - AABB 的原点的 Y 坐标。
|
||||
* @param pz - AABB 的原点的 Z 坐标。
|
||||
* @param hw - AABB 宽度的一半。
|
||||
* @param hh - AABB 高度的一半。
|
||||
* @param hl - AABB 长度度的一半。
|
||||
* @return {AABB} out 接受操作的 AABB。
|
||||
*/
|
||||
|
||||
static AABB *set(AABB *out, float px, float py,
|
||||
float pz,
|
||||
float hw,
|
||||
float hh,
|
||||
float hl) {
|
||||
out->setCenter(px, py, pz);
|
||||
out->setHalfExtents(hw, hh, hl);
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Merge tow AABB.
|
||||
* @zh
|
||||
* 合并两个 AABB 到 out。
|
||||
* @param out 接受操作的 AABB。
|
||||
* @param a 输入的 AABB。
|
||||
* @param b 输入的 AABB。
|
||||
* @returns {AABB} out 接受操作的 AABB。
|
||||
*/
|
||||
static AABB *merge(AABB *out, const AABB &a, const AABB &b);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* AABB to sphere
|
||||
* @zh
|
||||
* 包围盒转包围球
|
||||
* @param out 接受操作的 sphere。
|
||||
* @param a 输入的 AABB。
|
||||
*/
|
||||
|
||||
static Sphere *toBoundingSphere(Sphere *out, const AABB &a);
|
||||
|
||||
static AABB *fromPoints(const Vec3 &minPos, const Vec3 &maxPos, AABB *dst);
|
||||
static void transformExtentM4(Vec3 *out, const Vec3 &extent, const Mat4 &m4);
|
||||
|
||||
AABB(float px, float py, float pz, float hw, float hh, float hl);
|
||||
AABB() : ShapeBase(ShapeEnum::SHAPE_AABB) {}
|
||||
~AABB() override = default;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* aabb-plane intersect detect.
|
||||
* @zh
|
||||
* 轴对齐包围盒和平面的相交性检测。
|
||||
* @param {AABB} aabb 轴对齐包围盒
|
||||
* @param {Plane} plane 平面
|
||||
* @return {number} inside(back) = -1, outside(front) = 0, intersect = 1
|
||||
*/
|
||||
bool aabbAabb(const AABB &aabb) const;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* aabb-frustum intersect detect, faster but has false positive corner cases.
|
||||
* @zh
|
||||
* 轴对齐包围盒和锥台相交性检测,速度快,但有错误情况。
|
||||
* @param {AABB} aabb 轴对齐包围盒
|
||||
* @param {Frustum} frustum 锥台
|
||||
* @return {number} 0 或 非0
|
||||
*/
|
||||
bool aabbFrustum(const Frustum &) const;
|
||||
|
||||
int aabbPlane(const Plane &) const;
|
||||
void getBoundary(cc::Vec3 *minPos, cc::Vec3 *maxPos) const;
|
||||
void merge(const AABB &aabb);
|
||||
void merge(const cc::Vec3 &point);
|
||||
void merge(const ccstd::vector<cc::Vec3> &points);
|
||||
void merge(const Frustum &frustum);
|
||||
void set(const cc::Vec3 ¢erVal, const cc::Vec3 &halfExtentVal);
|
||||
void transform(const Mat4 &m, AABB *out) const;
|
||||
bool contain(const cc::Vec3 &point) const;
|
||||
inline void setCenter(float x, float y, float z) { center.set(x, y, z); }
|
||||
inline void setCenter(const Vec3 ¢er) { this->center.set(center); }
|
||||
inline void setValid(bool isValid) { _isValid = isValid; }
|
||||
inline const Vec3 &getCenter() const { return center; }
|
||||
inline bool isValid() const { return _isValid; }
|
||||
inline void setHalfExtents(float x, float y, float z) { halfExtents.set(x, y, z); }
|
||||
inline void setHalfExtents(const Vec3 &halfExtents) { this->halfExtents.set(halfExtents); }
|
||||
inline const Vec3 &getHalfExtents() const { return halfExtents; }
|
||||
|
||||
cc::Vec3 center;
|
||||
cc::Vec3 halfExtents{1, 1, 1};
|
||||
|
||||
private:
|
||||
bool _isValid{true};
|
||||
};
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
71
cocos/core/geometry/Capsule.cpp
Normal file
71
cocos/core/geometry/Capsule.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
/****************************************************************************
|
||||
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 "cocos/core/geometry/Capsule.h"
|
||||
#include "cocos/math/Vec3.h"
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
|
||||
void Capsule::transform(const Mat4 &m, const Vec3 & /*pos*/, const Quaternion &rot, const Vec3 &scale, Capsule *out) const {
|
||||
const auto maxComponent = mathutils::absMaxComponent(scale);
|
||||
out->radius = this->radius * std::abs(maxComponent);
|
||||
|
||||
const auto halfTotalWorldHeight = (this->halfHeight + this->radius) * std::abs(scale.y);
|
||||
auto halfWorldHeight = halfTotalWorldHeight - out->radius;
|
||||
if (halfWorldHeight < 0) halfWorldHeight = 0;
|
||||
out->halfHeight = halfWorldHeight;
|
||||
|
||||
out->center.transformMat4(this->center, m);
|
||||
Quaternion::multiply(this->rotation, rot, &out->rotation);
|
||||
out->updateCache();
|
||||
}
|
||||
|
||||
void Capsule::updateCache() {
|
||||
updateLocalCenter();
|
||||
ellipseCenter0.transformQuat(rotation);
|
||||
ellipseCenter1.transformQuat(rotation);
|
||||
ellipseCenter0 += center;
|
||||
ellipseCenter1 += center;
|
||||
}
|
||||
|
||||
void Capsule::updateLocalCenter() {
|
||||
switch (axis) {
|
||||
case CenterEnum::X:
|
||||
ellipseCenter0 = {halfHeight, 0, 0};
|
||||
ellipseCenter1 = {-halfHeight, 0, 0};
|
||||
break;
|
||||
case CenterEnum::Y:
|
||||
ellipseCenter0 = {0, halfHeight, 0};
|
||||
ellipseCenter1 = {0, -halfHeight, 0};
|
||||
break;
|
||||
case CenterEnum::Z:
|
||||
ellipseCenter0 = {0, 0, halfHeight};
|
||||
ellipseCenter1 = {0, 0, -halfHeight};
|
||||
break;
|
||||
default:
|
||||
CC_ABORT();
|
||||
}
|
||||
}
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
130
cocos/core/geometry/Capsule.h
Normal file
130
cocos/core/geometry/Capsule.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/****************************************************************************
|
||||
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 "core/geometry/Enums.h"
|
||||
#include "math/Mat4.h"
|
||||
#include "math/Quaternion.h"
|
||||
#include "math/Utils.h"
|
||||
#include "math/Vec3.h"
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Basic Geometry: capsule.
|
||||
* @zh
|
||||
* 基础几何,胶囊体。
|
||||
*/
|
||||
class Capsule final : public ShapeBase {
|
||||
/**
|
||||
* @en
|
||||
* Gets the type of the shape.
|
||||
* @zh
|
||||
* 获取形状的类型。
|
||||
*/
|
||||
public:
|
||||
enum class CenterEnum {
|
||||
X = 0,
|
||||
Y = 1,
|
||||
Z = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Capsule sphere radius.
|
||||
* @zh
|
||||
* 胶囊体球部半径。
|
||||
*/
|
||||
float radius{0.0F};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The distance between the center point of the capsule and the center of the sphere.
|
||||
* @zh
|
||||
* 胶囊体中心点和球部圆心的距离。
|
||||
*/
|
||||
float halfHeight{0.0F};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Local orientation of capsule [0,1,2] => [x,y,z].
|
||||
* @zh
|
||||
* 胶囊体的本地朝向,映射关系 [0,1,2] => [x,y,z]。
|
||||
*/
|
||||
CenterEnum axis;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The origin of the capsule.
|
||||
* @zh
|
||||
* 胶囊体的原点。
|
||||
*/
|
||||
Vec3 center;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The rotation of the capsule.
|
||||
* @zh
|
||||
* 胶囊体的旋转。
|
||||
*/
|
||||
Quaternion rotation;
|
||||
|
||||
/** cache, local center of ellipse */
|
||||
Vec3 ellipseCenter0;
|
||||
Vec3 ellipseCenter1;
|
||||
|
||||
explicit Capsule(float radius = 0.5, float halfHeight = 0.5, CenterEnum axis = CenterEnum::Y) : ShapeBase(ShapeEnum::SHAPE_CAPSULE) {
|
||||
this->radius = radius;
|
||||
this->halfHeight = halfHeight;
|
||||
this->axis = axis;
|
||||
this->center = {};
|
||||
this->rotation = {};
|
||||
ellipseCenter0 = {0, halfHeight, 0};
|
||||
ellipseCenter1 = {0, -halfHeight, 0};
|
||||
updateCache();
|
||||
}
|
||||
|
||||
Capsule(const Capsule &other) = default;
|
||||
Capsule(Capsule &&other) = default;
|
||||
Capsule &operator=(const Capsule &other) = default;
|
||||
Capsule &operator=(Capsule &&other) = default;
|
||||
~Capsule() override = default;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Transform this capsule.
|
||||
* @zh
|
||||
* 变换此胶囊体。
|
||||
*/
|
||||
void transform(const Mat4 &m, const Vec3 &pos, const Quaternion &rot, const Vec3 &scale, Capsule *out) const;
|
||||
|
||||
private:
|
||||
void updateCache();
|
||||
void updateLocalCenter();
|
||||
};
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
38
cocos/core/geometry/Curve.cpp
Normal file
38
cocos/core/geometry/Curve.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/****************************************************************************
|
||||
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 "cocos/core/geometry/Curve.h"
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
|
||||
float OptimizedKey::evaluate(float tt) {
|
||||
const t = tt - time;
|
||||
return evalOptCurve(t, coefficient);
|
||||
}
|
||||
|
||||
float evalOptCurve(float t, const ccstd::vector<float> &coefs) {
|
||||
return (t * (t * (t * coefs[0] + coefs[1]) + coefs[2])) + coefs[3];
|
||||
}
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
386
cocos/core/geometry/Curve.h
Normal file
386
cocos/core/geometry/Curve.h
Normal file
@@ -0,0 +1,386 @@
|
||||
/****************************************************************************
|
||||
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
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
|
||||
constexpr auto LOOK_FORWARD = 3;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* A key frame in the curve.
|
||||
* @zh
|
||||
* 曲线中的一个关键帧。
|
||||
*/
|
||||
struct Keyframe {
|
||||
/**
|
||||
* @en Current frame time.
|
||||
* @zh 当前帧时间。
|
||||
*/
|
||||
float time = 0;
|
||||
|
||||
/**
|
||||
* @en Current frame value.
|
||||
* @zh 当前帧的值。
|
||||
*/
|
||||
float value = 0;
|
||||
|
||||
/**
|
||||
* @en In tangent value.
|
||||
* @zh 左切线。
|
||||
*/
|
||||
float inTangent = 0;
|
||||
|
||||
/**
|
||||
* @en Out tangent value.
|
||||
* @zh 右切线。
|
||||
*/
|
||||
float outTangent = 0;
|
||||
};
|
||||
|
||||
float evalOptCurve(float t, const ccstd::vector<float> &coefs);
|
||||
|
||||
struct OptimizedKey {
|
||||
float index;
|
||||
float time;
|
||||
float endTime;
|
||||
ccstd::vector<float> coefficient;
|
||||
OptimizedKey() {
|
||||
index = -1;
|
||||
time = 0;
|
||||
endTime = 0;
|
||||
coefficient.resize(4);
|
||||
}
|
||||
static float evaluate(float t);
|
||||
};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Describe a curve in which three times Hermite interpolation is used for each adjacent key frame.
|
||||
* @zh
|
||||
* 描述一条曲线,其中每个相邻关键帧采用三次hermite插值计算。
|
||||
*/
|
||||
class AnimationCurve {
|
||||
// @serializable
|
||||
private:
|
||||
// _curve ! : RealCurve;
|
||||
|
||||
public:
|
||||
static ccstd::vector<KeyFrame> defaultKF = [ {
|
||||
time : 0,
|
||||
value : 1,
|
||||
inTangent : 0,
|
||||
outTangent : 0,
|
||||
},
|
||||
{
|
||||
time : 1,
|
||||
value : 1,
|
||||
inTangent : 0,
|
||||
outTangent : 0,
|
||||
} ];
|
||||
|
||||
/**
|
||||
* For internal usage only.
|
||||
* @internal
|
||||
*/
|
||||
get _internalCurve() {
|
||||
return this._curve;
|
||||
}
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The key frame of the curve.
|
||||
* @zh
|
||||
* 曲线的关键帧。
|
||||
*/
|
||||
auto getKeyFrames() {
|
||||
return Array.from(this._curve.keyframes()).map(([ time, value ]) = > {
|
||||
const legacyKeyframe = ccnew Keyframe();
|
||||
legacyKeyframe.time = time;
|
||||
legacyKeyframe.value = value.value;
|
||||
legacyKeyframe.inTangent = value.leftTangent;
|
||||
legacyKeyframe.outTangent = value.rightTangent;
|
||||
return legacyKeyframe;
|
||||
});
|
||||
}
|
||||
|
||||
void setKeyFrames(value) {
|
||||
this._curve.assignSorted(value.map((legacyCurve) = > [
|
||||
legacyCurve.time,
|
||||
{
|
||||
interpolationMode : RealInterpolationMode.CUBIC,
|
||||
value : legacyCurve.value,
|
||||
leftTangent : legacyCurve.inTangent,
|
||||
rightTangent : legacyCurve.outTangent,
|
||||
},
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Loop mode [[WrapMode]] when the sampling time exceeds the left end.
|
||||
* @zh
|
||||
* 当采样时间超出左端时采用的循环模式[[WrapMode]]。
|
||||
*/
|
||||
auto getPreWrapMode() {
|
||||
return toLegacyWrapMode(this._curve.preExtrapolation);
|
||||
}
|
||||
|
||||
void sPreWrapMode(value) {
|
||||
this._curve.preExtrapolation = fromLegacyWrapMode(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Cycle mode [[WrapMode]] when the sampling time exceeds the right end.
|
||||
* @zh
|
||||
* 当采样时间超出右端时采用的循环模式[[WrapMode]]。
|
||||
*/
|
||||
get postWrapMode() {
|
||||
return toLegacyWrapMode(this._curve.postExtrapolation);
|
||||
}
|
||||
|
||||
set postWrapMode(value) {
|
||||
this._curve.postExtrapolation = fromLegacyWrapMode(value);
|
||||
}
|
||||
|
||||
private
|
||||
cachedKey : OptimizedKey;
|
||||
|
||||
/**
|
||||
* 构造函数。
|
||||
* @param keyFrames 关键帧。
|
||||
*/
|
||||
constructor(keyFrames
|
||||
: Keyframe[] | null | RealCurve = null) {
|
||||
if (keyFrames instanceof RealCurve) {
|
||||
this._curve = keyFrames;
|
||||
} else {
|
||||
const curve = ccnew RealCurve();
|
||||
this._curve = curve;
|
||||
curve.preExtrapolation = ExtrapolationMode.LOOP;
|
||||
curve.postExtrapolation = ExtrapolationMode.CLAMP;
|
||||
if (!keyFrames) {
|
||||
curve.assignSorted([
|
||||
[ 0.0, {interpolationMode : RealInterpolationMode.CUBIC, value : 1.0} ],
|
||||
[ 1.0, {interpolationMode : RealInterpolationMode.CUBIC, value : 1.0} ],
|
||||
]);
|
||||
} else {
|
||||
curve.assignSorted(keyFrames.map((legacyKeyframe) = > [ legacyKeyframe.time, {
|
||||
interpolationMode : RealInterpolationMode.CUBIC,
|
||||
value : legacyKeyframe.value,
|
||||
leftTangent : legacyKeyframe.inTangent,
|
||||
rightTangent : legacyKeyframe.outTangent,
|
||||
} ]));
|
||||
}
|
||||
}
|
||||
this.cachedKey = ccnew OptimizedKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Add a keyframe.
|
||||
* @zh
|
||||
* 添加一个关键帧。
|
||||
* @param keyFrame 关键帧。
|
||||
*/
|
||||
public
|
||||
addKey(keyFrame
|
||||
: Keyframe | null) {
|
||||
if (!keyFrame) {
|
||||
this._curve.clear();
|
||||
} else {
|
||||
this._curve.addKeyFrame(keyFrame.time, {
|
||||
interpolationMode : RealInterpolationMode.CUBIC,
|
||||
value : keyFrame.value,
|
||||
leftTangent : keyFrame.inTangent,
|
||||
rightTangent : keyFrame.outTangent,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
* @param time
|
||||
*/
|
||||
public
|
||||
evaluate_slow(time
|
||||
: number) {
|
||||
return this._curve.evaluate(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Calculate the curve interpolation at a given point in time.
|
||||
* @zh
|
||||
* 计算给定时间点的曲线插值。
|
||||
* @param time 时间。
|
||||
*/
|
||||
public
|
||||
evaluate(time
|
||||
: number) {
|
||||
const {cachedKey, _curve : curve} = this;
|
||||
const nKeyframes = curve.keyFramesCount;
|
||||
const lastKeyframeIndex = nKeyframes - 1;
|
||||
let wrappedTime = time;
|
||||
const extrapolationMode = time < 0 ? curve.preExtrapolation : curve.postExtrapolation;
|
||||
const startTime = curve.getKeyframeTime(0);
|
||||
const endTime = curve.getKeyframeTime(lastKeyframeIndex);
|
||||
switch (extrapolationMode) {
|
||||
case ExtrapolationMode.LOOP:
|
||||
wrappedTime = repeat(time - startTime, endTime - startTime) + startTime;
|
||||
break;
|
||||
case ExtrapolationMode.PING_PONG:
|
||||
wrappedTime = pingPong(time - startTime, endTime - startTime) + startTime;
|
||||
break;
|
||||
case ExtrapolationMode.CLAMP:
|
||||
default:
|
||||
wrappedTime = clamp(time, startTime, endTime);
|
||||
break;
|
||||
}
|
||||
if (wrappedTime >= cachedKey.time && wrappedTime < cachedKey.endTime) {
|
||||
return cachedKey.evaluate(wrappedTime);
|
||||
}
|
||||
const leftIndex = this.findIndex(cachedKey, wrappedTime);
|
||||
const rightIndex = Math.min(leftIndex + 1, lastKeyframeIndex);
|
||||
this.calcOptimizedKey(cachedKey, leftIndex, rightIndex);
|
||||
return cachedKey.evaluate(wrappedTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
* @param optKey
|
||||
* @param leftIndex
|
||||
* @param rightIndex
|
||||
*/
|
||||
public
|
||||
calcOptimizedKey(optKey
|
||||
: OptimizedKey, leftIndex
|
||||
: number, rightIndex
|
||||
: number) {
|
||||
const lhsTime = this._curve.getKeyframeTime(leftIndex);
|
||||
const rhsTime = this._curve.getKeyframeTime(rightIndex);
|
||||
const {value : lhsValue, leftTangent : lhsOutTangent} = this._curve.getKeyframeValue(leftIndex);
|
||||
const {value : rhsValue, rightTangent : rhsInTangent} = this._curve.getKeyframeValue(rightIndex);
|
||||
optKey.index = leftIndex;
|
||||
optKey.time = lhsTime;
|
||||
optKey.endTime = rhsTime;
|
||||
|
||||
const dx = rhsTime - lhsTime;
|
||||
const dy = rhsValue - lhsValue;
|
||||
const length = 1 / (dx * dx);
|
||||
const d1 = lhsOutTangent * dx;
|
||||
const d2 = rhsInTangent * dx;
|
||||
|
||||
optKey.coefficient[0] = (d1 + d2 - dy - dy) * length / dx;
|
||||
optKey.coefficient[1] = (dy + dy + dy - d1 - d1 - d2) * length;
|
||||
optKey.coefficient[2] = lhsOutTangent;
|
||||
optKey.coefficient[3] = lhsValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
* @param optKey
|
||||
* @param t
|
||||
*/
|
||||
private
|
||||
findIndex(optKey
|
||||
: OptimizedKey, t
|
||||
: number) {
|
||||
const {_curve : curve} = this;
|
||||
const nKeyframes = curve.keyFramesCount;
|
||||
const cachedIndex = optKey.index;
|
||||
if (cachedIndex != = -1) {
|
||||
const cachedTime = curve.getKeyframeTime(cachedIndex);
|
||||
if (t > cachedTime) {
|
||||
for (let i = 0; i < LOOK_FORWARD; i++) {
|
||||
const currIndex = cachedIndex + i;
|
||||
if (currIndex + 1 < nKeyframes && curve.getKeyframeTime(currIndex + 1) > t) {
|
||||
return currIndex;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < LOOK_FORWARD; i++) {
|
||||
const currIndex = cachedIndex - i;
|
||||
if (currIndex >= 0 && curve.getKeyframeTime(currIndex - 1) <= t) {
|
||||
return currIndex - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let left = 0;
|
||||
let right = nKeyframes;
|
||||
let mid;
|
||||
while (right - left > 1) {
|
||||
mid = Math.floor((left + right) / 2);
|
||||
if (curve.getKeyframeTime(mid) >= t) {
|
||||
right = mid;
|
||||
} else {
|
||||
left = mid;
|
||||
}
|
||||
}
|
||||
return left;
|
||||
}
|
||||
}
|
||||
|
||||
function
|
||||
fromLegacyWrapMode(legacyWrapMode
|
||||
: WrapModeMask) : ExtrapolationMode {
|
||||
switch (legacyWrapMode) {
|
||||
default:
|
||||
case WrapModeMask.Default:
|
||||
case WrapModeMask.Normal:
|
||||
case WrapModeMask.Clamp: return ExtrapolationMode.CLAMP;
|
||||
case WrapModeMask.PingPong: return ExtrapolationMode.PING_PONG;
|
||||
case WrapModeMask.Loop: return ExtrapolationMode.LOOP;
|
||||
}
|
||||
}
|
||||
|
||||
function toLegacyWrapMode(extrapolationMode
|
||||
: ExtrapolationMode) : WrapModeMask {
|
||||
switch (extrapolationMode) {
|
||||
default:
|
||||
case ExtrapolationMode.LINEAR:
|
||||
case ExtrapolationMode.CLAMP: return WrapModeMask.Clamp;
|
||||
case ExtrapolationMode.PING_PONG: return WrapModeMask.PingPong;
|
||||
case ExtrapolationMode.LOOP: return WrapModeMask.Loop;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as but more effective than `new LegacyCurve()._internalCurve`.
|
||||
*/
|
||||
export function constructLegacyCurveAndConvert() {
|
||||
const curve = ccnew RealCurve();
|
||||
curve.assignSorted([
|
||||
[ 0.0, {interpolationMode : RealInterpolationMode.CUBIC, value : 1.0} ],
|
||||
[ 1.0, {interpolationMode : RealInterpolationMode.CUBIC, value : 1.0} ],
|
||||
]);
|
||||
return curve;
|
||||
}
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
104
cocos/core/geometry/Distance.cpp
Normal file
104
cocos/core/geometry/Distance.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
/****************************************************************************
|
||||
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 "cocos/core/geometry/Distance.h"
|
||||
|
||||
#include "cocos/core/geometry/AABB.h"
|
||||
#include "cocos/core/geometry/Obb.h"
|
||||
#include "cocos/core/geometry/Plane.h"
|
||||
#include "cocos/math/Mat4.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "base/std/container/array.h"
|
||||
#include "cocos/math/Utils.h"
|
||||
#include "cocos/math/Vec3.h"
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
|
||||
float pointPlane(const Vec3 &point, const Plane &plane) {
|
||||
return Vec3::dot(plane.n, point) - plane.d;
|
||||
}
|
||||
|
||||
Vec3 *ptPointPlane(Vec3 *out, const Vec3 &point, const Plane &plane) {
|
||||
auto t = pointPlane(point, plane);
|
||||
*out = point - t * plane.n;
|
||||
return out;
|
||||
}
|
||||
|
||||
Vec3 *ptPointAabb(Vec3 *out, const Vec3 &point, const AABB &aabb) {
|
||||
auto min = aabb.getCenter() - aabb.getHalfExtents();
|
||||
auto max = aabb.getCenter() + aabb.getHalfExtents();
|
||||
*out = {cc::mathutils::clamp(point.x, min.x, max.x),
|
||||
cc::mathutils::clamp(point.y, min.y, max.y),
|
||||
cc::mathutils::clamp(point.z, min.z, max.z)};
|
||||
return out;
|
||||
}
|
||||
|
||||
Vec3 *ptPointObb(Vec3 *out, const Vec3 &point, const OBB &obb) {
|
||||
ccstd::array<Vec3, 3> u = {
|
||||
Vec3{obb.orientation.m[0], obb.orientation.m[1], obb.orientation.m[2]},
|
||||
Vec3{obb.orientation.m[3], obb.orientation.m[4], obb.orientation.m[5]},
|
||||
Vec3{obb.orientation.m[6], obb.orientation.m[7], obb.orientation.m[8]},
|
||||
};
|
||||
ccstd::array<float, 3> e = {obb.halfExtents.x, obb.halfExtents.y, obb.halfExtents.z};
|
||||
|
||||
auto d = point - obb.center;
|
||||
float dist = 0.0F;
|
||||
|
||||
// Start result at center of obb; make steps from there
|
||||
*out = obb.center;
|
||||
|
||||
// For each OBB axis...
|
||||
for (int i = 0; i < 3; i++) {
|
||||
// ...project d onto that axis to get the distance
|
||||
// along the axis of d from the obb center
|
||||
dist = Vec3::dot(d, u[i]);
|
||||
// if distance farther than the obb extents, clamp to the obb
|
||||
dist = cc::mathutils::clamp(dist, -e[i], e[i]);
|
||||
|
||||
// Step that distance along the axis to get world coordinate
|
||||
*out += (dist * u[i]);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
Vec3 *ptPointLine(Vec3 *out, const Vec3 &point, const Vec3 &linePointA, const Vec3 &linePointB) {
|
||||
auto dir = linePointA - linePointB;
|
||||
auto dirSquared = dir.lengthSquared();
|
||||
|
||||
if (dirSquared == 0.0F) {
|
||||
// The point is at the segment start.
|
||||
*out = linePointA;
|
||||
} else {
|
||||
// Calculate the projection of the point onto the line extending through the segment.
|
||||
auto ap = point - linePointA;
|
||||
auto t = Vec3::dot(ap, dir) / dirSquared;
|
||||
*out = linePointA + cc::mathutils::clamp(t, 0.0F, 1.0F) * dir;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
96
cocos/core/geometry/Distance.h
Normal file
96
cocos/core/geometry/Distance.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/****************************************************************************
|
||||
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
|
||||
|
||||
namespace cc {
|
||||
|
||||
class Mat4;
|
||||
class Vec3;
|
||||
namespace geometry {
|
||||
|
||||
class Plane;
|
||||
class OBB;
|
||||
class AABB;
|
||||
/**
|
||||
* @en
|
||||
* the distance between a point and a plane
|
||||
* @zh
|
||||
* 计算点和平面之间的距离。
|
||||
* @param {Vec3} point 点。
|
||||
* @param {Plane} plane 平面。
|
||||
* @return 距离。
|
||||
*/
|
||||
float pointPlane(const Vec3 &point, const Plane &plane);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* the closest point on plane to a given point
|
||||
* @zh
|
||||
* 计算平面上最接近给定点的点。
|
||||
* @param out 最近点。
|
||||
* @param point 给定点。
|
||||
* @param plane 平面。
|
||||
* @return 最近点。
|
||||
*/
|
||||
Vec3 *ptPointPlane(Vec3 *out, const Vec3 &point, const Plane &plane);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* the closest point on aabb to a given point
|
||||
* @zh
|
||||
* 计算 aabb 上最接近给定点的点。
|
||||
* @param {Vec3} out 最近点。
|
||||
* @param {Vec3} point 给定点。
|
||||
* @param {AABB} aabb 轴对齐包围盒。
|
||||
* @return {Vec3} 最近点。
|
||||
*/
|
||||
Vec3 *ptPointAabb(Vec3 *out, const Vec3 &point, const AABB &aabb);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* the closest point on obb to a given point
|
||||
* @zh
|
||||
* 计算 obb 上最接近给定点的点。
|
||||
* @param {Vec3} out 最近点。
|
||||
* @param {Vec3} point 给定点。
|
||||
* @param {OBB} obb 方向包围盒。
|
||||
* @return {Vec3} 最近点。
|
||||
*/
|
||||
Vec3 *ptPointObb(Vec3 *out, const Vec3 &point, const OBB &obb);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Calculate the nearest point on the line to the given point.
|
||||
* @zh
|
||||
* 计算给定点距离直线上最近的一点。
|
||||
* @param out 最近点
|
||||
* @param point 给定点
|
||||
* @param linePointA 线上的某点 A
|
||||
* @param linePointB 线上的某点 B
|
||||
*/
|
||||
Vec3 *ptPointLine(Vec3 *out, const Vec3 &point, const Vec3 &linePointA, const Vec3 &linePointB);
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
69
cocos/core/geometry/Enums.h
Normal file
69
cocos/core/geometry/Enums.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/****************************************************************************
|
||||
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 "base/Macros.h"
|
||||
#include "base/RefCounted.h"
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
|
||||
enum class ShapeEnum {
|
||||
SHAPE_RAY = (1 << 0),
|
||||
SHAPE_LINE = (1 << 1),
|
||||
SHAPE_SPHERE = (1 << 2),
|
||||
SHAPE_AABB = (1 << 3),
|
||||
SHAPE_OBB = (1 << 4),
|
||||
SHAPE_PLANE = (1 << 5),
|
||||
SHAPE_TRIANGLE = (1 << 6),
|
||||
SHAPE_FRUSTUM = (1 << 7),
|
||||
SHAPE_FRUSTUM_ACCURATE = (1 << 8),
|
||||
SHAPE_CAPSULE = (1 << 9),
|
||||
SHAPE_SPLINE = (1 << 10),
|
||||
SHAPE_BAD = (1 << 11),
|
||||
};
|
||||
|
||||
class ShapeBase : public RefCounted {
|
||||
public:
|
||||
ShapeBase(ShapeEnum type) : _type(type) {}
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Gets the type of the shape.
|
||||
* @zh
|
||||
* 获取形状的类型。
|
||||
*/
|
||||
inline ShapeEnum getType() const {
|
||||
CC_ASSERT_NE(_type, ShapeEnum::SHAPE_BAD); // shape is not initialized
|
||||
return _type;
|
||||
}
|
||||
inline void setType(ShapeEnum type) { _type = type; }
|
||||
|
||||
private:
|
||||
ShapeEnum _type = ShapeEnum::SHAPE_BAD;
|
||||
};
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
215
cocos/core/geometry/Frustum.cpp
Normal file
215
cocos/core/geometry/Frustum.cpp
Normal file
@@ -0,0 +1,215 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-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 "core/geometry/Frustum.h"
|
||||
#include <cmath>
|
||||
#include "core/geometry/Enums.h"
|
||||
#include "scene/Define.h"
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
namespace {
|
||||
const ccstd::vector<cc::Vec3> VEC_VALS{
|
||||
{1, 1, 1},
|
||||
{-1, 1, 1},
|
||||
{-1, -1, 1},
|
||||
{1, -1, 1},
|
||||
{1, 1, -1},
|
||||
{-1, 1, -1},
|
||||
{-1, -1, -1},
|
||||
{1, -1, -1}};
|
||||
} // namespace
|
||||
|
||||
void Frustum::createOrtho(Frustum *out, float width,
|
||||
float height,
|
||||
float near,
|
||||
float far,
|
||||
const Mat4 &transform) {
|
||||
createOrthographic(out, width, height, near, far, transform);
|
||||
}
|
||||
|
||||
void Frustum::createOrthographic(Frustum *out, float width,
|
||||
float height,
|
||||
float near,
|
||||
float far,
|
||||
const Mat4 &transform) {
|
||||
auto halfWidth = width / 2.0F;
|
||||
auto halfHeight = height / 2.0F;
|
||||
Vec3::transformMat4({halfWidth, halfHeight, -near}, transform, &out->vertices[0]);
|
||||
Vec3::transformMat4({-halfWidth, halfHeight, -near}, transform, &out->vertices[1]);
|
||||
Vec3::transformMat4({-halfWidth, -halfHeight, -near}, transform, &out->vertices[2]);
|
||||
Vec3::transformMat4({halfWidth, -halfHeight, -near}, transform, &out->vertices[3]);
|
||||
Vec3::transformMat4({halfWidth, halfHeight, -far}, transform, &out->vertices[4]);
|
||||
Vec3::transformMat4({-halfWidth, halfHeight, -far}, transform, &out->vertices[5]);
|
||||
Vec3::transformMat4({-halfWidth, -halfHeight, -far}, transform, &out->vertices[6]);
|
||||
Vec3::transformMat4({halfWidth, -halfHeight, -far}, transform, &out->vertices[7]);
|
||||
|
||||
out->updatePlanes();
|
||||
}
|
||||
|
||||
Frustum *Frustum::createFromAABB(Frustum *out, const AABB &aabb) {
|
||||
Vec3 minPos;
|
||||
Vec3 maxPos;
|
||||
aabb.getBoundary(&minPos, &maxPos);
|
||||
|
||||
out->vertices[0].set(maxPos.x, maxPos.y, -minPos.z);
|
||||
out->vertices[1].set(minPos.x, maxPos.y, -minPos.z);
|
||||
out->vertices[2].set(minPos.x, minPos.y, -minPos.z);
|
||||
out->vertices[3].set(maxPos.x, minPos.y, -minPos.z);
|
||||
out->vertices[4].set(maxPos.x, maxPos.y, -maxPos.z);
|
||||
out->vertices[5].set(minPos.x, maxPos.y, -maxPos.z);
|
||||
out->vertices[6].set(minPos.x, minPos.y, -maxPos.z);
|
||||
out->vertices[7].set(maxPos.x, minPos.y, -maxPos.z);
|
||||
|
||||
out->updatePlanes();
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void Frustum::createPerspective(Frustum *out, float fov,
|
||||
float aspect,
|
||||
float near,
|
||||
float far,
|
||||
const Mat4 &transform) {
|
||||
const float h = tanf(fov * 0.5F);
|
||||
const float w = h * aspect;
|
||||
const Vec3 nearTemp(near * w, near * h, near);
|
||||
const Vec3 farTemp(far * w, far * h, far);
|
||||
|
||||
out->vertices[0].transformMat4(Vec3(nearTemp.x, nearTemp.y, -nearTemp.z), transform);
|
||||
out->vertices[1].transformMat4(Vec3(-nearTemp.x, nearTemp.y, -nearTemp.z), transform);
|
||||
out->vertices[2].transformMat4(Vec3(-nearTemp.x, -nearTemp.y, -nearTemp.z), transform);
|
||||
out->vertices[3].transformMat4(Vec3(nearTemp.x, -nearTemp.y, -nearTemp.z), transform);
|
||||
out->vertices[4].transformMat4(Vec3(farTemp.x, farTemp.y, -farTemp.z), transform);
|
||||
out->vertices[5].transformMat4(Vec3(-farTemp.x, farTemp.y, -farTemp.z), transform);
|
||||
out->vertices[6].transformMat4(Vec3(-farTemp.x, -farTemp.y, -farTemp.z), transform);
|
||||
out->vertices[7].transformMat4(Vec3(farTemp.x, -farTemp.y, -farTemp.z), transform);
|
||||
|
||||
out->updatePlanes();
|
||||
}
|
||||
|
||||
void Frustum::update(const Mat4 &m, const Mat4 &inv) {
|
||||
// left plane
|
||||
planes[0]->n.set(m.m[3] + m.m[0], m.m[7] + m.m[4], m.m[11] + m.m[8]);
|
||||
planes[0]->d = -(m.m[15] + m.m[12]);
|
||||
// right plane
|
||||
planes[1]->n.set(m.m[3] - m.m[0], m.m[7] - m.m[4], m.m[11] - m.m[8]);
|
||||
planes[1]->d = -(m.m[15] - m.m[12]);
|
||||
// bottom plane
|
||||
planes[2]->n.set(m.m[3] + m.m[1], m.m[7] + m.m[5], m.m[11] + m.m[9]);
|
||||
planes[2]->d = -(m.m[15] + m.m[13]);
|
||||
// top plane
|
||||
planes[3]->n.set(m.m[3] - m.m[1], m.m[7] - m.m[5], m.m[11] - m.m[9]);
|
||||
planes[3]->d = -(m.m[15] - m.m[13]);
|
||||
// near plane
|
||||
planes[4]->n.set(m.m[3] + m.m[2], m.m[7] + m.m[6], m.m[11] + m.m[10]);
|
||||
planes[4]->d = -(m.m[15] + m.m[14]);
|
||||
// far plane
|
||||
planes[5]->n.set(m.m[3] - m.m[2], m.m[7] - m.m[6], m.m[11] - m.m[10]);
|
||||
planes[5]->d = -(m.m[15] - m.m[14]);
|
||||
|
||||
for (Plane *plane : planes) {
|
||||
float invDist = 1 / plane->n.length();
|
||||
plane->n *= invDist;
|
||||
plane->d *= invDist;
|
||||
}
|
||||
uint32_t i = 0;
|
||||
for (const Vec3 &vec : VEC_VALS) {
|
||||
vertices[i].transformMat4(vec, inv);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void Frustum::transform(const Mat4 &mat) {
|
||||
for (auto i = 0; i < 8; i++) {
|
||||
vertices[i].transformMat4(vertices[i], mat);
|
||||
}
|
||||
updatePlanes();
|
||||
}
|
||||
|
||||
void Frustum::createOrthographic(float width, float height, float near, float far, const Mat4 &transform) {
|
||||
createOrthographic(this, width, height, near, far, transform);
|
||||
}
|
||||
|
||||
void Frustum::createOrtho(const float width, const float height, const float near, const float far, const Mat4 &transform) {
|
||||
createOrthographic(width, height, near, far, transform);
|
||||
}
|
||||
|
||||
void Frustum::split(float near, float far, float aspect, float fov, const Mat4 &transform) {
|
||||
createPerspective(this, fov, aspect, near, far, transform);
|
||||
}
|
||||
|
||||
void Frustum::updatePlanes() {
|
||||
// left plane
|
||||
planes[0]->define(vertices[1], vertices[6], vertices[5]);
|
||||
// right plane
|
||||
planes[1]->define(vertices[3], vertices[4], vertices[7]);
|
||||
// bottom plane
|
||||
planes[2]->define(vertices[6], vertices[3], vertices[7]);
|
||||
// top plane
|
||||
planes[3]->define(vertices[0], vertices[5], vertices[4]);
|
||||
// near plane
|
||||
planes[4]->define(vertices[2], vertices[0], vertices[3]);
|
||||
// far plane
|
||||
planes[5]->define(vertices[7], vertices[5], vertices[6]);
|
||||
}
|
||||
|
||||
Frustum::Frustum() : ShapeBase(ShapeEnum::SHAPE_FRUSTUM) {
|
||||
init();
|
||||
}
|
||||
|
||||
Frustum::Frustum(const Frustum &rhs) : ShapeBase(rhs) {
|
||||
init();
|
||||
*this = rhs;
|
||||
}
|
||||
|
||||
Frustum::~Frustum() {
|
||||
for (auto *plane : planes) {
|
||||
plane->release();
|
||||
}
|
||||
}
|
||||
|
||||
Frustum &Frustum::operator=(const Frustum &rhs) {
|
||||
if (this == &rhs) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
vertices = rhs.vertices;
|
||||
|
||||
for (size_t i = 0; i < planes.size(); ++i) { // NOLINT(modernize-loop-convert)
|
||||
Plane::copy(planes[i], *rhs.planes[i]);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Frustum::init() {
|
||||
for (size_t i = 0; i < planes.size(); ++i) { // NOLINT(modernize-loop-convert)
|
||||
planes[i] = ccnew Plane();
|
||||
planes[i]->addRef();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
207
cocos/core/geometry/Frustum.h
Normal file
207
cocos/core/geometry/Frustum.h
Normal file
@@ -0,0 +1,207 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-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 "base/memory/Memory.h"
|
||||
#include "base/std/container/array.h"
|
||||
#include "core/geometry/AABB.h"
|
||||
#include "core/geometry/Enums.h"
|
||||
#include "core/geometry/Plane.h"
|
||||
#include "math/Mat4.h"
|
||||
#include "math/Vec3.h"
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
|
||||
class Frustum final : public ShapeBase {
|
||||
public:
|
||||
/**
|
||||
* @en
|
||||
* Create a ortho frustum.
|
||||
* @zh
|
||||
* 创建一个正交视锥体。
|
||||
* @param out @en The result orthographic frustum. @zh 输出的正交视锥体。
|
||||
* @param width @en The width of the frustum. @zh 正交视锥体的宽度。
|
||||
* @param height @en The height of the frustum. @zh 正交视锥体的高度。
|
||||
* @param near @en The near plane of the frustum. @zh 正交视锥体的近平面值。
|
||||
* @param far @en The far plane of the frustum. @zh 正交视锥体的远平面值。
|
||||
* @param transform @en The transform matrix of the frustum. @zh 正交视锥体的变换矩阵。
|
||||
*
|
||||
* @deprecated since 3.8.0, please use [createOrthographic] instead of it.
|
||||
*/
|
||||
static void createOrtho(Frustum *out, float width,
|
||||
float height,
|
||||
float near,
|
||||
float far,
|
||||
const Mat4 &transform);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Create a ortho frustum.
|
||||
* @zh
|
||||
* 创建一个正交视锥体。
|
||||
* @param out @en The result orthographic frustum. @zh 输出的正交视锥体。
|
||||
* @param width @en The width of the frustum. @zh 正交视锥体的宽度。
|
||||
* @param height @en The height of the frustum. @zh 正交视锥体的高度。
|
||||
* @param near @en The near plane of the frustum. @zh 正交视锥体的近平面值。
|
||||
* @param far @en The far plane of the frustum. @zh 正交视锥体的远平面值。
|
||||
* @param transform @en The transform matrix of the frustum. @zh 正交视锥体的变换矩阵。
|
||||
*/
|
||||
static void createOrthographic(Frustum *out, float width,
|
||||
float height,
|
||||
float near,
|
||||
float far,
|
||||
const Mat4 &transform);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Create a perspective frustum.
|
||||
* @zh
|
||||
* 创建一个透视视锥体。
|
||||
* @param out @en The result perspective frustum. @zh 输出的透视视锥体。
|
||||
* @param fov @en The field of view of the frustum. @zh 视锥体的视野。
|
||||
* @param aspect @en The aspect ratio of the frustum. @zh 视锥体的宽高比。
|
||||
* @param near @en The near plane of the frustum. @zh 视锥体的近平面值。
|
||||
* @param far @en The far plane of the frustum. @zh 视锥体的远平面值。
|
||||
* @param transform @en The transform matrix of the frustum. @zh 视锥体的变换矩阵。
|
||||
*/
|
||||
static void createPerspective(Frustum *out, float fov,
|
||||
float aspect,
|
||||
float near,
|
||||
float far,
|
||||
const Mat4 &transform);
|
||||
|
||||
/**
|
||||
* @en Create a frustum from an AABB box.
|
||||
* @zh 从 AABB 包围盒中创建一个视锥体。
|
||||
* @param out @en The result frustum @zh 输出的视锥体对象。
|
||||
* @param aabb @en The AABB bounding box of the frustum @zh AABB 包围盒。
|
||||
* @return @en The out object @zh 返回视锥体.
|
||||
*
|
||||
* @deprecated since 3.8.0, please use [createOrthographic] instead of it.
|
||||
*/
|
||||
static Frustum *createFromAABB(Frustum *out, const AABB &aabb);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Create a ccnew frustum.
|
||||
* @zh
|
||||
* 创建一个新的截锥体。
|
||||
* @return @en An empty frustum. @zh 一个空截椎体
|
||||
*/
|
||||
static Frustum *create() {
|
||||
return ccnew Frustum();
|
||||
}
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Clone a frustum.
|
||||
* @zh
|
||||
* 克隆一个截锥体。
|
||||
* @param f @en The frustum to clone from @zh 用于克隆的截锥体
|
||||
* @return @en The cloned frustum @zh 克隆出的新截锥体
|
||||
*/
|
||||
static Frustum *clone(const Frustum &f) {
|
||||
return Frustum::copy(ccnew Frustum(), f);
|
||||
}
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Copy the values from one frustum to another.
|
||||
* @zh
|
||||
* 从一个视锥体拷贝到另一个视锥体。
|
||||
* @param out @en The result frustum @zh 用于存储拷贝数据的截锥体
|
||||
* @param f @en The frustum to copy from @zh 用于克隆的截锥体
|
||||
* @return @en The out object @zh 传入的 out 对象
|
||||
|
||||
*/
|
||||
static Frustum *copy(Frustum *out, const Frustum &f) {
|
||||
out->setType(f.getType());
|
||||
for (size_t i = 0; i < 6; ++i) { // NOLINT(modernize-loop-convert)
|
||||
Plane::copy(out->planes[i], *(f.planes[i]));
|
||||
}
|
||||
out->vertices = f.vertices;
|
||||
return out;
|
||||
}
|
||||
|
||||
Frustum();
|
||||
Frustum(const Frustum &rhs);
|
||||
Frustum(Frustum &&rhs) = delete;
|
||||
~Frustum() override;
|
||||
|
||||
// Can remove these operator override functions if not using Plane* in planes array.
|
||||
Frustum &operator=(const Frustum &rhs);
|
||||
Frustum &operator=(Frustum &&rhs) = delete;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Transform this frustum.
|
||||
* @zh
|
||||
* 变换此截锥体。
|
||||
* @param mat 变换矩阵。
|
||||
*/
|
||||
void transform(const Mat4 &);
|
||||
|
||||
void createOrtho(float width, float height, float near, float far, const Mat4 &transform);
|
||||
void createOrthographic(float width, float height, float near, float far, const Mat4 &transform);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Set as a perspective frustum.
|
||||
* @zh
|
||||
* 设置为一个透视视锥体。
|
||||
* @param near @en The near plane of the frustum. @zh 视锥体的近平面值。
|
||||
* @param far @en The far plane of the frustum. @zh 视锥体的远平面值。
|
||||
* @param fov @en The field of view of the frustum. @zh 视锥体的视野。
|
||||
* @param aspect @en The aspect ratio of the frustum. @zh 视锥体的宽高比。
|
||||
* @param transform @en The transform matrix of the frustum. @zh 视锥体的变换矩阵。
|
||||
*
|
||||
* @deprecated since 3.8.0, please use [createPerspective] instead of it.
|
||||
*/
|
||||
void split(float near, float far, float aspect, float fov, const Mat4 &transform);
|
||||
void updatePlanes();
|
||||
void update(const Mat4 &m, const Mat4 &inv);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Set whether to use accurate intersection testing function on this frustum.
|
||||
* @zh
|
||||
* 设置是否在此截锥体上使用精确的相交测试函数。
|
||||
*
|
||||
* @deprecated since v3.8.0 no need to set accurate flag since it doesn't affect the calculation at all.
|
||||
*/
|
||||
inline void setAccurate(bool accurate) {
|
||||
setType(accurate ? ShapeEnum::SHAPE_FRUSTUM_ACCURATE : ShapeEnum::SHAPE_FRUSTUM);
|
||||
}
|
||||
|
||||
ccstd::array<Vec3, 8> vertices;
|
||||
ccstd::array<Plane *, 6> planes;
|
||||
|
||||
private:
|
||||
void init();
|
||||
};
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
41
cocos/core/geometry/Geometry.h
Normal file
41
cocos/core/geometry/Geometry.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/****************************************************************************
|
||||
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 "AABB.h"
|
||||
#include "Capsule.h"
|
||||
// #include "Curve.h"
|
||||
#include "Distance.h"
|
||||
#include "Enums.h"
|
||||
#include "Frustum.h"
|
||||
#include "Intersect.h"
|
||||
#include "Line.h"
|
||||
#include "Obb.h"
|
||||
#include "Plane.h"
|
||||
#include "Ray.h"
|
||||
#include "Spec.h"
|
||||
#include "Sphere.h"
|
||||
#include "Spline.h"
|
||||
#include "Triangle.h"
|
||||
1100
cocos/core/geometry/Intersect.cpp
Normal file
1100
cocos/core/geometry/Intersect.cpp
Normal file
File diff suppressed because it is too large
Load Diff
498
cocos/core/geometry/Intersect.h
Normal file
498
cocos/core/geometry/Intersect.h
Normal file
@@ -0,0 +1,498 @@
|
||||
/****************************************************************************
|
||||
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 "base/Macros.h"
|
||||
|
||||
#include "core/assets/RenderingSubMesh.h"
|
||||
#include "core/geometry/Distance.h"
|
||||
#include "core/geometry/Enums.h"
|
||||
#include "core/geometry/Frustum.h"
|
||||
#include "core/geometry/Spec.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace cc {
|
||||
|
||||
class Vec3;
|
||||
class Mat3;
|
||||
|
||||
namespace scene {
|
||||
class Model;
|
||||
}
|
||||
|
||||
namespace geometry {
|
||||
|
||||
class Ray;
|
||||
class Plane;
|
||||
class OBB;
|
||||
class AABB;
|
||||
class Line;
|
||||
class Frustum;
|
||||
class Sphere;
|
||||
class Triangle;
|
||||
class Capsule;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* ray-plane intersect detect.
|
||||
* @zh
|
||||
* 射线与平面的相交性检测。
|
||||
* @param {Ray} ray 射线
|
||||
* @param {Plane} plane 平面
|
||||
* @return {number} 0 或 非0
|
||||
*/
|
||||
float rayPlane(const Ray &ray, const Plane &plane);
|
||||
|
||||
// based on http://fileadmin.cs.lth.se/cs/Personal/Tomas_Akenine-Moller/raytri/
|
||||
/**
|
||||
* @en
|
||||
* ray-triangle intersect detect.
|
||||
* @zh
|
||||
* 射线与三角形的相交性检测。
|
||||
* @param {Ray} ray 射线
|
||||
* @param {Triangle} triangle 三角形
|
||||
* @param {boolean} doubleSided 三角形是否为双面
|
||||
* @return {number} 0 或 非0
|
||||
*/
|
||||
float rayTriangle(const Ray &ray, const Triangle &triangle, bool doubleSided = false);
|
||||
/**
|
||||
* @en
|
||||
* ray-sphere intersect detect.
|
||||
* @zh
|
||||
* 射线和球的相交性检测。
|
||||
* @param {Ray} ray 射线
|
||||
* @param {Sphere} sphere 球
|
||||
* @return {number} 0 或 非0
|
||||
*/
|
||||
float raySphere(const Ray &ray, const Sphere &sphere);
|
||||
|
||||
float rayAABB2(const Ray &ray, const Vec3 &min, const Vec3 &max);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* ray-aabb intersect detect.
|
||||
* @zh
|
||||
* 射线和轴对齐包围盒的相交性检测。
|
||||
* @param {Ray} ray 射线
|
||||
* @param {AABB} aabb 轴对齐包围盒
|
||||
* @return {number} 0 或 非0
|
||||
*/
|
||||
float rayAABB(const Ray &ray, const AABB &aabb);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* ray-obb intersect detect.
|
||||
* @zh
|
||||
* 射线和方向包围盒的相交性检测。
|
||||
* @param {Ray} ray 射线
|
||||
* @param {OBB} obb 方向包围盒
|
||||
* @return {number} 0 或 非0
|
||||
*/
|
||||
float rayOBB(const Ray &ray, const OBB &obb);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* ray-capsule intersect detect.
|
||||
* @zh
|
||||
* 射线和胶囊体的相交性检测。
|
||||
* @param {Ray} ray 射线
|
||||
* @param {Capsule} capsule 胶囊体
|
||||
* @return {number} 0 或 非0
|
||||
*/
|
||||
float rayCapsule(const Ray &ray, const Capsule &capsule);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* ray-subMesh intersect detect, in model space.
|
||||
* @zh
|
||||
* 在模型空间中,射线和子三角网格的相交性检测。
|
||||
* @param {Ray} ray
|
||||
* @param {RenderingSubMesh} subMesh
|
||||
* @param {IRaySubMeshOptions} options
|
||||
* @return {number} 0 or !0
|
||||
*/
|
||||
float raySubMesh(const Ray &ray, const RenderingSubMesh &submesh, IRaySubMeshOptions *options = nullptr);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* ray-mesh intersect detect, in model space.
|
||||
* @zh
|
||||
* 在模型空间中,射线和三角网格资源的相交性检测。
|
||||
* @param {Ray} ray
|
||||
* @param {Mesh} mesh
|
||||
* @param {IRayMeshOptions} options
|
||||
* @return {number} 0 or !0
|
||||
*/
|
||||
float rayMesh(const Ray &ray, const Mesh &mesh, IRayMeshOptions *option);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* ray-model intersect detect, in world space.
|
||||
* @zh
|
||||
* 在世界空间中,射线和渲染模型的相交性检测。
|
||||
* @param ray
|
||||
* @param model
|
||||
* @param options
|
||||
* @return 0 or !0
|
||||
*/
|
||||
float rayModel(const Ray &ray, const scene::Model &model, IRayModelOptions *option);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* line-plane intersect detect.
|
||||
* @zh
|
||||
* 线段与平面的相交性检测。
|
||||
* @param {line} line 线段
|
||||
* @param {Plane} plane 平面
|
||||
* @return {number} 0 或 非0
|
||||
*/
|
||||
float linePlane(const Line &line, const Plane &plane);
|
||||
/**
|
||||
* @en
|
||||
* line-triangle intersect detect.
|
||||
* @zh
|
||||
* 线段与三角形的相交性检测。
|
||||
* @param {line} line 线段
|
||||
* @param {Triangle} triangle 三角形
|
||||
* @param {Vec3} outPt 可选,相交点
|
||||
* @return {number} 0 或 非0
|
||||
*/
|
||||
int lineTriangle(const Line &line, const Triangle &triangle, Vec3 *outPt = nullptr);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* line-aabb intersect detect.
|
||||
* @zh
|
||||
* 线段与轴对齐包围盒的相交性检测
|
||||
* @param line 线段
|
||||
* @param aabb 轴对齐包围盒
|
||||
* @return {number} 0 或 非0
|
||||
*/
|
||||
float lineAABB(const Line &line, const AABB &aabb);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* line-obb intersect detect.
|
||||
* @zh
|
||||
* 线段与方向包围盒的相交性检测
|
||||
* @param line 线段
|
||||
* @param obb 方向包围盒
|
||||
* @return {number} 0 或 非0
|
||||
*/
|
||||
float lineOBB(const Line &line, const OBB &obb);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* line-sphere intersect detect.
|
||||
* @zh
|
||||
* 线段与球的相交性检测
|
||||
* @param line 线段
|
||||
* @param sphere 球
|
||||
* @return {number} 0 或 非0
|
||||
*/
|
||||
float lineSphere(const Line &line, const Sphere &sphere);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* aabb-aabb intersect detect.
|
||||
* @zh
|
||||
* 轴对齐包围盒和轴对齐包围盒的相交性检测。
|
||||
* @param {AABB} aabb1 轴对齐包围盒1
|
||||
* @param {AABB} aabb2 轴对齐包围盒2
|
||||
* @return {number} 0 或 非0
|
||||
*/
|
||||
bool aabbWithAABB(const AABB &aabb1, const AABB &aabb2);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* aabb-obb intersect detect.
|
||||
* @zh
|
||||
* 轴对齐包围盒和方向包围盒的相交性检测。
|
||||
* @param {AABB} aabb 轴对齐包围盒
|
||||
* @param {OBB} obb 方向包围盒
|
||||
* @return {number} 0 或 非0
|
||||
*/
|
||||
int aabbWithOBB(const AABB &aabb, const OBB &obb);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* aabb-plane intersect detect.
|
||||
* @zh
|
||||
* 轴对齐包围盒和平面的相交性检测。
|
||||
* @param {AABB} aabb 轴对齐包围盒
|
||||
* @param {Plane} plane 平面
|
||||
* @return {number} inside(back) = -1, outside(front) = 0, intersect = 1
|
||||
*/
|
||||
|
||||
int aabbPlane(const AABB &aabb, const Plane &plane);
|
||||
/**
|
||||
* @en
|
||||
* aabb-frustum intersect detect, faster but has false positive corner cases.
|
||||
* @zh
|
||||
* 轴对齐包围盒和锥台相交性检测,速度快,但有错误情况。
|
||||
* @param {AABB} aabb 轴对齐包围盒
|
||||
* @param {Frustum} frustum 锥台
|
||||
* @return {number} 0 或 非0
|
||||
*/
|
||||
|
||||
int aabbFrustum(const AABB &aabb, const Frustum &frustum);
|
||||
/**
|
||||
* @en
|
||||
* aabb-frustum intersect detect, faster but false while frustum is completely inside the aabb.
|
||||
* @zh
|
||||
* 轴对齐包围盒和锥台的相交性检测。速度快,但是当锥台完全在aabb中时就会判断出错。
|
||||
* @param {AABB} aabb 轴对齐包围盒
|
||||
* @param {Frustum} frustum 锥台
|
||||
* @return {number} aabb completely inside the frustum = 1, otherwise = 0
|
||||
*/
|
||||
int aabbFrustumCompletelyInside(const AABB &aabb, const Frustum &frustum);
|
||||
|
||||
// https://cesium.com/blog/2017/02/02/tighter-frustum-culling-and-why-you-may-want-to-disregard-it/
|
||||
/**
|
||||
* @en
|
||||
* aabb-frustum intersect, handles most of the false positives correctly.
|
||||
* @zh
|
||||
* 轴对齐包围盒和锥台相交性检测,正确处理大多数错误情况。
|
||||
* @param {AABB} aabb 轴对齐包围盒
|
||||
* @param {Frustum} frustum 锥台
|
||||
* @return {number}
|
||||
*/
|
||||
int aabbFrustumAccurate(const AABB &aabb, const Frustum &frustum);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* obb contains the point.
|
||||
* @zh
|
||||
* 方向包围盒和点的相交性检测。
|
||||
* @param {OBB} obb 方向包围盒
|
||||
* @param {Vec3} point 点
|
||||
* @return {boolean} true or false
|
||||
*/
|
||||
bool obbPoint(const OBB &obb, const Vec3 &point);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* obb-plane intersect detect.
|
||||
* @zh
|
||||
* 方向包围盒和平面的相交性检测。
|
||||
* @param {OBB} obb 方向包围盒
|
||||
* @param {Plane} plane 平面
|
||||
* @return {number} inside(back) = -1, outside(front) = 0, intersect = 1
|
||||
*/
|
||||
int obbPlane(const OBB &obb, const Plane &plane);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* obb-frustum intersect, faster but has false positive corner cases.
|
||||
* @zh
|
||||
* 方向包围盒和锥台相交性检测,速度快,但有错误情况。
|
||||
* @param {OBB} obb 方向包围盒
|
||||
* @param {Frustum} frustum 锥台
|
||||
* @return {number} 0 或 非0
|
||||
*/
|
||||
int obbFrustum(const OBB &obb, const Frustum &frustum);
|
||||
|
||||
// https://cesium.com/blog/2017/02/02/tighter-frustum-culling-and-why-you-may-want-to-disregard-it/
|
||||
/**
|
||||
* @en
|
||||
* obb-frustum intersect, handles most of the false positives correctly.
|
||||
* @zh
|
||||
* 方向包围盒和锥台相交性检测,正确处理大多数错误情况。
|
||||
* @param {OBB} obb 方向包围盒
|
||||
* @param {Frustum} frustum 锥台
|
||||
* @return {number} 0 或 非0
|
||||
*/
|
||||
int obbFrustumAccurate(const OBB &obb, const Frustum &frustum);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* obb-obb intersect detect.
|
||||
* @zh
|
||||
* 方向包围盒和方向包围盒的相交性检测。
|
||||
* @param {OBB} obb1 方向包围盒1
|
||||
* @param {OBB} obb2 方向包围盒2
|
||||
* @return {number} 0 或 非0
|
||||
*/
|
||||
int obbWithOBB(const OBB &obb1, const OBB &obb2);
|
||||
|
||||
// https://github.com/diku-dk/bvh-tvcg18/blob/1fd3348c17bc8cf3da0b4ae60fdb8f2aa90a6ff0/FOUNDATION/GEOMETRY/GEOMETRY/include/overlap/geometry_overlap_obb_capsule.h
|
||||
/**
|
||||
* @en
|
||||
* obb-capsule intersect detect.
|
||||
* @zh
|
||||
* 方向包围盒和胶囊体的相交性检测。
|
||||
* @param obb 方向包围盒
|
||||
* @param capsule 胶囊体
|
||||
*/
|
||||
int obbCapsule(const OBB &obb, const Capsule &capsule);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* sphere-plane intersect, not necessarily faster than obb-plane,due to the length calculation of the
|
||||
* plane normal to factor out the unnomalized plane distance.
|
||||
* @zh
|
||||
* 球与平面的相交性检测。
|
||||
* @param {Sphere} sphere 球
|
||||
* @param {Plane} plane 平面
|
||||
* @return {number} inside(back) = -1, outside(front) = 0, intersect = 1
|
||||
*/
|
||||
int spherePlane(const Sphere &sphere, const Plane &plane);
|
||||
/**
|
||||
* @en
|
||||
* sphere-frustum intersect, faster but has false positive corner cases.
|
||||
* @zh
|
||||
* 球和锥台的相交性检测,速度快,但有错误情况。
|
||||
* @param {Sphere} sphere 球
|
||||
* @param {Frustum} frustum 锥台
|
||||
* @return {number} 0 或 非0
|
||||
*/
|
||||
int sphereFrustum(const Sphere &sphere, const Frustum &frustum);
|
||||
|
||||
// https://stackoverflow.com/questions/20912692/view-frustum-culling-corner-cases
|
||||
/**
|
||||
* @en
|
||||
* sphere-frustum intersect, handles the false positives correctly.
|
||||
* @zh
|
||||
* 球和锥台的相交性检测,正确处理大多数错误情况。
|
||||
* @param {Sphere} sphere 球
|
||||
* @param {Frustum} frustum 锥台
|
||||
* @return {number} 0 或 非0
|
||||
*/
|
||||
int sphereFrustumAccurate(const Sphere &sphere, const Frustum &frustum);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* sphere-sphere intersect detect.
|
||||
* @zh
|
||||
* 球和球的相交性检测。
|
||||
* @param {Sphere} sphere0 球0
|
||||
* @param {Sphere} sphere1 球1
|
||||
* @return {boolean} true or false
|
||||
*/
|
||||
bool sphereWithSphere(const Sphere &sphere0, const Sphere &sphere1);
|
||||
/**
|
||||
* @en
|
||||
* sphere-aabb intersect detect.
|
||||
* @zh
|
||||
* 球和轴对齐包围盒的相交性检测。
|
||||
* @param {Sphere} sphere 球
|
||||
* @param {AABB} aabb 轴对齐包围盒
|
||||
* @return {boolean} true or false
|
||||
*/
|
||||
bool sphereAABB(const Sphere &sphere, const AABB &aabb);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* sphere-obb intersect detect.
|
||||
* @zh
|
||||
* 球和方向包围盒的相交性检测。
|
||||
* @param {Sphere} sphere 球
|
||||
* @param {OBB} obb 方向包围盒
|
||||
* @return {boolean} true or false
|
||||
*/
|
||||
bool sphereOBB(const Sphere &sphere, const OBB &obb);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* sphere-capsule intersect detect.
|
||||
* @zh
|
||||
* 球和胶囊体的相交性检测。
|
||||
*/
|
||||
bool sphereCapsule(const Sphere &sphere, const Capsule &capsule);
|
||||
|
||||
// http://www.geomalgorithms.com/a07-_distance.html
|
||||
/**
|
||||
* @en
|
||||
* capsule-capsule intersect detect.
|
||||
* @zh
|
||||
* 胶囊体和胶囊体的相交性检测。
|
||||
*/
|
||||
bool capsuleWithCapsule(const Capsule &capsuleA, const Capsule &capsuleB);
|
||||
|
||||
template <typename T1, typename T2>
|
||||
auto intersects(const T1 & /*a*/, const T2 & /*b*/) {
|
||||
static_assert(std::is_base_of<T1, ShapeBase>::value, "type is not base of ShapeBase");
|
||||
static_assert(std::is_base_of<T2, ShapeBase>::value, "type is not base of ShapeBase");
|
||||
CC_ABORT(); // mismatch
|
||||
}
|
||||
|
||||
#define DECLARE_EXCHANGABLE_INTERSECT(TYPE1, TYPE2, FN) \
|
||||
template <> \
|
||||
inline auto intersects(const TYPE1 &arg1, const TYPE2 &arg2) { \
|
||||
return FN(arg1, arg2); \
|
||||
} \
|
||||
template <> \
|
||||
inline auto intersects(const TYPE2 &arg2, const TYPE1 &arg1) { \
|
||||
return FN(arg1, arg2); \
|
||||
}
|
||||
|
||||
#define DECLARE_SELF_INTERSECT(TYPE, FN) \
|
||||
template <> \
|
||||
inline auto intersects(const TYPE &arg1, const TYPE &arg2) { \
|
||||
return FN(arg1, arg2); \
|
||||
}
|
||||
|
||||
int dynObbFrustum(const OBB &obb, const Frustum &frustum);
|
||||
int dynSphereFrustum(const Sphere &sphere, const Frustum &frustum);
|
||||
int dynAabbFrustum(const AABB &aabb, const Frustum &frustum);
|
||||
|
||||
DECLARE_EXCHANGABLE_INTERSECT(Ray, Sphere, raySphere)
|
||||
DECLARE_EXCHANGABLE_INTERSECT(Ray, AABB, rayAABB)
|
||||
DECLARE_EXCHANGABLE_INTERSECT(Ray, OBB, rayOBB)
|
||||
DECLARE_EXCHANGABLE_INTERSECT(Ray, Plane, rayPlane)
|
||||
DECLARE_EXCHANGABLE_INTERSECT(Ray, Triangle, rayTriangle)
|
||||
DECLARE_EXCHANGABLE_INTERSECT(Ray, Capsule, rayCapsule)
|
||||
|
||||
DECLARE_EXCHANGABLE_INTERSECT(Line, Sphere, lineSphere)
|
||||
DECLARE_EXCHANGABLE_INTERSECT(Line, AABB, lineAABB)
|
||||
DECLARE_EXCHANGABLE_INTERSECT(Line, OBB, lineOBB)
|
||||
DECLARE_EXCHANGABLE_INTERSECT(Line, Plane, linePlane)
|
||||
DECLARE_EXCHANGABLE_INTERSECT(Line, Triangle, lineTriangle)
|
||||
|
||||
DECLARE_SELF_INTERSECT(Sphere, sphereWithSphere)
|
||||
DECLARE_EXCHANGABLE_INTERSECT(Sphere, AABB, sphereAABB)
|
||||
DECLARE_EXCHANGABLE_INTERSECT(Sphere, OBB, sphereOBB)
|
||||
DECLARE_EXCHANGABLE_INTERSECT(Sphere, Plane, spherePlane)
|
||||
DECLARE_EXCHANGABLE_INTERSECT(Sphere, Frustum, dynSphereFrustum)
|
||||
DECLARE_EXCHANGABLE_INTERSECT(Sphere, Capsule, sphereCapsule)
|
||||
|
||||
DECLARE_SELF_INTERSECT(AABB, aabbWithAABB)
|
||||
DECLARE_EXCHANGABLE_INTERSECT(AABB, OBB, aabbWithOBB)
|
||||
DECLARE_EXCHANGABLE_INTERSECT(AABB, Plane, aabbPlane)
|
||||
DECLARE_EXCHANGABLE_INTERSECT(AABB, Frustum, dynAabbFrustum)
|
||||
|
||||
DECLARE_SELF_INTERSECT(OBB, obbWithOBB)
|
||||
DECLARE_EXCHANGABLE_INTERSECT(OBB, Plane, obbPlane)
|
||||
DECLARE_EXCHANGABLE_INTERSECT(OBB, Frustum, dynObbFrustum)
|
||||
DECLARE_EXCHANGABLE_INTERSECT(OBB, Capsule, obbCapsule)
|
||||
|
||||
DECLARE_SELF_INTERSECT(Capsule, capsuleWithCapsule)
|
||||
|
||||
#undef DECLARE_SELF_INTERSECT
|
||||
#undef DECLARE_EXCHANGABLE_INTERSECT
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
81
cocos/core/geometry/Line.cpp
Normal file
81
cocos/core/geometry/Line.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
/****************************************************************************
|
||||
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 "core/geometry/Line.h"
|
||||
#include "base/memory/Memory.h"
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
|
||||
Line *Line::create(float sx,
|
||||
float sy,
|
||||
float sz,
|
||||
float ex,
|
||||
float ey,
|
||||
float ez) {
|
||||
return ccnew Line(sx, sy, sz, ex, ey, ez);
|
||||
}
|
||||
|
||||
Line *Line::clone(const Line &a) {
|
||||
return ccnew Line(
|
||||
a.s.x, a.s.y, a.s.z,
|
||||
a.e.x, a.e.y, a.e.z);
|
||||
}
|
||||
|
||||
Line *Line::copy(Line *out, const Line &a) {
|
||||
out->s = a.s;
|
||||
out->e = a.e;
|
||||
return out;
|
||||
}
|
||||
|
||||
Line *Line::fromPoints(Line *out, const Vec3 &start, const Vec3 &end) {
|
||||
out->s = start;
|
||||
out->e = end;
|
||||
return out;
|
||||
}
|
||||
|
||||
Line *Line::set(Line *out,
|
||||
float sx,
|
||||
float sy,
|
||||
float sz,
|
||||
float ex,
|
||||
float ey,
|
||||
float ez) {
|
||||
out->s.x = sx;
|
||||
out->s.y = sy;
|
||||
out->s.z = sz;
|
||||
out->e.x = ex;
|
||||
out->e.y = ey;
|
||||
out->e.z = ez;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
Line::Line(float sx, float sy, float sz, float ex, float ey, float ez) : ShapeBase(ShapeEnum::SHAPE_LINE) {
|
||||
s = {sx, sy, sz};
|
||||
e = {ex, ey, ez};
|
||||
}
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
171
cocos/core/geometry/Line.h
Normal file
171
cocos/core/geometry/Line.h
Normal file
@@ -0,0 +1,171 @@
|
||||
/****************************************************************************
|
||||
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 "core/geometry/Enums.h"
|
||||
#include "math/Vec3.h"
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Basic Geometry: Line.
|
||||
* @zh
|
||||
* 基础几何 line。
|
||||
*/
|
||||
|
||||
class Line final : public ShapeBase {
|
||||
public:
|
||||
/**
|
||||
* @en
|
||||
* create a new line
|
||||
* @zh
|
||||
* 创建一个新的 line。
|
||||
* @param sx 起点的 x 部分。
|
||||
* @param sy 起点的 y 部分。
|
||||
* @param sz 起点的 z 部分。
|
||||
* @param ex 终点的 x 部分。
|
||||
* @param ey 终点的 y 部分。
|
||||
* @param ez 终点的 z 部分。
|
||||
* @return
|
||||
*/
|
||||
|
||||
static Line *create(float sx,
|
||||
float sy,
|
||||
float sz,
|
||||
float ex,
|
||||
float ey,
|
||||
float ez);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Creates a new Line initialized with values from an existing Line
|
||||
* @zh
|
||||
* 克隆一个新的 line。
|
||||
* @param a 克隆的来源。
|
||||
* @return 克隆出的对象。
|
||||
*/
|
||||
|
||||
static Line *clone(const Line &a);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Copy the values from one Line to another
|
||||
* @zh
|
||||
* 复制一个线的值到另一个。
|
||||
* @param out 接受操作的对象。
|
||||
* @param a 复制的来源。
|
||||
* @return 接受操作的对象。
|
||||
*/
|
||||
static Line *copy(Line *out, const Line &a);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* create a line from two points
|
||||
* @zh
|
||||
* 用两个点创建一个线。
|
||||
* @param out 接受操作的对象。
|
||||
* @param start 起点。
|
||||
* @param end 终点。
|
||||
* @return out 接受操作的对象。
|
||||
*/
|
||||
|
||||
static Line *fromPoints(Line *out, const Vec3 &start, const Vec3 &end);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Set the components of a Vec3 to the given values
|
||||
* @zh
|
||||
* 将给定线的属性设置为给定值。
|
||||
* @param out 接受操作的对象。
|
||||
* @param sx 起点的 x 部分。
|
||||
* @param sy 起点的 y 部分。
|
||||
* @param sz 起点的 z 部分。
|
||||
* @param ex 终点的 x 部分。
|
||||
* @param ey 终点的 y 部分。
|
||||
* @param ez 终点的 z 部分。
|
||||
* @return out 接受操作的对象。
|
||||
*/
|
||||
static Line *set(Line *out,
|
||||
float sx,
|
||||
float sy,
|
||||
float sz,
|
||||
float ex,
|
||||
float ey,
|
||||
float ez);
|
||||
|
||||
/**
|
||||
* @zh
|
||||
* 计算线的长度。
|
||||
* @param a 要计算的线。
|
||||
* @return 长度。
|
||||
*/
|
||||
static inline float len(const Line &a) {
|
||||
return a.s.distance(a.e);
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh
|
||||
* 起点。
|
||||
*/
|
||||
Vec3 s;
|
||||
|
||||
/**
|
||||
* @zh
|
||||
* 终点。
|
||||
*/
|
||||
Vec3 e;
|
||||
|
||||
/**
|
||||
* 构造一条线。
|
||||
* @param sx 起点的 x 部分。
|
||||
* @param sy 起点的 y 部分。
|
||||
* @param sz 起点的 z 部分。
|
||||
* @param ex 终点的 x 部分。
|
||||
* @param ey 终点的 y 部分。
|
||||
* @param ez 终点的 z 部分。
|
||||
*/
|
||||
explicit Line(float sx = 0, float sy = 0, float sz = 0, float ex = 0, float ey = 0, float ez = -1);
|
||||
|
||||
Line(const Line &) = default;
|
||||
Line &operator=(const Line &) = default;
|
||||
Line &operator=(Line &&) = default;
|
||||
Line(Line &&) = default;
|
||||
~Line() override = default;
|
||||
|
||||
/**
|
||||
* @zh
|
||||
* 计算线的长度。
|
||||
* @param a 要计算的线。
|
||||
* @return 长度。
|
||||
*/
|
||||
|
||||
inline float length() const {
|
||||
return s.distance(e);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
128
cocos/core/geometry/Obb.cpp
Normal file
128
cocos/core/geometry/Obb.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
/****************************************************************************
|
||||
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 "cocos/core/geometry/Obb.h"
|
||||
#include "base/memory/Memory.h"
|
||||
|
||||
namespace {
|
||||
void transformExtentM3(cc::Vec3 *out, const cc::Vec3 &extent, const cc::Mat3 &m3) {
|
||||
cc::Mat3 m3Tmp;
|
||||
m3Tmp.m[0] = std::abs(m3.m[0]);
|
||||
m3Tmp.m[1] = std::abs(m3.m[1]);
|
||||
m3Tmp.m[2] = std::abs(m3.m[2]);
|
||||
m3Tmp.m[3] = std::abs(m3.m[3]);
|
||||
m3Tmp.m[4] = std::abs(m3.m[4]);
|
||||
m3Tmp.m[5] = std::abs(m3.m[5]);
|
||||
m3Tmp.m[6] = std::abs(m3.m[6]);
|
||||
m3Tmp.m[7] = std::abs(m3.m[7]);
|
||||
m3Tmp.m[8] = std::abs(m3.m[8]);
|
||||
out->transformMat3(extent, m3Tmp);
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
|
||||
OBB *OBB::create(
|
||||
float cx, float cy, float cz,
|
||||
float hw, float hh, float hl,
|
||||
float ox1, float ox2, float ox3,
|
||||
float oy1, float oy2, float oy3,
|
||||
float oz1, float oz2, float oz3) {
|
||||
return ccnew OBB(cx, cy, cz, hw, hh, hl,
|
||||
ox1, ox2, ox3,
|
||||
oy1, oy2, oy3,
|
||||
oz1, oz2, oz3);
|
||||
}
|
||||
|
||||
OBB *OBB::clone(const OBB &a) {
|
||||
return ccnew OBB(a.center.x, a.center.y, a.center.z,
|
||||
a.halfExtents.x, a.halfExtents.y, a.halfExtents.z,
|
||||
a.orientation.m[0], a.orientation.m[1], a.orientation.m[2],
|
||||
a.orientation.m[3], a.orientation.m[4], a.orientation.m[5],
|
||||
a.orientation.m[6], a.orientation.m[7], a.orientation.m[8]);
|
||||
}
|
||||
|
||||
OBB *OBB::copy(OBB *out, const OBB &a) {
|
||||
out->center = a.center;
|
||||
out->halfExtents = a.halfExtents;
|
||||
out->orientation = a.orientation;
|
||||
return out;
|
||||
}
|
||||
|
||||
OBB *OBB::fromPoints(OBB *out, const Vec3 &minPos, const Vec3 &maxPos) {
|
||||
out->center = 0.5F * (minPos + maxPos);
|
||||
out->halfExtents = 0.5F * (maxPos - minPos);
|
||||
Mat3::identity(out->orientation);
|
||||
return out;
|
||||
}
|
||||
|
||||
OBB *OBB::set(OBB *out,
|
||||
float cx, float cy, float cz,
|
||||
float hw, float hh, float hl,
|
||||
float ox1, float ox2, float ox3,
|
||||
float oy1, float oy2, float oy3,
|
||||
float oz1, float oz2, float oz3) {
|
||||
out->center = {cx, cy, cz};
|
||||
out->halfExtents = {hw, hh, hl};
|
||||
out->orientation = {ox1, ox2, ox3, oy1, oy2, oy3, oz1, oz2, oz3};
|
||||
return out;
|
||||
}
|
||||
|
||||
OBB::OBB(float cx, float cy, float cz,
|
||||
float hw, float hh, float hl,
|
||||
float ox1, float ox2, float ox3,
|
||||
float oy1, float oy2, float oy3,
|
||||
float oz1, float oz2, float oz3) : ShapeBase(ShapeEnum::SHAPE_OBB) {
|
||||
center = {cx, cy, cz};
|
||||
halfExtents = {hw, hh, hl};
|
||||
orientation = {ox1, ox2, ox3, oy1, oy2, oy3, oz1, oz2, oz3};
|
||||
}
|
||||
|
||||
void OBB::getBoundary(Vec3 *minPos, Vec3 *maxPos) const {
|
||||
Vec3 v3Tmp;
|
||||
transformExtentM3(&v3Tmp, halfExtents, orientation);
|
||||
*minPos = center - v3Tmp;
|
||||
*maxPos = center + v3Tmp;
|
||||
}
|
||||
|
||||
void OBB::transform(const Mat4 &m, const Vec3 & /*pos*/, const Quaternion &rot, const Vec3 &scale, OBB *out) const {
|
||||
Vec3::transformMat4(center, m, &out->center);
|
||||
// parent shape doesn't contain rotations for now
|
||||
Mat3::fromQuat(rot, &out->orientation);
|
||||
Vec3::multiply(halfExtents, scale, &out->halfExtents);
|
||||
}
|
||||
|
||||
void OBB::translateAndRotate(const Mat4 &m, const Quaternion &rot, OBB *out) const {
|
||||
Vec3::transformMat4(center, m, &out->center);
|
||||
// parent shape doesn't contain rotations for now
|
||||
Mat3::fromQuat(rot, &out->orientation);
|
||||
}
|
||||
|
||||
void OBB::setScale(const Vec3 &scale, OBB *out) const {
|
||||
Vec3::multiply(halfExtents, scale, &out->halfExtents);
|
||||
}
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
192
cocos/core/geometry/Obb.h
Normal file
192
cocos/core/geometry/Obb.h
Normal file
@@ -0,0 +1,192 @@
|
||||
/****************************************************************************
|
||||
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 "cocos/core/geometry/Enums.h"
|
||||
#include "cocos/math/Mat3.h"
|
||||
#include "cocos/math/Quaternion.h"
|
||||
#include "cocos/math/Vec3.h"
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
class OBB final : public ShapeBase {
|
||||
public:
|
||||
/**
|
||||
* @en
|
||||
* create a new obb
|
||||
* @zh
|
||||
* 创建一个新的 obb 实例。
|
||||
* @param cx 形状的相对于原点的 X 坐标。
|
||||
* @param cy 形状的相对于原点的 Y 坐标。
|
||||
* @param cz 形状的相对于原点的 Z 坐标。
|
||||
* @param hw - obb 宽度的一半。
|
||||
* @param hh - obb 高度的一半。
|
||||
* @param hl - obb 长度的一半。
|
||||
* @param ox1 方向矩阵参数。
|
||||
* @param ox2 方向矩阵参数。
|
||||
* @param ox3 方向矩阵参数。
|
||||
* @param oy1 方向矩阵参数。
|
||||
* @param oy2 方向矩阵参数。
|
||||
* @param oy3 方向矩阵参数。
|
||||
* @param oz1 方向矩阵参数。
|
||||
* @param oz2 方向矩阵参数。
|
||||
* @param oz3 方向矩阵参数。
|
||||
* @return 返回一个 obb。
|
||||
*/
|
||||
static OBB *create(
|
||||
float cx, float cy, float cz,
|
||||
float hw, float hh, float hl,
|
||||
float ox1, float ox2, float ox3,
|
||||
float oy1, float oy2, float oy3,
|
||||
float oz1, float oz2, float oz3);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* clone a new obb
|
||||
* @zh
|
||||
* 克隆一个 obb。
|
||||
* @param a 克隆的目标。
|
||||
* @returns 克隆出的新对象。
|
||||
*/
|
||||
static OBB *clone(const OBB &a);
|
||||
/**
|
||||
* @en
|
||||
* copy the values from one obb to another
|
||||
* @zh
|
||||
* 将从一个 obb 的值复制到另一个 obb。
|
||||
* @param {OBB} out 接受操作的 obb。
|
||||
* @param {OBB} a 被复制的 obb。
|
||||
* @return {OBB} out 接受操作的 obb。
|
||||
*/
|
||||
static OBB *copy(OBB *out, const OBB &a);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* create a new obb from two corner points
|
||||
* @zh
|
||||
* 用两个点创建一个新的 obb。
|
||||
* @param out - 接受操作的 obb。
|
||||
* @param minPos - obb 的最小点。
|
||||
* @param maxPos - obb 的最大点。
|
||||
* @returns {OBB} out 接受操作的 obb。
|
||||
*/
|
||||
static OBB *fromPoints(OBB *out, const Vec3 &minPos, const Vec3 &maxPos);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Set the components of a obb to the given values
|
||||
* @zh
|
||||
* 将给定 obb 的属性设置为给定的值。
|
||||
* @param cx - obb 的原点的 X 坐标。
|
||||
* @param cy - obb 的原点的 Y 坐标。
|
||||
* @param cz - obb 的原点的 Z 坐标。
|
||||
* @param hw - obb 宽度的一半。
|
||||
* @param hh - obb 高度的一半。
|
||||
* @param hl - obb 长度的一半。
|
||||
* @param ox1 方向矩阵参数。
|
||||
* @param ox2 方向矩阵参数。
|
||||
* @param ox3 方向矩阵参数。
|
||||
* @param oy1 方向矩阵参数。
|
||||
* @param oy2 方向矩阵参数。
|
||||
* @param oy3 方向矩阵参数。
|
||||
* @param oz1 方向矩阵参数。
|
||||
* @param oz2 方向矩阵参数。
|
||||
* @param oz3 方向矩阵参数。
|
||||
* @return {OBB} out
|
||||
*/
|
||||
|
||||
static OBB *set(OBB *out,
|
||||
float cx, float cy, float cz,
|
||||
float hw, float hh, float hl,
|
||||
float ox1, float ox2, float ox3,
|
||||
float oy1, float oy2, float oy3,
|
||||
float oz1, float oz2, float oz3);
|
||||
|
||||
/**
|
||||
* @zh
|
||||
* 本地坐标的中心点。
|
||||
*/
|
||||
Vec3 center;
|
||||
|
||||
/**
|
||||
* @zh
|
||||
* 长宽高的一半。
|
||||
*/
|
||||
Vec3 halfExtents;
|
||||
|
||||
/**
|
||||
* @zh
|
||||
* 方向矩阵。
|
||||
*/
|
||||
|
||||
Mat3 orientation;
|
||||
|
||||
explicit OBB(float cx = 0, float cy = 0, float cz = 0,
|
||||
float hw = 1, float hh = 1, float hl = 1,
|
||||
float ox1 = 1, float ox2 = 0, float ox3 = 0,
|
||||
float oy1 = 0, float oy2 = 1, float oy3 = 0,
|
||||
float oz1 = 0, float oz2 = 0, float oz3 = 1);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Get the bounding points of this shape
|
||||
* @zh
|
||||
* 获取 obb 的最小点和最大点。
|
||||
* @param {Vec3} minPos 最小点。
|
||||
* @param {Vec3} maxPos 最大点。
|
||||
*/
|
||||
void getBoundary(Vec3 *minPos, Vec3 *maxPos) const;
|
||||
/**
|
||||
* Transform this shape
|
||||
* @zh
|
||||
* 将 out 根据这个 obb 的数据进行变换。
|
||||
* @param m 变换的矩阵。
|
||||
* @param pos 变换的位置部分。
|
||||
* @param rot 变换的旋转部分。
|
||||
* @param scale 变换的缩放部分。
|
||||
* @param out 变换的目标。
|
||||
*/
|
||||
void transform(const Mat4 &m, const Vec3 &pos, const Quaternion &rot, const Vec3 &scale, OBB *out) const;
|
||||
|
||||
/**
|
||||
* @zh
|
||||
* 将 out 根据这个 obb 的数据进行变换。
|
||||
* @param m 变换的矩阵。
|
||||
* @param rot 变换的旋转部分。
|
||||
* @param out 变换的目标。
|
||||
*/
|
||||
void translateAndRotate(const Mat4 &m, const Quaternion &rot, OBB *out) const;
|
||||
|
||||
/**
|
||||
* @zh
|
||||
* 将 out 根据这个 obb 的数据进行缩放。
|
||||
* @param scale 缩放值。
|
||||
* @param out 缩放的目标。
|
||||
*/
|
||||
void setScale(const Vec3 &scale, OBB *out) const;
|
||||
};
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
118
cocos/core/geometry/Plane.cpp
Normal file
118
cocos/core/geometry/Plane.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/****************************************************************************
|
||||
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 "cocos/core/geometry/Plane.h"
|
||||
#include "base/memory/Memory.h"
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
Plane *Plane::create(float nx, float ny, float nz, float d) {
|
||||
return ccnew Plane{nx, ny, nz, d};
|
||||
}
|
||||
|
||||
Plane *Plane::clone(const Plane &p) {
|
||||
return ccnew Plane{p.n.x, p.n.y, p.n.z, p.d};
|
||||
}
|
||||
|
||||
Plane *Plane::copy(Plane *out, const Plane &p) {
|
||||
out->n = p.n;
|
||||
out->d = p.d;
|
||||
return out;
|
||||
}
|
||||
|
||||
Plane *Plane::fromPoints(Plane *out,
|
||||
const Vec3 &a,
|
||||
const Vec3 &b,
|
||||
const Vec3 &c) {
|
||||
Vec3::cross(b - a, c - a, &out->n);
|
||||
out->n.normalize();
|
||||
out->d = Vec3::dot(out->n, a);
|
||||
return out;
|
||||
}
|
||||
|
||||
Plane *Plane::fromNormalAndPoint(Plane *out, const Vec3 &normal, const Vec3 &point) {
|
||||
out->n = normal;
|
||||
out->d = Vec3::dot(normal, point);
|
||||
return out;
|
||||
}
|
||||
|
||||
Plane *Plane::normalize(Plane *out, const Plane &a) {
|
||||
const auto len = a.n.length();
|
||||
out->n = a.n.getNormalized();
|
||||
if (len > 0) {
|
||||
out->d = a.d / len;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
Plane *Plane::set(Plane *out, float nx, float ny, float nz, float d) {
|
||||
out->n = {nx, ny, nz};
|
||||
out->d = d;
|
||||
return out;
|
||||
}
|
||||
|
||||
Plane::Plane(float nx, float ny, float nz, float d) : Plane() {
|
||||
n = {nx, ny, nz};
|
||||
this->d = d;
|
||||
}
|
||||
|
||||
void Plane::transform(const Mat4 &mat) {
|
||||
Mat4 tempMat = mat.getInversed();
|
||||
tempMat.transpose();
|
||||
Vec4 tempVec4 = {n.x, n.y, n.z, -d};
|
||||
tempMat.transformVector(&tempVec4);
|
||||
n.set(tempVec4.x, tempVec4.y, tempVec4.z);
|
||||
d = -tempVec4.w;
|
||||
}
|
||||
|
||||
// Define from 3 vertices.
|
||||
void Plane::define(const Vec3 &v0, const Vec3 &v1, const Vec3 &v2) {
|
||||
const Vec3 dist1 = v1 - v0;
|
||||
const Vec3 dist2 = v2 - v0;
|
||||
|
||||
Vec3 dist;
|
||||
Vec3::cross(dist1, dist2, &dist);
|
||||
define(dist, v0);
|
||||
}
|
||||
// Define from a normal vector and a point on the plane.
|
||||
void Plane::define(const Vec3 &normal, const Vec3 &point) {
|
||||
n = normal.getNormalized();
|
||||
d = n.dot(point);
|
||||
}
|
||||
|
||||
// Return signed distance to a point.
|
||||
float Plane::distance(const Vec3 &point) const {
|
||||
return n.dot(point) - d;
|
||||
}
|
||||
|
||||
Plane Plane::clone() const {
|
||||
Plane plane;
|
||||
plane.n.set(n);
|
||||
plane.d = d;
|
||||
|
||||
return plane;
|
||||
}
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
191
cocos/core/geometry/Plane.h
Normal file
191
cocos/core/geometry/Plane.h
Normal file
@@ -0,0 +1,191 @@
|
||||
/****************************************************************************
|
||||
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 "cocos/core/geometry/Enums.h"
|
||||
#include "cocos/math/Mat4.h"
|
||||
#include "cocos/math/Vec3.h"
|
||||
#include "cocos/math/Vec4.h"
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
/**
|
||||
* @en
|
||||
* Basic Geometry: Plane.
|
||||
* @zh
|
||||
* 基础几何 Plane。
|
||||
*/
|
||||
class Plane final : public ShapeBase {
|
||||
/**
|
||||
* @en
|
||||
* create a new plane
|
||||
* @zh
|
||||
* 创建一个新的 plane。
|
||||
* @param nx 法向分量的 x 部分。
|
||||
* @param ny 法向分量的 y 部分。
|
||||
* @param nz 法向分量的 z 部分。
|
||||
* @param d 与原点的距离。
|
||||
* @return
|
||||
*/
|
||||
public:
|
||||
static Plane *create(float nx, float ny, float nz, float d);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* clone a new plane
|
||||
* @zh
|
||||
* 克隆一个新的 plane。
|
||||
* @param p 克隆的来源。
|
||||
* @return 克隆出的对象。
|
||||
*/
|
||||
static Plane *clone(const Plane &p);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* copy the values from one plane to another
|
||||
* @zh
|
||||
* 复制一个平面的值到另一个。
|
||||
* @param out 接受操作的对象。
|
||||
* @param p 复制的来源。
|
||||
* @return 接受操作的对象。
|
||||
*/
|
||||
|
||||
static Plane *copy(Plane *out, const Plane &p);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* create a plane from three points
|
||||
* @zh
|
||||
* 用三个点创建一个平面。
|
||||
* @param out 接受操作的对象。
|
||||
* @param a 点 a。
|
||||
* @param b 点 b。
|
||||
* @param c 点 c。
|
||||
* @return out 接受操作的对象。
|
||||
*/
|
||||
static Plane *fromPoints(Plane *out,
|
||||
const Vec3 &a,
|
||||
const Vec3 &b,
|
||||
const Vec3 &c);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Set the components of a plane to the given values
|
||||
* @zh
|
||||
* 将给定平面的属性设置为给定值。
|
||||
* @param out 接受操作的对象。
|
||||
* @param nx 法向分量的 x 部分。
|
||||
* @param ny 法向分量的 y 部分。
|
||||
* @param nz 法向分量的 z 部分。
|
||||
* @param d 与原点的距离。
|
||||
* @return out 接受操作的对象。
|
||||
*/
|
||||
static Plane *set(Plane *out, float nx, float ny, float nz, float d);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* create plane from normal and point
|
||||
* @zh
|
||||
* 用一条法线和一个点创建平面。
|
||||
* @param out 接受操作的对象。
|
||||
* @param normal 平面的法线。
|
||||
* @param point 平面上的一点。
|
||||
* @return out 接受操作的对象。
|
||||
*/
|
||||
static Plane *fromNormalAndPoint(Plane *out, const Vec3 &normal, const Vec3 &point);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* normalize a plane
|
||||
* @zh
|
||||
* 归一化一个平面。
|
||||
* @param out 接受操作的对象。
|
||||
* @param a 操作的源数据。
|
||||
* @return out 接受操作的对象。
|
||||
*/
|
||||
static Plane *normalize(Plane *out, const Plane &a);
|
||||
|
||||
// compatibility with vector interfaces
|
||||
inline void setX(float val) { n.x = val; }
|
||||
inline float getX() const { return n.x; }
|
||||
inline void setY(float val) { n.y = val; }
|
||||
inline float getY() const { return n.y; }
|
||||
inline void setZ(float val) { n.z = val; }
|
||||
inline float getZ() const { return n.z; }
|
||||
inline void setW(float val) { d = val; }
|
||||
inline float getW() const { return d; }
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Construct a plane.
|
||||
* @zh
|
||||
* 构造一个平面。
|
||||
* @param nx 法向分量的 x 部分。
|
||||
* @param ny 法向分量的 y 部分。
|
||||
* @param nz 法向分量的 z 部分。
|
||||
* @param d 与原点的距离。
|
||||
*/
|
||||
explicit Plane(float nx, float ny, float nz, float d);
|
||||
|
||||
Plane() : ShapeBase(ShapeEnum::SHAPE_PLANE) {}
|
||||
// Plane(const Plane& other) = default;
|
||||
// Plane(Plane&& other) = default;
|
||||
// Plane& operator=(const Plane& other) = default;
|
||||
// Plane& operator=(Plane&& other) = default;
|
||||
// ~Plane() = default;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* transform this plane.
|
||||
* @zh
|
||||
* 变换一个平面。
|
||||
* @param mat
|
||||
*/
|
||||
void transform(const Mat4 &mat);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The normal of the plane.
|
||||
* @zh
|
||||
* 法线向量。
|
||||
*/
|
||||
Vec3 n{0.0F, 1.0F, 0.0F};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The distance from the origin to the plane.
|
||||
* @zh
|
||||
* 原点到平面的距离。
|
||||
*/
|
||||
float d{0.0F};
|
||||
|
||||
void define(const Vec3 &v0, const Vec3 &v1, const Vec3 &v2);
|
||||
void define(const Vec3 &normal, const Vec3 &point);
|
||||
float distance(const Vec3 &point) const;
|
||||
Plane clone() const;
|
||||
};
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
76
cocos/core/geometry/Ray.cpp
Normal file
76
cocos/core/geometry/Ray.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/****************************************************************************
|
||||
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 "core/geometry/Ray.h"
|
||||
#include "base/memory/Memory.h"
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
Ray *Ray::create(float ox, float oy, float oz, float dx, float dy, float dz) {
|
||||
return ccnew Ray{ox, oy, oz, dx, dy, dz};
|
||||
}
|
||||
|
||||
Ray *Ray::clone(const Ray &a) {
|
||||
return ccnew Ray{
|
||||
a.o.x, a.o.y, a.o.z,
|
||||
a.d.x, a.d.y, a.d.z};
|
||||
}
|
||||
|
||||
Ray *Ray::copy(Ray *out, const Ray &a) {
|
||||
out->o = a.o;
|
||||
out->d = a.d;
|
||||
return out;
|
||||
}
|
||||
|
||||
Ray *Ray::fromPoints(Ray *out, const Vec3 &origin, const Vec3 &target) {
|
||||
out->o = origin;
|
||||
out->d = (target - origin).getNormalized();
|
||||
return out;
|
||||
}
|
||||
|
||||
Ray *Ray::set(Ray *out, float ox, float oy,
|
||||
float oz,
|
||||
float dx,
|
||||
float dy,
|
||||
float dz) {
|
||||
out->o.x = ox;
|
||||
out->o.y = oy;
|
||||
out->o.z = oz;
|
||||
out->d.x = dx;
|
||||
out->d.y = dy;
|
||||
out->d.z = dz;
|
||||
return out;
|
||||
}
|
||||
|
||||
Ray::Ray(float ox, float oy, float oz,
|
||||
float dx, float dy, float dz) : ShapeBase(ShapeEnum::SHAPE_RAY) {
|
||||
o = {ox, oy, oz};
|
||||
d = {dx, dy, dz};
|
||||
}
|
||||
|
||||
void Ray::computeHit(Vec3 *out, float distance) const {
|
||||
*out = o + d.getNormalized() * distance;
|
||||
}
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
160
cocos/core/geometry/Ray.h
Normal file
160
cocos/core/geometry/Ray.h
Normal file
@@ -0,0 +1,160 @@
|
||||
/****************************************************************************
|
||||
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 "core/geometry/Enums.h"
|
||||
#include "math/Vec3.h"
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Basic Geometry: ray.
|
||||
* @zh
|
||||
* 基础几何 射线。
|
||||
*/
|
||||
|
||||
class Ray final : public ShapeBase {
|
||||
public:
|
||||
/**
|
||||
* @en
|
||||
* create a new ray
|
||||
* @zh
|
||||
* 创建一条射线。
|
||||
* @param {number} ox 起点的 x 部分。
|
||||
* @param {number} oy 起点的 y 部分。
|
||||
* @param {number} oz 起点的 z 部分。
|
||||
* @param {number} dx 方向的 x 部分。
|
||||
* @param {number} dy 方向的 y 部分。
|
||||
* @param {number} dz 方向的 z 部分。
|
||||
* @return {Ray} 射线。
|
||||
*/
|
||||
static Ray *create(float ox = 0, float oy = 0, float oz = 0, float dx = 0, float dy = 0, float dz = 1);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Creates a new ray initialized with values from an existing ray
|
||||
* @zh
|
||||
* 从一条射线克隆出一条新的射线。
|
||||
* @param {Ray} a 克隆的目标。
|
||||
* @return {Ray} 克隆出的新对象。
|
||||
*/
|
||||
static Ray *clone(const Ray &a);
|
||||
/**
|
||||
* @en
|
||||
* Copy the values from one ray to another
|
||||
* @zh
|
||||
* 将从一个 ray 的值复制到另一个 ray。
|
||||
* @param {Ray} out 接受操作的 ray。
|
||||
* @param {Ray} a 被复制的 ray。
|
||||
* @return {Ray} out 接受操作的 ray。
|
||||
*/
|
||||
static Ray *copy(Ray *out, const Ray &a);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* create a ray from two points
|
||||
* @zh
|
||||
* 用两个点创建一条射线。
|
||||
* @param {Ray} out 接受操作的射线。
|
||||
* @param {Vec3} origin 射线的起点。
|
||||
* @param {Vec3} target 射线上的一点。
|
||||
* @return {Ray} out 接受操作的射线。
|
||||
*/
|
||||
static Ray *fromPoints(Ray *out, const Vec3 &origin, const Vec3 &target);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Set the components of a ray to the given values
|
||||
* @zh
|
||||
* 将给定射线的属性设置为给定的值。
|
||||
* @param {Ray} out 接受操作的射线。
|
||||
* @param {number} ox 起点的 x 部分。
|
||||
* @param {number} oy 起点的 y 部分。
|
||||
* @param {number} oz 起点的 z 部分。
|
||||
* @param {number} dx 方向的 x 部分。
|
||||
* @param {number} dy 方向的 y 部分。
|
||||
* @param {number} dz 方向的 z 部分。
|
||||
* @return {Ray} out 接受操作的射线。
|
||||
*/
|
||||
|
||||
static Ray *set(Ray *out, float ox, float oy,
|
||||
float oz,
|
||||
float dx,
|
||||
float dy,
|
||||
float dz);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The origin of the ray.
|
||||
* @zh
|
||||
* 起点。
|
||||
*/
|
||||
Vec3 o;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The direction of the ray.
|
||||
* @zh
|
||||
* 方向。
|
||||
*/
|
||||
Vec3 d;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Construct a ray;
|
||||
* @zh
|
||||
* 构造一条射线。
|
||||
* @param {number} ox 起点的 x 部分。
|
||||
* @param {number} oy 起点的 y 部分。
|
||||
* @param {number} oz 起点的 z 部分。
|
||||
* @param {number} dx 方向的 x 部分。
|
||||
* @param {number} dy 方向的 y 部分。
|
||||
* @param {number} dz 方向的 z 部分。
|
||||
*/
|
||||
explicit Ray(float ox = 0, float oy = 0, float oz = 0,
|
||||
float dx = 0, float dy = 0, float dz = -1);
|
||||
|
||||
Ray(const Ray &) = default;
|
||||
Ray &operator=(const Ray &) = default;
|
||||
Ray &operator=(Ray &&) = default;
|
||||
Ray(Ray &&) = default;
|
||||
~Ray() override = default;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Compute a point with the distance between the origin.
|
||||
* @zh
|
||||
* 根据给定距离计算出射线上的一点。
|
||||
* @param out 射线上的另一点。
|
||||
* @param distance 给定距离。
|
||||
*/
|
||||
|
||||
void computeHit(Vec3 *out, float distance) const;
|
||||
};
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
23
cocos/core/geometry/Spec.cpp
Normal file
23
cocos/core/geometry/Spec.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
/****************************************************************************
|
||||
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.
|
||||
****************************************************************************/
|
||||
174
cocos/core/geometry/Spec.h
Normal file
174
cocos/core/geometry/Spec.h
Normal file
@@ -0,0 +1,174 @@
|
||||
/****************************************************************************
|
||||
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 <cfloat>
|
||||
#include <cstdint>
|
||||
|
||||
#include "base/std/container/vector.h"
|
||||
#include "base/std/optional.h"
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The raycast mode.
|
||||
* @zh
|
||||
* 射线检测模式。
|
||||
*/
|
||||
enum class ERaycastMode {
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Detect and record all data.
|
||||
* @zh
|
||||
* 检测并记录所有的数据。
|
||||
*/
|
||||
ALL,
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Detect all, but record only the most recent data.
|
||||
* @zh
|
||||
* 检测所有,但只记录最近的数据。
|
||||
*/
|
||||
CLOSEST,
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Once the test is successful, the test is stopped and the data is recorded only once.
|
||||
* @zh
|
||||
* 一旦检测成功就停止检测,只会记录一次数据。
|
||||
*/
|
||||
ANY,
|
||||
};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The storage structure of the raycast results.
|
||||
* @zh
|
||||
* 射线检测结果的存储结构。
|
||||
*/
|
||||
struct IRaySubMeshResult {
|
||||
/**
|
||||
* @en
|
||||
* The distance between the hit point and the ray.
|
||||
* @zh
|
||||
* 击中点和射线的距离。
|
||||
*/
|
||||
float distance{0.0F};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The index of the triangle vertex 0。
|
||||
* @zh
|
||||
* 三角形顶点0的索引。
|
||||
*/
|
||||
uint32_t vertexIndex0{0};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The index of the triangle vertex 1。
|
||||
* @zh
|
||||
* 三角形顶点1的索引
|
||||
*/
|
||||
uint32_t vertexIndex1{0};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The index of the triangle vertex 2。
|
||||
* @zh
|
||||
* 三角形顶点2的索引
|
||||
*/
|
||||
uint32_t vertexIndex2{0};
|
||||
};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The optional param structure of the `raySubMesh`.
|
||||
* @zh
|
||||
* `raySubMesh`的可选参数结构。
|
||||
*/
|
||||
struct IRaySubMeshOptions {
|
||||
/**
|
||||
* @en
|
||||
* The raycast mode,`ANY` by default.
|
||||
* @zh
|
||||
* 射线检测模式:[0, 1, 2]=>[`ALL`, `CLOSEST`, `ANY`]
|
||||
*/
|
||||
ERaycastMode mode;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The maximum distance of the raycast, `Infinity` by default.
|
||||
* @zh
|
||||
* 射线检测的最大距离,默认为`Infinity`。
|
||||
*/
|
||||
float distance = FLT_MAX;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* An array used to store the results of a ray detection.
|
||||
* @zh
|
||||
* 用于存储射线检测结果的数组。
|
||||
*/
|
||||
ccstd::optional<ccstd::vector<IRaySubMeshResult>> result{};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Whether to detect the double-sided or not,`false` by default.
|
||||
* @zh
|
||||
* 是否检测双面,默认为`false`。
|
||||
*/
|
||||
bool doubleSided{false};
|
||||
};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The optional param structure of the `rayMesh`.
|
||||
* @zh
|
||||
* `rayMesh`的可选参数结构。
|
||||
*/
|
||||
struct IRayMeshOptions : public IRaySubMeshOptions {
|
||||
/**
|
||||
* @en
|
||||
* The index of the sub mesh.
|
||||
* @zh
|
||||
* 子网格的索引。
|
||||
*/
|
||||
ccstd::optional<ccstd::vector<uint32_t>> subIndices{};
|
||||
};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The optional param structure of the `rayModel`.
|
||||
* @zh
|
||||
* `rayModel`的可选参数结构。
|
||||
*/
|
||||
using IRayModelOptions = IRayMeshOptions;
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
202
cocos/core/geometry/Sphere.cpp
Normal file
202
cocos/core/geometry/Sphere.cpp
Normal file
@@ -0,0 +1,202 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-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 "core/geometry/Sphere.h"
|
||||
#include <algorithm>
|
||||
#include "core/geometry/AABB.h"
|
||||
#include "math/Vec3.h"
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
|
||||
Sphere *Sphere::create(float cx, float cy, float cz, float radius) {
|
||||
return ccnew Sphere(cx, cy, cz, radius);
|
||||
}
|
||||
|
||||
Sphere *Sphere::clone(const Sphere &p) {
|
||||
return ccnew Sphere(p._center.x, p._center.y, p._center.z, p._radius);
|
||||
}
|
||||
|
||||
Sphere *Sphere::copy(Sphere *out, const Sphere &p) {
|
||||
out->_center = p._center;
|
||||
out->_radius = p._radius;
|
||||
return out;
|
||||
}
|
||||
|
||||
Sphere *Sphere::fromPoints(Sphere *out, const Vec3 &minPos, const Vec3 &maxPos) {
|
||||
out->_center = 0.5F * (minPos + maxPos);
|
||||
out->_radius = 0.5F * (maxPos - minPos).length();
|
||||
return out;
|
||||
}
|
||||
|
||||
Sphere *Sphere::set(Sphere *out, float cx, float cy, float cz, float r) {
|
||||
out->_center = {cx, cy, cz};
|
||||
out->_radius = r;
|
||||
return out;
|
||||
}
|
||||
|
||||
Sphere *Sphere::mergePoint(Sphere *out, const Sphere &s, const Vec3 &point) {
|
||||
// if sphere.radius Less than 0,
|
||||
// Set this point as anchor,
|
||||
// And set radius to 0.
|
||||
if (s._radius < 0.0) {
|
||||
out->_center = point;
|
||||
out->_radius = 0.0F;
|
||||
return out;
|
||||
}
|
||||
|
||||
auto offset = point - s._center;
|
||||
auto dist = offset.length();
|
||||
|
||||
if (dist > s._radius) {
|
||||
auto half = (dist - s._radius) * 0.5F;
|
||||
out->_radius += half;
|
||||
offset.scale(half / dist);
|
||||
out->_center = out->_center + offset;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void Sphere::merge(const ccstd::vector<cc::Vec3> &points) {
|
||||
if (points.empty()) return;
|
||||
_radius = -1.0F;
|
||||
for (const auto &p : points) {
|
||||
merge(p);
|
||||
}
|
||||
}
|
||||
|
||||
Sphere *Sphere::mergeAABB(Sphere *out, const Sphere &s, const AABB &a) {
|
||||
Vec3 aabbMin;
|
||||
Vec3 aabbMax;
|
||||
a.getBoundary(&aabbMin, &aabbMax);
|
||||
Sphere::mergePoint(out, s, aabbMin);
|
||||
Sphere::mergePoint(out, s, aabbMax);
|
||||
return out;
|
||||
}
|
||||
|
||||
Sphere::Sphere(float cx, float cy, float cz, float radius) : ShapeBase(ShapeEnum::SHAPE_SPHERE) {
|
||||
_center = {cx, cy, cz};
|
||||
_radius = radius;
|
||||
}
|
||||
|
||||
void Sphere::getBoundary(Vec3 *minPos, Vec3 *maxPos) const {
|
||||
Vec3 half = {_radius, _radius, _radius};
|
||||
*minPos = _center - half;
|
||||
*maxPos = _center + half;
|
||||
}
|
||||
|
||||
void Sphere::transform(const Mat4 &m,
|
||||
const Vec3 & /*pos*/,
|
||||
const Quaternion & /*rot*/,
|
||||
const Vec3 &scale,
|
||||
Sphere *out) const {
|
||||
Vec3::transformMat4(_center, m, &out->_center);
|
||||
out->_radius = _radius * mathutils::maxComponent(scale);
|
||||
}
|
||||
|
||||
int Sphere::intersect(const Plane &plane) const {
|
||||
const float dot = plane.n.dot(_center);
|
||||
const float r = _radius * plane.n.length();
|
||||
if (dot + r < plane.d) {
|
||||
return -1; // Sphere is on the back of the plane
|
||||
}
|
||||
|
||||
if (dot - r > plane.d) {
|
||||
return 0; // Sphere is on the front of the plane
|
||||
}
|
||||
|
||||
return 1; // intersect
|
||||
}
|
||||
|
||||
bool Sphere::intersect(const Frustum &frustum) const {
|
||||
const auto &planes = frustum.planes;
|
||||
const auto *self = this;
|
||||
return std::all_of(planes.begin(),
|
||||
planes.end(),
|
||||
// frustum plane normal points to the inside
|
||||
[self](const Plane *plane) { return self->intersect(*plane) != -1; });
|
||||
}
|
||||
|
||||
void Sphere::mergePoint(const Vec3 &point) {
|
||||
if (_radius < 0.0F) {
|
||||
_center = point;
|
||||
_radius = 0.0F;
|
||||
return;
|
||||
}
|
||||
|
||||
auto offset = point - _center;
|
||||
auto distance = offset.length();
|
||||
|
||||
if (distance > _radius) {
|
||||
auto half = (distance - _radius) * 0.5F;
|
||||
_radius += half;
|
||||
offset.scale(half / distance);
|
||||
_center += offset;
|
||||
}
|
||||
}
|
||||
|
||||
void Sphere::define(const AABB &aabb) {
|
||||
cc::Vec3 minPos;
|
||||
cc::Vec3 maxPos;
|
||||
aabb.getBoundary(&minPos, &maxPos);
|
||||
|
||||
// Initialize sphere
|
||||
_center.set(minPos);
|
||||
_radius = 0.0F;
|
||||
|
||||
// Calculate sphere
|
||||
const cc::Vec3 offset = maxPos - _center;
|
||||
const float dist = offset.length();
|
||||
|
||||
const float half = dist * 0.5F;
|
||||
_radius += dist * 0.5F;
|
||||
_center += (half / dist) * offset;
|
||||
}
|
||||
|
||||
void Sphere::mergeAABB(const AABB *aabb) {
|
||||
cc::Vec3 minPos;
|
||||
cc::Vec3 maxPos;
|
||||
aabb->getBoundary(&minPos, &maxPos);
|
||||
mergePoint(minPos);
|
||||
mergePoint(maxPos);
|
||||
}
|
||||
|
||||
int Sphere::spherePlane(const Plane &plane) const {
|
||||
return intersect(plane);
|
||||
}
|
||||
|
||||
bool Sphere::sphereFrustum(const Frustum &frustum) const {
|
||||
return intersect(frustum);
|
||||
}
|
||||
|
||||
void Sphere::mergeFrustum(const Frustum &frustum) {
|
||||
const ccstd::array<Vec3, 8> &vertices = frustum.vertices;
|
||||
for (size_t i = 0; i < vertices.max_size(); ++i) {
|
||||
merge(vertices[i]);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
201
cocos/core/geometry/Sphere.h
Normal file
201
cocos/core/geometry/Sphere.h
Normal file
@@ -0,0 +1,201 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-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 "core/geometry/Enums.h"
|
||||
#include "core/geometry/Frustum.h"
|
||||
#include "math/Utils.h"
|
||||
#include "math/Vec3.h"
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
|
||||
class AABB;
|
||||
|
||||
class Sphere final : public ShapeBase {
|
||||
public:
|
||||
/**
|
||||
* @en
|
||||
* create a new sphere
|
||||
* @zh
|
||||
* 创建一个新的 sphere 实例。
|
||||
* @param cx 形状的相对于原点的 X 坐标。
|
||||
* @param cy 形状的相对于原点的 Y 坐标。
|
||||
* @param cz 形状的相对于原点的 Z 坐标。
|
||||
* @param r 球体的半径
|
||||
* @return {Sphere} 返回一个 sphere。
|
||||
*/
|
||||
static Sphere *create(float cx, float cy, float cz, float radius);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* clone a new sphere
|
||||
* @zh
|
||||
* 克隆一个新的 sphere 实例。
|
||||
* @param {Sphere} p 克隆的目标。
|
||||
* @return {Sphere} 克隆出的示例。
|
||||
*/
|
||||
static Sphere *clone(const Sphere &p);
|
||||
/**
|
||||
* @en
|
||||
* copy the values from one sphere to another
|
||||
* @zh
|
||||
* 将从一个 sphere 的值复制到另一个 sphere。
|
||||
* @param {Sphere} out 接受操作的 sphere。
|
||||
* @param {Sphere} a 被复制的 sphere。
|
||||
* @return {Sphere} out 接受操作的 sphere。
|
||||
*/
|
||||
static Sphere *copy(Sphere *out, const Sphere &p);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* create a new bounding sphere from two corner points
|
||||
* @zh
|
||||
* 从两个点创建一个新的 sphere。
|
||||
* @param out - 接受操作的 sphere。
|
||||
* @param minPos - sphere 的最小点。
|
||||
* @param maxPos - sphere 的最大点。
|
||||
* @returns {Sphere} out 接受操作的 sphere。
|
||||
*/
|
||||
static Sphere *fromPoints(Sphere *out, const Vec3 &minPos, const Vec3 &maxPos);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Set the components of a sphere to the given values
|
||||
* @zh
|
||||
* 将球体的属性设置为给定的值。
|
||||
* @param {Sphere} out 接受操作的 sphere。
|
||||
* @param cx 形状的相对于原点的 X 坐标。
|
||||
* @param cy 形状的相对于原点的 Y 坐标。
|
||||
* @param cz 形状的相对于原点的 Z 坐标。
|
||||
* @param {number} r 半径。
|
||||
* @return {Sphere} out 接受操作的 sphere。
|
||||
* @function
|
||||
*/
|
||||
static Sphere *set(Sphere *out, float cx, float cy, float cz, float r);
|
||||
/**
|
||||
* @zh
|
||||
* 球跟点合并
|
||||
*/
|
||||
static Sphere *mergePoint(Sphere *out, const Sphere &s, const Vec3 &point);
|
||||
|
||||
/**
|
||||
* @zh
|
||||
* 球跟立方体合并
|
||||
*/
|
||||
static Sphere *mergeAABB(Sphere *out, const Sphere &s, const AABB &a);
|
||||
explicit Sphere(float cx = 0, float cy = 0, float cz = 0, float radius = 1.0F);
|
||||
|
||||
Sphere(const Sphere &) = default;
|
||||
Sphere(Sphere &&) = delete;
|
||||
~Sphere() override = default;
|
||||
Sphere &operator=(const Sphere &) = default;
|
||||
Sphere &operator=(Sphere &&) = delete;
|
||||
|
||||
inline float getRadius() const { return _radius; }
|
||||
inline const Vec3 &getCenter() const { return _center; }
|
||||
inline void setCenter(const Vec3 &val) { _center = val; }
|
||||
inline void setRadius(float val) { _radius = val; }
|
||||
|
||||
inline Sphere *clone() const {
|
||||
return Sphere::clone(*this);
|
||||
}
|
||||
|
||||
inline Sphere *copy(Sphere *out) const {
|
||||
return Sphere::copy(out, *this);
|
||||
}
|
||||
|
||||
void define(const AABB &aabb);
|
||||
void mergeAABB(const AABB *aabb);
|
||||
void mergePoint(const Vec3 &point);
|
||||
void mergeFrustum(const Frustum &frustum);
|
||||
inline void merge(const AABB *aabb) { mergeAABB(aabb); }
|
||||
inline void merge(const Vec3 &point) { mergePoint(point); }
|
||||
void merge(const ccstd::vector<Vec3> &points);
|
||||
inline void merge(const Frustum &frustum) { mergeFrustum(frustum); }
|
||||
bool intersect(const Frustum &frustum) const;
|
||||
int intersect(const Plane &plane) const;
|
||||
int spherePlane(const Plane &plane) const;
|
||||
bool sphereFrustum(const Frustum &frustum) const;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Get the bounding points of this shape
|
||||
* @zh
|
||||
* 获取此形状的边界点。
|
||||
* @param {Vec3} minPos 最小点。
|
||||
* @param {Vec3} maxPos 最大点。
|
||||
*/
|
||||
void getBoundary(Vec3 *minPos, Vec3 *maxPos) const;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Transform this shape
|
||||
* @zh
|
||||
* 将 out 根据这个 sphere 的数据进行变换。
|
||||
* @param m 变换的矩阵。
|
||||
* @param pos 变换的位置部分。
|
||||
* @param rot 变换的旋转部分。
|
||||
* @param scale 变换的缩放部分。
|
||||
* @param out 变换的目标。
|
||||
*/
|
||||
void transform(const Mat4 &m,
|
||||
const Vec3 & /*pos*/,
|
||||
const Quaternion & /*rot*/,
|
||||
const Vec3 &scale,
|
||||
Sphere *out) const;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Translate and rotate this sphere.
|
||||
* @zh
|
||||
* 将 out 根据这个 sphere 的数据进行变换。
|
||||
* @param m 变换的矩阵。
|
||||
* @param rot 变换的旋转部分。
|
||||
* @param out 变换的目标。
|
||||
*/
|
||||
inline void translateAndRotate(const Mat4 &m, const Quaternion & /*rot*/, Sphere *out) const {
|
||||
Vec3::transformMat4(_center, m, &out->_center);
|
||||
}
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Scaling this sphere.
|
||||
* @zh
|
||||
* 将 out 根据这个 sphere 的数据进行缩放。
|
||||
* @param scale 缩放值。
|
||||
* @param out 缩放的目标。
|
||||
*/
|
||||
inline void setScale(const Vec3 &scale, Sphere *out) const {
|
||||
out->_radius = _radius * mathutils::maxComponent(scale);
|
||||
}
|
||||
|
||||
// private: // make public for js bindings
|
||||
float _radius{-1.0};
|
||||
Vec3 _center;
|
||||
};
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
200
cocos/core/geometry/Spline.cpp
Normal file
200
cocos/core/geometry/Spline.cpp
Normal file
@@ -0,0 +1,200 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-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 "core/geometry/Spline.h"
|
||||
#include <cmath>
|
||||
#include "base/Log.h"
|
||||
#include "base/Macros.h"
|
||||
#include "base/memory/Memory.h"
|
||||
#include "math/Utils.h"
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
|
||||
Spline::Spline(SplineMode mode /*= SplineMode::CATMULL_ROM*/, ccstd::vector<Vec3> knots /*= {}*/)
|
||||
: ShapeBase(ShapeEnum::SHAPE_SPLINE), _mode(mode), _knots(std::move(knots)) {
|
||||
}
|
||||
|
||||
Spline *Spline::create(SplineMode mode, const ccstd::vector<Vec3> &knots /*= {}*/) {
|
||||
return ccnew Spline(mode, knots);
|
||||
}
|
||||
|
||||
Spline *Spline::clone(const Spline &s) {
|
||||
return ccnew Spline(s._mode, s._knots);
|
||||
}
|
||||
|
||||
Spline *Spline::copy(Spline *out, const Spline &s) {
|
||||
out->_mode = s._mode;
|
||||
out->_knots = s._knots;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void Spline::setModeAndKnots(SplineMode mode, const ccstd::vector<Vec3> &knots) {
|
||||
_mode = mode;
|
||||
_knots = knots;
|
||||
}
|
||||
|
||||
void Spline::insertKnot(uint32_t index, const Vec3 &knot) {
|
||||
if (index >= static_cast<uint32_t>(_knots.size())) {
|
||||
_knots.push_back(knot);
|
||||
return;
|
||||
}
|
||||
|
||||
_knots.insert(_knots.begin() + index, knot);
|
||||
}
|
||||
|
||||
void Spline::removeKnot(uint32_t index) {
|
||||
CC_ASSERT(index < static_cast<uint32_t>(_knots.size()));
|
||||
|
||||
_knots.erase(_knots.begin() + index);
|
||||
}
|
||||
|
||||
void Spline::setKnot(uint32_t index, const Vec3 &knot) {
|
||||
CC_ASSERT(index < static_cast<uint32_t>(_knots.size()));
|
||||
|
||||
_knots[index] = knot;
|
||||
}
|
||||
|
||||
const Vec3 &Spline::getKnot(uint32_t index) const {
|
||||
CC_ASSERT(index < static_cast<uint32_t>(_knots.size()));
|
||||
|
||||
return _knots[index];
|
||||
}
|
||||
Vec3 &Spline::getKnot(uint32_t index) {
|
||||
CC_ASSERT(index < static_cast<uint32_t>(_knots.size()));
|
||||
|
||||
return _knots[index];
|
||||
}
|
||||
|
||||
Vec3 Spline::getPoint(float t, uint32_t index /*= SPLINE_WHOLE_INDEX*/) const {
|
||||
t = mathutils::clamp(t, 0.0F, 1.0F);
|
||||
|
||||
const auto segments = getSegments();
|
||||
if (segments == 0) {
|
||||
return Vec3(0.0F, 0.0F, 0.0F);
|
||||
}
|
||||
|
||||
if (index == SPLINE_WHOLE_INDEX) {
|
||||
const auto deltaT = 1.0F / static_cast<float>(segments);
|
||||
|
||||
index = static_cast<uint32_t>(t / deltaT);
|
||||
t = std::fmod(t, deltaT) / deltaT;
|
||||
}
|
||||
|
||||
if (index >= segments) {
|
||||
return _knots.back();
|
||||
}
|
||||
|
||||
switch (_mode) {
|
||||
case SplineMode::LINEAR:
|
||||
return calcLinear(_knots[index], _knots[index + 1], t);
|
||||
case SplineMode::BEZIER:
|
||||
return calcBezier(_knots[index * 4], _knots[index * 4 + 1], _knots[index * 4 + 2], _knots[index * 4 + 3], t);
|
||||
case SplineMode::CATMULL_ROM: {
|
||||
const auto v0 = index > 0 ? _knots[index - 1] : _knots[index];
|
||||
const auto v3 = index + 2 < static_cast<uint32_t>(_knots.size()) ? _knots[index + 2] : _knots[index + 1];
|
||||
return calcCatmullRom(v0, _knots[index], _knots[index + 1], v3, t);
|
||||
}
|
||||
default:
|
||||
return Vec3(0.0F, 0.0F, 0.0F);
|
||||
}
|
||||
}
|
||||
|
||||
ccstd::vector<Vec3> Spline::getPoints(uint32_t num, uint32_t index /*= SPLINE_WHOLE_INDEX*/) const {
|
||||
if (num == 0U) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (num == 1U) {
|
||||
auto point = getPoint(0.0F, index);
|
||||
return {point};
|
||||
}
|
||||
|
||||
ccstd::vector<Vec3> points;
|
||||
const float deltaT = 1.0F / (static_cast<float>(num) - 1.0F);
|
||||
|
||||
for (auto i = 0; i < num; i++) {
|
||||
const auto t = static_cast<float>(i) * deltaT;
|
||||
const auto point = getPoint(t, index);
|
||||
|
||||
points.push_back(point);
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
uint32_t Spline::getSegments() const {
|
||||
const auto count = static_cast<uint32_t>(_knots.size());
|
||||
switch (_mode) {
|
||||
case SplineMode::LINEAR:
|
||||
case SplineMode::CATMULL_ROM:
|
||||
if (count < 2) {
|
||||
CC_LOG_WARNING("Spline error: less than 2 knots.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return count - 1;
|
||||
case SplineMode::BEZIER:
|
||||
if (count < 4 || count % 4 != 0) {
|
||||
CC_LOG_WARNING("Spline error: less than 4 knots or not a multiple of 4.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return count / 4;
|
||||
default:
|
||||
CC_ABORT();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Vec3 Spline::calcLinear(const Vec3 &v0, const Vec3 &v1, float t) {
|
||||
const auto result = v0 * (1.0F - t) + v1 * t;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Vec3 Spline::calcBezier(const Vec3 &v0, const Vec3 &v1, const Vec3 &v2, const Vec3 &v3, float t) {
|
||||
const auto s = 1.0F - t;
|
||||
const auto result = v0 * s * s * s +
|
||||
v1 * 3.0F * t * s * s +
|
||||
v2 * 3.0F * t * t * s +
|
||||
v3 * t * t * t;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Vec3 Spline::calcCatmullRom(const Vec3 &v0, const Vec3 &v1, const Vec3 &v2, const Vec3 &v3, float t) {
|
||||
const auto t2 = t * t;
|
||||
const auto t3 = t2 * t;
|
||||
const auto result = v0 * (-0.5F * t3 + t2 - 0.5F * t) +
|
||||
v1 * (1.5F * t3 - 2.5F * t2 + 1.0F) +
|
||||
v2 * (-1.5F * t3 + 2.0F * t2 + 0.5F * t) +
|
||||
v3 * (0.5F * t3 - 0.5F * t2);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
115
cocos/core/geometry/Spline.h
Normal file
115
cocos/core/geometry/Spline.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-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 "base/std/container/vector.h"
|
||||
#include "core/geometry/Enums.h"
|
||||
#include "math/Vec3.h"
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
|
||||
enum class SplineMode {
|
||||
/**
|
||||
* Broken line:
|
||||
* Each knot is connected with a straight line from the beginning to the end to form a curve. At least two knots.
|
||||
*/
|
||||
LINEAR = 0,
|
||||
|
||||
/**
|
||||
* Piecewise Bezier curve:
|
||||
* Every four knots form a curve. Total knots number must be a multiple of 4.
|
||||
* Each curve passes only the first and fourth knots, and does not pass through the middle two control knots.
|
||||
*
|
||||
* If you need a whole continuous curve:
|
||||
* (1) Suppose the four knots of the previous curve are A, B, C, D
|
||||
* (2) The four knots of the next curve must be D, E, F, G
|
||||
* (3) C and E need to be symmetrical about D
|
||||
*/
|
||||
BEZIER = 1,
|
||||
|
||||
/**
|
||||
* Catmull Rom curve:
|
||||
* All knots(including start & end knots) form a whole continuous curve. At least two knots.
|
||||
* The whole curve passes through all knots.
|
||||
*/
|
||||
CATMULL_ROM = 2
|
||||
};
|
||||
|
||||
constexpr uint32_t SPLINE_WHOLE_INDEX = 0xffffffff;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Basic Geometry: Spline.
|
||||
* @zh
|
||||
* 基础几何 Spline。
|
||||
*/
|
||||
|
||||
class Spline final : public ShapeBase {
|
||||
public:
|
||||
explicit Spline(SplineMode mode = SplineMode::CATMULL_ROM, ccstd::vector<Vec3> knots = {});
|
||||
|
||||
Spline(const Spline &) = default;
|
||||
Spline(Spline &&) = default;
|
||||
~Spline() override = default;
|
||||
Spline &operator=(const Spline &) = default;
|
||||
Spline &operator=(Spline &&) = default;
|
||||
|
||||
static Spline *create(SplineMode mode, const ccstd::vector<Vec3> &knots = {});
|
||||
static Spline *clone(const Spline &s);
|
||||
static Spline *copy(Spline *out, const Spline &s);
|
||||
|
||||
inline void setMode(SplineMode mode) { _mode = mode; }
|
||||
inline SplineMode getMode() const { return _mode; }
|
||||
inline void setKnots(const ccstd::vector<Vec3> &knots) { _knots = knots; }
|
||||
inline const ccstd::vector<Vec3> &getKnots() const { return _knots; }
|
||||
inline void clearKnots() { _knots.clear(); }
|
||||
inline uint32_t getKnotCount() const { return static_cast<uint32_t>(_knots.size()); }
|
||||
inline void addKnot(const Vec3 &knot) { _knots.push_back(knot); }
|
||||
void setModeAndKnots(SplineMode mode, const ccstd::vector<Vec3> &knots);
|
||||
void insertKnot(uint32_t index, const Vec3 &knot);
|
||||
void removeKnot(uint32_t index);
|
||||
void setKnot(uint32_t index, const Vec3 &knot);
|
||||
const Vec3 &getKnot(uint32_t index) const;
|
||||
Vec3 &getKnot(uint32_t index);
|
||||
|
||||
// get a point at t with repect to the `index` segment of curve or the whole curve.
|
||||
Vec3 getPoint(float t, uint32_t index = SPLINE_WHOLE_INDEX) const;
|
||||
|
||||
// get num points from 0 to 1 uniformly with repect to the `index` segment of curve or the whole curve
|
||||
ccstd::vector<Vec3> getPoints(uint32_t num, uint32_t index = SPLINE_WHOLE_INDEX) const;
|
||||
|
||||
private:
|
||||
uint32_t getSegments() const;
|
||||
static Vec3 calcLinear(const Vec3 &v0, const Vec3 &v1, float t);
|
||||
static Vec3 calcBezier(const Vec3 &v0, const Vec3 &v1, const Vec3 &v2, const Vec3 &v3, float t);
|
||||
static Vec3 calcCatmullRom(const Vec3 &v0, const Vec3 &v1, const Vec3 &v2, const Vec3 &v3, float t);
|
||||
|
||||
SplineMode _mode{SplineMode::CATMULL_ROM};
|
||||
ccstd::vector<Vec3> _knots; // control points of the curve.
|
||||
};
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
87
cocos/core/geometry/Triangle.cpp
Normal file
87
cocos/core/geometry/Triangle.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
/****************************************************************************
|
||||
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 "core/geometry/Triangle.h"
|
||||
#include "base/memory/Memory.h"
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
|
||||
Triangle *Triangle::create(float ax, float ay, float az,
|
||||
float bx, float by, float bz,
|
||||
float cx, float cy, float cz) {
|
||||
return ccnew Triangle(ax, ay, az, bx, by, bz, cx, cy, cz);
|
||||
}
|
||||
|
||||
Triangle *Triangle::clone(const Triangle &t) {
|
||||
return ccnew Triangle(
|
||||
t.a.x, t.a.y, t.a.z,
|
||||
t.b.x, t.b.y, t.b.z,
|
||||
t.c.x, t.c.y, t.c.z);
|
||||
}
|
||||
|
||||
Triangle *Triangle::copy(Triangle *out, const Triangle &t) {
|
||||
out->a = t.a;
|
||||
out->b = t.b;
|
||||
out->c = t.c;
|
||||
return out;
|
||||
}
|
||||
|
||||
Triangle *Triangle::fromPoints(Triangle *out, const Vec3 &a,
|
||||
const Vec3 &b,
|
||||
const Vec3 &c) {
|
||||
out->a = a;
|
||||
out->b = b;
|
||||
out->c = c;
|
||||
return out;
|
||||
}
|
||||
|
||||
Triangle *Triangle::set(Triangle *out,
|
||||
float ax, float ay, float az,
|
||||
float bx, float by, float bz,
|
||||
float cx, float cy, float cz) {
|
||||
out->a.x = ax;
|
||||
out->a.y = ay;
|
||||
out->a.z = az;
|
||||
|
||||
out->b.x = bx;
|
||||
out->b.y = by;
|
||||
out->b.z = bz;
|
||||
|
||||
out->c.x = cx;
|
||||
out->c.y = cy;
|
||||
out->c.z = cz;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
Triangle::Triangle(float ax, float ay, float az,
|
||||
float bx, float by, float bz,
|
||||
float cx, float cy, float cz) : ShapeBase(ShapeEnum::SHAPE_TRIANGLE) {
|
||||
a = {ax, ay, az};
|
||||
b = {bx, by, bz};
|
||||
c = {cx, cy, cz};
|
||||
}
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
175
cocos/core/geometry/Triangle.h
Normal file
175
cocos/core/geometry/Triangle.h
Normal file
@@ -0,0 +1,175 @@
|
||||
/****************************************************************************
|
||||
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 "core/geometry/Enums.h"
|
||||
|
||||
#include "math/Vec3.h"
|
||||
|
||||
namespace cc {
|
||||
namespace geometry {
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Basic Geometry: Triangle.
|
||||
* @zh
|
||||
* 基础几何 三角形。
|
||||
*/
|
||||
|
||||
class Triangle final : public ShapeBase {
|
||||
public:
|
||||
/**
|
||||
* @en
|
||||
* create a new triangle
|
||||
* @zh
|
||||
* 创建一个新的 triangle。
|
||||
* @param {number} ax a 点的 x 部分。
|
||||
* @param {number} ay a 点的 y 部分。
|
||||
* @param {number} az a 点的 z 部分。
|
||||
* @param {number} bx b 点的 x 部分。
|
||||
* @param {number} by b 点的 y 部分。
|
||||
* @param {number} bz b 点的 z 部分。
|
||||
* @param {number} cx c 点的 x 部分。
|
||||
* @param {number} cy c 点的 y 部分。
|
||||
* @param {number} cz c 点的 z 部分。
|
||||
* @return {Triangle} 一个新的 triangle。
|
||||
*/
|
||||
static Triangle *create(float ax = 1, float ay = 0, float az = 0,
|
||||
float bx = 0, float by = 0, float bz = 0,
|
||||
float cx = 0, float cy = 0, float cz = 1);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* clone a new triangle
|
||||
* @zh
|
||||
* 克隆一个新的 triangle。
|
||||
* @param {Triangle} t 克隆的目标。
|
||||
* @return {Triangle} 克隆出的新对象。
|
||||
*/
|
||||
|
||||
static Triangle *clone(const Triangle &t);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* copy the values from one triangle to another
|
||||
* @zh
|
||||
* 将一个 triangle 的值复制到另一个 triangle。
|
||||
* @param {Triangle} out 接受操作的 triangle。
|
||||
* @param {Triangle} t 被复制的 triangle。
|
||||
* @return {Triangle} out 接受操作的 triangle。
|
||||
*/
|
||||
|
||||
static Triangle *copy(Triangle *out, const Triangle &t);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Create a triangle from three points
|
||||
* @zh
|
||||
* 用三个点创建一个 triangle。
|
||||
* @param {Triangle} out 接受操作的 triangle。
|
||||
* @param {Vec3} a a 点。
|
||||
* @param {Vec3} b b 点。
|
||||
* @param {Vec3} c c 点。
|
||||
* @return {Triangle} out 接受操作的 triangle。
|
||||
*/
|
||||
static Triangle *fromPoints(Triangle *out, const Vec3 &a,
|
||||
const Vec3 &b,
|
||||
const Vec3 &c);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Set the components of a triangle to the given values
|
||||
* @zh
|
||||
* 将给定三角形的属性设置为给定值。
|
||||
* @param {Triangle} out 给定的三角形。
|
||||
* @param {number} ax a 点的 x 部分。
|
||||
* @param {number} ay a 点的 y 部分。
|
||||
* @param {number} az a 点的 z 部分。
|
||||
* @param {number} bx b 点的 x 部分。
|
||||
* @param {number} by b 点的 y 部分。
|
||||
* @param {number} bz b 点的 z 部分。
|
||||
* @param {number} cx c 点的 x 部分。
|
||||
* @param {number} cy c 点的 y 部分。
|
||||
* @param {number} cz c 点的 z 部分。
|
||||
* @return {Triangle}
|
||||
* @function
|
||||
*/
|
||||
static Triangle *set(Triangle *out,
|
||||
float ax, float ay, float az,
|
||||
float bx, float by, float bz,
|
||||
float cx, float cy, float cz);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Point a.
|
||||
* @zh
|
||||
* 点 a。
|
||||
*/
|
||||
|
||||
Vec3 a;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Point b.
|
||||
* @zh
|
||||
* 点 b。
|
||||
*/
|
||||
Vec3 b;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Point c.
|
||||
* @zh
|
||||
* 点 c。
|
||||
*/
|
||||
Vec3 c;
|
||||
/**
|
||||
* @en
|
||||
* Construct a triangle.
|
||||
* @zh
|
||||
* 构造一个三角形。
|
||||
* @param {number} ax a 点的 x 部分。
|
||||
* @param {number} ay a 点的 y 部分。
|
||||
* @param {number} az a 点的 z 部分。
|
||||
* @param {number} bx b 点的 x 部分。
|
||||
* @param {number} by b 点的 y 部分。
|
||||
* @param {number} bz b 点的 z 部分。
|
||||
* @param {number} cx c 点的 x 部分。
|
||||
* @param {number} cy c 点的 y 部分。
|
||||
* @param {number} cz c 点的 z 部分。
|
||||
*/
|
||||
explicit Triangle(float ax = 0, float ay = 0, float az = 0,
|
||||
float bx = 1, float by = 0, float bz = 0,
|
||||
float cx = 0, float cy = 1, float cz = 0);
|
||||
|
||||
Triangle(const Triangle &) = default;
|
||||
Triangle(Triangle &&) = default;
|
||||
~Triangle() override = default;
|
||||
Triangle &operator=(const Triangle &) = default;
|
||||
Triangle &operator=(Triangle &&) = default;
|
||||
|
||||
}; // namespace geometry
|
||||
|
||||
} // namespace geometry
|
||||
} // namespace cc
|
||||
Reference in New Issue
Block a user