Compare commits

...

2 Commits

Author SHA1 Message Date
bjorn dc9e93103f Pass:sphere; 2022-06-23 21:23:16 -07:00
bjorn dc73d2309a Pass:donut; 2022-06-23 19:52:37 -07:00
4 changed files with 152 additions and 5 deletions

View File

@ -517,6 +517,26 @@ static int l_lovrPassCircle(lua_State* L) {
return 0;
}
static int l_lovrPassSphere(lua_State* L) {
Pass* pass = luax_checktype(L, 1, Pass);
float transform[16];
int index = luax_readmat4(L, 2, transform, 1);
uint32_t segmentsH = luax_optu32(L, index++, 48);
uint32_t segmentsV = luax_optu32(L, index++, segmentsH / 2);
lovrPassSphere(pass, transform, segmentsH, segmentsV);
return 0;
}
static int l_lovrPassTorus(lua_State* L) {
Pass* pass = luax_checktype(L, 1, Pass);
float transform[16];
int index = luax_readmat4(L, 2, transform, -2);
uint32_t segmentsT = luax_optu32(L, index++, 64);
uint32_t segmentsP = luax_optu32(L, index++, 32);
lovrPassTorus(pass, transform, segmentsT, segmentsP);
return 0;
}
static int l_lovrPassText(lua_State* L) {
Pass* pass = luax_checktype(L, 1, Pass);
Font* font = luax_totype(L, 2, Font);
@ -779,6 +799,8 @@ const luaL_Reg lovrPass[] = {
{ "cube", l_lovrPassCube },
{ "box", l_lovrPassBox },
{ "circle", l_lovrPassCircle },
{ "sphere", l_lovrPassSphere },
{ "torus", l_lovrPassTorus },
{ "text", l_lovrPassText },
{ "mesh", l_lovrPassMesh },
{ "multimesh", l_lovrPassMultimesh },

View File

@ -70,6 +70,9 @@ int luax_readscale(lua_State* L, int index, vec3 v, int components, const char*
case LUA_TNUMBER:
if (components == 1) {
v[0] = v[1] = v[2] = luax_optfloat(L, index++, 0.f);
} else if (components == -2) { // -2 is special and means "2 components: xy and z"
v[0] = v[1] = luax_tofloat(L, index++);
v[2] = luax_optfloat(L, index++, 1.f);
} else {
v[0] = 1.f;
for (int i = 0; i < components; i++) {

View File

@ -2882,14 +2882,14 @@ void lovrPassBox(Pass* pass, float* transform, DrawStyle style) {
}
void lovrPassCircle(Pass* pass, float* transform, DrawStyle style, float angle1, float angle2, uint32_t segments) {
ShapeVertex* vertices;
uint16_t* indices;
if (fabsf(angle1 - angle2) >= 2.f * (float) M_PI) {
angle1 = 0.f;
angle2 = 2.f * (float) M_PI;
}
ShapeVertex* vertices;
uint16_t* indices;
if (style == STYLE_LINE) {
uint32_t vertexCount = segments + 1;
uint32_t indexCount = segments * 2;
@ -2922,8 +2922,8 @@ void lovrPassCircle(Pass* pass, float* transform, DrawStyle style, float angle1,
float angleShift = (angle2 - angle1) / segments;
for (uint32_t i = 0; i <= segments; i++) {
float theta = angle1 + i * angleShift;
float x = cosf(theta) * .5f;
float y = sinf(theta) * .5f;
float x = cosf(theta);
float y = sinf(theta);
*vertices++ = (ShapeVertex) { { x, y, 0.f }, { 0.f, 0.f, 1.f }, { x + .5f, .5f - y } };
}
@ -2942,6 +2942,126 @@ void lovrPassCircle(Pass* pass, float* transform, DrawStyle style, float angle1,
}
}
void lovrPassSphere(Pass* pass, float* transform, uint32_t segmentsH, uint32_t segmentsV) {
uint32_t vertexCount = 2 + (segmentsH + 1) * (segmentsV - 1);
uint32_t indexCount = 2 * 3 * segmentsH + segmentsH * (segmentsV - 2) * 6;
ShapeVertex* vertices;
uint16_t* indices;
lovrPassDraw(pass, &(Draw) {
.mode = VERTEX_TRIANGLES,
.transform = transform,
.vertex.pointer = (void**) &vertices,
.vertex.count = vertexCount,
.index.pointer = (void**) &indices,
.index.count = indexCount
});
// Top
*vertices++ = (ShapeVertex) { { 0.f, 1.f, 0.f }, { 0.f, 1.f, 0.f }, { .5f, 0.f } };
// Rings
for (uint32_t i = 1; i < segmentsV; i++) {
float v = i / (float) segmentsV;
float phi = v * (float) M_PI;
float sinphi = sinf(phi);
float cosphi = cosf(phi);
for (uint32_t j = 0; j <= segmentsH; j++) {
float u = j / (float) segmentsH;
float theta = u * 2.f * (float) M_PI;
float sintheta = sinf(theta);
float costheta = cosf(theta);
float x = sintheta * sinphi;
float y = cosphi;
float z = -costheta * sinphi;
*vertices++ = (ShapeVertex) { { x, y, z }, { x, y, z }, { u, v } };
}
}
// Bottom
*vertices++ = (ShapeVertex) { { 0.f, -1.f, 0.f }, { 0.f, -1.f, 0.f }, { .5f, 1.f } };
// Top
for (uint32_t i = 0; i < segmentsH; i++) {
uint16_t wedge[] = { 0, i + 2, i + 1 };
memcpy(indices, wedge, sizeof(wedge));
indices += COUNTOF(wedge);
}
// Rings
for (uint32_t i = 0; i < segmentsV - 2; i++) {
for (uint32_t j = 0; j < segmentsH; j++) {
uint16_t a = 1 + i * (segmentsH + 1) + 0 + j;
uint16_t b = 1 + i * (segmentsH + 1) + 1 + j;
uint16_t c = 1 + i * (segmentsH + 1) + 0 + segmentsH + 1 + j;
uint16_t d = 1 + i * (segmentsH + 1) + 1 + segmentsH + 1 + j;
uint16_t quad[] = { a, b, c, c, b, d };
memcpy(indices, quad, sizeof(quad));
indices += COUNTOF(quad);
}
}
// Bottom
for (uint32_t i = 0; i < segmentsH; i++) {
uint16_t wedge[] = { vertexCount - 1, vertexCount - 1 - (i + 2), vertexCount - 1 - (i + 1) };
memcpy(indices, wedge, sizeof(wedge));
indices += COUNTOF(wedge);
}
}
void lovrPassTorus(Pass* pass, float* transform, uint32_t segmentsT, uint32_t segmentsP) {
float sx = vec3_length(transform + 0);
float sy = vec3_length(transform + 4);
float sz = vec3_length(transform + 8);
vec3_scale(transform + 0, 1.f / sx);
vec3_scale(transform + 4, 1.f / sy);
vec3_scale(transform + 8, 1.f / sz);
float radius = sx * .5f;
float thickness = sz * .5f;
uint32_t vertexCount = segmentsT * segmentsP;
uint32_t indexCount = segmentsT * segmentsP * 6;
ShapeVertex* vertices;
uint16_t* indices;
lovrPassDraw(pass, &(Draw) {
.mode = VERTEX_TRIANGLES,
.transform = transform,
.vertex.pointer = (void**) &vertices,
.vertex.count = vertexCount,
.index.pointer = (void**) &indices,
.index.count = indexCount
});
// T and P stand for toroidal and poloidal, or theta and phi
float dt = (2.f * (float) M_PI) / segmentsT;
float dp = (2.f * (float) M_PI) / segmentsP;
for (uint32_t t = 0; t < segmentsT; t++) {
float theta = t * dt;
float tx = cosf(theta);
float ty = sinf(theta);
for (uint32_t p = 0; p < segmentsP; p++) {
float phi = p * dp;
float nx = cosf(phi) * tx;
float ny = cosf(phi) * ty;
float nz = sinf(phi);
*vertices++ = (ShapeVertex) {
.position = { tx * radius + nx * thickness, ty * radius + ny * thickness, nz * thickness },
.normal = { nx, ny, nz }
};
uint16_t a = (t + 0) * segmentsP + p;
uint16_t b = (t + 1) % segmentsT * segmentsP + p;
uint16_t c = (t + 0) * segmentsP + (p + 1) % segmentsP;
uint16_t d = (t + 1) % segmentsT * segmentsP + (p + 1) % segmentsP;
uint16_t quad[] = { a, b, c, b, c, d };
memcpy(indices, quad, sizeof(quad));
indices += COUNTOF(quad);
}
}
}
void lovrPassText(Pass* pass, Font* font, const char* text, uint32_t length, float* transform, float wrap, HorizontalAlign halign, VerticalAlign valign) {
if (!font) {
font = lovrGraphicsGetDefaultFont();

View File

@ -478,6 +478,8 @@ void lovrPassLine(Pass* pass, uint32_t count, float** vertices);
void lovrPassPlane(Pass* pass, float* transform, DrawStyle style, uint32_t cols, uint32_t rows);
void lovrPassBox(Pass* pass, float* transform, DrawStyle style);
void lovrPassCircle(Pass* pass, float* transform, DrawStyle style, float angle1, float angle2, uint32_t segments);
void lovrPassSphere(Pass* pass, float* transform, uint32_t segmentsH, uint32_t segmentsV);
void lovrPassTorus(Pass* pass, float* transform, uint32_t segmentsT, uint32_t segmentsP);
void lovrPassText(Pass* pass, Font* font, const char* text, uint32_t length, float* transform, float wrap, HorizontalAlign halign, VerticalAlign valign);
void lovrPassMesh(Pass* pass, Buffer* vertices, Buffer* indices, float* transform, uint32_t start, uint32_t count, uint32_t instances);
void lovrPassMultimesh(Pass* pass, Buffer* vertices, Buffer* indices, Buffer* indirect, uint32_t count, uint32_t offset, uint32_t stride);