Example Camera

This commit is contained in:
2026-06-01 23:04:55 -05:00
parent b14196ff0d
commit d73edb403f
11 changed files with 436 additions and 22 deletions
+12 -14
View File
@@ -9,29 +9,27 @@
#include "console/console.h"
#include "scene/scene.h"
#include "script/script.h"
#include "time/time.h"
#include "ui/uiloading.h"
#include "entity/entitymanager.h"
#include "entity/entity.h"
#include "entity/component/display/entityposition.h"
#include "entity/component/display/entityrenderable.h"
void initialSceneInit(void) {
consolePrint("Initial scene initialized");
// Cube entity — RENDERABLE init defaults to a white unit cube at origin
entityid_t cubeId = entityManagerAdd();
SCENE.data.initial.cubeEntityId = cubeId;
entityAddComponent(cubeId, COMPONENT_TYPE_POSITION);
entityAddComponent(cubeId, COMPONENT_TYPE_RENDERABLE);
errorCatch(errorPrint(scriptExecFile("testentity.js")));
// SCENE.data.initial.timer = 0.0f;
// SCENE.data.initial.hiding = false;
// uiLoadingShow(NULL, NULL);
}
errorret_t initialSceneUpdate(void) {
// initialscene_t *scene = &SCENE.data.initial;
// if(scene->hiding) errorOk();
// scene->timer += TIME.delta;
// if(scene->timer >= INITIAL_SCENE_WAIT) {
// scene->hiding = true;
// uiLoadingHide(NULL, NULL);
// }
errorOk();
}
void initialSceneDispose(void) {
entityDispose(SCENE.data.initial.cubeEntityId);
}
+2 -4
View File
@@ -7,12 +7,10 @@
#pragma once
#include "error/error.h"
#define INITIAL_SCENE_WAIT 2.0f
#include "entity/entitybase.h"
typedef struct {
float_t timer;
bool_t hiding;
entityid_t cubeEntityId;
} initialscene_t;
void initialSceneInit(void);
@@ -0,0 +1,174 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "script/module/modulebase.h"
#include "script/scriptproto.h"
#include "script/module/entity/modulecomponent.h"
#include "entity/component/display/entitycamera.h"
static scriptproto_t MODULE_CAMERA_PROTO;
moduleBaseFunction(moduleCameraCtor) {
(void)callInfo; (void)args; (void)argc;
return moduleBaseThrow("Camera cannot be instantiated with new");
}
static inline jscomponent_t *moduleCameraSelf(
const jerry_call_info_t *callInfo
) {
return (jscomponent_t *)scriptProtoGetValue(
&MODULE_CAMERA_PROTO, callInfo->this_value
);
}
static inline entitycamera_t *moduleCameraData(const jscomponent_t *c) {
return (entitycamera_t *)componentGetData(
c->entityId, c->componentId, COMPONENT_TYPE_CAMERA
);
}
moduleBaseFunction(moduleCameraGetEntity) {
jscomponent_t *c = moduleCameraSelf(callInfo);
if(!c) return jerry_undefined();
return jerry_number((double)c->entityId);
}
moduleBaseFunction(moduleCameraGetId) {
jscomponent_t *c = moduleCameraSelf(callInfo);
if(!c) return jerry_undefined();
return jerry_number((double)c->componentId);
}
moduleBaseFunction(moduleCameraGetFov) {
jscomponent_t *c = moduleCameraSelf(callInfo);
if(!c) return jerry_undefined();
entitycamera_t *cam = moduleCameraData(c);
if(!cam) return jerry_undefined();
return jerry_number((double)cam->perspective.fov);
}
moduleBaseFunction(moduleCameraSetFov) {
moduleBaseRequireArgs(1);
jscomponent_t *c = moduleCameraSelf(callInfo);
if(!c) return jerry_undefined();
entitycamera_t *cam = moduleCameraData(c);
if(!cam) return jerry_undefined();
cam->perspective.fov = moduleBaseArgFloat(0);
return jerry_undefined();
}
moduleBaseFunction(moduleCameraGetNearClip) {
jscomponent_t *c = moduleCameraSelf(callInfo);
if(!c) return jerry_undefined();
entitycamera_t *cam = moduleCameraData(c);
if(!cam) return jerry_undefined();
return jerry_number((double)cam->nearClip);
}
moduleBaseFunction(moduleCameraSetNearClip) {
moduleBaseRequireArgs(1);
jscomponent_t *c = moduleCameraSelf(callInfo);
if(!c) return jerry_undefined();
entitycamera_t *cam = moduleCameraData(c);
if(!cam) return jerry_undefined();
cam->nearClip = moduleBaseArgFloat(0);
return jerry_undefined();
}
moduleBaseFunction(moduleCameraGetFarClip) {
jscomponent_t *c = moduleCameraSelf(callInfo);
if(!c) return jerry_undefined();
entitycamera_t *cam = moduleCameraData(c);
if(!cam) return jerry_undefined();
return jerry_number((double)cam->farClip);
}
moduleBaseFunction(moduleCameraSetFarClip) {
moduleBaseRequireArgs(1);
jscomponent_t *c = moduleCameraSelf(callInfo);
if(!c) return jerry_undefined();
entitycamera_t *cam = moduleCameraData(c);
if(!cam) return jerry_undefined();
cam->farClip = moduleBaseArgFloat(0);
return jerry_undefined();
}
moduleBaseFunction(moduleCameraGetProjType) {
jscomponent_t *c = moduleCameraSelf(callInfo);
if(!c) return jerry_undefined();
entitycamera_t *cam = moduleCameraData(c);
if(!cam) return jerry_undefined();
return jerry_number((double)cam->projType);
}
moduleBaseFunction(moduleCameraSetProjType) {
moduleBaseRequireArgs(1);
jscomponent_t *c = moduleCameraSelf(callInfo);
if(!c) return jerry_undefined();
entitycamera_t *cam = moduleCameraData(c);
if(!cam) return jerry_undefined();
cam->projType = (entitycameraprojectiontype_t)moduleBaseArgInt(0);
return jerry_undefined();
}
moduleBaseFunction(moduleCameraToString) {
jscomponent_t *c = moduleCameraSelf(callInfo);
if(!c) return jerry_string_sz("Camera:invalid");
char_t buf[32];
snprintf(buf, sizeof(buf), "Camera(%u)", (unsigned)c->componentId);
return jerry_string_sz(buf);
}
static void moduleCameraInit(void) {
scriptProtoInit(
&MODULE_CAMERA_PROTO, "Camera",
sizeof(jscomponent_t), moduleCameraCtor
);
scriptProtoDefineProp(
&MODULE_CAMERA_PROTO, "entity", moduleCameraGetEntity, NULL
);
scriptProtoDefineProp(
&MODULE_CAMERA_PROTO, "id", moduleCameraGetId, NULL
);
scriptProtoDefineProp(
&MODULE_CAMERA_PROTO, "fov", moduleCameraGetFov, moduleCameraSetFov
);
scriptProtoDefineProp(
&MODULE_CAMERA_PROTO, "nearClip",
moduleCameraGetNearClip, moduleCameraSetNearClip
);
scriptProtoDefineProp(
&MODULE_CAMERA_PROTO, "farClip",
moduleCameraGetFarClip, moduleCameraSetFarClip
);
scriptProtoDefineProp(
&MODULE_CAMERA_PROTO, "projType",
moduleCameraGetProjType, moduleCameraSetProjType
);
scriptProtoDefineToString(&MODULE_CAMERA_PROTO, moduleCameraToString);
/* Camera.PERSPECTIVE, Camera.PERSPECTIVE_FLIPPED, Camera.ORTHOGRAPHIC */
jerry_value_t ctor = MODULE_CAMERA_PROTO.constructor;
struct { const char_t *name; int val; } projtypes[] = {
{ "PERSPECTIVE", ENTITY_CAMERA_PROJECTION_TYPE_PERSPECTIVE },
{ "PERSPECTIVE_FLIPPED", ENTITY_CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED },
{ "ORTHOGRAPHIC", ENTITY_CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC },
};
for(int i = 0; i < 3; i++) {
jerry_value_t k = jerry_string_sz(projtypes[i].name);
jerry_value_t v = jerry_number((double)projtypes[i].val);
jerry_object_set(ctor, k, v);
jerry_value_free(v);
jerry_value_free(k);
}
}
static void moduleCameraDispose(void) {
scriptProtoDispose(&MODULE_CAMERA_PROTO);
}
@@ -7,6 +7,7 @@
#pragma once
#include "script/module/entity/modulecomponent.h"
#include "camera/modulecamera.h"
#include "position/moduleposition.h"
/**
@@ -20,6 +21,8 @@ static jerry_value_t moduleComponentListCreateInstance(
switch(type) {
case COMPONENT_TYPE_POSITION:
return scriptProtoCreateValue(&MODULE_POSITION_PROTO, comp);
case COMPONENT_TYPE_CAMERA:
return scriptProtoCreateValue(&MODULE_CAMERA_PROTO, comp);
default:
return scriptProtoCreateValue(&MODULE_COMPONENT_PROTO, comp);
}
@@ -27,8 +30,10 @@ static jerry_value_t moduleComponentListCreateInstance(
static void moduleComponentListInit(void) {
modulePositionInit();
moduleCameraInit();
}
static void moduleComponentListDispose(void) {
moduleCameraDispose();
modulePositionDispose();
}
@@ -147,6 +147,26 @@ moduleBaseFunction(modulePositionSetWorldScale) {
return jerry_undefined();
}
moduleBaseFunction(modulePositionLookAt) {
jscomponent_t *c = modulePositionSelf(callInfo);
if(!c) return jerry_undefined();
moduleBaseRequireArgs(1);
float_t *target = moduleVec3From(args[0]);
if(!target) return moduleBaseThrow("Position.lookAt: expected Vec3 target");
vec3 eye;
entityPositionGetLocalPosition(c->entityId, c->componentId, eye);
vec3 up = { 0.0f, 1.0f, 0.0f };
if(argc >= 2) {
float_t *upArg = moduleVec3From(args[1]);
if(upArg) glm_vec3_copy(upArg, up);
}
entityPositionLookAt(c->entityId, c->componentId, eye, target, up);
return jerry_undefined();
}
moduleBaseFunction(modulePositionSetParent) {
jscomponent_t *c = modulePositionSelf(callInfo);
if(!c) return jerry_undefined();
@@ -214,6 +234,9 @@ static void modulePositionInit(void) {
&MODULE_POSITION_PROTO, "worldScale",
modulePositionGetWorldScale, modulePositionSetWorldScale
);
scriptProtoDefineFunc(
&MODULE_POSITION_PROTO, "lookAt", modulePositionLookAt
);
scriptProtoDefineFunc(
&MODULE_POSITION_PROTO, "setParent", modulePositionSetParent
);
@@ -12,8 +12,43 @@
static scriptproto_t MODULE_SCENE_PROTO;
moduleBaseFunction(moduleSceneGetCurrent) {
return jerry_number((double)SCENE.type);
}
moduleBaseFunction(moduleSceneSet) {
moduleBaseRequireArgs(1);
moduleBaseRequireNumber(0);
const scenetype_t type = (scenetype_t)moduleBaseArgInt(0);
if(type <= SCENE_TYPE_NULL || type >= SCENE_TYPE_COUNT) {
return moduleBaseThrow("Scene.set: invalid scene type");
}
sceneSet(type);
return jerry_undefined();
}
static void moduleSceneInit(void) {
scriptProtoInit(&MODULE_SCENE_PROTO, "Scene", sizeof(uint8_t), NULL);
scriptProtoDefineStaticProp(
&MODULE_SCENE_PROTO, "current", moduleSceneGetCurrent, NULL
);
scriptProtoDefineStaticFunc(
&MODULE_SCENE_PROTO, "set", moduleSceneSet
);
/* Scene.INITIAL, Scene.TEST, Scene.OVERWORLD, ... */
jerry_value_t global = MODULE_SCENE_PROTO.prototype;
#define X(structName, varName, varNameUpper, initFunc, updateFunc, disposeFunc) \
do { \
jerry_value_t _key = jerry_string_sz(#varNameUpper); \
jerry_value_t _val = jerry_number((double)SCENE_TYPE_##varNameUpper); \
jerry_object_set(global, _key, _val); \
jerry_value_free(_val); \
jerry_value_free(_key); \
} while(0);
#include "scene/scenelist.h"
#undef X
}
static void moduleSceneDispose(void) {