Compare commits
10 commits
62c36b9660
...
1b7b915548
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1b7b915548 | ||
![]() |
315ae2d3b4 | ||
![]() |
0ca2972218 | ||
![]() |
b60cf6cb6c | ||
![]() |
4d28ff8829 | ||
![]() |
f79fda16e9 | ||
![]() |
a9bc57a175 | ||
![]() |
30d8182f4d | ||
![]() |
b3f9d7222e | ||
![]() |
2fbc198d7d |
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
resources/building_a.glb
Normal file
BIN
resources/building_a.glb
Normal file
Binary file not shown.
BIN
resources/building_b.glb
Normal file
BIN
resources/building_b.glb
Normal file
Binary file not shown.
BIN
resources/building_c.glb
Normal file
BIN
resources/building_c.glb
Normal file
Binary file not shown.
BIN
resources/building_d.glb
Normal file
BIN
resources/building_d.glb
Normal file
Binary file not shown.
|
@ -1,4 +1,5 @@
|
|||
#include "camera_controller.h"
|
||||
#include "core/camera_node.h"
|
||||
#include "utils/mirror.h"
|
||||
|
||||
START_REFLECT(CameraController);
|
||||
|
@ -18,10 +19,11 @@ SceneNode *CreateCameraController(Transformable target) {
|
|||
CameraController *self = new(CameraController);
|
||||
*self = (CameraController){
|
||||
.transform = tc_null(Transformable),
|
||||
.rotation_speed = 5.f,
|
||||
.rotation_speed = 2.f,
|
||||
.max_speed_time = 4.f,
|
||||
.target = target,
|
||||
.time_rotated = 0.f
|
||||
.time_rotated = 0.f,
|
||||
.camera = NULL,
|
||||
};
|
||||
SceneNode *node = CreateSceneNode(CameraController_as_SceneNodeEntity(self));
|
||||
return node;
|
||||
|
@ -34,6 +36,9 @@ 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) {}
|
||||
|
@ -49,11 +54,10 @@ 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, fminf(fminf(step, angle) / angle, 0.99f));
|
||||
target.rotation = QuaternionSlerp(current.rotation, target.rotation, step);
|
||||
if(step > angle && self->time_rotated > delta)
|
||||
self->time_rotated -= 3.f * delta;
|
||||
else if(step > angle)
|
||||
self->time_rotated = 0.f;
|
||||
self->time_rotated += delta;
|
||||
self->time_rotated -= delta;
|
||||
else
|
||||
self->time_rotated += delta;
|
||||
self->transform.tc->set_global_transform(self->transform.data, target);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ typedef struct CameraController {
|
|||
float max_speed_time;
|
||||
Transformable target;
|
||||
float time_rotated;
|
||||
CameraNode *camera;
|
||||
} CameraController;
|
||||
|
||||
extern SceneNode *CreateCameraController(Transformable target);
|
||||
|
|
45
src/city_generator.c
Normal file
45
src/city_generator.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
#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;
|
||||
}
|
8
src/city_generator.h
Normal file
8
src/city_generator.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef CITY_GENERATOR_H
|
||||
#define CITY_GENERATOR_H
|
||||
|
||||
#include "core/scene.h"
|
||||
|
||||
extern SceneNode *GenerateCity();
|
||||
|
||||
#endif // !CITY_GENERATOR_H
|
|
@ -20,6 +20,11 @@ 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));
|
||||
}
|
||||
|
||||
|
@ -51,7 +56,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 = 90,
|
||||
.fovy = self->fov,
|
||||
.position = global_transform.translation,
|
||||
.projection = CAMERA_PERSPECTIVE,
|
||||
.target = Vector3Add(global_transform.translation, forward),
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
typedef struct CameraNode {
|
||||
SceneNode *node;
|
||||
Transformable transform;
|
||||
float fov;
|
||||
} CameraNode;
|
||||
|
||||
//! Instantiate new camera node
|
||||
|
|
|
@ -54,7 +54,6 @@ 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, "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;
|
||||
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);
|
||||
*out = (ModelResource) {
|
||||
.handle = container,
|
||||
.resource = &container->model
|
||||
|
@ -174,16 +174,20 @@ bool IsResourceLoaded(ResourceHandle handle) {
|
|||
|
||||
void LoadResource(ResourceHandle handle) {
|
||||
ASSERT_RETURN(handle != NULL,, "LoadResource: Resource handle invalid");
|
||||
g_load_functions[handle->type](handle);
|
||||
handle->is_loaded = true;
|
||||
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);
|
||||
g_unload_functions[handle->type](handle);
|
||||
handle->is_loaded = false;
|
||||
if(handle->use_counter == 1) {
|
||||
g_unload_functions[handle->type](handle);
|
||||
handle->is_loaded = false;
|
||||
}
|
||||
--handle->use_counter;
|
||||
}
|
||||
|
||||
|
|
|
@ -170,8 +170,23 @@ SceneNode *SceneNodeGetChildByTypeclass(SceneNode *self, char const *typeclass,
|
|||
SceneNodeEntity entity = (*child)->entity;
|
||||
if(mirror_get_function(entity.data, entity.mirror, typeclass))
|
||||
return *child;
|
||||
if(recurse)
|
||||
SceneNodeGetChildByTypeclass(*child, typeclass, recurse);
|
||||
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;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -41,10 +41,12 @@ 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 that implements a specific typeclass.
|
||||
//! Returns the first child node with an entity 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,6 +1,7 @@
|
|||
#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"
|
||||
|
@ -48,6 +49,7 @@ Scene *CreateInitialScene() {
|
|||
SceneNodeAddChild(root, model);
|
||||
SceneNodeAddChild(root, camera_scene);
|
||||
SceneNodeAddChild(camera_scene, CreateCameraController(TC_CAST(model->entity, Transformable)));
|
||||
SceneNodeAddChild(root, GenerateCity());
|
||||
return CreateScene(root);
|
||||
}
|
||||
|
||||
|
@ -56,7 +58,10 @@ 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("stop", INPUT_LISTENER_KEY, 0, KEY_SPACE);
|
||||
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);
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#include "player_controller.h"
|
||||
#include "core/render.h"
|
||||
#include "utils/debug.h"
|
||||
#include "core/input.h"
|
||||
#include "utils/typeclass_helpers.h"
|
||||
#include "utils/debug.h"
|
||||
#include "raylib.h"
|
||||
|
||||
START_REFLECT(PlayerController);
|
||||
|
@ -19,10 +20,25 @@ 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->rotation = self->fly_input = Vector2Zero();
|
||||
self->stopped = false;
|
||||
*self = (PlayerController) {
|
||||
.node = NULL,
|
||||
.transform = tc_null(Transformable),
|
||||
.rotation = Vector3Zero(),
|
||||
.fly_input = Vector3Zero(),
|
||||
.speed = 10.f,
|
||||
.brake = false
|
||||
};
|
||||
return CreateSceneNode(PlayerController_as_SceneNodeEntity(self));
|
||||
}
|
||||
|
||||
|
@ -33,32 +49,42 @@ void DestroyPlayerController(PlayerController *self) {
|
|||
void PlayerControllerEnterTree(PlayerController *self) {
|
||||
self->transform = TC_CAST(self->node->parent->entity, Transformable);
|
||||
DisableCursor();
|
||||
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));
|
||||
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));
|
||||
}
|
||||
|
||||
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) {
|
||||
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)));
|
||||
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);
|
||||
}
|
||||
|
||||
//! linear acceleration limited to the local Z axis
|
||||
static
|
||||
void PlayerControllerTickLinearAcceleration(PlayerController *self, double delta) {
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
//! Update linear transform based on velocities
|
||||
|
@ -66,9 +92,11 @@ 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 * 2.f * delta), global_transform.rotation);
|
||||
global_transform.rotation = QuaternionMultiply(QuaternionFromAxisAngle(MATRIX_RIGHT(global_matrix), self->rotation.y * 2.5f * delta), global_transform.rotation);
|
||||
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);
|
||||
self->transform.tc->set_global_transform(self->transform.data, global_transform);
|
||||
}
|
||||
|
||||
|
@ -78,22 +106,34 @@ void PlayerControllerTick(PlayerController *self, double delta) {
|
|||
PlayerControllerTickTransform(self, delta);
|
||||
}
|
||||
|
||||
void PlayerControllerLeftInput(PlayerController *self, bool value) {
|
||||
void PlayerControllerInputRollLeft(PlayerController *self, bool value) {
|
||||
self->fly_input.x += value ? -1 : +1;
|
||||
}
|
||||
|
||||
void PlayerControllerRightInput(PlayerController *self, bool value) {
|
||||
void PlayerControllerInputRollRight(PlayerController *self, bool value) {
|
||||
self->fly_input.x += value ? +1 : -1;
|
||||
}
|
||||
|
||||
void PlayerControllerUpInput(PlayerController *self, bool value) {
|
||||
void PlayerControllerInputPitchUp(PlayerController *self, bool value) {
|
||||
self->fly_input.y += value ? -1 : +1;
|
||||
}
|
||||
|
||||
void PlayerControllerDownInput(PlayerController *self, bool value) {
|
||||
void PlayerControllerInputPitchDown(PlayerController *self, bool value) {
|
||||
self->fly_input.y += value ? +1 : -1;
|
||||
}
|
||||
|
||||
void PlayerControllerStopInput(PlayerController *self, bool value) {
|
||||
self->stopped = value;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -12,10 +12,11 @@
|
|||
typedef struct PlayerController {
|
||||
SceneNode *node;
|
||||
Transformable transform;
|
||||
Vector2 fly_input;
|
||||
Vector2 rotation;
|
||||
Vector3 fly_input;
|
||||
Vector3 rotation;
|
||||
float speed;
|
||||
bool stopped;
|
||||
bool brake;
|
||||
bool boost;
|
||||
} PlayerController;
|
||||
|
||||
SceneNode *CreatePlayerController();
|
||||
|
@ -25,11 +26,14 @@ extern void PlayerControllerEnterTree(PlayerController *self);
|
|||
extern void PlayerControllerExitTree(PlayerController *self);
|
||||
extern void PlayerControllerTick(PlayerController *self, double delta);
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
DECL_REFLECT(PlayerController);
|
||||
decl_typeclass_impl(SceneNodeEntity, PlayerController);
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit faf0463e3791ee97dfc370282ecad4cd3b4ca475
|
||||
Subproject commit bb201d5085cfb2e54ebad9a0bf22347a5251f7a2
|
Loading…
Reference in a new issue