Compare commits
No commits in common. "1b7b915548da503993ceebdadd8d5c2784c7fcbf" and "62c36b96600ea90eb32d9618844306a835fc4240" have entirely different histories.
1b7b915548
...
62c36b9660
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,5 +1,4 @@
|
|||
#include "camera_controller.h"
|
||||
#include "core/camera_node.h"
|
||||
#include "utils/mirror.h"
|
||||
|
||||
START_REFLECT(CameraController);
|
||||
|
@ -19,11 +18,10 @@ SceneNode *CreateCameraController(Transformable target) {
|
|||
CameraController *self = new(CameraController);
|
||||
*self = (CameraController){
|
||||
.transform = tc_null(Transformable),
|
||||
.rotation_speed = 2.f,
|
||||
.rotation_speed = 5.f,
|
||||
.max_speed_time = 4.f,
|
||||
.target = target,
|
||||
.time_rotated = 0.f,
|
||||
.camera = NULL,
|
||||
.time_rotated = 0.f
|
||||
};
|
||||
SceneNode *node = CreateSceneNode(CameraController_as_SceneNodeEntity(self));
|
||||
return node;
|
||||
|
@ -36,9 +34,6 @@ void DestroyCameraController(CameraController *self) {
|
|||
void CameraControllerEnterTree(CameraController *self) {
|
||||
self->transform = TC_CAST(self->node->parent->entity, Transformable);
|
||||
self->global = self->transform.tc->get_global_transform(self->transform.data);
|
||||
SceneNode *camera_node = SceneNodeGetChildByTypeid(self->node->parent, GET_TYPEID(CameraNode), true);
|
||||
self->camera = camera_node->entity.data;
|
||||
self->camera->fov = 100;
|
||||
}
|
||||
|
||||
void CameraControllerExitTree(CameraController *self) {}
|
||||
|
@ -54,10 +49,11 @@ void CameraControllerTick(CameraController *self, double delta) {
|
|||
// ... and maximum frame step size
|
||||
float const step = self->rotation_speed * time_mul * delta;
|
||||
if(angle > 0.f)
|
||||
target.rotation = QuaternionSlerp(current.rotation, target.rotation, step);
|
||||
target.rotation = QuaternionSlerp(current.rotation, target.rotation, fminf(fminf(step, angle) / angle, 0.99f));
|
||||
if(step > angle && self->time_rotated > delta)
|
||||
self->time_rotated -= delta;
|
||||
else
|
||||
self->time_rotated -= 3.f * delta;
|
||||
else if(step > angle)
|
||||
self->time_rotated = 0.f;
|
||||
self->time_rotated += delta;
|
||||
self->transform.tc->set_global_transform(self->transform.data, target);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ typedef struct CameraController {
|
|||
float max_speed_time;
|
||||
Transformable target;
|
||||
float time_rotated;
|
||||
CameraNode *camera;
|
||||
} CameraController;
|
||||
|
||||
extern SceneNode *CreateCameraController(Transformable target);
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
#include "city_generator.h"
|
||||
#include "core/mesh_render_entity.h"
|
||||
#include "core/transform_node.h"
|
||||
|
||||
static struct {
|
||||
size_t x, y;
|
||||
} const CITY_SIZE = {20, 20};
|
||||
|
||||
#define MODELS_LENGTH 4
|
||||
static ModelResource models[MODELS_LENGTH] = {
|
||||
ResourceEmpty(Model),
|
||||
ResourceEmpty(Model),
|
||||
ResourceEmpty(Model),
|
||||
ResourceEmpty(Model)
|
||||
};
|
||||
|
||||
static void Internal_LoadModelsIfRequired() {
|
||||
for(size_t i = 0; i < MODELS_LENGTH; ++i)
|
||||
if(models[i].handle == NULL && GetModelResource(TextFormat("building_%c", 'a' + i), &models[i]))
|
||||
LoadResource(models[i].handle);
|
||||
}
|
||||
|
||||
static SceneNode *Internal_CreateBuilding(size_t x, size_t y) {
|
||||
size_t building_index = (3 * (x + y + GetRandomValue(0, 50))) % MODELS_LENGTH; // semi-random number based on the x,y coordinate
|
||||
SceneNode *mesh_render_node = CreateMeshRenderEntity(TextFormat("building_%c", 'a' + building_index));
|
||||
SceneNode *transform_node = CreateTransformNode();
|
||||
SceneNodeAddChild(transform_node, mesh_render_node);
|
||||
Transformable transform = TC_CAST(transform_node->entity, Transformable);
|
||||
Transform local = transform.tc->get_transform(transform.data);
|
||||
local.translation.x = (float)(x * 40);
|
||||
local.translation.z = (float)(y * 40);
|
||||
transform.tc->set_transform(transform.data, local);
|
||||
return transform_node;
|
||||
}
|
||||
|
||||
SceneNode *GenerateCity() {
|
||||
Internal_LoadModelsIfRequired();
|
||||
SceneNode *root = CreateTransformNode();
|
||||
for(size_t x = 0; x < CITY_SIZE.x; ++x) {
|
||||
for(size_t y = 0; y < CITY_SIZE.y; ++y) {
|
||||
SceneNodeAddChild(root, Internal_CreateBuilding(x, y));
|
||||
}
|
||||
}
|
||||
return root;
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
#ifndef CITY_GENERATOR_H
|
||||
#define CITY_GENERATOR_H
|
||||
|
||||
#include "core/scene.h"
|
||||
|
||||
extern SceneNode *GenerateCity();
|
||||
|
||||
#endif // !CITY_GENERATOR_H
|
|
@ -20,11 +20,6 @@ impl_SceneNodeEntity_for(CameraNode,
|
|||
|
||||
SceneNode *CreateCameraNode() {
|
||||
CameraNode *self = new(CameraNode);
|
||||
*self = (CameraNode){
|
||||
.fov = 60,
|
||||
.node = NULL,
|
||||
.transform = tc_null(Transformable)
|
||||
};
|
||||
return CreateSceneNode(CameraNode_as_SceneNodeEntity(self));
|
||||
}
|
||||
|
||||
|
@ -56,7 +51,7 @@ Camera3D CameraNodeGetCamera(CameraNode *self) {
|
|||
Vector3 forward = MATRIX_FORWARD(mat);
|
||||
// construct a new camera at the global transform location and facing the forward vector
|
||||
return (Camera3D){
|
||||
.fovy = self->fov,
|
||||
.fovy = 90,
|
||||
.position = global_transform.translation,
|
||||
.projection = CAMERA_PERSPECTIVE,
|
||||
.target = Vector3Add(global_transform.translation, forward),
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
typedef struct CameraNode {
|
||||
SceneNode *node;
|
||||
Transformable transform;
|
||||
float fov;
|
||||
} CameraNode;
|
||||
|
||||
//! Instantiate new camera node
|
||||
|
|
|
@ -54,6 +54,7 @@ void RenderNextFrame() {
|
|||
BeginMode3D(CameraNodeGetCamera(camera));
|
||||
list_foreach(Renderable *,object, &g_render_objects)
|
||||
object->tc->draw(object->data);
|
||||
DrawGrid(500, 1.f); // TODO Remove this (or make it a scene node entity)
|
||||
EndMode3D();
|
||||
}
|
||||
DrawFPS(20, 20);
|
||||
|
|
|
@ -132,9 +132,9 @@ bool GetModelResource(char const *path, ModelResource *out) {
|
|||
ResourceContainer *container = hash_map_get_as(ResourceContainer, &g_resource_map, &path);
|
||||
*out = ResourceEmpty(Model);
|
||||
// assert some assumptions about the found resource
|
||||
ASSERT_RETURN(container != NULL, false, "GetModelResource: Resource %s not in index.", path);
|
||||
ASSERT_RETURN(container->type == RESOURCE_MODEL, false, "GetModelResource: Resource %s is not a Texture.", path);
|
||||
ASSERT_RETURN(strcmp(container->name, path) == 0, false, "GetModelResource: Resource %s was loaded for path %s", container->name, path);
|
||||
ASSERT_RETURN(container != NULL, false, "GetTextureResource: Resource %s not in index.", path);
|
||||
ASSERT_RETURN(container->type == RESOURCE_MODEL, false, "GetTextureResource: Resource %s is not a Texture.", path);
|
||||
++container->use_counter;
|
||||
*out = (ModelResource) {
|
||||
.handle = container,
|
||||
.resource = &container->model
|
||||
|
@ -174,20 +174,16 @@ bool IsResourceLoaded(ResourceHandle handle) {
|
|||
|
||||
void LoadResource(ResourceHandle handle) {
|
||||
ASSERT_RETURN(handle != NULL,, "LoadResource: Resource handle invalid");
|
||||
if(!handle->is_loaded) {
|
||||
g_load_functions[handle->type](handle);
|
||||
handle->is_loaded = true;
|
||||
}
|
||||
++handle->use_counter;
|
||||
}
|
||||
|
||||
void ReleaseResource(ResourceHandle handle) {
|
||||
ASSERT_RETURN(handle != NULL,, "ReleaseResource: Resource handle invalid");
|
||||
ASSERT_RETURN_WARN(handle->is_loaded,, "ReleaseResource: Resource %s is not loaded.", handle->path);
|
||||
if(handle->use_counter == 1) {
|
||||
g_unload_functions[handle->type](handle);
|
||||
handle->is_loaded = false;
|
||||
}
|
||||
--handle->use_counter;
|
||||
}
|
||||
|
||||
|
|
|
@ -170,23 +170,8 @@ SceneNode *SceneNodeGetChildByTypeclass(SceneNode *self, char const *typeclass,
|
|||
SceneNodeEntity entity = (*child)->entity;
|
||||
if(mirror_get_function(entity.data, entity.mirror, typeclass))
|
||||
return *child;
|
||||
if(recurse) {
|
||||
SceneNode *recursed = SceneNodeGetChildByTypeclass(*child, typeclass, recurse);
|
||||
if(recursed != NULL) return recursed;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SceneNode *SceneNodeGetChildByTypeid(SceneNode *self, typeid id, bool recurse) {
|
||||
list_foreach(SceneNode **,child, &self->children) {
|
||||
SceneNodeEntity entity = (*child)->entity;
|
||||
if(entity.mirror->get_typeid() == id)
|
||||
return *child;
|
||||
if(recurse) {
|
||||
SceneNode *recursed = SceneNodeGetChildByTypeid(*child, id, recurse);
|
||||
if(recursed != NULL) return recursed;
|
||||
}
|
||||
if(recurse)
|
||||
SceneNodeGetChildByTypeclass(*child, typeclass, recurse);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -41,12 +41,10 @@ extern void SceneNodeRemoveChild(SceneNode *self, SceneNode *child);
|
|||
extern void SceneNodeAttachEntity(SceneNode *self, SceneNodeEntity entity);
|
||||
//! Detach an entity from a scene node
|
||||
extern SceneNodeEntity SceneNodeDetachEntity(SceneNode *self);
|
||||
//! Returns the first child node with an entity that implements a specific typeclass.
|
||||
//! Returns the first child node that implements a specific typeclass.
|
||||
//! Optionally recurses through the entire branch
|
||||
extern SceneNode *SceneNodeGetChildByTypeclass(SceneNode *self, char const *typeclass, bool recurse);
|
||||
//! Returns the first child node with an entity that matches the given typeid.
|
||||
//! Optionally recurses through the entire branch.
|
||||
extern SceneNode *SceneNodeGetChildByTypeid(SceneNode *self, typeid id, bool recurse);
|
||||
|
||||
//! Instantiate a new scene with a root node.
|
||||
extern Scene *CreateScene(SceneNode *root);
|
||||
//! Destroy a node and it's scene tree.
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "raylib.h"
|
||||
#include "player_controller.h"
|
||||
#include "camera_controller.h"
|
||||
#include "city_generator.h"
|
||||
#include "core/input.h"
|
||||
#include "core/camera_node.h"
|
||||
#include "core/engine_global.h"
|
||||
|
@ -49,7 +48,6 @@ Scene *CreateInitialScene() {
|
|||
SceneNodeAddChild(root, model);
|
||||
SceneNodeAddChild(root, camera_scene);
|
||||
SceneNodeAddChild(camera_scene, CreateCameraController(TC_CAST(model->entity, Transformable)));
|
||||
SceneNodeAddChild(root, GenerateCity());
|
||||
return CreateScene(root);
|
||||
}
|
||||
|
||||
|
@ -58,10 +56,7 @@ void ConfigureInput() {
|
|||
AddAction("pitch_down", INPUT_LISTENER_KEY, 0, KEY_W);
|
||||
AddAction("roll_left", INPUT_LISTENER_KEY, 0, KEY_A);
|
||||
AddAction("roll_right", INPUT_LISTENER_KEY, 0, KEY_D);
|
||||
AddAction("yaw_right", INPUT_LISTENER_KEY, 0, KEY_E);
|
||||
AddAction("yaw_left", INPUT_LISTENER_KEY, 0, KEY_Q);
|
||||
AddAction("brake", INPUT_LISTENER_KEY, 0, KEY_SPACE);
|
||||
AddAction("boost", INPUT_LISTENER_KEY, 0, KEY_LEFT_SHIFT);
|
||||
AddAction("stop", INPUT_LISTENER_KEY, 0, KEY_SPACE);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#include "player_controller.h"
|
||||
#include "core/render.h"
|
||||
#include "core/input.h"
|
||||
#include "utils/typeclass_helpers.h"
|
||||
#include "utils/debug.h"
|
||||
#include "core/input.h"
|
||||
#include "raylib.h"
|
||||
|
||||
START_REFLECT(PlayerController);
|
||||
|
@ -20,25 +19,10 @@ impl_SceneNodeEntity_for(PlayerController,
|
|||
PlayerControllerTick
|
||||
)
|
||||
|
||||
static float const PLAYER_BASE_SPEED = 10.f;
|
||||
static float const PLAYER_BASE_ACCELERATION = 10.f;
|
||||
static float const PLAYER_BOOST_SPEED = 30.f;
|
||||
static float const PLAYER_BOOST_ACCELERATION = 60.f;
|
||||
static float const PLAYER_BRAKE_SPEED = 0.5f;
|
||||
static float const PLAYER_BRAKE_DECELERATION = 10.f;
|
||||
static float const PLAYER_FALL_SPEED = 10.f;
|
||||
static float const PLAYER_FALL_ACCELERATION = 10.f;
|
||||
|
||||
SceneNode *CreatePlayerController() {
|
||||
PlayerController *self = new(PlayerController);
|
||||
*self = (PlayerController) {
|
||||
.node = NULL,
|
||||
.transform = tc_null(Transformable),
|
||||
.rotation = Vector3Zero(),
|
||||
.fly_input = Vector3Zero(),
|
||||
.speed = 10.f,
|
||||
.brake = false
|
||||
};
|
||||
self->rotation = self->fly_input = Vector2Zero();
|
||||
self->stopped = false;
|
||||
return CreateSceneNode(PlayerController_as_SceneNodeEntity(self));
|
||||
}
|
||||
|
||||
|
@ -49,42 +33,32 @@ void DestroyPlayerController(PlayerController *self) {
|
|||
void PlayerControllerEnterTree(PlayerController *self) {
|
||||
self->transform = TC_CAST(self->node->parent->entity, Transformable);
|
||||
DisableCursor();
|
||||
AddListener("pitch_up", ButtonInputListener(self, PlayerControllerInputPitchUp));
|
||||
AddListener("pitch_down", ButtonInputListener(self, PlayerControllerInputPitchDown));
|
||||
AddListener("roll_left", ButtonInputListener(self, PlayerControllerInputRollLeft));
|
||||
AddListener("roll_right", ButtonInputListener(self, PlayerControllerInputRollRight));
|
||||
AddListener("yaw_left", ButtonInputListener(self, PlayerControllerInputYawLeft));
|
||||
AddListener("yaw_right", ButtonInputListener(self, PlayerControllerInputYawRight));
|
||||
AddListener("brake", ButtonInputListener(self, PlayerControllerInputBrake));
|
||||
AddListener("boost", ButtonInputListener(self, PlayerControllerInputBoost));
|
||||
AddListener("pitch_up", ButtonInputListener(self, PlayerControllerUpInput));
|
||||
AddListener("pitch_down", ButtonInputListener(self, PlayerControllerDownInput));
|
||||
AddListener("roll_left", ButtonInputListener(self, PlayerControllerLeftInput));
|
||||
AddListener("roll_right", ButtonInputListener(self, PlayerControllerRightInput));
|
||||
AddListener("stop", ButtonInputListener(self, PlayerControllerStopInput));
|
||||
}
|
||||
|
||||
void PlayerControllerExitTree(PlayerController *self) {
|
||||
RemoveAllListeners(self);
|
||||
}
|
||||
|
||||
static
|
||||
float MoveTowards(float from, float to, float delta) {
|
||||
if(from == to) return to;
|
||||
float const diff = to - from;
|
||||
float const sign = signbit(diff) ? -1.f : 1.f;
|
||||
return from + sign * fminf(delta, fabsf(diff));
|
||||
}
|
||||
|
||||
//! angular acceleration limited to local X and Z axes
|
||||
static
|
||||
void PlayerControllerTickAngularAcceleration(PlayerController *self, double delta) {
|
||||
self->rotation.x = MoveTowards(self->rotation.x, self->fly_input.x, delta * 4.f);
|
||||
self->rotation.y = MoveTowards(self->rotation.y, self->fly_input.y, delta * 4.f);
|
||||
self->rotation.z = MoveTowards(self->rotation.z, self->fly_input.z, delta * 4.f);
|
||||
Vector2 diff = Vector2Subtract(self->fly_input, self->rotation);
|
||||
float const length = Vector2Length(diff);
|
||||
if(length != 0.f)
|
||||
self->rotation = Vector2Add(self->rotation, Vector2Scale(diff, 1.0f/length * fminf(4.f * delta, length)));
|
||||
}
|
||||
|
||||
//! linear acceleration limited to the local Z axis
|
||||
static
|
||||
void PlayerControllerTickLinearAcceleration(PlayerController *self, double delta) {
|
||||
float const target = self->brake ? PLAYER_BRAKE_SPEED : (self->boost ? PLAYER_BOOST_SPEED : PLAYER_BASE_SPEED);
|
||||
float const acceleration = target < self->speed ? PLAYER_BRAKE_DECELERATION : (self->boost ? PLAYER_BOOST_ACCELERATION : PLAYER_BASE_ACCELERATION);
|
||||
self->speed = MoveTowards(self->speed, target, delta * acceleration);
|
||||
float const target = self->stopped ? 10.f : (self->rotation.y == 0.f ? 30.f : 20.f);
|
||||
float const speed_diff = target - self->speed;
|
||||
self->speed = self->speed + copysignf(fminf(fabsf(speed_diff), 10.f * delta), speed_diff);
|
||||
}
|
||||
|
||||
//! Update linear transform based on velocities
|
||||
|
@ -92,11 +66,9 @@ static
|
|||
void PlayerControllerTickTransform(PlayerController *self, double delta) {
|
||||
Transform global_transform = self->transform.tc->get_global_transform(self->transform.data);
|
||||
Matrix global_matrix = TransformGetMatrix(global_transform);
|
||||
float const rotate_speed = 1.f - 0.9f * self->speed / PLAYER_BOOST_SPEED;
|
||||
global_transform.translation = Vector3Add(global_transform.translation, Vector3Scale(MATRIX_FORWARD(global_matrix), self->speed * delta));
|
||||
global_transform.rotation = QuaternionMultiply(QuaternionFromAxisAngle(MATRIX_FORWARD(global_matrix), self->rotation.x * 1.25f * delta), global_transform.rotation);
|
||||
global_transform.rotation = QuaternionMultiply(QuaternionFromAxisAngle(MATRIX_RIGHT(global_matrix), self->rotation.y * rotate_speed * 3.75f * delta), global_transform.rotation);
|
||||
global_transform.rotation = QuaternionMultiply(QuaternionFromAxisAngle(MATRIX_UP(global_matrix), self->rotation.z * rotate_speed * 1.f * delta), global_transform.rotation);
|
||||
global_transform.rotation = QuaternionMultiply(QuaternionFromAxisAngle(MATRIX_FORWARD(global_matrix), self->rotation.x * 2.f * delta), global_transform.rotation);
|
||||
global_transform.rotation = QuaternionMultiply(QuaternionFromAxisAngle(MATRIX_RIGHT(global_matrix), self->rotation.y * 2.5f * delta), global_transform.rotation);
|
||||
self->transform.tc->set_global_transform(self->transform.data, global_transform);
|
||||
}
|
||||
|
||||
|
@ -106,34 +78,22 @@ void PlayerControllerTick(PlayerController *self, double delta) {
|
|||
PlayerControllerTickTransform(self, delta);
|
||||
}
|
||||
|
||||
void PlayerControllerInputRollLeft(PlayerController *self, bool value) {
|
||||
void PlayerControllerLeftInput(PlayerController *self, bool value) {
|
||||
self->fly_input.x += value ? -1 : +1;
|
||||
}
|
||||
|
||||
void PlayerControllerInputRollRight(PlayerController *self, bool value) {
|
||||
void PlayerControllerRightInput(PlayerController *self, bool value) {
|
||||
self->fly_input.x += value ? +1 : -1;
|
||||
}
|
||||
|
||||
void PlayerControllerInputPitchUp(PlayerController *self, bool value) {
|
||||
void PlayerControllerUpInput(PlayerController *self, bool value) {
|
||||
self->fly_input.y += value ? -1 : +1;
|
||||
}
|
||||
|
||||
void PlayerControllerInputPitchDown(PlayerController *self, bool value) {
|
||||
void PlayerControllerDownInput(PlayerController *self, bool value) {
|
||||
self->fly_input.y += value ? +1 : -1;
|
||||
}
|
||||
|
||||
void PlayerControllerInputYawRight(PlayerController *self, bool value) {
|
||||
self->fly_input.z += value ? -1 : +1;
|
||||
}
|
||||
|
||||
void PlayerControllerInputYawLeft(PlayerController *self, bool value) {
|
||||
self->fly_input.z += value ? +1 : -1;
|
||||
}
|
||||
|
||||
void PlayerControllerInputBrake(PlayerController *self, bool value) {
|
||||
self->brake = value;
|
||||
}
|
||||
|
||||
void PlayerControllerInputBoost(PlayerController *self, bool value) {
|
||||
self->boost = value;
|
||||
void PlayerControllerStopInput(PlayerController *self, bool value) {
|
||||
self->stopped = value;
|
||||
}
|
||||
|
|
|
@ -12,11 +12,10 @@
|
|||
typedef struct PlayerController {
|
||||
SceneNode *node;
|
||||
Transformable transform;
|
||||
Vector3 fly_input;
|
||||
Vector3 rotation;
|
||||
Vector2 fly_input;
|
||||
Vector2 rotation;
|
||||
float speed;
|
||||
bool brake;
|
||||
bool boost;
|
||||
bool stopped;
|
||||
} PlayerController;
|
||||
|
||||
SceneNode *CreatePlayerController();
|
||||
|
@ -26,14 +25,11 @@ extern void PlayerControllerEnterTree(PlayerController *self);
|
|||
extern void PlayerControllerExitTree(PlayerController *self);
|
||||
extern void PlayerControllerTick(PlayerController *self, double delta);
|
||||
|
||||
extern void PlayerControllerInputRollLeft(PlayerController *self, bool value);
|
||||
extern void PlayerControllerInputRollRight(PlayerController *self, bool value);
|
||||
extern void PlayerControllerInputPitchUp(PlayerController *self, bool value);
|
||||
extern void PlayerControllerInputPitchDown(PlayerController *self, bool value);
|
||||
extern void PlayerControllerInputYawRight(PlayerController *self, bool value);
|
||||
extern void PlayerControllerInputYawLeft(PlayerController *self, bool value);
|
||||
extern void PlayerControllerInputBrake(PlayerController *self, bool value);
|
||||
extern void PlayerControllerInputBoost(PlayerController *self, bool value);
|
||||
extern void PlayerControllerLeftInput(PlayerController *self, bool value);
|
||||
extern void PlayerControllerRightInput(PlayerController *self, bool value);
|
||||
extern void PlayerControllerUpInput(PlayerController *self, bool value);
|
||||
extern void PlayerControllerDownInput(PlayerController *self, bool value);
|
||||
extern void PlayerControllerStopInput(PlayerController *self, bool value);
|
||||
|
||||
DECL_REFLECT(PlayerController);
|
||||
decl_typeclass_impl(SceneNodeEntity, PlayerController);
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit bb201d5085cfb2e54ebad9a0bf22347a5251f7a2
|
||||
Subproject commit faf0463e3791ee97dfc370282ecad4cd3b4ca475
|
Loading…
Reference in a new issue