Skip to content

Commit fa53448

Browse files
author
Roberto De Ioris
committed
improved quaternion support, first round of transform improvements
1 parent eb9f1cd commit fa53448

4 files changed

Lines changed: 160 additions & 41 deletions

File tree

‎Source/UnrealEnginePython/Private/PythonComponent.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ void UPythonComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
108108
FScopePythonGIL gil;
109109

110110
if (PyObject_HasAttrString(py_component_instance, (char *)"end_play")) {
111-
PyObject *ep_ret = PyObject_CallMethod(py_component_instance, (char *)"end_play", NULL);
111+
PyObject *ep_ret = PyObject_CallMethod(py_component_instance, (char *)"end_play", (char*)"i", (int)EndPlayReason);
112112

113113
if (!ep_ret) {
114114
unreal_engine_py_log_error();

‎Source/UnrealEnginePython/Private/UEPyModule.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1951,7 +1951,7 @@ bool ue_py_convert_pyobject(PyObject *py_obj, UProperty *prop, uint8 *buffer) {
19511951
}
19521952
return false;
19531953
}
1954-
1954+
19551955
if (ue_PyFTransform *py_transform = py_ue_is_ftransform(py_obj)) {
19561956
if (auto casted_prop = Cast<UStructProperty>(prop)) {
19571957
if (casted_prop->Struct == TBaseStructure<FTransform>::Get()) {

‎Source/UnrealEnginePython/Private/UObject/UEPyTransform.cpp‎

Lines changed: 150 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,74 @@
11
#include "UnrealEnginePythonPrivatePCH.h"
22

3-
3+
static bool check_vector_args(PyObject *args, FVector &vec, bool &sweep, bool &teleport_physics) {
4+
PyObject *py_vec = nullptr;
5+
float x, y, z;
6+
PyObject *py_sweep = nullptr;
7+
PyObject *py_teleport_physics = nullptr;
8+
9+
if (!PyArg_ParseTuple(args, "O|OO", &py_vec, &py_sweep, &py_teleport_physics)) {
10+
PyErr_Clear();
11+
if (!PyArg_ParseTuple(args, "fff|OO", &x, &y, &z, &py_sweep, &py_teleport_physics)) {
12+
return false;
13+
}
14+
}
15+
16+
if (py_vec) {
17+
ue_PyFVector *ue_py_vec = py_ue_is_fvector(py_vec);
18+
if (!ue_py_vec) {
19+
PyErr_SetString(PyExc_Exception, "argument is not a FVector");
20+
return false;
21+
}
22+
vec = ue_py_vec->vec;
23+
}
24+
else {
25+
vec.X = x ;
26+
vec.Y = y;
27+
vec.Z = z;
28+
}
29+
30+
sweep = (py_sweep && PyObject_IsTrue(py_sweep));
31+
teleport_physics = (py_teleport_physics && PyObject_IsTrue(py_teleport_physics));
32+
33+
return true;
34+
}
35+
36+
static bool check_rotation_args(PyObject *args, FQuat &quat, bool &sweep, bool &teleport_physics) {
37+
PyObject *py_rotation = nullptr;
38+
float pitch, yaw, roll;
39+
PyObject *py_sweep = nullptr;
40+
PyObject *py_teleport_physics = nullptr;
41+
42+
if (!PyArg_ParseTuple(args, "O|OO", &py_rotation, &py_sweep, &py_teleport_physics)) {
43+
PyErr_Clear();
44+
if (!PyArg_ParseTuple(args, "fff|OO", &roll, &pitch, &yaw, &py_teleport_physics)) {
45+
return false;
46+
}
47+
}
48+
49+
if (py_rotation) {
50+
ue_PyFQuat *ue_py_quat = py_ue_is_fquat(py_rotation);
51+
if (ue_py_quat) {
52+
quat = ue_py_quat->quat;
53+
}
54+
else {
55+
ue_PyFRotator *ue_py_rot = py_ue_is_frotator(py_rotation);
56+
if (!ue_py_rot) {
57+
PyErr_SetString(PyExc_Exception, "argument is not a FQuat or FRotator");
58+
return false;
59+
}
60+
quat = ue_py_rot->rot.Quaternion();
61+
}
62+
}
63+
else {
64+
quat = FQuat(FRotator(pitch, yaw, roll));
65+
}
66+
67+
sweep = (py_sweep && PyObject_IsTrue(py_sweep));
68+
teleport_physics = (py_teleport_physics && PyObject_IsTrue(py_teleport_physics));
69+
70+
return true;
71+
}
472

573
PyObject *py_ue_get_actor_location(ue_PyUObject *self, PyObject * args) {
674

@@ -93,85 +161,122 @@ PyObject *py_ue_set_actor_location(ue_PyUObject *self, PyObject * args) {
93161
ue_py_check(self);
94162

95163
FVector vec;
96-
if (!py_ue_vector_arg(args, vec))
97-
return NULL;
164+
bool sweep;
165+
bool teleport_physics;
166+
if (!check_vector_args(args, vec, sweep, teleport_physics))
167+
return nullptr;
98168

99169
AActor *actor = ue_get_actor(self);
100170
if (!actor)
101171
PyErr_Format(PyExc_Exception, "uobject is not an actor or a component");
102172

103-
actor->SetActorLocation(vec);
173+
FHitResult hit;
174+
bool success = actor->SetActorLocation(vec, sweep, &hit, teleport_physics ? ETeleportType::TeleportPhysics :ETeleportType::None);
104175

105-
Py_INCREF(Py_None);
106-
return Py_None;
176+
if (!sweep) {
177+
if (success) {
178+
Py_RETURN_TRUE;
179+
}
180+
Py_RETURN_FALSE;
181+
}
182+
183+
return Py_BuildValue("(OO)", success ? Py_True : Py_False, py_ue_new_fhitresult(hit));
107184
}
108185

109186
PyObject *py_ue_add_actor_world_offset(ue_PyUObject *self, PyObject * args) {
110187

111188
ue_py_check(self);
112189

113-
FVector vec;
114-
if (!py_ue_vector_arg(args, vec))
115-
return NULL;
190+
FVector vec;
191+
bool sweep;
192+
bool teleport_physics;
193+
if (!check_vector_args(args, vec, sweep, teleport_physics))
194+
return nullptr;
116195

117196
AActor *actor = ue_get_actor(self);
118197
if (!actor)
119198
PyErr_Format(PyExc_Exception, "uobject is not an actor or a component");
120199

121-
actor->AddActorWorldOffset(vec);
122-
123-
Py_INCREF(Py_None);
124-
return Py_None;
200+
FHitResult hit;
201+
actor->AddActorWorldOffset(vec, sweep, &hit, teleport_physics ? ETeleportType::TeleportPhysics :ETeleportType::None);
202+
203+
if (!sweep) {
204+
Py_RETURN_NONE;
205+
}
206+
207+
return py_ue_new_fhitresult(hit);
125208
}
126209

127210
PyObject *py_ue_add_actor_local_offset(ue_PyUObject *self, PyObject * args) {
128211

129212
ue_py_check(self);
130213

131-
FVector vec;
132-
if (!py_ue_vector_arg(args, vec))
133-
return NULL;
214+
FVector vec;
215+
bool sweep;
216+
bool teleport_physics;
217+
if (!check_vector_args(args, vec, sweep, teleport_physics))
218+
return nullptr;
134219

135220
AActor *actor = ue_get_actor(self);
136221
if (!actor)
137222
PyErr_Format(PyExc_Exception, "uobject is not an actor or a component");
138223

139-
actor->AddActorLocalOffset(vec);
224+
FHitResult hit;
225+
actor->AddActorLocalOffset(vec, sweep, &hit, teleport_physics ? ETeleportType::TeleportPhysics :ETeleportType::None);
226+
227+
if (!sweep) {
228+
Py_RETURN_NONE;
229+
}
230+
231+
return py_ue_new_fhitresult(hit);
140232

141-
Py_INCREF(Py_None);
142-
return Py_None;
143233
}
144234

145235
PyObject *py_ue_add_actor_world_rotation(ue_PyUObject *self, PyObject * args) {
146236

147237
ue_py_check(self);
148238

149-
FRotator rot;
150-
if (!py_ue_rotator_arg(args, rot))
151-
return NULL;
152-
239+
FQuat quat;
240+
bool sweep;
241+
bool teleport_physics;
242+
if (!check_rotation_args(args, quat, sweep, teleport_physics))
243+
return nullptr;
244+
153245
AActor *actor = ue_get_actor(self);
154246
if (!actor)
155247
return PyErr_Format(PyExc_Exception, "uobject is not an actor or a component");
156-
actor->AddActorWorldRotation(rot);
157-
Py_INCREF(Py_None);
158-
return Py_None;
248+
FHitResult hit;
249+
actor->AddActorWorldRotation(quat, sweep, &hit, teleport_physics ? ETeleportType::TeleportPhysics : ETeleportType::None);
250+
251+
if (!sweep) {
252+
Py_RETURN_NONE;
253+
}
254+
255+
return py_ue_new_fhitresult(hit);
159256
}
160257

161258
PyObject *py_ue_add_actor_local_rotation(ue_PyUObject *self, PyObject * args) {
162259

163260
ue_py_check(self);
164261

165-
FRotator rot;
166-
if (!py_ue_rotator_arg(args, rot))
167-
return NULL;
262+
FQuat quat;
263+
bool sweep;
264+
bool teleport_physics;
265+
if (!check_rotation_args(args, quat, sweep, teleport_physics))
266+
return nullptr;
168267

169268
AActor *actor = ue_get_actor(self);
170269
if (!actor)
171270
return PyErr_Format(PyExc_Exception, "uobject is not an actor or a component");
172-
actor->AddActorLocalRotation(rot);
173-
Py_INCREF(Py_None);
174-
return Py_None;
271+
FHitResult hit;
272+
actor->AddActorLocalRotation(quat, sweep, &hit, teleport_physics ? ETeleportType::TeleportPhysics : ETeleportType::None);
273+
274+
if (!sweep) {
275+
Py_RETURN_NONE;
276+
}
277+
278+
return py_ue_new_fhitresult(hit);
279+
175280
}
176281

177282
PyObject *py_ue_set_actor_scale(ue_PyUObject *self, PyObject * args) {
@@ -333,13 +438,19 @@ PyObject *py_ue_get_right_vector(ue_PyUObject *self, PyObject * args) {
333438
PyObject *py_ue_set_world_location(ue_PyUObject *self, PyObject * args) {
334439
ue_py_check(self);
335440
FVector vec;
336-
if (!py_ue_vector_arg(args, vec))
337-
return NULL;
338-
441+
bool sweep;
442+
bool teleport_physics;
443+
if (!check_vector_args(args, vec, sweep, teleport_physics))
444+
return nullptr;
445+
446+
FHitResult hit;
447+
339448
if (self->ue_object->IsA<USceneComponent>()) {
340-
((USceneComponent *)self->ue_object)->SetWorldLocation(vec);
341-
Py_INCREF(Py_None);
342-
return Py_None;
449+
((USceneComponent *)self->ue_object)->SetWorldLocation(vec, sweep, &hit, teleport_physics ? ETeleportType::TeleportPhysics : ETeleportType::None);
450+
if (!sweep) {
451+
Py_RETURN_NONE;
452+
}
453+
return py_ue_new_fhitresult(hit);
343454
}
344455
return PyErr_Format(PyExc_Exception, "uobject is not a USceneComponent");
345456
}
@@ -442,4 +553,4 @@ PyObject *py_ue_set_relative_scale(ue_PyUObject *self, PyObject * args) {
442553
return Py_None;
443554
}
444555
return PyErr_Format(PyExc_Exception, "uobject is not a USceneComponent");
445-
}
556+
}

‎Source/UnrealEnginePython/Private/Wrappers/UEPyFRotator.cpp‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,14 @@ PySequenceMethods ue_PyFRotator_sequence_methods;
224224

225225
static int ue_py_frotator_init(ue_PyFRotator *self, PyObject *args, PyObject *kwargs) {
226226
float pitch = 0, yaw = 0, roll = 0;
227+
228+
if (PyTuple_Size(args) == 1) {
229+
if (ue_PyFQuat *py_quat = py_ue_is_fquat(PyTuple_GetItem(args, 0))) {
230+
self->rot = FRotator(py_quat->quat);
231+
return 0;
232+
}
233+
}
234+
227235
if (!PyArg_ParseTuple(args, "|fff", &roll, &pitch, &yaw))
228236
return -1;
229237

0 commit comments

Comments
 (0)