mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-10 23:24:06 +02:00
#370 use soft transform for transformBoxRect
This commit is contained in:
@@ -2001,14 +2001,16 @@ struct IMA_STATE
|
||||
};
|
||||
|
||||
#if defined(MODEHW)
|
||||
#define PERSPECTIVE_DZ(z) (z >> 4)
|
||||
#define PROJ_SHIFT 4
|
||||
|
||||
#define PERSPECTIVE_DZ(z) (z >> PROJ_SHIFT)
|
||||
|
||||
#define PERSPECTIVE(x, y, z) {\
|
||||
int32 dz = PERSPECTIVE_DZ(z);\
|
||||
if (dz >= DIV_TABLE_SIZE) dz = DIV_TABLE_SIZE - 1;\
|
||||
int32 d = FixedInvU(dz);\
|
||||
x = (x * d) >> 12;\
|
||||
y = (y * d) >> 12;\
|
||||
x = (x * d) >> (16 - PROJ_SHIFT);\
|
||||
y = (y * d) >> (16 - PROJ_SHIFT);\
|
||||
}
|
||||
#elif defined(MODE13)
|
||||
#define PERSPECTIVE(x, y, z) {\
|
||||
|
@@ -60,4 +60,7 @@ DIV_TABLE_END EQU (1025 - 1)
|
||||
VIEW_MIN EQU (256 << CLIP_SHIFT)
|
||||
VIEW_MAX EQU (VIEW_DIST << CLIP_SHIFT)
|
||||
|
||||
MIN_INT32 EQU 0x80000000
|
||||
MAX_INT32 EQU 0x7FFFFFFF
|
||||
|
||||
MulManyVec3Mat33_F16 EQU (0x50000 + 2)
|
@@ -696,7 +696,7 @@ bool transformBoxRect_c(const AABBs* box, RectMinMax* rect)
|
||||
}
|
||||
|
||||
const int32* ptr = (int32*)box;
|
||||
|
||||
#if 0
|
||||
int32 minX = ptr[0] >> 16 << F16_SHIFT;
|
||||
int32 maxX = ptr[0] << 16 >> (16 - F16_SHIFT);
|
||||
int32 minY = ptr[1] >> 16 << F16_SHIFT;
|
||||
@@ -741,6 +741,107 @@ bool transformBoxRect_c(const AABBs* box, RectMinMax* rect)
|
||||
rect->y0 = y0 + (FRAME_HEIGHT / 2);
|
||||
rect->x1 = x1 + (FRAME_WIDTH / 2);
|
||||
rect->y1 = y1 + (FRAME_HEIGHT / 2);
|
||||
#else
|
||||
enum {
|
||||
MAX_X,
|
||||
MIN_X,
|
||||
MAX_Y,
|
||||
MIN_Y,
|
||||
MAX_Z,
|
||||
MIN_Z,
|
||||
MIN_MAX_SIZE
|
||||
};
|
||||
|
||||
int32 mm[MIN_MAX_SIZE][3];
|
||||
int32 min, max, minX, minY, minZ, maxX, maxY, maxZ;
|
||||
|
||||
#define PROJECT(dx,dy,dz){\
|
||||
int32 x, y, z;\
|
||||
x = mm[dx][0] + mm[dy][0] + mm[dz][0];\
|
||||
y = mm[dx][1] + mm[dy][1] + mm[dz][1];\
|
||||
z = mm[dx][2] + mm[dy][2] + mm[dz][2];\
|
||||
if (z >= VIEW_MIN_F && z <= VIEW_MAX_F) {\
|
||||
z = divTable[z >> (FIXED_SHIFT + PROJ_SHIFT)];\
|
||||
x = x * z;\
|
||||
y = y * z;\
|
||||
if (x < rMinX) rMinX = x;\
|
||||
if (y < rMinY) rMinY = y;\
|
||||
if (x > rMaxX) rMaxX = x;\
|
||||
if (y > rMaxY) rMaxY = y;\
|
||||
}\
|
||||
}
|
||||
|
||||
int32 xx = ptr[0];
|
||||
int32 yy = ptr[1];
|
||||
int32 zz = ptr[2];
|
||||
|
||||
// pre-transform min/max Z
|
||||
min = zz >> 16;
|
||||
minX = m.e02 * min + m.e03;
|
||||
minY = m.e12 * min + m.e13;
|
||||
minZ = m.e22 * min + m.e23;
|
||||
max = zz << 16 >> 16;
|
||||
maxX = m.e02 * max + m.e03;
|
||||
maxY = m.e12 * max + m.e13;
|
||||
maxZ = m.e22 * max + m.e23;
|
||||
mm[MAX_Z][0] = maxX >> FIXED_SHIFT;
|
||||
mm[MAX_Z][1] = maxY >> FIXED_SHIFT;
|
||||
mm[MAX_Z][2] = maxZ;
|
||||
mm[MIN_Z][0] = minX >> FIXED_SHIFT;
|
||||
mm[MIN_Z][1] = minY >> FIXED_SHIFT;
|
||||
mm[MIN_Z][2] = minZ;
|
||||
|
||||
// pre-transform min/max Y
|
||||
min = yy >> 16;
|
||||
minX = m.e01 * min;
|
||||
minY = m.e11 * min;
|
||||
minZ = m.e21 * min;
|
||||
max = yy << 16 >> 16;
|
||||
maxX = m.e01 * max;
|
||||
maxY = m.e11 * max;
|
||||
maxZ = m.e21 * max;
|
||||
mm[MAX_Y][0] = maxX >> FIXED_SHIFT;
|
||||
mm[MAX_Y][1] = maxY >> FIXED_SHIFT;
|
||||
mm[MAX_Y][2] = maxZ;
|
||||
mm[MIN_Y][0] = minX >> FIXED_SHIFT;
|
||||
mm[MIN_Y][1] = minY >> FIXED_SHIFT;
|
||||
mm[MIN_Y][2] = minZ;
|
||||
|
||||
// pre-transform min/max X
|
||||
min = xx >> 16;
|
||||
minX = m.e00 * min;
|
||||
minY = m.e10 * min;
|
||||
minZ = m.e20 * min;
|
||||
max = xx << 16 >> 16;
|
||||
maxX = m.e00 * max;
|
||||
maxY = m.e10 * max;
|
||||
maxZ = m.e20 * max;
|
||||
mm[MAX_X][0] = maxX >> FIXED_SHIFT;
|
||||
mm[MAX_X][1] = maxY >> FIXED_SHIFT;
|
||||
mm[MAX_X][2] = maxZ;
|
||||
mm[MIN_X][0] = minX >> FIXED_SHIFT;
|
||||
mm[MIN_X][1] = minY >> FIXED_SHIFT;
|
||||
mm[MIN_X][2] = minZ;
|
||||
|
||||
int32 rMinX = INT_MAX;
|
||||
int32 rMinY = INT_MAX;
|
||||
int32 rMaxX = INT_MIN;
|
||||
int32 rMaxY = INT_MIN;
|
||||
|
||||
PROJECT(MIN_X, MIN_Y, MIN_Z);
|
||||
PROJECT(MAX_X, MIN_Y, MIN_Z);
|
||||
PROJECT(MIN_X, MAX_Y, MIN_Z);
|
||||
PROJECT(MAX_X, MAX_Y, MIN_Z);
|
||||
PROJECT(MIN_X, MIN_Y, MAX_Z);
|
||||
PROJECT(MAX_X, MIN_Y, MAX_Z);
|
||||
PROJECT(MIN_X, MAX_Y, MAX_Z);
|
||||
PROJECT(MAX_X, MAX_Y, MAX_Z);
|
||||
|
||||
rect->x0 = (rMinX >> (16 - PROJ_SHIFT)) + (FRAME_WIDTH / 2);
|
||||
rect->y0 = (rMinY >> (16 - PROJ_SHIFT)) + (FRAME_HEIGHT / 2);
|
||||
rect->x1 = (rMaxX >> (16 - PROJ_SHIFT)) + (FRAME_WIDTH / 2);
|
||||
rect->y1 = (rMaxY >> (16 - PROJ_SHIFT)) + (FRAME_HEIGHT / 2);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -9,115 +9,184 @@
|
||||
|
||||
boxArg RN r0
|
||||
rectArg RN r1
|
||||
m RN r2
|
||||
vert RN r3
|
||||
vptr RN r4
|
||||
rect RN r5 ; must be in r4-r6
|
||||
minX RN boxArg
|
||||
maxX RN rectArg
|
||||
minY RN m
|
||||
maxY RN r6
|
||||
minZ RN r12
|
||||
maxZ RN lr
|
||||
divLUT RN r2
|
||||
m RN r3
|
||||
vx RN r4
|
||||
vy RN r5
|
||||
vz RN r6
|
||||
x RN r7
|
||||
y RN r8
|
||||
z RN r9
|
||||
rMinX RN r10
|
||||
rMinY RN r11
|
||||
rMaxX RN r12
|
||||
rMaxY RN lr
|
||||
|
||||
xx RN maxX
|
||||
yy RN maxY
|
||||
zz RN maxZ
|
||||
rMinX RN boxArg
|
||||
rMinY RN rectArg
|
||||
rMaxX RN m
|
||||
rMaxY RN maxY
|
||||
vx RN vptr
|
||||
vy RN minZ
|
||||
vz RN maxZ
|
||||
bz RN divLUT
|
||||
offset RN m
|
||||
xx RN rMinX
|
||||
yy RN rMinY
|
||||
zz RN rMaxX
|
||||
min RN rMaxY
|
||||
max RN rMaxY
|
||||
w RN x
|
||||
h RN y
|
||||
mx RN boxArg
|
||||
my RN rectArg
|
||||
mz RN divLUT
|
||||
|
||||
INT_MIN EQU 0x80000000
|
||||
INT_MAX EQU 0x7FFFFFFF
|
||||
minX RN x
|
||||
minY RN y
|
||||
minZ RN z
|
||||
maxX RN mx
|
||||
maxY RN my
|
||||
maxZ RN mz
|
||||
|
||||
MAX_X EQU (0 * 3 * 4)
|
||||
MIN_X EQU (1 * 3 * 4)
|
||||
MAX_Y EQU (2 * 3 * 4)
|
||||
MIN_Y EQU (3 * 3 * 4)
|
||||
MAX_Z EQU (4 * 3 * 4)
|
||||
MIN_Z EQU (5 * 3 * 4)
|
||||
SIZE EQU (6 * 3 * 4)
|
||||
|
||||
MACRO
|
||||
$index check
|
||||
ldmia vert!, {vx, vy, vz}
|
||||
tst vz, #(CLIP_NEAR | CLIP_FAR)
|
||||
bne $index.skip
|
||||
cmp vx, rMinX
|
||||
movlt rMinX, vx
|
||||
cmp vy, rMinY
|
||||
movlt rMinY, vy
|
||||
cmp vx, rMaxX
|
||||
movgt rMaxX, vx
|
||||
cmp vy, rMaxY
|
||||
movgt rMaxY, vy
|
||||
$index project $dx, $dy, $dz
|
||||
add offset, sp, $dz
|
||||
ldmia offset, {x, y, z}
|
||||
|
||||
add offset, sp, $dy
|
||||
ldmia offset, {vx, vy, vz}
|
||||
add x, x, vx
|
||||
add y, y, vy
|
||||
add z, z, vz
|
||||
|
||||
add offset, sp, $dx
|
||||
ldmia offset, {vx, vy, vz}
|
||||
add z, z, vz
|
||||
|
||||
; check z clipping
|
||||
sub offset, z, #VIEW_MIN_F
|
||||
cmp offset, #(VIEW_MAX_F - VIEW_MIN_F)
|
||||
bhi $index.skip
|
||||
|
||||
add x, x, vx
|
||||
add y, y, vy
|
||||
|
||||
mov z, z, lsr #(FIXED_SHIFT + PROJ_SHIFT) ; z is positive
|
||||
ldr z, [divLUT, z, lsl #2]
|
||||
mul x, z, x
|
||||
mul y, z, y
|
||||
|
||||
cmp x, rMinX
|
||||
movlt rMinX, x
|
||||
cmp y, rMinY
|
||||
movlt rMinY, y
|
||||
cmp x, rMaxX
|
||||
movgt rMaxX, x
|
||||
cmp y, rMaxY
|
||||
movgt rMaxY, y
|
||||
$index.skip
|
||||
MEND
|
||||
|
||||
transformBoxRect_asm
|
||||
ldr m, =matrixPtr
|
||||
ldr m, [m]
|
||||
ldr m, [m, #(11 * 4)]
|
||||
cmp m, #VIEW_MIN_F
|
||||
movlt r0, #0
|
||||
movlt pc, lr
|
||||
cmp m, #VIEW_MAX_F
|
||||
movge r0, #0
|
||||
movge pc, lr
|
||||
ldr bz, [m, #(11 * 4)]
|
||||
sub bz, bz, #VIEW_MIN_F
|
||||
cmp bz, #(VIEW_MAX_F - VIEW_MIN_F)
|
||||
movhi r0, #0
|
||||
movhi pc, lr
|
||||
|
||||
stmfd sp!, {r4-r6, lr}
|
||||
stmfd sp!, {rectArg, r4-r11, lr}
|
||||
|
||||
mov rect, rectArg ; to use after projectVertices_asm call
|
||||
ldmia boxArg, {xx, yy, zz}
|
||||
|
||||
mov minX, xx, asr #16
|
||||
mov maxX, xx, lsl #16
|
||||
mov maxX, maxX, asr #(16 - F16_SHIFT)
|
||||
mov minX, minX, lsl #2
|
||||
add m, m, #(12 * 4)
|
||||
|
||||
mov minY, yy, asr #16
|
||||
mov maxY, yy, lsl #16
|
||||
mov maxY, maxY, asr #(16 - F16_SHIFT)
|
||||
mov minY, minY, lsl #2
|
||||
; pre-transform min/max Z
|
||||
ldmdb m!, {mx, my, mz, vx, vy, vz}
|
||||
mov min, zz, asr #16
|
||||
mla minX, min, mx, vx
|
||||
mla minY, min, my, vy
|
||||
mla minZ, min, mz, vz
|
||||
mov minX, minX, asr #FIXED_SHIFT
|
||||
mov minY, minY, asr #FIXED_SHIFT
|
||||
|
||||
mov minZ, zz, asr #16
|
||||
mov maxZ, zz, lsl #16
|
||||
mov maxZ, maxZ, asr #(16 - F16_SHIFT)
|
||||
mov minZ, minZ, lsl #2
|
||||
mov max, zz, lsl #16
|
||||
mov max, max, asr #16
|
||||
mla maxX, max, mx, vx
|
||||
mla maxY, max, my, vy
|
||||
mla maxZ, max, mz, vz
|
||||
mov maxX, maxX, asr #FIXED_SHIFT
|
||||
mov maxY, maxY, asr #FIXED_SHIFT
|
||||
stmdb sp!, {maxX, maxY, maxZ, minX, minY, minZ}
|
||||
|
||||
ldr vptr, =gVertices
|
||||
; pre-transform min/max Y
|
||||
ldmdb m!, {mx, my, mz}
|
||||
|
||||
mov vert, vptr
|
||||
stmia vert!, {minX, minY, minZ}
|
||||
stmia vert!, {maxX, minY, minZ}
|
||||
stmia vert!, {minX, maxY, minZ}
|
||||
stmia vert!, {maxX, maxY, minZ}
|
||||
stmia vert!, {minX, minY, maxZ}
|
||||
stmia vert!, {maxX, minY, maxZ}
|
||||
stmia vert!, {minX, maxY, maxZ}
|
||||
stmia vert!, {maxX, maxY, maxZ}
|
||||
mov min, yy, asr #16
|
||||
mul minX, mx, min
|
||||
mul minY, my, min
|
||||
mul minZ, mz, min
|
||||
mov minX, minX, asr #FIXED_SHIFT
|
||||
mov minY, minY, asr #FIXED_SHIFT
|
||||
|
||||
mov r0, #8
|
||||
bl projectVertices_asm ; TODO compare with non-SWI version
|
||||
mov max, yy, lsl #16
|
||||
mov max, max, asr #16
|
||||
mul maxX, max, mx
|
||||
mul maxY, max, my
|
||||
mul maxZ, max, mz
|
||||
mov maxX, maxX, asr #FIXED_SHIFT
|
||||
mov maxY, maxY, asr #FIXED_SHIFT
|
||||
stmdb sp!, {maxX, maxY, maxZ, minX, minY, minZ}
|
||||
|
||||
mov rMinX, #INT_MAX
|
||||
mov rMinY, #INT_MAX
|
||||
mov rMaxX, #INT_MIN
|
||||
mov rMaxY, #INT_MIN
|
||||
; pre-transform min/max X
|
||||
ldmdb m!, {mx, my, mz}
|
||||
|
||||
mov vert, vptr
|
||||
_0 check
|
||||
_1 check
|
||||
_2 check
|
||||
_3 check
|
||||
_4 check
|
||||
_5 check
|
||||
_6 check
|
||||
_7 check
|
||||
mov min, xx, asr #16
|
||||
mul minX, mx, min
|
||||
mul minY, my, min
|
||||
mul minZ, mz, min
|
||||
mov minX, minX, asr #FIXED_SHIFT
|
||||
mov minY, minY, asr #FIXED_SHIFT
|
||||
|
||||
_done add rMinX, rMinX, #(FRAME_WIDTH >> 1)
|
||||
add rMinY, rMinY, #(FRAME_HEIGHT >> 1)
|
||||
add rMaxX, rMaxX, #(FRAME_WIDTH >> 1)
|
||||
add rMaxY, rMaxY, #(FRAME_HEIGHT >> 1)
|
||||
mov max, xx, lsl #16
|
||||
mov max, max, asr #16
|
||||
mul maxX, max, mx
|
||||
mul maxY, max, my
|
||||
mul maxZ, max, mz
|
||||
mov maxX, maxX, asr #FIXED_SHIFT
|
||||
mov maxY, maxY, asr #FIXED_SHIFT
|
||||
stmdb sp!, {maxX, maxY, maxZ, minX, minY, minZ}
|
||||
|
||||
stmia rect, {rMinX, rMinY, rMaxX, rMaxY}
|
||||
ldr divLUT, =divTable
|
||||
mov rMinX, #MAX_INT32
|
||||
mov rMinY, #MAX_INT32
|
||||
mov rMaxX, #MIN_INT32
|
||||
mov rMaxY, #MIN_INT32
|
||||
|
||||
_0 project #MIN_X, #MIN_Y, #MIN_Z
|
||||
_1 project #MAX_X, #MIN_Y, #MIN_Z
|
||||
_2 project #MIN_X, #MAX_Y, #MIN_Z
|
||||
_3 project #MAX_X, #MAX_Y, #MIN_Z
|
||||
_4 project #MIN_X, #MIN_Y, #MAX_Z
|
||||
_5 project #MAX_X, #MIN_Y, #MAX_Z
|
||||
_6 project #MIN_X, #MAX_Y, #MAX_Z
|
||||
_7 project #MAX_X, #MAX_Y, #MAX_Z
|
||||
|
||||
_done mov w, #(FRAME_WIDTH >> 1)
|
||||
mov h, #(FRAME_HEIGHT >> 1)
|
||||
add rMinX, w, rMinX, asr #(16 - PROJ_SHIFT)
|
||||
add rMinY, h, rMinY, asr #(16 - PROJ_SHIFT)
|
||||
add rMaxX, w, rMaxX, asr #(16 - PROJ_SHIFT)
|
||||
add rMaxY, h, rMaxY, asr #(16 - PROJ_SHIFT)
|
||||
|
||||
add sp, sp, #SIZE
|
||||
ldmfd sp!, {rectArg}
|
||||
|
||||
stmia rectArg, {rMinX, rMinY, rMaxX, rMaxY}
|
||||
|
||||
mov r0, #1
|
||||
ldmfd sp!, {r4-r6, pc}
|
||||
ldmfd sp!, {r4-r11, pc}
|
||||
END
|
||||
|
Reference in New Issue
Block a user