mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-06-15 06:58:37 +02:00
Reimplement Bounding Box calculation using the software renderer.
This commit is contained in:
@ -14,6 +14,7 @@
|
||||
#include "VideoCommon/LookUpTables.h"
|
||||
#include "VideoCommon/PixelEngine.h"
|
||||
#include "VideoCommon/VertexLoader.h"
|
||||
#include "VideoCommon/BoundingBox.h"
|
||||
#include "VideoCommon/VertexLoader_Color.h"
|
||||
#include "VideoCommon/VertexLoader_Normal.h"
|
||||
#include "VideoCommon/VertexLoader_Position.h"
|
||||
@ -21,8 +22,6 @@
|
||||
#include "VideoCommon/VideoCommon.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
//BBox
|
||||
#include "VideoCommon/XFMemory.h"
|
||||
|
||||
#define COMPILED_CODE_SIZE 4096
|
||||
|
||||
@ -45,21 +44,6 @@ int colElements[2];
|
||||
float posScale;
|
||||
float tcScale[8];
|
||||
|
||||
// bbox variables
|
||||
// bbox must read vertex position, so convert it to this buffer
|
||||
static float s_bbox_vertex_buffer[3];
|
||||
static u8 *s_bbox_pCurBufferPointer_orig;
|
||||
static int s_bbox_primitive;
|
||||
static struct Point
|
||||
{
|
||||
s32 x;
|
||||
s32 y;
|
||||
float z;
|
||||
} s_bbox_points[3];
|
||||
static u8 s_bbox_currPoint;
|
||||
static u8 s_bbox_loadedPoints;
|
||||
static const u8 s_bbox_primitivePoints[8] = { 3, 0, 3, 3, 3, 2, 2, 1 };
|
||||
|
||||
static const float fractionTable[32] = {
|
||||
1.0f / (1U << 0), 1.0f / (1U << 1), 1.0f / (1U << 2), 1.0f / (1U << 3),
|
||||
1.0f / (1U << 4), 1.0f / (1U << 5), 1.0f / (1U << 6), 1.0f / (1U << 7),
|
||||
@ -75,7 +59,7 @@ using namespace Gen;
|
||||
|
||||
static void LOADERDECL PosMtx_ReadDirect_UByte()
|
||||
{
|
||||
s_curposmtx = DataReadU8() & 0x3f;
|
||||
BoundingBox::posMtxIdx = s_curposmtx = DataReadU8() & 0x3f;
|
||||
PRIM_LOG("posmtx: %d, ", s_curposmtx);
|
||||
}
|
||||
|
||||
@ -85,437 +69,12 @@ static void LOADERDECL PosMtx_Write()
|
||||
DataWrite<u8>(0);
|
||||
DataWrite<u8>(0);
|
||||
DataWrite<u8>(0);
|
||||
|
||||
// Resetting current position matrix to default is needed for bbox to behave
|
||||
s_curposmtx = (u8) g_main_cp_state.matrix_index_a.PosNormalMtxIdx;
|
||||
}
|
||||
|
||||
static void LOADERDECL UpdateBoundingBoxPrepare()
|
||||
{
|
||||
if (!PixelEngine::bbox_active)
|
||||
return;
|
||||
|
||||
// set our buffer as videodata buffer, so we will get a copy of the vertex positions
|
||||
// this is a big hack, but so we can use the same converting function then without bbox
|
||||
s_bbox_pCurBufferPointer_orig = VertexManager::s_pCurBufferPointer;
|
||||
VertexManager::s_pCurBufferPointer = (u8*)s_bbox_vertex_buffer;
|
||||
}
|
||||
|
||||
static inline bool UpdateBoundingBoxVars()
|
||||
{
|
||||
switch (s_bbox_primitive)
|
||||
{
|
||||
// Quads: fill 0,1,2 (check),1 (check, clear, repeat)
|
||||
case 0:
|
||||
++s_bbox_loadedPoints;
|
||||
if (s_bbox_loadedPoints == 3)
|
||||
{
|
||||
s_bbox_currPoint = 1;
|
||||
return true;
|
||||
}
|
||||
if (s_bbox_loadedPoints == 4)
|
||||
{
|
||||
s_bbox_loadedPoints = 0;
|
||||
s_bbox_currPoint = 0;
|
||||
return true;
|
||||
}
|
||||
++s_bbox_currPoint;
|
||||
return false;
|
||||
|
||||
// Triangles: 0,1,2 (check, clear, repeat)
|
||||
case 2:
|
||||
++s_bbox_loadedPoints;
|
||||
if (s_bbox_loadedPoints == 3)
|
||||
{
|
||||
s_bbox_loadedPoints = 0;
|
||||
s_bbox_currPoint = 0;
|
||||
return true;
|
||||
}
|
||||
++s_bbox_currPoint;
|
||||
return false;
|
||||
|
||||
// Triangle strip: 0, 1, 2 (check), 0 (check), 1, (check), 2 (check, repeat checking 0, 1, 2)
|
||||
case 3:
|
||||
if (++s_bbox_currPoint == 3)
|
||||
s_bbox_currPoint = 0;
|
||||
|
||||
if (s_bbox_loadedPoints == 2)
|
||||
return true;
|
||||
|
||||
++s_bbox_loadedPoints;
|
||||
return false;
|
||||
|
||||
// Triangle fan: 0,1,2 (check), 1 (check), 2 (check, repeat checking 1,2)
|
||||
case 4:
|
||||
s_bbox_currPoint ^= s_bbox_currPoint ? 3 : 1;
|
||||
|
||||
if (s_bbox_loadedPoints == 2)
|
||||
return true;
|
||||
|
||||
++s_bbox_loadedPoints;
|
||||
return false;
|
||||
|
||||
// Lines: 0,1 (check, clear, repeat)
|
||||
case 5:
|
||||
++s_bbox_loadedPoints;
|
||||
if (s_bbox_loadedPoints == 2)
|
||||
{
|
||||
s_bbox_loadedPoints = 0;
|
||||
s_bbox_currPoint = 0;
|
||||
return true;
|
||||
}
|
||||
++s_bbox_currPoint;
|
||||
return false;
|
||||
|
||||
// Line strip: 0,1 (check), 0 (check), 1 (check, repeat checking 0,1)
|
||||
case 6:
|
||||
s_bbox_currPoint ^= 1;
|
||||
|
||||
if (s_bbox_loadedPoints == 1)
|
||||
return true;
|
||||
|
||||
++s_bbox_loadedPoints;
|
||||
return false;
|
||||
|
||||
// Points: 0 (check, clear, repeat)
|
||||
case 7:
|
||||
return true;
|
||||
|
||||
// This should not happen!
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void LOADERDECL UpdateBoundingBox()
|
||||
{
|
||||
if (!PixelEngine::bbox_active)
|
||||
return;
|
||||
|
||||
// Reset videodata pointer
|
||||
VertexManager::s_pCurBufferPointer = s_bbox_pCurBufferPointer_orig;
|
||||
|
||||
// Copy vertex pointers
|
||||
memcpy(VertexManager::s_pCurBufferPointer, s_bbox_vertex_buffer, 12);
|
||||
VertexManager::s_pCurBufferPointer += 12;
|
||||
|
||||
// We must transform the just loaded point by the current world and projection matrix - in software
|
||||
float transformed[3];
|
||||
float screenPoint[3];
|
||||
|
||||
// We need to get the raw projection values for the bounding box calculation
|
||||
// to work properly. That means, no projection hacks!
|
||||
const float * const orig_point = s_bbox_vertex_buffer;
|
||||
const float * const world_matrix = (float*)xfmem.posMatrices + s_curposmtx * 4;
|
||||
const float * const proj_matrix = xfmem.projection.rawProjection;
|
||||
|
||||
// Transform by world matrix
|
||||
// Only calculate what we need, discard the rest
|
||||
transformed[0] = orig_point[0] * world_matrix[0] + orig_point[1] * world_matrix[1] + orig_point[2] * world_matrix[2] + world_matrix[3];
|
||||
transformed[1] = orig_point[0] * world_matrix[4] + orig_point[1] * world_matrix[5] + orig_point[2] * world_matrix[6] + world_matrix[7];
|
||||
|
||||
// Transform by projection matrix
|
||||
switch (xfmem.projection.type)
|
||||
{
|
||||
// Perspective projection, we must divide by w
|
||||
case GX_PERSPECTIVE:
|
||||
transformed[2] = orig_point[0] * world_matrix[8] + orig_point[1] * world_matrix[9] + orig_point[2] * world_matrix[10] + world_matrix[11];
|
||||
screenPoint[0] = (transformed[0] * proj_matrix[0] + transformed[2] * proj_matrix[1]) / (-transformed[2]);
|
||||
screenPoint[1] = (transformed[1] * proj_matrix[2] + transformed[2] * proj_matrix[3]) / (-transformed[2]);
|
||||
screenPoint[2] = ((transformed[2] * proj_matrix[4] + proj_matrix[5]) * (1.0f - (float) 1e-7)) / (-transformed[2]);
|
||||
break;
|
||||
|
||||
// Orthographic projection
|
||||
case GX_ORTHOGRAPHIC:
|
||||
screenPoint[0] = transformed[0] * proj_matrix[0] + proj_matrix[1];
|
||||
screenPoint[1] = transformed[1] * proj_matrix[2] + proj_matrix[3];
|
||||
|
||||
// We don't really have to care about z here
|
||||
screenPoint[2] = -0.2f;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR_LOG(VIDEO, "Unknown projection type: %d", xfmem.projection.type);
|
||||
screenPoint[0] = screenPoint[1] = screenPoint[2] = 1;
|
||||
}
|
||||
|
||||
// Convert to screen space and add the point to the list - round like the real hardware
|
||||
s_bbox_points[s_bbox_currPoint].x = (((s32) (0.5f + (16.0f * (screenPoint[0] * xfmem.viewport.wd + (xfmem.viewport.xOrig - 342.0f))))) + 3) >> 4;
|
||||
s_bbox_points[s_bbox_currPoint].y = (((s32) (0.5f + (16.0f * (screenPoint[1] * xfmem.viewport.ht + (xfmem.viewport.yOrig - 342.0f))))) + 3) >> 4;
|
||||
s_bbox_points[s_bbox_currPoint].z = screenPoint[2];
|
||||
|
||||
// Update point list for primitive
|
||||
bool check_bbox = UpdateBoundingBoxVars();
|
||||
|
||||
// If we do not have enough points to check the bounding box yet, we are done for now
|
||||
if (!check_bbox)
|
||||
return;
|
||||
|
||||
// How many points does our primitive have?
|
||||
const u8 numPoints = s_bbox_primitivePoints[s_bbox_primitive];
|
||||
|
||||
// If the primitive is a point, update the bounding box now
|
||||
if (numPoints == 1)
|
||||
{
|
||||
Point & p = s_bbox_points[0];
|
||||
|
||||
// Point is out of bounds
|
||||
if (p.x < 0 || p.x > 607 || p.y < 0 || p.y > 479 || p.z >= 0.0f)
|
||||
return;
|
||||
|
||||
// Point is in bounds. Update bounding box if necessary and return
|
||||
PixelEngine::bbox[0] = (p.x < PixelEngine::bbox[0]) ? p.x : PixelEngine::bbox[0];
|
||||
PixelEngine::bbox[1] = (p.x > PixelEngine::bbox[1]) ? p.x : PixelEngine::bbox[1];
|
||||
PixelEngine::bbox[2] = (p.y < PixelEngine::bbox[2]) ? p.y : PixelEngine::bbox[2];
|
||||
PixelEngine::bbox[3] = (p.y > PixelEngine::bbox[3]) ? p.y : PixelEngine::bbox[3];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Now comes the fun part. We must clip the triangles/lines to the viewport - also in software
|
||||
Point & p0 = s_bbox_points[0], &p1 = s_bbox_points[1], &p2 = s_bbox_points[2];
|
||||
|
||||
// Check for z-clip. This crude method is required for Mickey's Magical Mirror, at least
|
||||
if ((p0.z > 0.0f) || (p1.z > 0.0f) || ((numPoints == 3) && (p2.z > 0.0f)))
|
||||
return;
|
||||
|
||||
// Check points for bounds
|
||||
u8 b0 = ((p0.x > 0) ? 1 : 0) | ((p0.y > 0) ? 2 : 0) | ((p0.x > 607) ? 4 : 0) | ((p0.y > 479) ? 8 : 0);
|
||||
u8 b1 = ((p1.x > 0) ? 1 : 0) | ((p1.y > 0) ? 2 : 0) | ((p1.x > 607) ? 4 : 0) | ((p1.y > 479) ? 8 : 0);
|
||||
|
||||
// Let's be practical... If we only have a line, setting b2 to 3 saves an "if"-clause later on
|
||||
u8 b2 = 3;
|
||||
|
||||
// Otherwise if we have a triangle, we need to check the third point
|
||||
if (numPoints == 3)
|
||||
b2 = ((p2.x > 0) ? 1 : 0) | ((p2.y > 0) ? 2 : 0) | ((p2.x > 607) ? 4 : 0) | ((p2.y > 479) ? 8 : 0);
|
||||
|
||||
// These are the internal bbox vars
|
||||
s32 left = 608, right = -1, top = 480, bottom = -1;
|
||||
|
||||
// If the polygon is inside viewport, let's update the bounding box and be done with it
|
||||
if ((b0 == 3) && (b0 == b1) && (b0 == b2))
|
||||
{
|
||||
left = std::min(p0.x, p1.x);
|
||||
top = std::min(p0.y, p1.y);
|
||||
right = std::max(p0.x, p1.x);
|
||||
bottom = std::max(p0.y, p1.y);
|
||||
|
||||
// Triangle
|
||||
if (numPoints == 3)
|
||||
{
|
||||
left = std::min(left, p2.x);
|
||||
top = std::min(top, p2.y);
|
||||
right = std::max(right, p2.x);
|
||||
bottom = std::max(bottom, p2.y);
|
||||
}
|
||||
|
||||
// Update bounding box
|
||||
PixelEngine::bbox[0] = (left < PixelEngine::bbox[0]) ? left : PixelEngine::bbox[0];
|
||||
PixelEngine::bbox[1] = (right > PixelEngine::bbox[1]) ? right : PixelEngine::bbox[1];
|
||||
PixelEngine::bbox[2] = (top < PixelEngine::bbox[2]) ? top : PixelEngine::bbox[2];
|
||||
PixelEngine::bbox[3] = (bottom > PixelEngine::bbox[3]) ? bottom : PixelEngine::bbox[3];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// If it is not inside, then either it is completely outside, or it needs clipping.
|
||||
// Check the primitive's lines
|
||||
u8 i0 = b0 ^ b1;
|
||||
u8 i1 = (numPoints == 3) ? (b1 ^ b2) : i0;
|
||||
u8 i2 = (numPoints == 3) ? (b0 ^ b2) : i0;
|
||||
|
||||
// Primitive out of bounds - return
|
||||
if (!(i0 | i1 | i2))
|
||||
return;
|
||||
|
||||
// First point inside viewport - update internal bbox
|
||||
if (b0 == 3)
|
||||
{
|
||||
left = p0.x;
|
||||
top = p0.y;
|
||||
right = p0.x;
|
||||
bottom = p0.y;
|
||||
}
|
||||
|
||||
// Second point inside
|
||||
if (b1 == 3)
|
||||
{
|
||||
left = std::min(p1.x, left);
|
||||
top = std::min(p1.y, top);
|
||||
right = std::max(p1.x, right);
|
||||
bottom = std::max(p1.y, bottom);
|
||||
}
|
||||
|
||||
// Third point inside
|
||||
if ((b2 == 3) && (numPoints == 3))
|
||||
{
|
||||
left = std::min(p2.x, left);
|
||||
top = std::min(p2.y, top);
|
||||
right = std::max(p2.x, right);
|
||||
bottom = std::max(p2.y, bottom);
|
||||
}
|
||||
|
||||
// Triangle equation vars
|
||||
float m, c;
|
||||
|
||||
// Some definitions to help with rounding later on
|
||||
const float highNum = 89374289734.0f;
|
||||
const float roundUp = 0.001f;
|
||||
|
||||
// Intersection result
|
||||
s32 s;
|
||||
|
||||
// First line intersects
|
||||
if (i0)
|
||||
{
|
||||
m = (p1.x - p0.x) ? ((p1.y - p0.y) / (p1.x - p0.x)) : highNum;
|
||||
c = p0.y - (m * p0.x);
|
||||
if (i0 & 1)
|
||||
{
|
||||
s = (s32)(c + roundUp);
|
||||
if (s >= 0 && s <= 479)
|
||||
left = 0;
|
||||
top = std::min(s, top);
|
||||
bottom = std::max(s, bottom);
|
||||
}
|
||||
|
||||
if (i0 & 2)
|
||||
{
|
||||
s = (s32)((-c / m) + roundUp);
|
||||
if (s >= 0 && s <= 607)
|
||||
top = 0;
|
||||
left = std::min(s, left);
|
||||
right = std::max(s, right);
|
||||
}
|
||||
|
||||
if (i0 & 4)
|
||||
{
|
||||
s = (s32)((m * 607) + c + roundUp);
|
||||
if (s >= 0 && s <= 479)
|
||||
right = 607;
|
||||
top = std::min(s, top);
|
||||
bottom = std::max(s, bottom);
|
||||
}
|
||||
|
||||
if (i0 & 8)
|
||||
{
|
||||
s = (s32)(((479 - c) / m) + roundUp);
|
||||
if (s >= 0 && s <= 607)
|
||||
bottom = 479;
|
||||
left = std::min(s, left);
|
||||
right = std::max(s, right);
|
||||
}
|
||||
}
|
||||
|
||||
// Only check other lines if we are dealing with a triangle
|
||||
if (numPoints == 3)
|
||||
{
|
||||
// Second line intersects
|
||||
if (i1)
|
||||
{
|
||||
m = (p2.x - p1.x) ? ((p2.y - p1.y) / (p2.x - p1.x)) : highNum;
|
||||
c = p1.y - (m * p1.x);
|
||||
if (i1 & 1)
|
||||
{
|
||||
s = (s32)(c + roundUp);
|
||||
if (s >= 0 && s <= 479)
|
||||
left = 0;
|
||||
top = std::min(s, top);
|
||||
bottom = std::max(s, bottom);
|
||||
}
|
||||
|
||||
if (i1 & 2)
|
||||
{
|
||||
s = (s32)((-c / m) + roundUp);
|
||||
if (s >= 0 && s <= 607)
|
||||
top = 0;
|
||||
left = std::min(s, left);
|
||||
right = std::max(s, right);
|
||||
}
|
||||
|
||||
if (i1 & 4)
|
||||
{
|
||||
s = (s32)((m * 607) + c + roundUp);
|
||||
if (s >= 0 && s <= 479)
|
||||
right = 607;
|
||||
top = std::min(s, top);
|
||||
bottom = std::max(s, bottom);
|
||||
}
|
||||
|
||||
if (i1 & 8)
|
||||
{
|
||||
s = (s32)(((479 - c) / m) + roundUp);
|
||||
if (s >= 0 && s <= 607)
|
||||
bottom = 479;
|
||||
left = std::min(s, left);
|
||||
right = std::max(s, right);
|
||||
}
|
||||
}
|
||||
|
||||
// Third line intersects
|
||||
if (i2)
|
||||
{
|
||||
m = (p2.x - p0.x) ? ((p2.y - p0.y) / (p2.x - p0.x)) : highNum;
|
||||
c = p0.y - (m * p0.x);
|
||||
if (i2 & 1)
|
||||
{
|
||||
s = (s32)(c + roundUp);
|
||||
if (s >= 0 && s <= 479)
|
||||
left = 0;
|
||||
top = std::min(s, top);
|
||||
bottom = std::max(s, bottom);
|
||||
}
|
||||
|
||||
if (i2 & 2)
|
||||
{
|
||||
s = (s32)((-c / m) + roundUp);
|
||||
if (s >= 0 && s <= 607)
|
||||
top = 0;
|
||||
left = std::min(s, left);
|
||||
right = std::max(s, right);
|
||||
}
|
||||
|
||||
if (i2 & 4)
|
||||
{
|
||||
s = (s32)((m * 607) + c + roundUp);
|
||||
if (s >= 0 && s <= 479)
|
||||
right = 607;
|
||||
top = std::min(s, top);
|
||||
bottom = std::max(s, bottom);
|
||||
}
|
||||
|
||||
if (i2 & 8)
|
||||
{
|
||||
s = (s32)(((479 - c) / m) + roundUp);
|
||||
if (s >= 0 && s <= 607)
|
||||
bottom = 479;
|
||||
left = std::min(s, left);
|
||||
right = std::max(s, right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wrong bounding box values, discard this polygon (it is outside)
|
||||
if (left > 607 || top > 479 || right < 0 || bottom < 0)
|
||||
return;
|
||||
|
||||
// Trim bounding box to viewport
|
||||
left = (left < 0) ? 0 : left;
|
||||
top = (top < 0) ? 0 : top;
|
||||
right = (right > 607) ? 607 : right;
|
||||
bottom = (bottom > 479) ? 479 : bottom;
|
||||
|
||||
// Update bounding box
|
||||
PixelEngine::bbox[0] = (left < PixelEngine::bbox[0]) ? left : PixelEngine::bbox[0];
|
||||
PixelEngine::bbox[1] = (right > PixelEngine::bbox[1]) ? right : PixelEngine::bbox[1];
|
||||
PixelEngine::bbox[2] = (top < PixelEngine::bbox[2]) ? top : PixelEngine::bbox[2];
|
||||
PixelEngine::bbox[3] = (bottom > PixelEngine::bbox[3]) ? bottom : PixelEngine::bbox[3];
|
||||
}
|
||||
|
||||
static void LOADERDECL TexMtx_ReadDirect_UByte()
|
||||
{
|
||||
s_curtexmtx[s_texmtxread] = DataReadU8() & 0x3f;
|
||||
BoundingBox::texMtxIdx[s_texmtxread] = s_curtexmtx[s_texmtxread] = DataReadU8() & 0x3f;
|
||||
|
||||
PRIM_LOG("texmtx%d: %d, ", s_texmtxread, s_curtexmtx[s_texmtxread]);
|
||||
s_texmtxread++;
|
||||
}
|
||||
@ -611,6 +170,10 @@ void VertexLoader::CompileVertexTranslator()
|
||||
m_numPipelineStages = 0;
|
||||
#endif
|
||||
|
||||
// Get the pointer to this vertex's buffer data for the bounding box
|
||||
if (g_ActiveConfig.bUseBBox)
|
||||
WriteCall(BoundingBox::SetVertexBufferPosition);
|
||||
|
||||
// Colors
|
||||
const u64 col[2] = {m_VtxDesc.Color0, m_VtxDesc.Color1};
|
||||
// TextureCoord
|
||||
@ -643,16 +206,8 @@ void VertexLoader::CompileVertexTranslator()
|
||||
if (m_VtxDesc.Tex7MatIdx) {m_VertexSize += 1; components |= VB_HAS_TEXMTXIDX7; WriteCall(TexMtx_ReadDirect_UByte); }
|
||||
|
||||
// Write vertex position loader
|
||||
if (g_ActiveConfig.bUseBBox)
|
||||
{
|
||||
WriteCall(UpdateBoundingBoxPrepare);
|
||||
WriteCall(VertexLoader_Position::GetFunction(m_VtxDesc.Position, m_VtxAttr.PosFormat, m_VtxAttr.PosElements));
|
||||
WriteCall(UpdateBoundingBox);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteCall(VertexLoader_Position::GetFunction(m_VtxDesc.Position, m_VtxAttr.PosFormat, m_VtxAttr.PosElements));
|
||||
}
|
||||
WriteCall(VertexLoader_Position::GetFunction(m_VtxDesc.Position, m_VtxAttr.PosFormat, m_VtxAttr.PosElements));
|
||||
|
||||
m_VertexSize += VertexLoader_Position::GetSize(m_VtxDesc.Position, m_VtxAttr.PosFormat, m_VtxAttr.PosElements);
|
||||
nat_offset += 12;
|
||||
m_native_vtx_decl.position.components = 3;
|
||||
@ -826,6 +381,10 @@ void VertexLoader::CompileVertexTranslator()
|
||||
}
|
||||
}
|
||||
|
||||
// Update the bounding box
|
||||
if (g_ActiveConfig.bUseBBox)
|
||||
WriteCall(BoundingBox::Update);
|
||||
|
||||
if (m_VtxDesc.PosMatIdx)
|
||||
{
|
||||
WriteCall(PosMtx_Write);
|
||||
@ -901,9 +460,7 @@ void VertexLoader::SetupRunVertices(const VAT& vat, int primitive, int const cou
|
||||
colElements[i] = m_VtxAttr.color[i].Elements;
|
||||
|
||||
// Prepare bounding box
|
||||
s_bbox_primitive = primitive;
|
||||
s_bbox_currPoint = 0;
|
||||
s_bbox_loadedPoints = 0;
|
||||
BoundingBox::Prepare(vat, primitive, m_VtxDesc, m_native_vtx_decl);
|
||||
}
|
||||
|
||||
void VertexLoader::ConvertVertices ( int count )
|
||||
|
Reference in New Issue
Block a user