utility functions

This commit is contained in:
h4570
2022-08-17 00:19:16 +02:00
parent 4fb0ab3b6c
commit fea2398699
27 changed files with 419 additions and 247 deletions
+10
View File
@@ -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++) {
+231 -47
View File
@@ -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
@@ -32,7 +32,7 @@ RendererCore2D::~RendererCore2D() {
delete rects[1];
}
const float RendererCore2D::GS_CENTER = 4096.0F;
const float RendererCore2D::GS_DRAW_AREA = 4096.0F;
const float RendererCore2D::SCREEN_CENTER = 4096.0F / 2.0F;
void RendererCore2D::setPrim() {
@@ -143,6 +143,10 @@ CoreBBox::CoreBBox(const CoreBBox& t_bbox) {
Vec4::copy(&vertices[i], t_bbox.vertices[i].xyzw);
}
void CoreBBox::operator=(const CoreBBox& v) {
for (auto i = 0; i < 8; i++) Vec4::copy(&vertices[i], v.vertices[i].xyzw);
}
CoreBBox::CoreBBox(Vec4* t_vertices) {
for (auto i = 0; i < 8; i++) Vec4::copy(&vertices[i], t_vertices[i].xyzw);
}
@@ -178,6 +182,30 @@ std::string CoreBBox::getPrint(const char* name) const {
return res.str();
}
CoreBBox CoreBBox::create(const Vec4& center, const float& size) {
CoreBBox bbox;
float lowX = center.x - size;
float lowY = center.y - size;
float lowZ = center.z - size;
float hiX = center.x + size;
float hiY = center.y + size;
float hiZ = center.z + size;
bbox.vertices[0].set(lowX, lowY, lowZ);
bbox.vertices[1].set(lowX, lowY, hiZ);
bbox.vertices[2].set(lowX, hiY, lowZ);
bbox.vertices[3].set(lowX, hiY, hiZ);
bbox.vertices[4].set(hiX, lowY, lowZ);
bbox.vertices[5].set(hiX, lowY, hiZ);
bbox.vertices[6].set(hiX, hiY, lowZ);
bbox.vertices[7].set(hiX, hiY, hiZ);
return bbox;
}
CoreBBoxFrustum CoreBBox::isInFrustum(const Plane* frustumPlanes,
const M4x4& model,
const float* margins) const {
@@ -8,25 +8,28 @@
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "renderer/core/3d/clipper/ee_clip_algorithm.hpp"
#include "renderer/core/3d/clipper/planes_clip_algorithm.hpp"
namespace Tyra {
EEClipAlgorithm::EEClipAlgorithm() { tempVertices = new EEClipVertex[9]; }
PlanesClipAlgorithm::PlanesClipAlgorithm() {
tempVertices = new PlanesClipVertex[9];
}
EEClipAlgorithm::~EEClipAlgorithm() { delete[] tempVertices; }
PlanesClipAlgorithm::~PlanesClipAlgorithm() { delete[] tempVertices; }
float EEClipAlgorithm::clipMargin = -10.0F;
float PlanesClipAlgorithm::clipMargin = -10.0F;
void EEClipAlgorithm::init(const RendererSettings& settings) {
void PlanesClipAlgorithm::init(const RendererSettings& settings) {
halfWidth = 0.5F;
halfHeight = 0.5F;
near = settings.getNear() - (-clipMargin);
far = -settings.getFar();
}
u8 EEClipAlgorithm::clip(EEClipVertex* o_vertices, EEClipVertexPtrs* i_vertices,
const EEClipAlgorithmSettings& settings) {
u8 PlanesClipAlgorithm::clip(PlanesClipVertex* o_vertices,
PlanesClipVertexPtrs* i_vertices,
const EEClipAlgorithmSettings& settings) {
for (int i = 0; i < 3; i++) {
o_vertices[i].position = *i_vertices[i].position;
if (settings.lerpColors) o_vertices[i].color = *i_vertices[i].color;
@@ -58,8 +61,8 @@ u8 EEClipAlgorithm::clip(EEClipVertex* o_vertices, EEClipVertexPtrs* i_vertices,
return outputSize;
}
float EEClipAlgorithm::getValueByPlane(const EEClipVertex& v,
const int& plane) {
float PlanesClipAlgorithm::getValueByPlane(const PlanesClipVertex& v,
const int& plane) {
switch (plane) {
case 1:
return v.position.x; // x plane
@@ -73,8 +76,9 @@ float EEClipAlgorithm::getValueByPlane(const EEClipVertex& v,
}
}
bool EEClipAlgorithm::isInside(const int& plane, const float& v, const float& w,
const float& planeLimitValue) {
bool PlanesClipAlgorithm::isInside(const int& plane, const float& v,
const float& w,
const float& planeLimitValue) {
switch (plane) {
case 3:
return v <= planeLimitValue; // near z plane
@@ -86,11 +90,10 @@ bool EEClipAlgorithm::isInside(const int& plane, const float& v, const float& w,
}
}
u8 EEClipAlgorithm::clipAgainstPlane(EEClipVertex* original,
const u8& originalSize,
EEClipVertex* clipped, const int& plane,
const float& planeLimitValue,
const EEClipAlgorithmSettings& settings) {
u8 PlanesClipAlgorithm::clipAgainstPlane(
PlanesClipVertex* original, const u8& originalSize,
PlanesClipVertex* clipped, const int& plane, const float& planeLimitValue,
const EEClipAlgorithmSettings& settings) {
int clippedSize = 0;
for (u32 i = 0; i < originalSize; i++) {