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