载入中...
搜索中...
未找到
PrototypeKitPrimitives.cpp
浏览该文件的文档.
2
3#include <algorithm>
4#include <cmath>
5#include <cstdint>
6
8namespace {
9
10constexpr float kPi = 3.14159265358979323846f;
11
12uint32_t addVertex(MeshBuild& mesh, Vec3 p, Vec3 n, float u, float v) {
13 const auto index = static_cast<uint32_t>(mesh.getVertexCount());
14 mesh.addVertex(p.x, p.y, p.z, n.x, n.y, n.z, u, v);
15 return index;
16}
17
18struct UV {
19 float u;
20 float v;
21};
22
23UV projectUv(Vec3 p, Vec3 normal) {
24 const float ax = std::abs(normal.x);
25 const float ay = std::abs(normal.y);
26 const float az = std::abs(normal.z);
27 if (ay >= ax && ay >= az) return {p.x, p.z};
28 if (ax >= az) return {p.z, p.y};
29 return {p.x, p.y};
30}
31
32void addQuad(MeshBuild& mesh, Vec3 a, Vec3 b, Vec3 c, Vec3 d, Vec3 normal) {
33 const uint32_t base = static_cast<uint32_t>(mesh.getVertexCount());
34 const UV uvA = projectUv(a, normal);
35 const UV uvB = projectUv(b, normal);
36 const UV uvC = projectUv(c, normal);
37 const UV uvD = projectUv(d, normal);
38 addVertex(mesh, a, normal, uvA.u, uvA.v);
39 addVertex(mesh, b, normal, uvB.u, uvB.v);
40 addVertex(mesh, c, normal, uvC.u, uvC.v);
41 addVertex(mesh, d, normal, uvD.u, uvD.v);
42 mesh.addTriangle(base, base + 1, base + 2);
43 mesh.addTriangle(base, base + 2, base + 3);
44}
45
46Vec3 normalOf(Vec3 a, Vec3 b, Vec3 c) {
47 const Vec3 u{b.x - a.x, b.y - a.y, b.z - a.z};
48 const Vec3 v{c.x - a.x, c.y - a.y, c.z - a.z};
49 Vec3 n{u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x};
50 const float length = std::sqrt(n.x * n.x + n.y * n.y + n.z * n.z);
51 if (length > 1.0e-6f) {
52 n.x /= length;
53 n.y /= length;
54 n.z /= length;
55 }
56 return n;
57}
58
59} // namespace
60
61void addBox(MeshBuild& mesh, Vec3 center, Vec3 size, const char* group) {
62 mesh.setActiveGroup(group);
63 const float x0 = center.x - size.x * 0.5f;
64 const float x1 = center.x + size.x * 0.5f;
65 const float y0 = center.y - size.y * 0.5f;
66 const float y1 = center.y + size.y * 0.5f;
67 const float z0 = center.z - size.z * 0.5f;
68 const float z1 = center.z + size.z * 0.5f;
69 addQuad(mesh, {x0, y0, z1}, {x1, y0, z1}, {x1, y1, z1}, {x0, y1, z1}, {0, 0, 1});
70 addQuad(mesh, {x1, y0, z0}, {x0, y0, z0}, {x0, y1, z0}, {x1, y1, z0}, {0, 0, -1});
71 addQuad(mesh, {x0, y0, z0}, {x0, y0, z1}, {x0, y1, z1}, {x0, y1, z0}, {-1, 0, 0});
72 addQuad(mesh, {x1, y0, z1}, {x1, y0, z0}, {x1, y1, z0}, {x1, y1, z1}, {1, 0, 0});
73 addQuad(mesh, {x0, y1, z1}, {x1, y1, z1}, {x1, y1, z0}, {x0, y1, z0}, {0, 1, 0});
74 addQuad(mesh, {x0, y0, z0}, {x1, y0, z0}, {x1, y0, z1}, {x0, y0, z1}, {0, -1, 0});
75}
76
77void addWedge(MeshBuild& mesh, Vec3 center, Vec3 size, bool riseAlongX, const char* group) {
78 mesh.setActiveGroup(group);
79 const float x0 = center.x - size.x * 0.5f;
80 const float x1 = center.x + size.x * 0.5f;
81 const float y0 = center.y - size.y * 0.5f;
82 const float y1 = center.y + size.y * 0.5f;
83 const float z0 = center.z - size.z * 0.5f;
84 const float z1 = center.z + size.z * 0.5f;
85 Vec3 a{x0, y0, z0}, b{x1, y0, z0}, c{x1, y1, z0};
86 Vec3 d{x0, y0, z1}, e{x1, y0, z1}, f{x1, y1, z1};
87 if (!riseAlongX) {
88 a = {x1, y0, z0};
89 b = {x1, y0, z1};
90 c = {x1, y1, z1};
91 d = {x0, y0, z0};
92 e = {x0, y0, z1};
93 f = {x0, y1, z1};
94 }
95 const uint32_t first = static_cast<uint32_t>(mesh.getVertexCount());
96 const Vec3 n0 = normalOf(a, c, b);
97 const UV uvA = projectUv(a, n0);
98 const UV uvC = projectUv(c, n0);
99 const UV uvB = projectUv(b, n0);
100 addVertex(mesh, a, n0, uvA.u, uvA.v);
101 addVertex(mesh, c, n0, uvC.u, uvC.v);
102 addVertex(mesh, b, n0, uvB.u, uvB.v);
103 mesh.addTriangle(first, first + 1, first + 2);
104 const uint32_t second = static_cast<uint32_t>(mesh.getVertexCount());
105 const Vec3 n1 = normalOf(d, e, f);
106 const UV uvD = projectUv(d, n1);
107 const UV uvE = projectUv(e, n1);
108 const UV uvF = projectUv(f, n1);
109 addVertex(mesh, d, n1, uvD.u, uvD.v);
110 addVertex(mesh, e, n1, uvE.u, uvE.v);
111 addVertex(mesh, f, n1, uvF.u, uvF.v);
112 mesh.addTriangle(second, second + 1, second + 2);
113 addQuad(mesh, a, b, e, d, {0, -1, 0});
114 const Vec3 slopeNormal = normalOf(a, d, f);
115 addQuad(mesh, a, d, f, c, slopeNormal);
116 const Vec3 highNormal = normalOf(b, c, f);
117 addQuad(mesh, b, c, f, e, highNormal);
118}
119
120void addCylinder(MeshBuild& mesh, Vec3 center, float radiusBottom, float radiusTop, float height, int sides,
121 const char* group) {
122 mesh.setActiveGroup(group);
123 sides = std::clamp(sides, 3, 64);
124 const float y0 = center.y - height * 0.5f;
125 const float y1 = center.y + height * 0.5f;
126 const float radius = (radiusBottom + radiusTop) * 0.5f;
127 for (int i = 0; i < sides; ++i) {
128 const float a0 = 2.0f * kPi * float(i) / float(sides);
129 const float a1 = 2.0f * kPi * float(i + 1) / float(sides);
130 const Vec3 p0{center.x + std::cos(a0) * radiusBottom, y0, center.z + std::sin(a0) * radiusBottom};
131 const Vec3 p1{center.x + std::cos(a1) * radiusBottom, y0, center.z + std::sin(a1) * radiusBottom};
132 const Vec3 p2{center.x + std::cos(a1) * radiusTop, y1, center.z + std::sin(a1) * radiusTop};
133 const Vec3 p3{center.x + std::cos(a0) * radiusTop, y1, center.z + std::sin(a0) * radiusTop};
134 const Vec3 normal = normalOf(p0, p2, p1);
135 const uint32_t side = static_cast<uint32_t>(mesh.getVertexCount());
136 addVertex(mesh, p0, normal, a0 * radius, y0);
137 addVertex(mesh, p1, normal, a1 * radius, y0);
138 addVertex(mesh, p2, normal, a1 * radius, y1);
139 addVertex(mesh, p3, normal, a0 * radius, y1);
140 mesh.addTriangle(side, side + 2, side + 1);
141 mesh.addTriangle(side, side + 3, side + 2);
142 const uint32_t bottom = static_cast<uint32_t>(mesh.getVertexCount());
143 addVertex(mesh, {center.x, y0, center.z}, {0, -1, 0}, center.x, center.z);
144 addVertex(mesh, p1, {0, -1, 0}, p1.x, p1.z);
145 addVertex(mesh, p0, {0, -1, 0}, p0.x, p0.z);
146 mesh.addTriangle(bottom, bottom + 2, bottom + 1);
147 const uint32_t top = static_cast<uint32_t>(mesh.getVertexCount());
148 addVertex(mesh, {center.x, y1, center.z}, {0, 1, 0}, center.x, center.z);
149 addVertex(mesh, p3, {0, 1, 0}, p3.x, p3.z);
150 addVertex(mesh, p2, {0, 1, 0}, p2.x, p2.z);
151 mesh.addTriangle(top, top + 2, top + 1);
152 }
153}
154
155void addSphere(MeshBuild& mesh, Vec3 center, Vec3 radii, int rings, int sides, const char* group) {
156 mesh.setActiveGroup(group);
157 rings = std::clamp(rings, 2, 32);
158 sides = std::clamp(sides, 3, 64);
159 const uint32_t base = static_cast<uint32_t>(mesh.getVertexCount());
160 for (int ring = 0; ring <= rings; ++ring) {
161 const float v = float(ring) / float(rings);
162 const float phi = v * kPi;
163 for (int side = 0; side <= sides; ++side) {
164 const float u = float(side) / float(sides);
165 const float theta = u * 2.0f * kPi;
166 const Vec3 n{std::sin(phi) * std::cos(theta), std::cos(phi), std::sin(phi) * std::sin(theta)};
167 const float horizontalRadius = (radii.x + radii.z) * 0.5f;
168 addVertex(mesh, {center.x + n.x * radii.x, center.y + n.y * radii.y, center.z + n.z * radii.z}, n,
169 theta * horizontalRadius, phi * radii.y);
170 }
171 }
172 for (int ring = 0; ring < rings; ++ring) {
173 for (int side = 0; side < sides; ++side) {
174 const uint32_t a = base + uint32_t(ring * (sides + 1) + side);
175 const uint32_t b = a + uint32_t(sides + 1);
176 mesh.addTriangle(a, a + 1, b);
177 mesh.addTriangle(a + 1, b + 1, b);
178 }
179 }
180}
181
182void addTorus(MeshBuild& mesh, Vec3 center, float majorRadius, float minorRadius, int majorSegments, int minorSegments,
183 const char* group) {
184 mesh.setActiveGroup(group);
185 majorSegments = std::clamp(majorSegments, 3, 64);
186 minorSegments = std::clamp(minorSegments, 3, 32);
187 const uint32_t base = static_cast<uint32_t>(mesh.getVertexCount());
188 for (int major = 0; major <= majorSegments; ++major) {
189 const float u = float(major) / float(majorSegments);
190 const float a = 2.0f * kPi * u;
191 for (int minor = 0; minor <= minorSegments; ++minor) {
192 const float v = float(minor) / float(minorSegments);
193 const float b = 2.0f * kPi * v;
194 const Vec3 n{std::cos(a) * std::cos(b), std::sin(b), std::sin(a) * std::cos(b)};
195 const float radial = majorRadius + minorRadius * std::cos(b);
196 addVertex(mesh,
197 {center.x + radial * std::cos(a), center.y + minorRadius * std::sin(b),
198 center.z + radial * std::sin(a)},
199 n, a * majorRadius, b * minorRadius);
200 }
201 }
202 for (int major = 0; major < majorSegments; ++major) {
203 for (int minor = 0; minor < minorSegments; ++minor) {
204 const uint32_t a = base + uint32_t(major * (minorSegments + 1) + minor);
205 const uint32_t b = a + uint32_t(minorSegments + 1);
206 mesh.addTriangle(a, a + 1, b);
207 mesh.addTriangle(a + 1, b + 1, b);
208 }
209 }
210}
211
212} // namespace eve::procgen::prototype_detail
SQInteger top
building::EdgeCurveGroup group
int ax
Definition CaveMesh.cpp:113
int ay
Definition CaveMesh.cpp:113
float length
Definition CaveMesh.cpp:94
int az
Definition CaveMesh.cpp:113
Vec3 radii
Definition CaveMesh.cpp:56
glm::vec4 p[6]
float u
Definition Grass.cpp:233
glm::vec3 n
Definition Grass.cpp:63
float v
std::int32_t second
std::int32_t c
std::int32_t first
std::uint32_t height
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
Texture * normal
float f
float radius
float d
Mesh * mesh
ecs::EntityHandle side
int sides
Definition TreeMesh.cpp:322
float size
Definition TreeMesh.cpp:156
uint32_t index
std::vector< double > phi
float bottom
CPU triangle mesh from procedural mesh recipes (e.g. marching cubes). Positions/normals are xyz-packe...
Definition MeshBuild.h:19
void addWedge(MeshBuild &mesh, Vec3 center, Vec3 size, bool riseAlongX, const char *group)
Adds wedge.
void addTorus(MeshBuild &mesh, Vec3 center, float majorRadius, float minorRadius, int majorSegments, int minorSegments, const char *group)
Adds torus.
void addCylinder(MeshBuild &mesh, Vec3 center, float radiusBottom, float radiusTop, float height, int sides, const char *group)
Adds cylinder.
void addBox(MeshBuild &mesh, Vec3 center, Vec3 size, const char *group)
Adds box.
void addSphere(MeshBuild &mesh, Vec3 center, Vec3 radii, int rings, int sides, const char *group)
Adds sphere.