utility functions
This commit is contained in:
@@ -102,6 +102,16 @@ Vec4 BBox::max() const {
|
||||
return _max;
|
||||
}
|
||||
|
||||
BBox BBox::create(const Vec4& center, const float& size) {
|
||||
auto core = CoreBBox::create(center, size);
|
||||
return BBox(core.vertices);
|
||||
}
|
||||
|
||||
void BBox::operator=(const BBox& v) {
|
||||
for (auto i = 0; i < 8; i++) Vec4::copy(&vertices[i], v.vertices[i].xyzw);
|
||||
setData();
|
||||
}
|
||||
|
||||
void BBox::getMinMax(Vec4* res_min, Vec4* res_max) const {
|
||||
Vec4 temp = Vec4();
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ void McpipClip::initStaticPacket() {
|
||||
void McpipClip::addData(McpipBlock* block, const bool& isMulti,
|
||||
RendererCoreTextureBuffers* texBuffers,
|
||||
packet2_t* packet, const u8& context) {
|
||||
std::vector<EEClipVertex> clippedVertices;
|
||||
std::vector<PlanesClipVertex> clippedVertices;
|
||||
auto mvp = rendererCore->renderer3D.getViewProj() * (*block->model);
|
||||
|
||||
const auto* blockData = isMulti ? multiBlockData : singleBlockData;
|
||||
@@ -92,7 +92,7 @@ void McpipClip::addData(McpipBlock* block, const bool& isMulti,
|
||||
addDataToPacket(packet, context, block, clippedVertices.size(), texBuffers);
|
||||
}
|
||||
|
||||
void McpipClip::addCorrections(std::vector<EEClipVertex>* vertices,
|
||||
void McpipClip::addCorrections(std::vector<PlanesClipVertex>* vertices,
|
||||
McpipBlock* block) {
|
||||
for (u32 i = 0; i < vertices->size(); i++) {
|
||||
(*vertices)[i].position /= (*vertices)[i].position.w; // Perspective divide
|
||||
@@ -100,7 +100,7 @@ void McpipClip::addCorrections(std::vector<EEClipVertex>* vertices,
|
||||
}
|
||||
}
|
||||
|
||||
void McpipClip::moveDataToBuffer(std::vector<EEClipVertex>* vertices,
|
||||
void McpipClip::moveDataToBuffer(std::vector<PlanesClipVertex>* vertices,
|
||||
const u8& context) {
|
||||
for (u32 i = 0; i < vertices->size(); i++) {
|
||||
vertexBuffers[context][i].set(vertices->at(i).position);
|
||||
|
||||
@@ -31,7 +31,7 @@ void StaPipClipper::clip(StaPipQBuffer* buffer) {
|
||||
buffer->bag->texture != nullptr,
|
||||
buffer->bag->color->many != nullptr};
|
||||
|
||||
std::vector<EEClipVertex> clippedVertices;
|
||||
std::vector<PlanesClipVertex> clippedVertices;
|
||||
|
||||
for (u32 i = 0; i < buffer->size / 3; i++) {
|
||||
for (u8 j = 0; j < 3; j++) {
|
||||
@@ -63,14 +63,14 @@ void StaPipClipper::clip(StaPipQBuffer* buffer) {
|
||||
moveDataToBuffer(clippedVertices, buffer);
|
||||
}
|
||||
|
||||
void StaPipClipper::perspectiveDivide(std::vector<EEClipVertex>* vertices) {
|
||||
void StaPipClipper::perspectiveDivide(std::vector<PlanesClipVertex>* vertices) {
|
||||
for (u32 i = 0; i < vertices->size(); i++) {
|
||||
(*vertices)[i].position /= (*vertices)[i].position.w;
|
||||
}
|
||||
}
|
||||
|
||||
void StaPipClipper::moveDataToBuffer(const std::vector<EEClipVertex>& vertices,
|
||||
StaPipQBuffer* buffer) {
|
||||
void StaPipClipper::moveDataToBuffer(
|
||||
const std::vector<PlanesClipVertex>& vertices, StaPipQBuffer* buffer) {
|
||||
buffer->reallocateManually(vertices.size());
|
||||
|
||||
for (u32 i = 0; i < vertices.size(); i++) {
|
||||
|
||||
@@ -23,83 +23,85 @@ Renderer3DUtility::Renderer3DUtility() {}
|
||||
|
||||
Renderer3DUtility::~Renderer3DUtility() {}
|
||||
|
||||
#define TYRA_UTILS_LINE_REGLIST \
|
||||
((u64)GIF_REG_XYZ2) << 0 | ((u64)GIF_REG_XYZ2) << 4
|
||||
|
||||
void Renderer3DUtility::init(RendererCore* t_core) {
|
||||
core = t_core;
|
||||
|
||||
basePrim.type = PRIM_LINE;
|
||||
basePrim.shading = PRIM_SHADE_FLAT;
|
||||
basePrim.mapping = DRAW_DISABLE;
|
||||
basePrim.fogging = DRAW_DISABLE;
|
||||
basePrim.blending = DRAW_DISABLE;
|
||||
basePrim.antialiasing = DRAW_DISABLE;
|
||||
basePrim.mapping_type = PRIM_MAP_ST;
|
||||
basePrim.colorfix = PRIM_UNFIXED;
|
||||
prim.type = PRIM_LINE;
|
||||
prim.shading = PRIM_SHADE_FLAT;
|
||||
prim.mapping = DRAW_DISABLE;
|
||||
prim.fogging = DRAW_DISABLE;
|
||||
prim.blending = DRAW_DISABLE;
|
||||
prim.antialiasing = DRAW_ENABLE;
|
||||
prim.mapping_type = PRIM_MAP_ST;
|
||||
prim.colorfix = PRIM_UNFIXED;
|
||||
|
||||
baseColor.r = 0x80;
|
||||
baseColor.g = 0x80;
|
||||
baseColor.b = 0x80;
|
||||
baseColor.a = 0x80;
|
||||
baseColor.q = 1.0F;
|
||||
const auto& settings = core->getSettings();
|
||||
planesClipAlgorithm.init(settings);
|
||||
}
|
||||
|
||||
void Renderer3DUtility::drawPoint(const Vec4& v) {
|
||||
drawPoint(v, Color(128.0F, 0.0F, 0.0F, 128.0F));
|
||||
void Renderer3DUtility::drawBox(const Vec4& v, const float& size) {
|
||||
drawBox(v, size, Color(192.0F, 32.0F, 32.0F, 128.0F));
|
||||
}
|
||||
|
||||
void Renderer3DUtility::drawLine(const Vec4& from, const Vec4& to) {
|
||||
drawLine(from, to, Color(255.0F, 32.0F, 32.0F, 128.0F));
|
||||
drawLine(from, to, Color(192.0F, 32.0F, 32.0F, 128.0F));
|
||||
}
|
||||
|
||||
void Renderer3DUtility::drawBBox(const CoreBBox& v) {
|
||||
drawBBox(v, Color(255.0F, 32.0F, 32.0F, 128.0F));
|
||||
drawBBox(v, Color(192.0F, 32.0F, 32.0F, 128.0F));
|
||||
}
|
||||
|
||||
void Renderer3DUtility::drawPoint(const Vec4& v, const Color& color) {
|
||||
// TODO
|
||||
void Renderer3DUtility::drawBox(const Vec4& v, const float& size,
|
||||
const Color& color) {
|
||||
auto bbox = CoreBBox::create(v, size);
|
||||
drawBBox(bbox, color);
|
||||
}
|
||||
|
||||
void Renderer3DUtility::drawLine(const Vec4& from, const Vec4& to,
|
||||
const Color& color) {
|
||||
const u16 packetSize = 20;
|
||||
auto* packet = packet2_create(20, P2_TYPE_NORMAL, P2_MODE_CHAIN, false);
|
||||
const u8 vertCount = 2;
|
||||
const s8 thickness = 2;
|
||||
s16 packetSize = 8 * thickness;
|
||||
prim.type = PRIM_LINE;
|
||||
auto gsColor = getGSColor(color);
|
||||
|
||||
auto mvp = core->renderer3D.getViewProj();
|
||||
std::array<Vec4, 2> inputVerts;
|
||||
std::array<color_f_t, 2> inputColors;
|
||||
inputVerts[0] = mvp * from;
|
||||
inputVerts[1] = mvp * to;
|
||||
inputColors[0] = {color.r, color.g, color.b, color.a};
|
||||
inputColors[1] = {color.r, color.g, color.b, color.a};
|
||||
auto* packet =
|
||||
packet2_create(packetSize, P2_TYPE_NORMAL, P2_MODE_CHAIN, false);
|
||||
|
||||
std::array<xyz_t, 2> outputVerts;
|
||||
std::array<color_t, 2> outputColors;
|
||||
std::array<Vec4, vertCount> inputVerts;
|
||||
inputVerts[0] = from;
|
||||
inputVerts[1] = to;
|
||||
|
||||
draw_convert_xyz(outputVerts.data(), 2048, 2048,
|
||||
static_cast<int>(0xFFFFFF / 32.0F), 2,
|
||||
reinterpret_cast<vertex_f_t*>(inputVerts.data()));
|
||||
draw_convert_rgbq(outputColors.data(), 2,
|
||||
reinterpret_cast<vertex_f_t*>(inputVerts.data()),
|
||||
inputColors.data(), 0x80);
|
||||
std::array<xyz_t, vertCount> outputVerts;
|
||||
|
||||
packet2_chain_open_end(packet, 0, 0);
|
||||
packet2_update(packet, draw_prim_start(packet->next, 0, &prim, &gsColor));
|
||||
|
||||
basePrim.type = PRIM_LINE;
|
||||
for (s8 i = 0; i < thickness; i++) {
|
||||
auto draw =
|
||||
calcLineVertices(outputVerts.data(), inputVerts[0], inputVerts[1], i);
|
||||
|
||||
if (!draw) {
|
||||
packet2_free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
packet2_add_u64(packet, outputVerts[0].xyz);
|
||||
packet2_add_u64(packet, outputVerts[1].xyz);
|
||||
}
|
||||
|
||||
packet2_pad128(packet, 0);
|
||||
|
||||
packet2_update(packet,
|
||||
draw_prim_start(packet->next, 0, &basePrim, &baseColor));
|
||||
for (auto i = 0; i < 2; i++) {
|
||||
packet2_add_u64(packet, outputColors[i].rgbaq);
|
||||
packet2_add_u64(packet, outputVerts[i].xyz);
|
||||
}
|
||||
packet2_update(packet, draw_prim_end(packet->next, 2, DRAW_RGBAQ_REGLIST));
|
||||
draw_prim_end(packet->next, 2, TYRA_UTILS_LINE_REGLIST));
|
||||
|
||||
packet2_update(packet, draw_finish(packet->next));
|
||||
|
||||
packet2_chain_close_tag(packet);
|
||||
|
||||
TYRA_ASSERT(packet2_get_qw_count(packet) < packetSize,
|
||||
"To small packet size!");
|
||||
|
||||
dma_channel_wait(DMA_CHANNEL_GIF, 0);
|
||||
dma_channel_send_packet2(packet, DMA_CHANNEL_GIF, true);
|
||||
dma_channel_wait(DMA_CHANNEL_GIF, 0);
|
||||
@@ -108,7 +110,189 @@ void Renderer3DUtility::drawLine(const Vec4& from, const Vec4& to,
|
||||
}
|
||||
|
||||
void Renderer3DUtility::drawBBox(const CoreBBox& v, const Color& color) {
|
||||
// TODO
|
||||
const u8 stripsCount = 6;
|
||||
const u8 vertCount = 4;
|
||||
const s8 thickness = 2;
|
||||
s16 packetSize = 150 * thickness;
|
||||
prim.type = PRIM_LINE;
|
||||
auto gsColor = getGSColor(color);
|
||||
|
||||
auto* packet =
|
||||
packet2_create(packetSize, P2_TYPE_NORMAL, P2_MODE_CHAIN, false);
|
||||
|
||||
std::array<std::array<Vec4, vertCount>, stripsCount> inputVerts;
|
||||
fillBBoxVertices(inputVerts, v);
|
||||
|
||||
packet2_chain_open_end(packet, 0, 0);
|
||||
|
||||
bool drawedSomething = false;
|
||||
|
||||
for (s8 i = 0; i < thickness; i++) {
|
||||
for (s8 j = 0; j < stripsCount; j++) {
|
||||
for (s8 k = 0; k < vertCount; k++) {
|
||||
auto index1 = k;
|
||||
auto index2 = (k + 1) % vertCount;
|
||||
|
||||
std::array<xyz_t, 2> outputVerts;
|
||||
auto draw = calcLineVertices(outputVerts.data(), inputVerts[j][index1],
|
||||
inputVerts[j][index2], i);
|
||||
|
||||
if (!draw) {
|
||||
continue;
|
||||
}
|
||||
|
||||
drawedSomething = true;
|
||||
|
||||
packet2_update(packet,
|
||||
draw_prim_start(packet->next, 0, &prim, &gsColor));
|
||||
|
||||
packet2_add_u64(packet, outputVerts[0].xyz);
|
||||
packet2_add_u64(packet, outputVerts[1].xyz);
|
||||
|
||||
packet2_update(packet,
|
||||
draw_prim_end(packet->next, 2, TYRA_UTILS_LINE_REGLIST));
|
||||
|
||||
packet2_pad128(packet, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!drawedSomething) {
|
||||
packet2_free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
packet2_update(packet, draw_finish(packet->next));
|
||||
|
||||
packet2_chain_close_tag(packet);
|
||||
|
||||
dma_channel_wait(DMA_CHANNEL_GIF, 0);
|
||||
dma_channel_send_packet2(packet, DMA_CHANNEL_GIF, true);
|
||||
dma_channel_wait(DMA_CHANNEL_GIF, 0);
|
||||
|
||||
packet2_free(packet);
|
||||
}
|
||||
|
||||
void Renderer3DUtility::fillBBoxVertices(std::array<std::array<Vec4, 4>, 6>& v,
|
||||
const CoreBBox& bbox) {
|
||||
// Up
|
||||
/**
|
||||
* 2 - lowX, hiY, lowZ
|
||||
* 3 - lowX, hiY, hiZ
|
||||
* 7 - hiX, hiY, hiZ
|
||||
* 6 - hiX, hiY, lowZ
|
||||
*/
|
||||
v[1][0] = bbox.vertices[2];
|
||||
v[1][1] = bbox.vertices[3];
|
||||
v[1][2] = bbox.vertices[7];
|
||||
v[1][3] = bbox.vertices[6];
|
||||
|
||||
// Down
|
||||
/**
|
||||
* 0 - lowX, lowY, lowZ
|
||||
* 1 - lowX, lowY, hiZ
|
||||
* 5 - hiX, lowY, hiZ
|
||||
* 4 - hiX, lowY, lowZ
|
||||
*/
|
||||
v[0][0] = bbox.vertices[0];
|
||||
v[0][1] = bbox.vertices[1];
|
||||
v[0][2] = bbox.vertices[5];
|
||||
v[0][3] = bbox.vertices[4];
|
||||
|
||||
// Near
|
||||
/**
|
||||
* 0 - lowX, lowY, lowZ
|
||||
* 2 - lowX, hiY, lowZ
|
||||
* 6 - hiX, hiY, lowZ
|
||||
* 4 - hiX, lowY, lowZ
|
||||
*/
|
||||
v[2][0] = bbox.vertices[0];
|
||||
v[2][1] = bbox.vertices[2];
|
||||
v[2][2] = bbox.vertices[6];
|
||||
v[2][3] = bbox.vertices[4];
|
||||
|
||||
// Far
|
||||
/**
|
||||
* 1 - lowX, lowY, hiZ
|
||||
* 3 - lowX, hiY, hiZ
|
||||
* 7 - hiX, hiY, hiZ
|
||||
* 5 - hiX, lowY, hiZ
|
||||
*/
|
||||
v[3][0] = bbox.vertices[1];
|
||||
v[3][1] = bbox.vertices[3];
|
||||
v[3][2] = bbox.vertices[7];
|
||||
v[3][3] = bbox.vertices[5];
|
||||
|
||||
// Left
|
||||
/**
|
||||
* 0 - lowX, lowY, lowZ
|
||||
* 1 - lowX, lowY, hiZ
|
||||
* 3 - lowX, hiY, hiZ
|
||||
* 2 - lowX, hiY, lowZ
|
||||
*/
|
||||
v[4][0] = bbox.vertices[0];
|
||||
v[4][1] = bbox.vertices[1];
|
||||
v[4][2] = bbox.vertices[3];
|
||||
v[4][3] = bbox.vertices[2];
|
||||
|
||||
// Right
|
||||
/**
|
||||
* 4 - hiX, lowY, lowZ
|
||||
* 5 - hiX, lowY, hiZ
|
||||
* 7 - hiX, hiY, hiZ
|
||||
* 6 - hiX, hiY, lowZ
|
||||
*/
|
||||
v[5][0] = bbox.vertices[4];
|
||||
v[5][1] = bbox.vertices[5];
|
||||
v[5][2] = bbox.vertices[7];
|
||||
v[5][3] = bbox.vertices[6];
|
||||
}
|
||||
|
||||
color_t Renderer3DUtility::getGSColor(const Color& color) {
|
||||
color_t gsColor;
|
||||
gsColor.r = static_cast<u8>(color.r);
|
||||
gsColor.g = static_cast<u8>(color.g);
|
||||
gsColor.b = static_cast<u8>(color.b);
|
||||
gsColor.a = static_cast<u8>(color.a);
|
||||
return gsColor;
|
||||
}
|
||||
|
||||
bool Renderer3DUtility::calcLineVertices(xyz_t* outputArray, const Vec4& a,
|
||||
const Vec4& b,
|
||||
const u8& displayOffset) {
|
||||
const auto& mvp = core->renderer3D.getViewProj();
|
||||
Vec4 tmpA = mvp * a;
|
||||
Vec4 tmpB = mvp * b;
|
||||
|
||||
clipInput[0].position = &tmpA;
|
||||
clipInput[1].position = &tmpB;
|
||||
clipInput[2].position = &tmpA;
|
||||
|
||||
auto clippedSize = planesClipAlgorithm.clip(
|
||||
clippedVerts.data(), clipInput.data(), {false, false, false});
|
||||
|
||||
if (clippedSize == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Perspective divide
|
||||
clippedVerts[0].position /= clippedVerts[0].position.w;
|
||||
clippedVerts[1].position /= clippedVerts[1].position.w;
|
||||
|
||||
// To screen space
|
||||
s32 centerX = ftoi4(2048 + displayOffset);
|
||||
s32 centerY = ftoi4(2048 + displayOffset);
|
||||
const u32 maxZ = ftoi4(((float)0xFFFFFF) / 32.0F);
|
||||
|
||||
outputArray[0].x = (clippedVerts[0].position.x + 1.0F) * centerX;
|
||||
outputArray[0].y = (clippedVerts[0].position.y + 1.0F) * centerY;
|
||||
outputArray[0].z = (clippedVerts[0].position.z + 1.0F) * maxZ;
|
||||
|
||||
outputArray[1].x = (clippedVerts[1].position.x + 1.0F) * centerX;
|
||||
outputArray[1].y = (clippedVerts[1].position.y + 1.0F) * centerY;
|
||||
outputArray[1].z = (clippedVerts[1].position.z + 1.0F) * maxZ;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Tyra
|
||||
|
||||
Reference in New Issue
Block a user