no message
This commit is contained in:
147
cocos/primitive/Box.cpp
Normal file
147
cocos/primitive/Box.cpp
Normal file
@@ -0,0 +1,147 @@
|
||||
/****************************************************************************
|
||||
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 "primitive/Box.h"
|
||||
#include "base/std/optional.h"
|
||||
|
||||
namespace cc {
|
||||
namespace {
|
||||
const ccstd::vector<ccstd::vector<uint32_t>> FACE_AXES{
|
||||
{2, 3, 1}, // FRONT
|
||||
{4, 5, 7}, // BACK
|
||||
{7, 6, 2}, // TOP
|
||||
{1, 0, 4}, // BOTTOM
|
||||
{1, 4, 2}, // RIGHT
|
||||
{5, 0, 6} // LEFT
|
||||
};
|
||||
|
||||
const ccstd::vector<ccstd::vector<float>> FACE_NORMALS{
|
||||
{0, 0, 1}, // FRONT
|
||||
{0, 0, -1}, // BACK
|
||||
{0, 1, 0}, // TOP
|
||||
{0, -1, 0}, // BOTTOM
|
||||
{1, 0, 0}, // RIGHT
|
||||
{-1, 0, 0} // LEFT
|
||||
};
|
||||
|
||||
const ccstd::vector<ccstd::vector<float>> FACE_TANGENTS{
|
||||
{-1, 0, 0, 1}, // FRONT
|
||||
{-1, 0, 0, 1}, // BACK
|
||||
{-1, 0, 0, 1}, // TOP
|
||||
{-1, 0, 0, 1}, // BOTTOM
|
||||
{0, 0, -1, 1}, // RIGHT
|
||||
{0, 0, 1, 1} // LEFT
|
||||
};
|
||||
} // namespace
|
||||
|
||||
IGeometry box(const ccstd::optional<IBoxOptions> &options) {
|
||||
const uint32_t ws = options->widthSegments.has_value() ? options->widthSegments.value() : 1;
|
||||
const uint32_t hs = options->heightSegments.has_value() ? options->heightSegments.value() : 1;
|
||||
const uint32_t ls = options->lengthSegments.has_value() ? options->lengthSegments.value() : 1;
|
||||
|
||||
const float hw = options->width.has_value() ? options->width.value() / 2 : 1.0F / 2;
|
||||
const float hh = options->height.has_value() ? options->height.value() / 2 : 1.0F / 2;
|
||||
const float hl = options->length.has_value() ? options->length.value() / 2 : 1.0F / 2;
|
||||
|
||||
ccstd::vector<Vec3> corners{Vec3{-hw, -hh, hl}, Vec3{hw, -hh, hl}, Vec3{hw, hh, hl}, Vec3{-hw, hh, hl}, Vec3{hw, -hh, -hl}, Vec3{-hw, -hh, -hl}, Vec3{-hw, hh, -hl}, Vec3{hw, hh, -hl}};
|
||||
|
||||
ccstd::vector<float> positions;
|
||||
ccstd::vector<float> normals;
|
||||
ccstd::vector<float> uvs;
|
||||
ccstd::vector<float> tangents;
|
||||
ccstd::vector<uint32_t> indices;
|
||||
const Vec3 minPos(-hw, -hh, -hl);
|
||||
const Vec3 maxPos(hw, hh, hl);
|
||||
float boundingRadius{static_cast<float>(sqrt(hw * hw + hh * hh + hl * hl))};
|
||||
|
||||
auto buildPlane = [&](uint32_t side, uint32_t uSegments, uint32_t vSegments) {
|
||||
float u = 0;
|
||||
float v = 0;
|
||||
const auto offset = static_cast<uint32_t>(positions.size() / 3);
|
||||
const ccstd::vector<uint32_t> faceAxe = FACE_AXES[side];
|
||||
const ccstd::vector<float> faceNormal = FACE_NORMALS[side];
|
||||
const ccstd::vector<float> faceTangent = FACE_TANGENTS[side];
|
||||
|
||||
for (index_t iy = 0; iy <= vSegments; ++iy) {
|
||||
for (index_t ix = 0; ix <= uSegments; ++ix) {
|
||||
u = static_cast<float>(ix) / static_cast<float>(uSegments);
|
||||
v = static_cast<float>(iy) / static_cast<float>(vSegments);
|
||||
Vec3 temp1 = corners[faceAxe[0]].lerp(corners[faceAxe[1]], u);
|
||||
Vec3 temp2 = corners[faceAxe[0]].lerp(corners[faceAxe[2]], v);
|
||||
temp2.subtract(corners[faceAxe[0]]);
|
||||
temp1.add(temp2);
|
||||
positions.emplace_back(temp1.x);
|
||||
positions.emplace_back(temp1.y);
|
||||
positions.emplace_back(temp1.z);
|
||||
|
||||
normals.emplace_back(faceNormal[0]);
|
||||
normals.emplace_back(faceNormal[1]);
|
||||
normals.emplace_back(faceNormal[2]);
|
||||
|
||||
uvs.emplace_back(u);
|
||||
uvs.emplace_back(v);
|
||||
tangents.emplace_back(faceTangent[0]);
|
||||
tangents.emplace_back(faceTangent[1]);
|
||||
tangents.emplace_back(faceTangent[2]);
|
||||
tangents.emplace_back(faceTangent[3]);
|
||||
|
||||
if ((ix < uSegments) && (iy < vSegments)) {
|
||||
auto uSeg1 = uSegments + 1;
|
||||
const auto a = ix + iy * uSeg1;
|
||||
const auto b = ix + (iy + 1) * uSeg1;
|
||||
const auto c = (ix + 1) + (iy + 1) * uSeg1;
|
||||
const auto d = (ix + 1) + iy * uSeg1;
|
||||
|
||||
indices.emplace_back(offset + a);
|
||||
indices.emplace_back(offset + d);
|
||||
indices.emplace_back(offset + b);
|
||||
|
||||
indices.emplace_back(offset + b);
|
||||
indices.emplace_back(offset + d);
|
||||
indices.emplace_back(offset + c);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
buildPlane(0, ws, hs); // FRONT
|
||||
buildPlane(4, ls, hs); // RIGHT
|
||||
buildPlane(1, ws, hs); // BACK
|
||||
buildPlane(5, ls, hs); // LEFT
|
||||
buildPlane(3, ws, ls); // BOTTOM
|
||||
buildPlane(2, ws, ls); // TOP
|
||||
|
||||
IGeometry info;
|
||||
info.positions = positions;
|
||||
info.normals = normals;
|
||||
info.uvs = uvs;
|
||||
info.tangents = tangents;
|
||||
info.boundingRadius = boundingRadius;
|
||||
info.minPos = minPos;
|
||||
info.maxPos = maxPos;
|
||||
info.indices = indices;
|
||||
return info;
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
95
cocos/primitive/Box.h
Normal file
95
cocos/primitive/Box.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/****************************************************************************
|
||||
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 "primitive/PrimitiveDefine.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The definition of the parameter for building a box.
|
||||
* @zh
|
||||
* 立方体参数选项。
|
||||
*/
|
||||
struct IBoxOptions : public IGeometryOptions {
|
||||
/**
|
||||
* @en
|
||||
* Box extent on X-axis.
|
||||
* @zh
|
||||
* 立方体宽度。
|
||||
*/
|
||||
ccstd::optional<float> width;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Box extent on Y-axis.
|
||||
* @zh
|
||||
* 立方体高度。
|
||||
*/
|
||||
ccstd::optional<float> height;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Box extent on Z-axis.
|
||||
* @zh
|
||||
* 立方体长度。
|
||||
*/
|
||||
ccstd::optional<float> length;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Segment count on X-axis.
|
||||
* @zh
|
||||
* 宽度线段数。
|
||||
*/
|
||||
ccstd::optional<uint32_t> widthSegments;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Segment count on Y-axis.
|
||||
* @zh
|
||||
* 高度线段数。
|
||||
*/
|
||||
ccstd::optional<uint32_t> heightSegments;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Segment count on Z-axis.
|
||||
* @zh
|
||||
* 长度线段数。
|
||||
*/
|
||||
ccstd::optional<uint32_t> lengthSegments;
|
||||
};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* This function generates a box with specified extents and centered at origin,
|
||||
* but may be repositioned through the `center` option.
|
||||
* @zh
|
||||
* 生成一个立方体,其大小是定义的范围且中心在原点。
|
||||
* @param options 参数选项。
|
||||
*/
|
||||
IGeometry box(const ccstd::optional<IBoxOptions> &options = ccstd::nullopt);
|
||||
} // namespace cc
|
||||
238
cocos/primitive/Capsule.cpp
Normal file
238
cocos/primitive/Capsule.cpp
Normal file
@@ -0,0 +1,238 @@
|
||||
/****************************************************************************
|
||||
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 "primitive/Capsule.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
IGeometry capsule(float radiusTop, float radiusBottom, float height, const ccstd::optional<ICapsuleOptions> &opts) {
|
||||
const float torsoHeight = height - radiusTop - radiusBottom;
|
||||
const uint32_t sides = opts.has_value() ? opts->sides : 32;
|
||||
const uint32_t heightSegments = opts.has_value() ? opts->heightSegments : 32;
|
||||
const float bottomProp = radiusBottom / height;
|
||||
const float torProp = torsoHeight / height;
|
||||
const float topProp = radiusTop / height;
|
||||
const uint32_t bottomSegments = floor(static_cast<float>(heightSegments) * bottomProp);
|
||||
const uint32_t topSegments = floor(static_cast<float>(heightSegments) * topProp);
|
||||
const uint32_t torSegments = floor(static_cast<float>(heightSegments) * torProp);
|
||||
const float topOffset = torsoHeight + radiusBottom - height / 2;
|
||||
const float torOffset = radiusBottom - height / 2;
|
||||
const float bottomOffset = radiusBottom - height / 2;
|
||||
|
||||
const float arc = opts.has_value() ? opts->arc : math::PI_2;
|
||||
|
||||
// calculate vertex count
|
||||
ccstd::vector<float> positions;
|
||||
ccstd::vector<float> normals;
|
||||
ccstd::vector<float> uvs;
|
||||
ccstd::vector<uint32_t> indices;
|
||||
const float maxRadius = std::max(radiusTop, radiusBottom);
|
||||
const Vec3 minPos(-maxRadius, -height / 2, -maxRadius);
|
||||
const Vec3 maxPos(maxRadius, height / 2, maxRadius);
|
||||
const float boundingRadius = height / 2;
|
||||
|
||||
uint32_t index = 0;
|
||||
ccstd::vector<ccstd::vector<uint32_t>> indexArray;
|
||||
|
||||
// =======================
|
||||
// internal functions
|
||||
// =======================
|
||||
auto generateTorso = [&]() {
|
||||
// this will be used to calculate the normal
|
||||
float slope = (radiusTop - radiusBottom) / torsoHeight;
|
||||
|
||||
// generate positions, normals and uvs
|
||||
for (uint32_t y = 0; y <= torSegments; y++) {
|
||||
ccstd::vector<uint32_t> indexRow;
|
||||
const float lat = static_cast<float>(y) / static_cast<float>(torSegments);
|
||||
const float radius = lat * (radiusTop - radiusBottom) + radiusBottom;
|
||||
|
||||
for (uint32_t x = 0; x <= sides; ++x) {
|
||||
const float u = static_cast<float>(x) / static_cast<float>(sides);
|
||||
const float v = lat * torProp + bottomProp;
|
||||
const float theta = u * arc - (arc / 4);
|
||||
|
||||
const float sinTheta = sin(theta);
|
||||
const float cosTheta = cos(theta);
|
||||
|
||||
// vertex
|
||||
positions.emplace_back(radius * sinTheta);
|
||||
positions.emplace_back(lat * torsoHeight + torOffset);
|
||||
positions.emplace_back(radius * cosTheta);
|
||||
|
||||
// normal
|
||||
Vec3 temp1(sinTheta, -slope, cosTheta);
|
||||
temp1.normalize();
|
||||
|
||||
normals.emplace_back(temp1.x);
|
||||
normals.emplace_back(temp1.y);
|
||||
normals.emplace_back(temp1.z);
|
||||
|
||||
// uv
|
||||
uvs.emplace_back(u);
|
||||
uvs.emplace_back(v);
|
||||
// save index of vertex in respective row
|
||||
indexRow.emplace_back(index);
|
||||
|
||||
// increase index
|
||||
++index;
|
||||
}
|
||||
|
||||
// now save positions of the row in our index array
|
||||
indexArray.emplace_back(indexRow);
|
||||
}
|
||||
|
||||
// generate indices
|
||||
for (uint32_t y = 0; y < torSegments; ++y) {
|
||||
for (uint32_t x = 0; x < sides; ++x) {
|
||||
// we use the index array to access the correct indices
|
||||
const uint32_t i1 = indexArray[y][x];
|
||||
const uint32_t i2 = indexArray[y + 1][x];
|
||||
const uint32_t i3 = indexArray[y + 1][x + 1];
|
||||
const uint32_t i4 = indexArray[y][x + 1];
|
||||
|
||||
// face one
|
||||
indices.emplace_back(i1);
|
||||
indices.emplace_back(i4);
|
||||
indices.emplace_back(i2);
|
||||
|
||||
// face two
|
||||
indices.emplace_back(i4);
|
||||
indices.emplace_back(i3);
|
||||
indices.emplace_back(i2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto generateBottom = [&]() {
|
||||
for (uint32_t lat = 0; lat <= bottomSegments; ++lat) {
|
||||
float theta = static_cast<float>(lat) * math::PI / static_cast<float>(bottomSegments) / 2;
|
||||
float sinTheta = sin(theta);
|
||||
float cosTheta = -cos(theta);
|
||||
|
||||
for (uint32_t lon = 0; lon <= sides; ++lon) {
|
||||
const float phi = static_cast<float>(lon) * math::PI_2 / static_cast<float>(sides) - math::PI / 2;
|
||||
const float sinPhi = sin(phi);
|
||||
const float cosPhi = cos(phi);
|
||||
|
||||
const float x = sinPhi * sinTheta;
|
||||
const float y = cosTheta;
|
||||
const float z = cosPhi * sinTheta;
|
||||
const float u = static_cast<float>(lon) / static_cast<float>(sides);
|
||||
const float v = static_cast<float>(lat) / static_cast<float>(heightSegments);
|
||||
|
||||
positions.emplace_back(x * radiusBottom);
|
||||
positions.emplace_back(y * radiusBottom + bottomOffset);
|
||||
positions.emplace_back(z * radiusBottom);
|
||||
|
||||
normals.emplace_back(x);
|
||||
normals.emplace_back(y);
|
||||
normals.emplace_back(z);
|
||||
uvs.emplace_back(u);
|
||||
uvs.emplace_back(v);
|
||||
|
||||
if ((lat < bottomSegments) && (lon < sides)) {
|
||||
const uint32_t seg1 = sides + 1;
|
||||
const uint32_t a = seg1 * lat + lon;
|
||||
const uint32_t b = seg1 * (lat + 1) + lon;
|
||||
const uint32_t c = seg1 * (lat + 1) + lon + 1;
|
||||
const uint32_t d = seg1 * lat + lon + 1;
|
||||
|
||||
indices.emplace_back(a);
|
||||
indices.emplace_back(d);
|
||||
indices.emplace_back(b);
|
||||
|
||||
indices.emplace_back(d);
|
||||
indices.emplace_back(c);
|
||||
indices.emplace_back(b);
|
||||
}
|
||||
|
||||
++index;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto generateTop = [&]() {
|
||||
for (uint32_t lat = 0; lat <= topSegments; ++lat) {
|
||||
const float theta = static_cast<float>(lat) * math::PI / static_cast<float>(topSegments) / 2 + math::PI / 2;
|
||||
const float sinTheta = sin(theta);
|
||||
const float cosTheta = -cos(theta);
|
||||
|
||||
for (uint32_t lon = 0; lon <= sides; ++lon) {
|
||||
const float phi = static_cast<float>(lon) * 2 * math::PI / static_cast<float>(sides) - math::PI / 2;
|
||||
const float sinPhi = sin(phi);
|
||||
const float cosPhi = cos(phi);
|
||||
const float x = sinPhi * sinTheta;
|
||||
const float y = cosTheta;
|
||||
const float z = cosPhi * sinTheta;
|
||||
const float u = static_cast<float>(lon) / static_cast<float>(sides);
|
||||
const float v = static_cast<float>(lat) / static_cast<float>(heightSegments) + (1 - topProp);
|
||||
|
||||
positions.emplace_back(x * radiusTop);
|
||||
positions.emplace_back(y * radiusTop + topOffset);
|
||||
positions.emplace_back(z * radiusTop);
|
||||
|
||||
normals.emplace_back(x);
|
||||
normals.emplace_back(y);
|
||||
normals.emplace_back(z);
|
||||
uvs.emplace_back(u);
|
||||
uvs.emplace_back(v);
|
||||
|
||||
if ((lat < topSegments) && (lon < sides)) {
|
||||
const uint32_t seg1 = sides + 1;
|
||||
const uint32_t a = seg1 * lat + lon + indexArray[torSegments][sides] + 1;
|
||||
const uint32_t b = seg1 * (lat + 1) + lon + indexArray[torSegments][sides] + 1;
|
||||
const uint32_t c = seg1 * (lat + 1) + lon + 1 + indexArray[torSegments][sides] + 1;
|
||||
const uint32_t d = seg1 * lat + lon + 1 + indexArray[torSegments][sides] + 1;
|
||||
|
||||
indices.emplace_back(a);
|
||||
indices.emplace_back(d);
|
||||
indices.emplace_back(b);
|
||||
|
||||
indices.emplace_back(d);
|
||||
indices.emplace_back(c);
|
||||
indices.emplace_back(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
generateBottom();
|
||||
|
||||
generateTorso();
|
||||
|
||||
generateTop();
|
||||
|
||||
IGeometry info;
|
||||
info.positions = positions;
|
||||
info.normals = normals;
|
||||
info.uvs = uvs;
|
||||
info.boundingRadius = boundingRadius;
|
||||
info.minPos = minPos;
|
||||
info.maxPos = maxPos;
|
||||
info.indices = indices;
|
||||
return info;
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
53
cocos/primitive/Capsule.h
Normal file
53
cocos/primitive/Capsule.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/****************************************************************************
|
||||
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 "primitive/PrimitiveDefine.h"
|
||||
namespace cc {
|
||||
/**
|
||||
* @en
|
||||
* The definition of the parameter for building a capsule.
|
||||
* @zh
|
||||
* 胶囊体参数选项。
|
||||
*/
|
||||
struct ICapsuleOptions {
|
||||
uint32_t sides{32};
|
||||
uint32_t heightSegments{32};
|
||||
bool capped{true};
|
||||
float arc{math::PI_2};
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a capsule with radiusTop radiusBottom 0.5, height 2, centered at origin,
|
||||
* but may be repositioned through the `center` option.
|
||||
* @zh
|
||||
* 生成一个胶囊体。
|
||||
* @param radiusTop 顶部半径。
|
||||
* @param radiusBottom 底部半径。
|
||||
* @param opts 胶囊体参数选项。
|
||||
*/
|
||||
IGeometry capsule(float radiusTop = 0.5, float radiusBottom = 0.5, float height = 2, const ccstd::optional<ICapsuleOptions> &opts = ccstd::nullopt);
|
||||
|
||||
} // namespace cc
|
||||
64
cocos/primitive/Circle.cpp
Normal file
64
cocos/primitive/Circle.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
/****************************************************************************
|
||||
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 "primitive/Circle.h"
|
||||
#include "gfx-base/GFXDef-common.h"
|
||||
|
||||
namespace cc {
|
||||
IGeometry circle(ccstd::optional<ICircleOptions> &options) {
|
||||
if (!options.has_value()) options = ICircleOptions();
|
||||
const uint32_t segments = options->segments;
|
||||
ccstd::vector<float> positions(3 * (segments + 1));
|
||||
positions[0] = 0;
|
||||
positions[1] = 0;
|
||||
positions[2] = 0;
|
||||
ccstd::vector<uint32_t> indices(1 + segments * 2);
|
||||
indices[0] = 0;
|
||||
const float step = math::PI * 2 / static_cast<float>(segments);
|
||||
for (uint32_t iSegment = 0; iSegment < segments; ++iSegment) {
|
||||
const float angle = step * static_cast<float>(iSegment);
|
||||
const float x = cos(angle);
|
||||
const float y = sin(angle);
|
||||
const uint32_t p = (iSegment + 1) * 3;
|
||||
positions[p + 0] = x;
|
||||
positions[p + 1] = y;
|
||||
positions[p + 2] = 0;
|
||||
const uint32_t i = iSegment * 2;
|
||||
indices[1 + (i)] = iSegment + 1;
|
||||
indices[1 + (i + 1)] = iSegment + 2;
|
||||
}
|
||||
if (segments > 0) {
|
||||
indices[indices.size() - 1] = 1;
|
||||
}
|
||||
|
||||
IGeometry info;
|
||||
info.positions = positions;
|
||||
info.boundingRadius = 1;
|
||||
info.minPos = Vec3(1, 1, 0);
|
||||
info.maxPos = Vec3(-1, -1, 0);
|
||||
info.indices = indices;
|
||||
info.primitiveMode = gfx::PrimitiveMode::TRIANGLE_FAN;
|
||||
return info;
|
||||
}
|
||||
} // namespace cc
|
||||
51
cocos/primitive/Circle.h
Normal file
51
cocos/primitive/Circle.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/****************************************************************************
|
||||
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 "primitive/PrimitiveDefine.h"
|
||||
|
||||
namespace cc {
|
||||
/**
|
||||
* @en
|
||||
* The definition of the parameter for building a circle.
|
||||
* @zh
|
||||
* 圆形参数选项。
|
||||
*/
|
||||
struct ICircleOptions : public IGeometryOptions {
|
||||
// The segments. Default to 64.
|
||||
uint32_t segments{64};
|
||||
};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Generate a circle with radius 1, centered at origin,
|
||||
* but may be repositioned through the `center` option.
|
||||
* @zh
|
||||
* 生成一个圆,其半径是单位1,中心点在原点。
|
||||
* @param options 参数选项。
|
||||
*/
|
||||
IGeometry circle(ccstd::optional<ICircleOptions> &options);
|
||||
|
||||
} // namespace cc
|
||||
33
cocos/primitive/Cone.cpp
Normal file
33
cocos/primitive/Cone.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/****************************************************************************
|
||||
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 "primitive/Cone.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
IGeometry cone(float radius, float height, const ccstd::optional<IConeOptions> &opts) {
|
||||
return cylinder(0, radius, height, opts);
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
41
cocos/primitive/Cone.h
Normal file
41
cocos/primitive/Cone.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/****************************************************************************
|
||||
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 "primitive/Cylinder.h"
|
||||
#include "primitive/PrimitiveDefine.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The definition of the parameter for building a cylinder.
|
||||
* @zh
|
||||
* 圆锥参数选项。
|
||||
*/
|
||||
using IConeOptions = ICylinderOptions;
|
||||
|
||||
IGeometry cone(float radius = 0.5F, float height = 1.0F, const ccstd::optional<IConeOptions> &opts = ccstd::nullopt);
|
||||
|
||||
} // namespace cc
|
||||
265
cocos/primitive/Cylinder.cpp
Normal file
265
cocos/primitive/Cylinder.cpp
Normal file
@@ -0,0 +1,265 @@
|
||||
/****************************************************************************
|
||||
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 "primitive/Cylinder.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
float sign(float v) {
|
||||
return (v < 0 ? -1.0F : (v > 0 ? 1.0F : 0.0F));
|
||||
}
|
||||
|
||||
IGeometry cylinder(float radiusTop, float radiusBottom, float height, const ccstd::optional<ICylinderOptions> &opts) {
|
||||
const float halfHeight = height * 0.5F;
|
||||
const uint32_t radialSegments = opts.has_value() ? opts->radialSegments : 32;
|
||||
const uint32_t heightSegments = opts.has_value() ? opts->heightSegments : 1;
|
||||
const bool capped = opts.has_value() ? opts->capped : true;
|
||||
const float arc = opts.has_value() ? opts->arc : math::PI_2;
|
||||
|
||||
uint32_t cntCap = 0;
|
||||
if (capped) {
|
||||
if (radiusTop > 0) {
|
||||
++cntCap;
|
||||
}
|
||||
|
||||
if (radiusBottom > 0) {
|
||||
++cntCap;
|
||||
}
|
||||
}
|
||||
|
||||
// calculate vertex count
|
||||
uint32_t vertCount = (radialSegments + 1) * (heightSegments + 1);
|
||||
if (capped) {
|
||||
vertCount += ((radialSegments + 1) * cntCap) + (radialSegments * cntCap);
|
||||
}
|
||||
|
||||
// calculate index count
|
||||
uint32_t indexCount = radialSegments * heightSegments * 2 * 3;
|
||||
if (capped) {
|
||||
indexCount += radialSegments * cntCap * 3;
|
||||
}
|
||||
|
||||
ccstd::vector<uint32_t> indices(indexCount);
|
||||
ccstd::vector<float> positions(vertCount * 3);
|
||||
ccstd::vector<float> normals(vertCount * 3);
|
||||
ccstd::vector<float> uvs(vertCount * 2);
|
||||
const float maxRadius = std::max(radiusTop, radiusBottom);
|
||||
const Vec3 minPos(-maxRadius, -halfHeight, -maxRadius);
|
||||
const Vec3 maxPos(maxRadius, halfHeight, maxRadius);
|
||||
const float boundingRadius = sqrt(maxRadius * maxRadius + halfHeight * halfHeight);
|
||||
|
||||
uint32_t index = 0;
|
||||
uint32_t indexOffset = 0;
|
||||
|
||||
// =======================
|
||||
// internal functions
|
||||
// =======================
|
||||
auto generateTorso = [&]() {
|
||||
ccstd::vector<ccstd::vector<uint32_t>> indexArray;
|
||||
|
||||
// this will be used to calculate the normal
|
||||
const float r = radiusTop - radiusBottom;
|
||||
|
||||
const float slope = r * r / height * sign(r);
|
||||
// generate positions, normals and uvs
|
||||
for (uint32_t y = 0; y <= heightSegments; y++) {
|
||||
ccstd::vector<uint32_t> indexRow;
|
||||
const float v = static_cast<float>(y) / static_cast<float>(heightSegments);
|
||||
|
||||
// calculate the radius of the current row
|
||||
const float radius = v * r + radiusBottom;
|
||||
|
||||
for (uint32_t x = 0; x <= radialSegments; ++x) {
|
||||
const float u = static_cast<float>(x) / static_cast<float>(radialSegments);
|
||||
const float theta = u * arc;
|
||||
|
||||
const float sinTheta = sin(theta);
|
||||
const float cosTheta = cos(theta);
|
||||
|
||||
// vertex
|
||||
positions[3 * index] = radius * sinTheta;
|
||||
positions[3 * index + 1] = v * height - halfHeight;
|
||||
positions[3 * index + 2] = radius * cosTheta;
|
||||
|
||||
// normal
|
||||
Vec3 temp1(sinTheta, -slope, cosTheta);
|
||||
temp1.normalize();
|
||||
|
||||
normals[3 * index] = temp1.x;
|
||||
normals[3 * index + 1] = temp1.y;
|
||||
normals[3 * index + 2] = temp1.z;
|
||||
|
||||
// uv
|
||||
uvs[2 * index] = fmod((1 - u) * 2.0F, 1.0F);
|
||||
uvs[2 * index + 1] = v;
|
||||
|
||||
// save index of vertex in respective row
|
||||
indexRow.emplace_back(index);
|
||||
|
||||
// increase index
|
||||
++index;
|
||||
}
|
||||
|
||||
// now save positions of the row in our index array
|
||||
indexArray.emplace_back(indexRow);
|
||||
}
|
||||
|
||||
// generate indices
|
||||
for (uint32_t y = 0; y < heightSegments; ++y) {
|
||||
for (uint32_t x = 0; x < radialSegments; ++x) {
|
||||
// we use the index array to access the correct indices
|
||||
const uint32_t i1 = indexArray[y][x];
|
||||
const uint32_t i2 = indexArray[y + 1][x];
|
||||
const uint32_t i3 = indexArray[y + 1][x + 1];
|
||||
const uint32_t i4 = indexArray[y][x + 1];
|
||||
|
||||
// face one
|
||||
indices[indexOffset] = i1;
|
||||
++indexOffset;
|
||||
indices[indexOffset] = i4;
|
||||
++indexOffset;
|
||||
indices[indexOffset] = i2;
|
||||
++indexOffset;
|
||||
|
||||
// face two
|
||||
indices[indexOffset] = i4;
|
||||
++indexOffset;
|
||||
indices[indexOffset] = i3;
|
||||
++indexOffset;
|
||||
indices[indexOffset] = i2;
|
||||
++indexOffset;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto generateCap = [&](bool top) {
|
||||
const float radius = top ? radiusTop : radiusBottom;
|
||||
const float sign = top ? 1 : -1;
|
||||
|
||||
// save the index of the first center vertex
|
||||
const uint32_t centerIndexStart = index;
|
||||
|
||||
// first we generate the center vertex data of the cap.
|
||||
// because the geometry needs one set of uvs per face,
|
||||
// we must generate a center vertex per face/segment
|
||||
|
||||
for (uint32_t x = 1; x <= radialSegments; ++x) {
|
||||
// vertex
|
||||
positions[3 * index] = 0;
|
||||
positions[3 * index + 1] = halfHeight * sign;
|
||||
positions[3 * index + 2] = 0;
|
||||
|
||||
// // normal
|
||||
normals[3 * index] = 0;
|
||||
normals[3 * index + 1] = sign;
|
||||
normals[3 * index + 2] = 0;
|
||||
|
||||
// uv
|
||||
uvs[2 * index] = 0.5;
|
||||
uvs[2 * index + 1] = 0.5;
|
||||
|
||||
// increase index
|
||||
++index;
|
||||
}
|
||||
|
||||
// save the index of the last center vertex
|
||||
const uint32_t centerIndexEnd = index;
|
||||
|
||||
// now we generate the surrounding positions, normals and uvs
|
||||
|
||||
for (uint32_t x = 0; x <= radialSegments; ++x) {
|
||||
const float u = static_cast<float>(x) / static_cast<float>(radialSegments);
|
||||
const float theta = u * arc;
|
||||
|
||||
const float cosTheta = cos(theta);
|
||||
const float sinTheta = sin(theta);
|
||||
|
||||
// vertex
|
||||
positions[3 * index] = radius * sinTheta;
|
||||
positions[3 * index + 1] = halfHeight * sign;
|
||||
positions[3 * index + 2] = radius * cosTheta;
|
||||
|
||||
// normal
|
||||
normals[3 * index] = 0;
|
||||
normals[3 * index + 1] = sign;
|
||||
normals[3 * index + 2] = 0;
|
||||
|
||||
// uv
|
||||
uvs[2 * index] = 0.5F - (sinTheta * 0.5F * sign);
|
||||
uvs[2 * index + 1] = 0.5F + (cosTheta * 0.5F);
|
||||
|
||||
// increase index
|
||||
++index;
|
||||
}
|
||||
|
||||
// generate indices
|
||||
|
||||
for (uint32_t x = 0; x < radialSegments; ++x) {
|
||||
const uint32_t c = centerIndexStart + x;
|
||||
const uint32_t i = centerIndexEnd + x;
|
||||
|
||||
if (top) {
|
||||
// face top
|
||||
indices[indexOffset] = i + 1;
|
||||
++indexOffset;
|
||||
indices[indexOffset] = c;
|
||||
++indexOffset;
|
||||
indices[indexOffset] = i;
|
||||
++indexOffset;
|
||||
} else {
|
||||
// face bottom
|
||||
indices[indexOffset] = c;
|
||||
++indexOffset;
|
||||
indices[indexOffset] = i + 1;
|
||||
++indexOffset;
|
||||
indices[indexOffset] = i;
|
||||
++indexOffset;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
generateTorso();
|
||||
|
||||
if (capped) {
|
||||
if (radiusBottom > 0) {
|
||||
generateCap(false);
|
||||
}
|
||||
|
||||
if (radiusTop > 0) {
|
||||
generateCap(true);
|
||||
}
|
||||
}
|
||||
|
||||
IGeometry info;
|
||||
info.positions = positions;
|
||||
info.normals = normals;
|
||||
info.uvs = uvs;
|
||||
info.boundingRadius = boundingRadius;
|
||||
info.minPos = minPos;
|
||||
info.maxPos = maxPos;
|
||||
info.indices = indices;
|
||||
return info;
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
55
cocos/primitive/Cylinder.h
Normal file
55
cocos/primitive/Cylinder.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/****************************************************************************
|
||||
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 <cmath>
|
||||
#include "3d/assets/Mesh.h"
|
||||
#include "primitive/PrimitiveDefine.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
/**
|
||||
* @zh
|
||||
* 球参数选项。
|
||||
*/
|
||||
struct ICylinderOptions : public IGeometryOptions {
|
||||
uint32_t radialSegments{32};
|
||||
uint32_t heightSegments{1};
|
||||
bool capped{true};
|
||||
float arc{math::PI_2};
|
||||
};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Generate a sphere with radius 0.5.
|
||||
* @zh
|
||||
* 生成一个球。
|
||||
* @param radius 球半径。
|
||||
* @param options 参数选项。
|
||||
*/
|
||||
|
||||
IGeometry cylinder(float radiusTop = 0.5, float radiusBottom = 0.5, float height = 2, const ccstd::optional<ICylinderOptions> &opts = ccstd::nullopt);
|
||||
|
||||
} // namespace cc
|
||||
110
cocos/primitive/Plane.cpp
Normal file
110
cocos/primitive/Plane.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
|
||||
/****************************************************************************
|
||||
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 "primitive/Plane.h"
|
||||
namespace cc {
|
||||
|
||||
IGeometry plane(ccstd::optional<IPlaneOptions> options) {
|
||||
if (!options.has_value()) {
|
||||
options = IPlaneOptions();
|
||||
}
|
||||
const float width = options->width;
|
||||
const float length = options->length;
|
||||
const uint32_t uSegments = options->widthSegments;
|
||||
const uint32_t vSegments = options->lengthSegments;
|
||||
|
||||
const float hw = width * 0.5F;
|
||||
const float hl = length * 0.5F;
|
||||
|
||||
ccstd::vector<float> positions;
|
||||
ccstd::vector<float> uvs;
|
||||
ccstd::vector<uint32_t> indices;
|
||||
const Vec3 minPos(-hw, 0, -hl);
|
||||
const Vec3 maxPos(hw, 0, hl);
|
||||
const float boundingRadius = sqrt(width * width + length * length);
|
||||
|
||||
Vec3 c00(-hw, 0, hl);
|
||||
Vec3 c10(hw, 0, hl);
|
||||
Vec3 c01(-hw, 0, -hl);
|
||||
|
||||
for (uint32_t y = 0; y <= vSegments; ++y) {
|
||||
for (uint32_t x = 0; x <= uSegments; ++x) {
|
||||
const float u = static_cast<float>(x) / static_cast<float>(uSegments);
|
||||
const float v = static_cast<float>(y) / static_cast<float>(vSegments);
|
||||
|
||||
Vec3 temp1 = c00.lerp(c10, u);
|
||||
Vec3 temp2 = c00.lerp(c01, v);
|
||||
temp2.subtract(c00);
|
||||
temp1.add(temp2);
|
||||
|
||||
positions.emplace_back(temp1.x);
|
||||
positions.emplace_back(temp1.y);
|
||||
positions.emplace_back(temp1.z);
|
||||
if (options->includeUV) {
|
||||
uvs.emplace_back(u);
|
||||
uvs.emplace_back(v);
|
||||
}
|
||||
|
||||
if ((x < uSegments) && (y < vSegments)) {
|
||||
const uint32_t uSeg1 = uSegments + 1;
|
||||
const uint32_t a = x + y * uSeg1;
|
||||
const uint32_t b = x + (y + 1) * uSeg1;
|
||||
const uint32_t c = (x + 1) + (y + 1) * uSeg1;
|
||||
const uint32_t d = (x + 1) + y * uSeg1;
|
||||
|
||||
indices.emplace_back(a);
|
||||
indices.emplace_back(d);
|
||||
indices.emplace_back(b);
|
||||
indices.emplace_back(d);
|
||||
indices.emplace_back(c);
|
||||
indices.emplace_back(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IGeometry result;
|
||||
result.positions = positions;
|
||||
result.boundingRadius = boundingRadius;
|
||||
result.minPos = minPos;
|
||||
result.maxPos = maxPos;
|
||||
result.indices = indices;
|
||||
|
||||
if (options->includeNormal) {
|
||||
const uint32_t nVertex = (vSegments + 1) * (uSegments + 1);
|
||||
ccstd::vector<float> normals(3 * nVertex);
|
||||
for (uint32_t i = 0; i < nVertex; ++i) {
|
||||
normals[i * 3 + 0] = 0;
|
||||
normals[i * 3 + 1] = 1;
|
||||
normals[i * 3 + 2] = 0;
|
||||
}
|
||||
result.normals = normals;
|
||||
}
|
||||
if (options->includeUV) {
|
||||
result.uvs = uvs;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
68
cocos/primitive/Plane.h
Normal file
68
cocos/primitive/Plane.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/****************************************************************************
|
||||
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 "primitive/PrimitiveDefine.h"
|
||||
|
||||
namespace cc {
|
||||
/**
|
||||
* @en
|
||||
* The definition of the parameter for building a plane.
|
||||
* @zh
|
||||
* 平面参数选项。
|
||||
*/
|
||||
struct IPlaneOptions : public IGeometryOptions {
|
||||
/**
|
||||
* Plane extent on X-axis. Default to 10.
|
||||
*/
|
||||
float width{10};
|
||||
|
||||
/**
|
||||
* Plane extent on Z-axis. Default to 10.
|
||||
*/
|
||||
float length{10};
|
||||
|
||||
/**
|
||||
* Segment count on X-axis. Default to 10.
|
||||
*/
|
||||
uint32_t widthSegments{10};
|
||||
|
||||
/**
|
||||
* Segment count on Z-axis. Default to 10.
|
||||
*/
|
||||
uint32_t lengthSegments{10};
|
||||
};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* This function generates a plane on XOZ plane with positive Y direction.
|
||||
* @zh
|
||||
* 生成一个平面,其位于XOZ平面,方向为Y轴正方向。
|
||||
* @param options 平面参数选项。
|
||||
*/
|
||||
|
||||
IGeometry plane(ccstd::optional<IPlaneOptions> options = ccstd::nullopt);
|
||||
|
||||
} // namespace cc
|
||||
79
cocos/primitive/Primitive.cpp
Normal file
79
cocos/primitive/Primitive.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
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 "primitive/Primitive.h"
|
||||
#include "3d/misc/CreateMesh.h"
|
||||
#include "core/assets/RenderingSubMesh.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
Primitive::Primitive(PrimitiveType type) : type(type) {
|
||||
}
|
||||
|
||||
Primitive::~Primitive() = default;
|
||||
|
||||
void Primitive::onLoaded() {
|
||||
reset(MeshUtils::createMeshInfo(createGeometry(type)));
|
||||
}
|
||||
|
||||
IGeometry createGeometry(PrimitiveType type, const ccstd::optional<PrimitiveOptions> &options) {
|
||||
switch (type) {
|
||||
case PrimitiveType::BOX: {
|
||||
return options.has_value() ? box(ccstd::get<IBoxOptions>(options.value())) : box();
|
||||
break;
|
||||
}
|
||||
case PrimitiveType::SPHERE: {
|
||||
return options.has_value() ? sphere(0.5F, ccstd::get<ISphereOptions>(options.value())) : sphere();
|
||||
break;
|
||||
}
|
||||
case PrimitiveType::CYLINDER: {
|
||||
return options.has_value() ? cylinder(0.5F, 0.5F, 2, ccstd::get<4>(options.value())) : cylinder();
|
||||
break;
|
||||
}
|
||||
case PrimitiveType::CONE: {
|
||||
return options.has_value() ? cone(0.5F, 1.0F, ccstd::get<5>(options.value())) : cone();
|
||||
break;
|
||||
}
|
||||
case PrimitiveType::CAPSULE: {
|
||||
return options.has_value() ? capsule(0.5F, 0.5F, 2, ccstd::get<ICapsuleOptions>(options.value())) : capsule();
|
||||
break;
|
||||
}
|
||||
case PrimitiveType::TORUS: {
|
||||
return options.has_value() ? torus(0.4F, 0.1F, ccstd::get<ITorusOptions>(options.value())) : torus();
|
||||
break;
|
||||
}
|
||||
case PrimitiveType::PLANE: {
|
||||
return options.has_value() ? quad(ccstd::get<IGeometryOptions>(options.value())) : plane();
|
||||
break;
|
||||
}
|
||||
case PrimitiveType::QUAD: {
|
||||
return options.has_value() ? quad(ccstd::get<IGeometryOptions>(options.value())) : quad();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return box();
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
98
cocos/primitive/Primitive.h
Normal file
98
cocos/primitive/Primitive.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
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/optional.h"
|
||||
|
||||
#include "3d/assets/Mesh.h"
|
||||
#include "base/std/variant.h"
|
||||
#include "primitive/Box.h"
|
||||
#include "primitive/Capsule.h"
|
||||
#include "primitive/Circle.h"
|
||||
#include "primitive/Cone.h"
|
||||
#include "primitive/Cylinder.h"
|
||||
#include "primitive/Plane.h"
|
||||
#include "primitive/Quad.h"
|
||||
#include "primitive/Sphere.h"
|
||||
#include "primitive/Torus.h"
|
||||
|
||||
#include "primitive/PrimitiveDefine.h"
|
||||
namespace cc {
|
||||
|
||||
using PrimitiveOptions = ccstd::variant<IGeometryOptions, IBoxOptions, ICapsuleOptions, ICircleOptions, ICylinderOptions, IConeOptions, IPlaneOptions, ISphereOptions, ITorusOptions>;
|
||||
enum class PrimitiveType {
|
||||
BOX = 0,
|
||||
SPHERE = 1,
|
||||
CYLINDER = 2,
|
||||
CONE = 3,
|
||||
CAPSULE = 4,
|
||||
TORUS = 5,
|
||||
PLANE = 6,
|
||||
QUAD = 7,
|
||||
};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Basic primitive mesh, this can be generate some primitive mesh at runtime.
|
||||
* @zh
|
||||
* 基础图形网格,可以在运行时构建一些基础的网格。
|
||||
*/
|
||||
class Primitive : public Mesh {
|
||||
public:
|
||||
/**
|
||||
* @en
|
||||
* The type of the primitive mesh, set it before you call onLoaded.
|
||||
* @zh
|
||||
* 此基础图形网格的类型,请在 onLoaded 调用之前设置。
|
||||
*/
|
||||
// @type(PrimitiveType)
|
||||
PrimitiveType type{PrimitiveType::BOX};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The option for build the primitive mesh, set it before you call onLoaded.
|
||||
* @zh
|
||||
* 创建此基础图形网格的可选参数,请在 onLoaded 调用之前设置。
|
||||
*/
|
||||
// @serializable
|
||||
// @editable
|
||||
ccstd::unordered_map<ccstd::string, float> info; // cjh float?
|
||||
|
||||
explicit Primitive(PrimitiveType type = PrimitiveType::BOX);
|
||||
~Primitive() override;
|
||||
/**
|
||||
* @en
|
||||
* Construct the primitive mesh with `type` and `info`.
|
||||
* @zh
|
||||
* 根据`type`和`info`构建相应的网格。
|
||||
*/
|
||||
void onLoaded() override;
|
||||
|
||||
private:
|
||||
CC_DISALLOW_COPY_MOVE_ASSIGN(Primitive);
|
||||
};
|
||||
|
||||
IGeometry createGeometry(PrimitiveType type, const ccstd::optional<PrimitiveOptions> &options = ccstd::nullopt);
|
||||
|
||||
} // namespace cc
|
||||
284
cocos/primitive/PrimitiveDefine.h
Normal file
284
cocos/primitive/PrimitiveDefine.h
Normal file
@@ -0,0 +1,284 @@
|
||||
/****************************************************************************
|
||||
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/optional.h"
|
||||
#include "core/TypedArray.h"
|
||||
#include "math/Vec3.h"
|
||||
#include "math/Vec4.h"
|
||||
#include "renderer/gfx-base/GFXDef.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The definition of the parameter for building a primitive geometry.
|
||||
* @zh
|
||||
* 几何体参数选项。
|
||||
*/
|
||||
struct IGeometryOptions {
|
||||
/**
|
||||
* @en
|
||||
* Whether to include normal. Default to true.
|
||||
* @zh
|
||||
* 是否包含法线。默认为true。
|
||||
*/
|
||||
bool includeNormal{true};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Whether to include uv. Default to true.
|
||||
* @zh
|
||||
* 是否包含UV。默认为true。
|
||||
*/
|
||||
bool includeUV{true};
|
||||
};
|
||||
|
||||
struct CustomAttribute {
|
||||
gfx::Attribute attr;
|
||||
ccstd::vector<float> values;
|
||||
};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The definition of the geometry, this struct can build a mesh.
|
||||
* @zh
|
||||
* 几何体信息。
|
||||
*/
|
||||
struct IGeometry {
|
||||
/**
|
||||
* @en
|
||||
* Vertex positions.
|
||||
* @zh
|
||||
* 顶点位置。
|
||||
*/
|
||||
ccstd::vector<float> positions;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Vertex normals.
|
||||
* @zh
|
||||
* 顶点法线。
|
||||
*/
|
||||
ccstd::optional<ccstd::vector<float>> normals;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Texture coordinates.
|
||||
* @zh
|
||||
* 纹理坐标。
|
||||
*/
|
||||
ccstd::optional<ccstd::vector<float>> uvs;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Vertex Tangents.
|
||||
* @zh
|
||||
* 顶点切线。
|
||||
*/
|
||||
ccstd::optional<ccstd::vector<float>> tangents;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Vertex colors.
|
||||
* @zh
|
||||
* 顶点颜色。
|
||||
*/
|
||||
ccstd::optional<ccstd::vector<float>> colors;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* specify vertex attributes, use (positions|normals|uvs|colors) as keys
|
||||
* @zh
|
||||
* 顶点属性。
|
||||
*/
|
||||
ccstd::optional<gfx::AttributeList> attributes;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Custom attributes
|
||||
* @zh
|
||||
* 定制属性列表。
|
||||
*/
|
||||
ccstd::optional<ccstd::vector<CustomAttribute>> customAttributes;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Bounding sphere radius.
|
||||
* @zh
|
||||
* 包围球半径。
|
||||
*/
|
||||
ccstd::optional<float> boundingRadius;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Min position.
|
||||
* @zh
|
||||
* 最小位置。
|
||||
*/
|
||||
ccstd::optional<Vec3> minPos;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Max position.
|
||||
* @zh
|
||||
* 最大位置。
|
||||
*/
|
||||
ccstd::optional<Vec3> maxPos;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Geometry indices, if one needs indexed-draw.
|
||||
* @zh
|
||||
* 几何索引,当使用索引绘制时。
|
||||
*/
|
||||
ccstd::optional<ccstd::vector<uint32_t>> indices; //cjh uint16_t ?
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Topology of the geometry vertices. Default is TRIANGLE_LIST.
|
||||
* @zh
|
||||
* 几何顶点的拓扑图元。默认值是TRIANGLE_LIST。
|
||||
*/
|
||||
ccstd::optional<gfx::PrimitiveMode> primitiveMode;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* whether rays casting from the back face of this geometry could collide with it
|
||||
* @zh
|
||||
* 是否是双面,用于判断来自于几何体背面的射线检测。
|
||||
*/
|
||||
ccstd::optional<bool> doubleSided;
|
||||
};
|
||||
|
||||
struct DynamicCustomAttribute {
|
||||
gfx::Attribute attr;
|
||||
Float32Array values;
|
||||
};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* The definition of the dynamic geometry, this struct can build a dynamic mesh.
|
||||
* @zh
|
||||
* 几何体信息。
|
||||
*/
|
||||
struct IDynamicGeometry {
|
||||
/**
|
||||
* @en
|
||||
* Vertex positions: 3 float components.
|
||||
* @zh
|
||||
* 顶点位置:3个float分量。
|
||||
*/
|
||||
Float32Array positions;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Vertex normals: 3 float components.
|
||||
* @zh
|
||||
* 顶点法线:3个float分量。
|
||||
*/
|
||||
ccstd::optional<Float32Array> normals;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Texture coordinates: 2 float components.
|
||||
* @zh
|
||||
* 纹理坐标:2个float分量。
|
||||
*/
|
||||
ccstd::optional<Float32Array> uvs;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Vertex Tangents: 4 float components.
|
||||
* @zh
|
||||
* 顶点切线:4个float分量。
|
||||
*/
|
||||
ccstd::optional<Float32Array> tangents;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Vertex colors: 4 float components.
|
||||
* @zh
|
||||
* 顶点颜色:4个float分量。
|
||||
*/
|
||||
ccstd::optional<Float32Array> colors;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Custom attributes
|
||||
* @zh
|
||||
* 定制属性列表。
|
||||
*/
|
||||
ccstd::optional<ccstd::vector<DynamicCustomAttribute>> customAttributes;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Min position, it is more efficient to calculate bounding box by user.
|
||||
* @zh
|
||||
* 最小位置。包围盒大小由用户提供,更高效。
|
||||
*/
|
||||
ccstd::optional<Vec3> minPos;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Max position, it is more efficient to calculate bounding box by user.
|
||||
* @zh
|
||||
* 最大位置。包围盒大小由用户提供,更高效。
|
||||
*/
|
||||
ccstd::optional<Vec3> maxPos;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* 16 bits Geometry indices, if one needs indexed-draw.
|
||||
* @zh
|
||||
* 16位几何索引,当使用索引绘制时。
|
||||
*/
|
||||
ccstd::optional<Uint16Array> indices16;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* 32 bits Geometry indices, if one needs indexed-draw.
|
||||
* @zh
|
||||
* 32位几何索引,当使用索引绘制时。
|
||||
*/
|
||||
ccstd::optional<Uint32Array> indices32;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Topology of the geometry vertices. Default is TRIANGLE_LIST.
|
||||
* @zh
|
||||
* 几何顶点的拓扑图元。默认值是TRIANGLE_LIST。
|
||||
*/
|
||||
ccstd::optional<gfx::PrimitiveMode> primitiveMode;
|
||||
|
||||
/**
|
||||
* @en
|
||||
* whether rays casting from the back face of this geometry could collide with it
|
||||
* @zh
|
||||
* 是否是双面,用于判断来自于几何体背面的射线检测。
|
||||
*/
|
||||
ccstd::optional<bool> doubleSided;
|
||||
};
|
||||
|
||||
} // namespace cc
|
||||
23
cocos/primitive/PrimitiveUtils.cpp
Normal file
23
cocos/primitive/PrimitiveUtils.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.
|
||||
****************************************************************************/
|
||||
29
cocos/primitive/PrimitiveUtils.h
Normal file
29
cocos/primitive/PrimitiveUtils.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/****************************************************************************
|
||||
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
|
||||
|
||||
namespace cc {
|
||||
|
||||
}
|
||||
54
cocos/primitive/Quad.cpp
Normal file
54
cocos/primitive/Quad.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/****************************************************************************
|
||||
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 "primitive/Quad.h"
|
||||
namespace cc {
|
||||
IGeometry quad(ccstd::optional<IGeometryOptions> options) {
|
||||
if (!options.has_value()) {
|
||||
options = IGeometryOptions();
|
||||
}
|
||||
IGeometry result;
|
||||
result.positions = ccstd::vector<float>{-0.5, -0.5, 0, -0.5, 0.5, 0, 0.5, 0.5, 0, 0.5, -0.5, 0};
|
||||
result.boundingRadius = sqrt(0.5 * 0.5 + 0.5 * 0.5);
|
||||
result.minPos = Vec3(-0.5, -0.5, 0);
|
||||
result.maxPos = Vec3(0.5, 0.5, 0);
|
||||
result.indices = ccstd::vector<uint32_t>{0, 3, 1, 3, 2, 1};
|
||||
if (options->includeNormal) {
|
||||
result.normals = ccstd::vector<float>{
|
||||
0, 0, 1,
|
||||
0, 0, 1,
|
||||
0, 0, 1,
|
||||
0, 0, 1};
|
||||
}
|
||||
if (options->includeUV) {
|
||||
result.uvs = ccstd::vector<float>{
|
||||
0, 0,
|
||||
0, 1,
|
||||
1, 1,
|
||||
1, 0};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
38
cocos/primitive/Quad.h
Normal file
38
cocos/primitive/Quad.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/****************************************************************************
|
||||
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 "primitive/PrimitiveDefine.h"
|
||||
namespace cc {
|
||||
/**
|
||||
* @en
|
||||
* Generate a quad with width and height both to 1, centered at origin.
|
||||
* @zh
|
||||
* 生成一个四边形,宽高都为1,中心在原点。
|
||||
* @param options 参数选项。
|
||||
*/
|
||||
|
||||
IGeometry quad(ccstd::optional<IGeometryOptions> options = ccstd::nullopt);
|
||||
} // namespace cc
|
||||
98
cocos/primitive/Sphere.cpp
Normal file
98
cocos/primitive/Sphere.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
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 "primitive/Sphere.h"
|
||||
|
||||
namespace cc {
|
||||
IGeometry sphere(float radius, const ccstd::optional<ISphereOptions> &opts) {
|
||||
const uint32_t segments = opts.has_value() ? opts->segments : 32;
|
||||
|
||||
// lat === latitude
|
||||
// lon === longitude
|
||||
|
||||
ccstd::vector<float> positions;
|
||||
ccstd::vector<float> normals;
|
||||
ccstd::vector<float> uvs;
|
||||
ccstd::vector<uint32_t> indices;
|
||||
const Vec3 minPos(-radius, -radius, -radius);
|
||||
const Vec3 maxPos(radius, radius, radius);
|
||||
const float boundingRadius = radius;
|
||||
|
||||
for (uint32_t lat = 0; lat <= segments; lat++) {
|
||||
const float theta = static_cast<float>(lat) * math::PI / static_cast<float>(segments);
|
||||
const float sinTheta = sin(theta);
|
||||
const float cosTheta = -cos(theta);
|
||||
|
||||
for (uint32_t lon = 0; lon <= segments; ++lon) {
|
||||
const float phi = static_cast<float>(lon) * 2.F * math::PI / static_cast<float>(segments) - math::PI / 2.F;
|
||||
const float sinPhi = sin(phi);
|
||||
const float cosPhi = cos(phi);
|
||||
|
||||
const float x = sinPhi * sinTheta;
|
||||
const float y = cosTheta;
|
||||
const float z = cosPhi * sinTheta;
|
||||
const float u = static_cast<float>(lon) / static_cast<float>(segments);
|
||||
const float v = static_cast<float>(lat) / static_cast<float>(segments);
|
||||
|
||||
positions.emplace_back(x * radius);
|
||||
positions.emplace_back(y * radius);
|
||||
positions.emplace_back(z * radius);
|
||||
|
||||
normals.emplace_back(x);
|
||||
normals.emplace_back(y);
|
||||
normals.emplace_back(z);
|
||||
|
||||
uvs.emplace_back(u);
|
||||
uvs.emplace_back(v);
|
||||
|
||||
if ((lat < segments) && (lon < segments)) {
|
||||
const uint32_t seg1 = segments + 1;
|
||||
const uint32_t a = seg1 * lat + lon;
|
||||
const uint32_t b = seg1 * (lat + 1) + lon;
|
||||
const uint32_t c = seg1 * (lat + 1) + lon + 1;
|
||||
const uint32_t d = seg1 * lat + lon + 1;
|
||||
|
||||
indices.emplace_back(a);
|
||||
indices.emplace_back(d);
|
||||
indices.emplace_back(b);
|
||||
|
||||
indices.emplace_back(d);
|
||||
indices.emplace_back(c);
|
||||
indices.emplace_back(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IGeometry info;
|
||||
info.positions = positions;
|
||||
info.normals = normals;
|
||||
info.uvs = uvs;
|
||||
info.boundingRadius = boundingRadius;
|
||||
info.minPos = minPos;
|
||||
info.maxPos = maxPos;
|
||||
info.indices = indices;
|
||||
return info;
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
52
cocos/primitive/Sphere.h
Normal file
52
cocos/primitive/Sphere.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/****************************************************************************
|
||||
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 <cmath>
|
||||
#include "3d/assets/Mesh.h"
|
||||
#include "primitive/PrimitiveDefine.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
/**
|
||||
* @zh
|
||||
* 球参数选项。
|
||||
*/
|
||||
struct ISphereOptions : public IGeometryOptions {
|
||||
uint32_t segments{0};
|
||||
};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Generate a shpere with radius 0.5.
|
||||
* @zh
|
||||
* 生成一个球。
|
||||
* @param radius 球半径。
|
||||
* @param options 参数选项。
|
||||
*/
|
||||
|
||||
IGeometry sphere(float radius = 0.5, const ccstd::optional<ISphereOptions> &opts = ccstd::nullopt);
|
||||
|
||||
} // namespace cc
|
||||
98
cocos/primitive/Torus.cpp
Normal file
98
cocos/primitive/Torus.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
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 "primitive/Torus.h"
|
||||
|
||||
namespace cc {
|
||||
IGeometry torus(float radius, float tube, const ccstd::optional<ITorusOptions> &opts) {
|
||||
const uint32_t radialSegments = opts.has_value() ? opts->radialSegments : 32;
|
||||
const uint32_t tubularSegments = opts.has_value() ? opts->tubularSegments : 32;
|
||||
const float arc = opts.has_value() ? opts->arc : math::PI_2;
|
||||
|
||||
ccstd::vector<float> positions;
|
||||
ccstd::vector<float> normals;
|
||||
ccstd::vector<float> uvs;
|
||||
ccstd::vector<uint32_t> indices;
|
||||
const Vec3 minPos(-radius - tube, -tube, -radius - tube);
|
||||
const Vec3 maxPos(radius + tube, tube, radius + tube);
|
||||
const float boundingRadius = radius + tube;
|
||||
|
||||
for (uint32_t j = 0; j <= radialSegments; j++) {
|
||||
for (uint32_t i = 0; i <= tubularSegments; i++) {
|
||||
const float u = static_cast<float>(i) / static_cast<float>(tubularSegments);
|
||||
const float v = static_cast<float>(j) / static_cast<float>(radialSegments);
|
||||
|
||||
const float u1 = u * arc;
|
||||
const float v1 = v * math::PI_2;
|
||||
|
||||
// vertex
|
||||
const float x = (radius + tube * cos(v1)) * sin(u1);
|
||||
const float y = tube * sin(v1);
|
||||
const float z = (radius + tube * cos(v1)) * cos(u1);
|
||||
|
||||
// this vector is used to calculate the normal
|
||||
const float nx = sin(u1) * cos(v1);
|
||||
const float ny = sin(v1);
|
||||
const float nz = cos(u1) * cos(v1);
|
||||
|
||||
positions.emplace_back(x);
|
||||
positions.emplace_back(y);
|
||||
positions.emplace_back(z);
|
||||
normals.emplace_back(nx);
|
||||
normals.emplace_back(ny);
|
||||
normals.emplace_back(nz);
|
||||
|
||||
uvs.emplace_back(u);
|
||||
uvs.emplace_back(v);
|
||||
|
||||
if ((i < tubularSegments) && (j < radialSegments)) {
|
||||
const uint32_t seg1 = tubularSegments + 1;
|
||||
const uint32_t a = seg1 * j + i;
|
||||
const uint32_t b = seg1 * (j + 1) + i;
|
||||
const uint32_t c = seg1 * (j + 1) + i + 1;
|
||||
const uint32_t d = seg1 * j + i + 1;
|
||||
|
||||
indices.emplace_back(a);
|
||||
indices.emplace_back(d);
|
||||
indices.emplace_back(b);
|
||||
|
||||
indices.emplace_back(d);
|
||||
indices.emplace_back(c);
|
||||
indices.emplace_back(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IGeometry info;
|
||||
info.positions = positions;
|
||||
info.normals = normals;
|
||||
info.uvs = uvs;
|
||||
info.boundingRadius = boundingRadius;
|
||||
info.minPos = minPos;
|
||||
info.maxPos = maxPos;
|
||||
info.indices = indices;
|
||||
return info;
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
50
cocos/primitive/Torus.h
Normal file
50
cocos/primitive/Torus.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/****************************************************************************
|
||||
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 "primitive/PrimitiveDefine.h"
|
||||
namespace cc {
|
||||
/**
|
||||
* @zh
|
||||
* 环面参数选项。
|
||||
*/
|
||||
struct ITorusOptions {
|
||||
uint32_t radialSegments{32};
|
||||
uint32_t tubularSegments{32};
|
||||
float arc{math::PI_2};
|
||||
};
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Generate a torus with raidus 0.4, tube 0.1 and centered at origin.
|
||||
* @zh
|
||||
* 生成一个环面。
|
||||
* @param radius 环面半径。
|
||||
* @param tube 管形大小。
|
||||
* @param opts 参数选项。
|
||||
*/
|
||||
IGeometry torus(float radius = 0.4, float tube = 0.1, const ccstd::optional<ITorusOptions> &opts = ccstd::nullopt);
|
||||
|
||||
} // namespace cc
|
||||
127
cocos/primitive/Transform.cpp
Normal file
127
cocos/primitive/Transform.cpp
Normal file
@@ -0,0 +1,127 @@
|
||||
/****************************************************************************
|
||||
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 "primitive/Transform.h"
|
||||
|
||||
namespace cc {
|
||||
IGeometry translate(IGeometry &geometry, const ccstd::optional<Vec3> &offset) {
|
||||
const float x = offset.has_value() ? offset->x : 0;
|
||||
const float y = offset.has_value() ? offset->y : 0;
|
||||
const float z = offset.has_value() ? offset->z : 0;
|
||||
|
||||
const uint32_t nVertex = floor(geometry.positions.size() / 3);
|
||||
|
||||
for (uint32_t iVertex = 0; iVertex < nVertex; ++iVertex) {
|
||||
const uint32_t iX = iVertex * 3;
|
||||
const uint32_t iY = iVertex * 3 + 1;
|
||||
const uint32_t iZ = iVertex * 3 + 2;
|
||||
geometry.positions[iX] += x;
|
||||
geometry.positions[iY] += y;
|
||||
geometry.positions[iZ] += z;
|
||||
}
|
||||
|
||||
if (geometry.minPos.has_value()) {
|
||||
geometry.minPos->x += x;
|
||||
geometry.minPos->y += y;
|
||||
geometry.minPos->z += z;
|
||||
}
|
||||
|
||||
if (geometry.maxPos.has_value()) {
|
||||
geometry.maxPos->x += x;
|
||||
geometry.maxPos->y += y;
|
||||
geometry.maxPos->z += z;
|
||||
}
|
||||
|
||||
return geometry;
|
||||
}
|
||||
|
||||
IGeometry scale(IGeometry &geometry, const ccstd::optional<Vec3> &value) {
|
||||
const float x = value.has_value() ? value->x : 0;
|
||||
const float y = value.has_value() ? value->y : 0;
|
||||
const float z = value.has_value() ? value->z : 0;
|
||||
|
||||
const uint32_t nVertex = floor(geometry.positions.size() / 3);
|
||||
|
||||
for (uint32_t iVertex = 0; iVertex < nVertex; ++iVertex) {
|
||||
const uint32_t iX = iVertex * 3;
|
||||
const uint32_t iY = iVertex * 3 + 1;
|
||||
const uint32_t iZ = iVertex * 3 + 2;
|
||||
geometry.positions[iX] += x;
|
||||
geometry.positions[iY] += y;
|
||||
geometry.positions[iZ] += z;
|
||||
}
|
||||
|
||||
if (geometry.minPos.has_value()) {
|
||||
geometry.minPos->x += x;
|
||||
geometry.minPos->y += y;
|
||||
geometry.minPos->z += z;
|
||||
}
|
||||
|
||||
if (geometry.maxPos.has_value()) {
|
||||
geometry.maxPos->x += x;
|
||||
geometry.maxPos->y += y;
|
||||
geometry.maxPos->z += z;
|
||||
}
|
||||
geometry.boundingRadius = std::max(std::max(x, y), z);
|
||||
|
||||
return geometry;
|
||||
}
|
||||
|
||||
IGeometry wireframed(IGeometry &geometry) {
|
||||
const auto indices = geometry.indices;
|
||||
if (!indices.has_value()) {
|
||||
return geometry;
|
||||
}
|
||||
|
||||
// We only support triangles' wireframe.
|
||||
if (geometry.primitiveMode.has_value() && geometry.primitiveMode.value() != gfx::PrimitiveMode::TRIANGLE_LIST) {
|
||||
return geometry;
|
||||
}
|
||||
|
||||
// const offsets = [ [ 0, 1 ], [ 1, 2 ], [ 2, 0 ] ];
|
||||
ccstd::vector<ccstd::vector<uint32_t>> offsets{{0, 1}, {1, 2}, {2, 0}};
|
||||
ccstd::vector<uint32_t> lines;
|
||||
ccstd::unordered_map<uint32_t, uint32_t> lineIDs;
|
||||
for (uint32_t i = 0; i < indices->size(); i += 3) {
|
||||
for (uint32_t k = 0; k < 3; ++k) {
|
||||
const uint32_t i1 = (*indices)[i + offsets[k][0]];
|
||||
const uint32_t i2 = (*indices)[i + offsets[k][1]];
|
||||
|
||||
// check if we already have the line in our lines
|
||||
const uint32_t id = (i1 > i2) ? ((i2 << 16) | i1) : ((i1 << 16) | i2);
|
||||
if (lineIDs.find(id) == lineIDs.end()) {
|
||||
lineIDs[id] = 0;
|
||||
lines.emplace_back(i1);
|
||||
lines.emplace_back(i2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
geometry.indices = lines;
|
||||
geometry.primitiveMode = gfx::PrimitiveMode::LINE_LIST;
|
||||
|
||||
return geometry;
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
60
cocos/primitive/Transform.h
Normal file
60
cocos/primitive/Transform.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/****************************************************************************
|
||||
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 "primitive/PrimitiveDefine.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Translate the geometry.
|
||||
* @zh
|
||||
* 平移几何体。
|
||||
* @param geometry 几何体信息。
|
||||
* @param offset 偏移量。
|
||||
*/
|
||||
IGeometry translate(IGeometry &geometry, const ccstd::optional<Vec3> &offset);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Scale the geometry.
|
||||
* @zh
|
||||
* 缩放几何体。
|
||||
* @param geometry 几何体信息。
|
||||
* @param value 缩放量。
|
||||
*/
|
||||
IGeometry scale(IGeometry &geometry, const ccstd::optional<Vec3> &value);
|
||||
|
||||
/**
|
||||
* @en
|
||||
* Converts geometry to wireframe mode. Only geometry with triangle topology is supported.
|
||||
* @zh
|
||||
* 将几何体转换为线框模式,仅支持三角形拓扑的几何体。
|
||||
* @param geometry 几何体信息。
|
||||
*/
|
||||
IGeometry wireframed(IGeometry &geometry);
|
||||
|
||||
} // namespace cc
|
||||
Reference in New Issue
Block a user