
06.11.2023, 05:03
|
|
Участник форума
Регистрация: 19.03.2014
Сообщений: 222
С нами:
6395080
Репутация:
128
|
|
Converts 2d screen coordinates (.z is depth) to world 3d coordinates. Actually, this is implementation of the SF opcode:
CLEO:
Код:
0B8F:
convert_screen_coords
1@
2@
depth
3@
to_world_3d
4@
5@
6@
C:
Код:
#if defined(_MSC_VER)
#define CC_STDCALL __stdcall
#elif defined(__GNUC__) || defined(__clang__)
#define CC_STDCALL __attribute__((stdcall))
#endif
typedef
struct
D3DMATRIX
{
union
{
struct
{
float
_11
;
float
_12
;
float
_13
;
float
_14
;
float
_21
;
float
_22
;
float
_23
;
float
_24
;
float
_31
;
float
_32
;
float
_33
;
float
_34
;
float
_41
;
float
_42
;
float
_43
;
float
_44
;
}
;
float
m
[
4
]
[
4
]
;
}
;
}
D3DMATRIX
;
typedef
struct
CVector
{
float
x
;
float
y
;
float
z
;
}
CVector
;
typedef
char
(
CC_STDCALL
*
D3DXMatrixInverse_t
)
(
void
*
a1
,
float
*
a2
,
const
void
*
a3
)
;
D3DXMatrixInverse_t D3DXMatrixInverse
=
(
D3DXMatrixInverse_t
)
0x76795B
;
void
convert_screen_coords_to_world_3d
(
const
CVector
*
screen_coors
,
CVector
*
world_coors
)
{
D3DMATRIX worldMatrix
;
/* Get the combined view-projection matrix and invert it */
memcpy
(
&
worldMatrix
,
(
const
void
*
)
0xB6FA2C
,
sizeof
(
worldMatrix
)
)
;
worldMatrix
.
m
[
3
]
[
3
]
=
1.0f
;
D3DMATRIX inverseMatrix
;
// TODO: Check is it possible to reuse the same matrix
D3DXMatrixInverse
(
&
inverseMatrix
,
NULL
,
&
worldMatrix
)
;
/* Apply the inverse view-projection matrix to the screen coordinates */
float
invZ
=
1.0f
/
screen_coors
->
z
;
float
screenX
=
screen_coors
->
x
/
(
*
(
int
*
)
0xC17044
*
invZ
)
;
float
screenY
=
screen_coors
->
y
/
(
*
(
int
*
)
0xC17048
*
invZ
)
;
/* Transform the screen coordinates into world coordinates */
world_coors
->
x
=
screenX
*
inverseMatrix
.
_11
+
screenY
*
inverseMatrix
.
_21
+
screen_coors
->
z
*
inverseMatrix
.
_31
+
inverseMatrix
.
_41
;
world_coors
->
y
=
screenX
*
inverseMatrix
.
_12
+
screenY
*
inverseMatrix
.
_22
+
screen_coors
->
z
*
inverseMatrix
.
_32
+
inverseMatrix
.
_42
;
world_coors
->
z
=
screenX
*
inverseMatrix
.
_13
+
screenY
*
inverseMatrix
.
_23
+
screen_coors
->
z
*
inverseMatrix
.
_33
+
inverseMatrix
.
_43
;
}
Tested on 1.0 US
|
|
|