Playertest first pass
This commit is contained in:
@@ -0,0 +1,17 @@
|
|||||||
|
module('entity')
|
||||||
|
|
||||||
|
function entityInit()
|
||||||
|
entityPositionAdd(ENTITY_ID)
|
||||||
|
|
||||||
|
local phys = entityPhysicsAdd(ENTITY_ID)
|
||||||
|
phys.bodyType = PHYSICS_BODY_STATIC
|
||||||
|
phys:setShapePlane(0, 1, 0, 0)
|
||||||
|
|
||||||
|
local mesh = entityMeshAdd(ENTITY_ID)
|
||||||
|
mesh:generatePlane(20, 20)
|
||||||
|
|
||||||
|
entityMaterialAdd(ENTITY_ID)
|
||||||
|
end
|
||||||
|
|
||||||
|
function entityDispose()
|
||||||
|
end
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
module('entity')
|
||||||
|
module('input')
|
||||||
|
module('color')
|
||||||
|
module('math')
|
||||||
|
module('scene')
|
||||||
|
module('event')
|
||||||
|
module('entitycamera')
|
||||||
|
|
||||||
|
local phys
|
||||||
|
local updateSub
|
||||||
|
local SPEED = 4.0
|
||||||
|
|
||||||
|
function entityInit()
|
||||||
|
local pos = entityPositionAdd(ENTITY_ID)
|
||||||
|
pos.x = 0
|
||||||
|
pos.y = 1
|
||||||
|
pos.z = 0
|
||||||
|
|
||||||
|
phys = entityPhysicsAdd(ENTITY_ID)
|
||||||
|
phys:setShapeCapsule(0.3, 0.9)
|
||||||
|
|
||||||
|
local mesh = entityMeshAdd(ENTITY_ID)
|
||||||
|
mesh:generateCapsule(0.3, 0.9)
|
||||||
|
|
||||||
|
local mat = entityMaterialAdd(ENTITY_ID)
|
||||||
|
mat.color = colorBlue()
|
||||||
|
|
||||||
|
updateSub = eventSubscribe(SCENE_EVENT_UPDATE, onUpdate)
|
||||||
|
end
|
||||||
|
|
||||||
|
function onUpdate()
|
||||||
|
local moveX = inputAxis(INPUT_ACTION_LEFT, INPUT_ACTION_RIGHT)
|
||||||
|
local moveZ = inputAxis(INPUT_ACTION_DOWN, INPUT_ACTION_UP)
|
||||||
|
|
||||||
|
local cam = entityCameraGetCurrent()
|
||||||
|
local fwd = cam:getForward()
|
||||||
|
local right = cam:getRight()
|
||||||
|
|
||||||
|
local vy = phys.velocityY
|
||||||
|
phys.velocityX = (moveX * right.x + moveZ * fwd.x) * SPEED
|
||||||
|
phys.velocityZ = (moveX * right.y + moveZ * fwd.y) * SPEED
|
||||||
|
end
|
||||||
|
|
||||||
|
function entityDispose()
|
||||||
|
eventUnsubscribe(SCENE_EVENT_UPDATE, updateSub)
|
||||||
|
end
|
||||||
@@ -6,6 +6,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "entity/entitymanager.h"
|
#include "entity/entitymanager.h"
|
||||||
|
#include "entity/entity.h"
|
||||||
|
#include "entity/component/display/entityposition.h"
|
||||||
#include "display/framebuffer/framebuffer.h"
|
#include "display/framebuffer/framebuffer.h"
|
||||||
#include "display/screen/screen.h"
|
#include "display/screen/screen.h"
|
||||||
|
|
||||||
@@ -93,3 +95,37 @@ void entityCameraGetProjection(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entityid_t entityCameraGetCurrent(void) {
|
||||||
|
entityid_t camEnts[ENTITY_COUNT_MAX];
|
||||||
|
componentid_t camComps[ENTITY_COUNT_MAX];
|
||||||
|
entityid_t count = componentGetEntitiesWithComponent(
|
||||||
|
COMPONENT_TYPE_CAMERA, camEnts, camComps
|
||||||
|
);
|
||||||
|
if(count == 0) return ENTITY_COUNT_MAX;
|
||||||
|
return camEnts[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
void entityCameraGetForward(const entityid_t entityId, vec2 out) {
|
||||||
|
componentid_t posComp = entityGetComponent(entityId, COMPONENT_TYPE_POSITION);
|
||||||
|
entityposition_t *pos = entityPositionGet(entityId, posComp);
|
||||||
|
// View matrix column layout: M[col][row], forward = {-M[0][2], -M[1][2], -M[2][2]}
|
||||||
|
float_t fx = -pos->transform[0][2];
|
||||||
|
float_t fz = -pos->transform[2][2];
|
||||||
|
float_t len = sqrtf(fx * fx + fz * fz);
|
||||||
|
if(len > 1e-6f) { fx /= len; fz /= len; }
|
||||||
|
out[0] = fx;
|
||||||
|
out[1] = fz;
|
||||||
|
}
|
||||||
|
|
||||||
|
void entityCameraGetRight(const entityid_t entityId, vec2 out) {
|
||||||
|
componentid_t posComp = entityGetComponent(entityId, COMPONENT_TYPE_POSITION);
|
||||||
|
entityposition_t *pos = entityPositionGet(entityId, posComp);
|
||||||
|
// View matrix column layout: right = {M[0][0], M[1][0], M[2][0]}
|
||||||
|
float_t rx = pos->transform[0][0];
|
||||||
|
float_t rz = pos->transform[2][0];
|
||||||
|
float_t len = sqrtf(rx * rx + rz * rz);
|
||||||
|
if(len > 1e-6f) { rx /= len; rz /= len; }
|
||||||
|
out[0] = rx;
|
||||||
|
out[1] = rz;
|
||||||
|
}
|
||||||
@@ -97,3 +97,26 @@ void entityCameraSetZFar(
|
|||||||
const componentid_t comp,
|
const componentid_t comp,
|
||||||
const float_t zFar
|
const float_t zFar
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the entity ID of the first active camera, or ENTITY_COUNT_MAX if none.
|
||||||
|
*/
|
||||||
|
entityid_t entityCameraGetCurrent(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the camera's horizontal forward direction (XZ plane) from its position
|
||||||
|
* component. Automatically finds the position component on the entity.
|
||||||
|
*
|
||||||
|
* @param entityId The camera entity ID.
|
||||||
|
* @param out Output vec2: {forwardX, forwardZ} normalized.
|
||||||
|
*/
|
||||||
|
void entityCameraGetForward(const entityid_t entityId, vec2 out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the camera's horizontal right direction (XZ plane) from its position
|
||||||
|
* component. Automatically finds the position component on the entity.
|
||||||
|
*
|
||||||
|
* @param entityId The camera entity ID.
|
||||||
|
* @param out Output vec2: {rightX, rightZ} normalized.
|
||||||
|
*/
|
||||||
|
void entityCameraGetRight(const entityid_t entityId, vec2 out);
|
||||||
@@ -49,3 +49,14 @@ void entityMaterialSetShader(
|
|||||||
);
|
);
|
||||||
mat->shader = shader;
|
mat->shader = shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void entityMaterialSetColor(
|
||||||
|
const entityid_t entityId,
|
||||||
|
const componentid_t componentId,
|
||||||
|
const color_t color
|
||||||
|
) {
|
||||||
|
entitymaterial_t *mat = componentGetData(
|
||||||
|
entityId, componentId, COMPONENT_TYPE_MATERIAL
|
||||||
|
);
|
||||||
|
mat->material.unlit.color = color;
|
||||||
|
}
|
||||||
@@ -61,3 +61,16 @@ void entityMaterialSetShader(
|
|||||||
const componentid_t componentId,
|
const componentid_t componentId,
|
||||||
shader_t *shader
|
shader_t *shader
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the unlit color for the given entity and component.
|
||||||
|
*
|
||||||
|
* @param entityId The entity ID.
|
||||||
|
* @param componentId The component ID.
|
||||||
|
* @param color The color to set.
|
||||||
|
*/
|
||||||
|
void entityMaterialSetColor(
|
||||||
|
const entityid_t entityId,
|
||||||
|
const componentid_t componentId,
|
||||||
|
const color_t color
|
||||||
|
);
|
||||||
@@ -5,9 +5,13 @@
|
|||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "entitymesh.h"
|
||||||
#include "entity/entitymanager.h"
|
#include "entity/entitymanager.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
#include "util/memory.h"
|
||||||
#include "display/mesh/cube.h"
|
#include "display/mesh/cube.h"
|
||||||
|
#include "display/mesh/plane.h"
|
||||||
|
#include "display/mesh/capsule.h"
|
||||||
|
|
||||||
void entityMeshInit(
|
void entityMeshInit(
|
||||||
const entityid_t entityId,
|
const entityid_t entityId,
|
||||||
@@ -17,6 +21,8 @@ void entityMeshInit(
|
|||||||
entityId, componentId, COMPONENT_TYPE_MESH
|
entityId, componentId, COMPONENT_TYPE_MESH
|
||||||
);
|
);
|
||||||
comp->mesh = &CUBE_MESH_SIMPLE;
|
comp->mesh = &CUBE_MESH_SIMPLE;
|
||||||
|
comp->ownedVertices = NULL;
|
||||||
|
comp->ownsData = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh_t * entityMeshGetMesh(
|
mesh_t * entityMeshGetMesh(
|
||||||
@@ -39,3 +45,99 @@ void entityMeshSetMesh(
|
|||||||
);
|
);
|
||||||
comp->mesh = mesh;
|
comp->mesh = mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void entityMeshDispose(
|
||||||
|
const entityid_t entityId,
|
||||||
|
const componentid_t componentId
|
||||||
|
) {
|
||||||
|
entitymesh_t *comp = componentGetData(
|
||||||
|
entityId, componentId, COMPONENT_TYPE_MESH
|
||||||
|
);
|
||||||
|
if(!comp->ownsData) return;
|
||||||
|
(void)meshDispose(&comp->ownedMesh);
|
||||||
|
memoryFree(comp->ownedVertices);
|
||||||
|
comp->ownedVertices = NULL;
|
||||||
|
comp->ownsData = false;
|
||||||
|
comp->mesh = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
errorret_t entityMeshGeneratePlane(
|
||||||
|
const entityid_t entityId,
|
||||||
|
const componentid_t componentId,
|
||||||
|
const float_t width,
|
||||||
|
const float_t height
|
||||||
|
) {
|
||||||
|
entitymesh_t *comp = componentGetData(
|
||||||
|
entityId, componentId, COMPONENT_TYPE_MESH
|
||||||
|
);
|
||||||
|
entityMeshDispose(entityId, componentId);
|
||||||
|
|
||||||
|
comp->ownedVertices = memoryAllocate(PLANE_VERTEX_COUNT * sizeof(meshvertex_t));
|
||||||
|
assertNotNull(comp->ownedVertices, "Failed to allocate plane vertices");
|
||||||
|
|
||||||
|
vec3 min = { -width * 0.5f, 0.0f, -height * 0.5f };
|
||||||
|
vec3 max = { width * 0.5f, 0.0f, height * 0.5f };
|
||||||
|
vec2 uvMin = { 0.0f, 0.0f };
|
||||||
|
vec2 uvMax = { 1.0f, 1.0f };
|
||||||
|
planeBuffer(
|
||||||
|
comp->ownedVertices,
|
||||||
|
PLANE_AXIS_XZ,
|
||||||
|
min,
|
||||||
|
max
|
||||||
|
#if MESH_ENABLE_COLOR
|
||||||
|
, COLOR_WHITE_4B
|
||||||
|
#endif
|
||||||
|
, uvMin,
|
||||||
|
uvMax
|
||||||
|
);
|
||||||
|
|
||||||
|
errorChain(meshInit(
|
||||||
|
&comp->ownedMesh,
|
||||||
|
PLANE_PRIMITIVE_TYPE,
|
||||||
|
PLANE_VERTEX_COUNT,
|
||||||
|
comp->ownedVertices
|
||||||
|
));
|
||||||
|
|
||||||
|
comp->mesh = &comp->ownedMesh;
|
||||||
|
comp->ownsData = true;
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
errorret_t entityMeshGenerateCapsule(
|
||||||
|
const entityid_t entityId,
|
||||||
|
const componentid_t componentId,
|
||||||
|
const float_t radius,
|
||||||
|
const float_t halfHeight
|
||||||
|
) {
|
||||||
|
entitymesh_t *comp = componentGetData(
|
||||||
|
entityId, componentId, COMPONENT_TYPE_MESH
|
||||||
|
);
|
||||||
|
entityMeshDispose(entityId, componentId);
|
||||||
|
|
||||||
|
comp->ownedVertices = memoryAllocate(CAPSULE_VERTEX_COUNT * sizeof(meshvertex_t));
|
||||||
|
assertNotNull(comp->ownedVertices, "Failed to allocate capsule vertices");
|
||||||
|
|
||||||
|
vec3 center = { 0.0f, 0.0f, 0.0f };
|
||||||
|
capsuleBuffer(
|
||||||
|
comp->ownedVertices,
|
||||||
|
center,
|
||||||
|
radius,
|
||||||
|
halfHeight,
|
||||||
|
CAPSULE_CAP_RINGS,
|
||||||
|
CAPSULE_SECTORS
|
||||||
|
#if MESH_ENABLE_COLOR
|
||||||
|
, COLOR_WHITE_4B
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
errorChain(meshInit(
|
||||||
|
&comp->ownedMesh,
|
||||||
|
CAPSULE_PRIMITIVE_TYPE,
|
||||||
|
CAPSULE_VERTEX_COUNT,
|
||||||
|
comp->ownedVertices
|
||||||
|
));
|
||||||
|
|
||||||
|
comp->mesh = &comp->ownedMesh;
|
||||||
|
comp->ownsData = true;
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
@@ -11,6 +11,9 @@
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
mesh_t *mesh;
|
mesh_t *mesh;
|
||||||
|
mesh_t ownedMesh;
|
||||||
|
meshvertex_t *ownedVertices;
|
||||||
|
bool_t ownsData;
|
||||||
} entitymesh_t;
|
} entitymesh_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,3 +51,46 @@ void entityMeshSetMesh(
|
|||||||
const componentid_t componentId,
|
const componentid_t componentId,
|
||||||
mesh_t *mesh
|
mesh_t *mesh
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disposes the entity mesh component, freeing any owned mesh data.
|
||||||
|
*
|
||||||
|
* @param entityId The entity ID.
|
||||||
|
* @param componentId The component ID.
|
||||||
|
*/
|
||||||
|
void entityMeshDispose(
|
||||||
|
const entityid_t entityId,
|
||||||
|
const componentid_t componentId
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates an XZ-aligned plane mesh owned by the component.
|
||||||
|
*
|
||||||
|
* @param entityId The entity ID.
|
||||||
|
* @param componentId The component ID.
|
||||||
|
* @param width Width of the plane along the X axis.
|
||||||
|
* @param height Height of the plane along the Z axis.
|
||||||
|
* @return Error return value.
|
||||||
|
*/
|
||||||
|
errorret_t entityMeshGeneratePlane(
|
||||||
|
const entityid_t entityId,
|
||||||
|
const componentid_t componentId,
|
||||||
|
const float_t width,
|
||||||
|
const float_t height
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a Y-axis capsule mesh owned by the component.
|
||||||
|
*
|
||||||
|
* @param entityId The entity ID.
|
||||||
|
* @param componentId The component ID.
|
||||||
|
* @param radius Radius of the cylinder and hemisphere caps.
|
||||||
|
* @param halfHeight Half-height of the cylindrical section.
|
||||||
|
* @return Error return value.
|
||||||
|
*/
|
||||||
|
errorret_t entityMeshGenerateCapsule(
|
||||||
|
const entityid_t entityId,
|
||||||
|
const componentid_t componentId,
|
||||||
|
const float_t radius,
|
||||||
|
const float_t halfHeight
|
||||||
|
);
|
||||||
@@ -100,6 +100,25 @@ bool_t entityPhysicsIsOnGround(
|
|||||||
return phys->onGround;
|
return phys->onGround;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void entityPhysicsSetBodyType(
|
||||||
|
const entityid_t entityId,
|
||||||
|
const componentid_t componentId,
|
||||||
|
const physicsbodytype_t type
|
||||||
|
) {
|
||||||
|
entityphysics_t *phys = entityPhysicsGet(entityId, componentId);
|
||||||
|
assertNotNull(phys, "Failed to get physics component data");
|
||||||
|
phys->type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
physicsbodytype_t entityPhysicsGetBodyType(
|
||||||
|
const entityid_t entityId,
|
||||||
|
const componentid_t componentId
|
||||||
|
) {
|
||||||
|
entityphysics_t *phys = entityPhysicsGet(entityId, componentId);
|
||||||
|
assertNotNull(phys, "Failed to get physics component data");
|
||||||
|
return phys->type;
|
||||||
|
}
|
||||||
|
|
||||||
void entityPhysicsDispose(
|
void entityPhysicsDispose(
|
||||||
const entityid_t entityId,
|
const entityid_t entityId,
|
||||||
const componentid_t componentId
|
const componentid_t componentId
|
||||||
|
|||||||
@@ -122,6 +122,31 @@ bool_t entityPhysicsIsOnGround(
|
|||||||
const componentid_t componentId
|
const componentid_t componentId
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the body type of the entity's physics body.
|
||||||
|
*
|
||||||
|
* @param entityId The entity ID.
|
||||||
|
* @param componentId The component ID.
|
||||||
|
* @param type The body type to set.
|
||||||
|
*/
|
||||||
|
void entityPhysicsSetBodyType(
|
||||||
|
const entityid_t entityId,
|
||||||
|
const componentid_t componentId,
|
||||||
|
const physicsbodytype_t type
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the body type of the entity's physics body.
|
||||||
|
*
|
||||||
|
* @param entityId The entity ID.
|
||||||
|
* @param componentId The component ID.
|
||||||
|
* @return The body type of the physics body.
|
||||||
|
*/
|
||||||
|
physicsbodytype_t entityPhysicsGetBodyType(
|
||||||
|
const entityid_t entityId,
|
||||||
|
const componentid_t componentId
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Releases the body slot back to PHYSICS_WORLD. Called automatically when
|
* Releases the body slot back to PHYSICS_WORLD. Called automatically when
|
||||||
* the component is disposed via the component system.
|
* the component is disposed via the component system.
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
X(POSITION, entityposition_t, position, entityPositionInit, NULL)
|
X(POSITION, entityposition_t, position, entityPositionInit, NULL)
|
||||||
X(CAMERA, entitycamera_t, camera, entityCameraInit, NULL)
|
X(CAMERA, entitycamera_t, camera, entityCameraInit, NULL)
|
||||||
X(MESH, entitymesh_t, mesh, entityMeshInit, NULL)
|
X(MESH, entitymesh_t, mesh, entityMeshInit, entityMeshDispose)
|
||||||
X(MATERIAL, entitymaterial_t, material, entityMaterialInit, NULL)
|
X(MATERIAL, entitymaterial_t, material, entityMaterialInit, NULL)
|
||||||
X(PHYSICS, entityphysics_t, physics, entityPhysicsInit, entityPhysicsDispose)
|
X(PHYSICS, entityphysics_t, physics, entityPhysicsInit, entityPhysicsDispose)
|
||||||
X(ENTITYSCRIPT, entityscript_t, entityscript, entityScriptInit, entityScriptDispose)
|
X(ENTITYSCRIPT, entityscript_t, entityscript, entityScriptInit, entityScriptDispose)
|
||||||
+25
-33
@@ -73,7 +73,7 @@ eventsub_t eventSubscribe(
|
|||||||
const eventcallback_t callback,
|
const eventcallback_t callback,
|
||||||
const void *user
|
const void *user
|
||||||
) {
|
) {
|
||||||
eventSubscribeUser(
|
return eventSubscribeUser(
|
||||||
event,
|
event,
|
||||||
EVENT_TYPE_C,
|
EVENT_TYPE_C,
|
||||||
(eventuserdata_t){ .c = { .callback = callback, .user = (void *)user } }
|
(eventuserdata_t){ .c = { .callback = callback, .user = (void *)user } }
|
||||||
@@ -147,30 +147,29 @@ void eventUnsubscribe(event_t *event, const eventsub_t id) {
|
|||||||
|
|
||||||
if(event->listenerCount == 0) return;
|
if(event->listenerCount == 0) return;
|
||||||
|
|
||||||
// Find listener
|
|
||||||
uint16_t index = 0;
|
uint16_t index = 0;
|
||||||
do {
|
do {
|
||||||
if(event->listenerArray[index].id == id) {
|
if(event->listenerArray[index].id != id) {
|
||||||
// Found it, remove by swapping with last and reducing count
|
index++;
|
||||||
event->listenerArray[index] = event->listenerArray[--event->listenerCount];
|
continue;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
index++;
|
|
||||||
|
// Release Lua registry reference before the slot is overwritten
|
||||||
|
if(event->listenerArray[index].type == EVENT_TYPE_SCRIPT) {
|
||||||
|
scriptcontext_t *ctx = event->listenerArray[index].user.script.context;
|
||||||
|
if(ctx != NULL && ctx->luaState != NULL) {
|
||||||
|
luaL_unref(
|
||||||
|
ctx->luaState,
|
||||||
|
LUA_REGISTRYINDEX,
|
||||||
|
event->listenerArray[index].user.script.luaFunctionRef
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap with last and shrink
|
||||||
|
event->listenerArray[index] = event->listenerArray[--event->listenerCount];
|
||||||
|
return;
|
||||||
} while(index < event->listenerCount);
|
} while(index < event->listenerCount);
|
||||||
|
|
||||||
// Did we find it?
|
|
||||||
if(index == event->listenerCount) return;
|
|
||||||
|
|
||||||
// Shift remaining listeners down (if any)
|
|
||||||
if(index < event->listenerCount - 1) {
|
|
||||||
memoryMove(
|
|
||||||
&event->listenerArray[index],
|
|
||||||
&event->listenerArray[index + 1],
|
|
||||||
sizeof(eventlistener_t) * (event->listenerCount - index - 1)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
event->listenerCount--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void eventUnsubscribeScriptContext(event_t *event, const scriptcontext_t *ctx) {
|
void eventUnsubscribeScriptContext(event_t *event, const scriptcontext_t *ctx) {
|
||||||
@@ -219,27 +218,20 @@ void eventInvoke(
|
|||||||
if(listener->type == EVENT_TYPE_C) {
|
if(listener->type == EVENT_TYPE_C) {
|
||||||
listener->user.c.callback(&data, listener->user.c);
|
listener->user.c.callback(&data, listener->user.c);
|
||||||
} else if(listener->type == EVENT_TYPE_SCRIPT) {
|
} else if(listener->type == EVENT_TYPE_SCRIPT) {
|
||||||
// Call Lua function
|
|
||||||
lua_State *L = listener->user.script.context->luaState;
|
lua_State *L = listener->user.script.context->luaState;
|
||||||
assertNotNull(L, "Lua state in event listener cannot be NULL");
|
assertNotNull(L, "Lua state in event listener cannot be NULL");
|
||||||
|
|
||||||
// Push function
|
|
||||||
lua_rawgeti(L, LUA_REGISTRYINDEX, listener->user.script.luaFunctionRef);
|
lua_rawgeti(L, LUA_REGISTRYINDEX, listener->user.script.luaFunctionRef);
|
||||||
|
|
||||||
if(eventParams != NULL && metatableName != NULL) {
|
int numArgs = 0;
|
||||||
lua_getmetatable(L, -1);
|
if(eventParams != NULL) {
|
||||||
luaL_getmetatable(L, metatableName);
|
lua_pushlightuserdata(L, (void *)eventParams);
|
||||||
assertTrue(
|
numArgs = 1;
|
||||||
lua_rawequal(L, -1, -2),
|
|
||||||
"Event parameter metatable does not match expected type"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call function with 1 arg, 0 return values
|
if(lua_pcall(L, numArgs, 0, 0) != LUA_OK) {
|
||||||
if(lua_pcall(L, 1, 0, 0) != LUA_OK) {
|
|
||||||
const char_t *strErr = lua_tostring(L, -1);
|
const char_t *strErr = lua_tostring(L, -1);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
// Log error but continue
|
|
||||||
printf("Error invoking Lua event listener: %s\n", strErr);
|
printf("Error invoking Lua event listener: %s\n", strErr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ scene_t SCENE;
|
|||||||
|
|
||||||
errorret_t sceneInit(void) {
|
errorret_t sceneInit(void) {
|
||||||
memoryZero(&SCENE, sizeof(scene_t));
|
memoryZero(&SCENE, sizeof(scene_t));
|
||||||
|
eventInit(&SCENE.eventUpdate, SCENE.updateListeners, SCENE_EVENT_UPDATE_MAX);
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,6 +43,8 @@ errorret_t sceneUpdate(void) {
|
|||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eventInvoke(&SCENE.eventUpdate, NULL, NULL);
|
||||||
|
|
||||||
assertNotNull(SCENE.script.luaState, "Script context null?");
|
assertNotNull(SCENE.script.luaState, "Script context null?");
|
||||||
lua_getglobal(SCENE.script.luaState, "sceneUpdate");
|
lua_getglobal(SCENE.script.luaState, "sceneUpdate");
|
||||||
if(lua_isfunction(SCENE.script.luaState, -1)) {
|
if(lua_isfunction(SCENE.script.luaState, -1)) {
|
||||||
|
|||||||
@@ -8,12 +8,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "script/scriptcontext.h"
|
#include "script/scriptcontext.h"
|
||||||
#include "asset/assetfile.h"
|
#include "asset/assetfile.h"
|
||||||
|
#include "event/event.h"
|
||||||
|
|
||||||
|
#define SCENE_EVENT_UPDATE_MAX 16
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
scriptcontext_t script;
|
scriptcontext_t script;
|
||||||
bool_t scriptActive;
|
bool_t scriptActive;
|
||||||
char_t sceneCurrent[ASSET_FILE_PATH_MAX];
|
char_t sceneCurrent[ASSET_FILE_PATH_MAX];
|
||||||
char_t sceneNext[ASSET_FILE_PATH_MAX];
|
char_t sceneNext[ASSET_FILE_PATH_MAX];
|
||||||
|
|
||||||
|
eventlistener_t updateListeners[SCENE_EVENT_UPDATE_MAX];
|
||||||
|
event_t eventUpdate;
|
||||||
} scene_t;
|
} scene_t;
|
||||||
|
|
||||||
extern scene_t SCENE;
|
extern scene_t SCENE;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ add_subdirectory(entity)
|
|||||||
add_subdirectory(event)
|
add_subdirectory(event)
|
||||||
add_subdirectory(input)
|
add_subdirectory(input)
|
||||||
add_subdirectory(locale)
|
add_subdirectory(locale)
|
||||||
|
add_subdirectory(math)
|
||||||
add_subdirectory(system)
|
add_subdirectory(system)
|
||||||
add_subdirectory(scene)
|
add_subdirectory(scene)
|
||||||
add_subdirectory(time)
|
add_subdirectory(time)
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
|||||||
PUBLIC
|
PUBLIC
|
||||||
moduleglm.c
|
moduleglm.c
|
||||||
modulespritebatch.c
|
modulespritebatch.c
|
||||||
moduleglm.c
|
|
||||||
modulecolor.c
|
modulecolor.c
|
||||||
moduletext.c
|
moduletext.c
|
||||||
modulescreen.c
|
modulescreen.c
|
||||||
|
|||||||
@@ -6,278 +6,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "moduleglm.h"
|
#include "moduleglm.h"
|
||||||
|
#include "script/module/math/modulemath.h"
|
||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "util/string.h"
|
|
||||||
#include "util/memory.h"
|
|
||||||
|
|
||||||
void moduleGLM(scriptcontext_t *context) {
|
void moduleGLM(scriptcontext_t *context) {
|
||||||
assertNotNull(context, "Context cannot be NULL.");
|
assertNotNull(context, "Context cannot be NULL.");
|
||||||
|
moduleMath(context);
|
||||||
// Create metatable for vec3 structure.
|
|
||||||
if(luaL_newmetatable(context->luaState, "vec3_mt")) {
|
|
||||||
// Metatable methods
|
|
||||||
lua_pushcfunction(context->luaState, moduleVec3Index);
|
|
||||||
lua_setfield(context->luaState, -2, "__index");
|
|
||||||
lua_pushcfunction(context->luaState, moduleVec3NewIndex);
|
|
||||||
lua_setfield(context->luaState, -2, "__newindex");
|
|
||||||
lua_pushcfunction(context->luaState, moduleVec3ToString);
|
|
||||||
lua_setfield(context->luaState, -2, "__tostring");
|
|
||||||
}
|
|
||||||
lua_pop(context->luaState, 1);
|
|
||||||
|
|
||||||
if(luaL_newmetatable(context->luaState, "vec4_mt")) {
|
|
||||||
// Metatable methods
|
|
||||||
lua_pushcfunction(context->luaState, moduleVec4Index);
|
|
||||||
lua_setfield(context->luaState, -2, "__index");
|
|
||||||
lua_pushcfunction(context->luaState, moduleVec4NewIndex);
|
|
||||||
lua_setfield(context->luaState, -2, "__newindex");
|
|
||||||
lua_pushcfunction(context->luaState, moduleVec4ToString);
|
|
||||||
lua_setfield(context->luaState, -2, "__tostring");
|
|
||||||
}
|
|
||||||
lua_pop(context->luaState, 1);
|
|
||||||
|
|
||||||
lua_register(context->luaState, "vec3", moduleVec3Create);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int moduleVec3Create(lua_State *l) {
|
|
||||||
assertNotNull(l, "Lua state cannot be NULL.");
|
|
||||||
|
|
||||||
vec3 *v = (vec3 *)lua_newuserdata(l, sizeof(vec3));
|
|
||||||
memoryZero(v, sizeof(vec3));
|
|
||||||
|
|
||||||
// May be expecting between 1 and 3 values.
|
|
||||||
int top = lua_gettop(l);
|
|
||||||
if(top >= 1) {
|
|
||||||
if(!lua_isnumber(l, 1)) {
|
|
||||||
luaL_error(l, "Vec3 x component must be a number.");
|
|
||||||
}
|
|
||||||
(*v)[0] = (float_t)lua_tonumber(l, 1);
|
|
||||||
}
|
|
||||||
if(top >= 2) {
|
|
||||||
if(!lua_isnumber(l, 2)) {
|
|
||||||
luaL_error(l, "Vec3 y component must be a number.");
|
|
||||||
}
|
|
||||||
(*v)[1] = (float_t)lua_tonumber(l, 2);
|
|
||||||
}
|
|
||||||
if(top >= 3) {
|
|
||||||
if(!lua_isnumber(l, 3)) {
|
|
||||||
luaL_error(l, "Vec3 z component must be a number.");
|
|
||||||
}
|
|
||||||
(*v)[2] = (float_t)lua_tonumber(l, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set metatable
|
|
||||||
luaL_getmetatable(l, "vec3_mt");
|
|
||||||
lua_setmetatable(l, -2);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleVec3Index(lua_State *l) {
|
|
||||||
assertNotNull(l, "Lua state cannot be NULL.");
|
|
||||||
|
|
||||||
const char_t *key = lua_tostring(l, 2);
|
|
||||||
assertStrLenMin(key, 1, "Key cannot be empty.");
|
|
||||||
|
|
||||||
vec3 *vec = (vec3 *)luaL_checkudata(l, 1, "vec3_mt");
|
|
||||||
assertNotNull(vec, "Vec3 pointer cannot be NULL.");
|
|
||||||
|
|
||||||
if(stringCompare(key, "x") == 0) {
|
|
||||||
lua_pushnumber(l, (*vec)[0]);
|
|
||||||
return 1;
|
|
||||||
} else if(stringCompare(key, "y") == 0) {
|
|
||||||
lua_pushnumber(l, (*vec)[1]);
|
|
||||||
return 1;
|
|
||||||
} else if(stringCompare(key, "z") == 0) {
|
|
||||||
lua_pushnumber(l, (*vec)[2]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleVec3NewIndex(lua_State *l) {
|
|
||||||
assertNotNull(l, "Lua state cannot be NULL.");
|
|
||||||
|
|
||||||
const char_t *key = luaL_checkstring(l, 2);
|
|
||||||
assertStrLenMin(key, 1, "Key cannot be empty.");
|
|
||||||
|
|
||||||
vec3 *vec = (vec3 *)luaL_checkudata(l, 1, "vec3_mt");
|
|
||||||
assertNotNull(vec, "Vec3 pointer cannot be NULL.");
|
|
||||||
|
|
||||||
if(stringCompare(key, "x") == 0) {
|
|
||||||
if(!lua_isnumber(l, 3)) {
|
|
||||||
luaL_error(l, "Vec3 x component must be a number.");
|
|
||||||
}
|
|
||||||
(*vec)[0] = (float_t)lua_tonumber(l, 3);
|
|
||||||
return 0;
|
|
||||||
} else if(stringCompare(key, "y") == 0) {
|
|
||||||
if(!lua_isnumber(l, 3)) {
|
|
||||||
luaL_error(l, "Vec3 y component must be a number.");
|
|
||||||
}
|
|
||||||
(*vec)[1] = (float_t)lua_tonumber(l, 3);
|
|
||||||
return 0;
|
|
||||||
} else if(stringCompare(key, "z") == 0) {
|
|
||||||
if(!lua_isnumber(l, 3)) {
|
|
||||||
luaL_error(l, "Vec3 z component must be a number.");
|
|
||||||
}
|
|
||||||
(*vec)[2] = (float_t)lua_tonumber(l, 3);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
luaL_error(l, "Invalid key for vec3: %s", key);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleVec3ToString(lua_State *l) {
|
|
||||||
assertNotNull(l, "Lua state cannot be NULL.");
|
|
||||||
|
|
||||||
vec3 *vec = (vec3 *)luaL_checkudata(l, 1, "vec3_mt");
|
|
||||||
assertNotNull(vec, "Vec3 pointer cannot be NULL.");
|
|
||||||
|
|
||||||
char buf[128];
|
|
||||||
snprintf(
|
|
||||||
buf, sizeof(buf),
|
|
||||||
"vec3(%.3f, %.3f, %.3f)",
|
|
||||||
(*vec)[0], (*vec)[1], (*vec)[2]
|
|
||||||
);
|
|
||||||
lua_pushstring(l, buf);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int moduleVec4Create(lua_State *l) {
|
|
||||||
assertNotNull(l, "Lua state cannot be NULL.");
|
|
||||||
|
|
||||||
vec4 *v = (vec4 *)lua_newuserdata(l, sizeof(vec4));
|
|
||||||
memoryZero(v, sizeof(vec4));
|
|
||||||
|
|
||||||
// May be expecting between 1 and 4 values.
|
|
||||||
int top = lua_gettop(l);
|
|
||||||
if(top >= 1) {
|
|
||||||
if(!lua_isnumber(l, 1)) {
|
|
||||||
luaL_error(l, "Vec4 x component must be a number.");
|
|
||||||
}
|
|
||||||
(*v)[0] = (float_t)lua_tonumber(l, 1);
|
|
||||||
}
|
|
||||||
if(top >= 2) {
|
|
||||||
if(!lua_isnumber(l, 2)) {
|
|
||||||
luaL_error(l, "Vec4 y component must be a number.");
|
|
||||||
}
|
|
||||||
(*v)[1] = (float_t)lua_tonumber(l, 2);
|
|
||||||
}
|
|
||||||
if(top >= 3) {
|
|
||||||
if(!lua_isnumber(l, 3)) {
|
|
||||||
luaL_error(l, "Vec4 z component must be a number.");
|
|
||||||
}
|
|
||||||
(*v)[2] = (float_t)lua_tonumber(l, 3);
|
|
||||||
}
|
|
||||||
if(top >= 4) {
|
|
||||||
if(!lua_isnumber(l, 4)) {
|
|
||||||
luaL_error(l, "Vec4 w component must be a number.");
|
|
||||||
}
|
|
||||||
(*v)[3] = (float_t)lua_tonumber(l, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set metatable
|
|
||||||
luaL_getmetatable(l, "vec4_mt");
|
|
||||||
lua_setmetatable(l, -2);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleVec4Index(lua_State *l) {
|
|
||||||
assertNotNull(l, "Lua state cannot be NULL.");
|
|
||||||
|
|
||||||
const char_t *key = lua_tostring(l, 2);
|
|
||||||
assertStrLenMin(key, 1, "Key cannot be empty.");
|
|
||||||
|
|
||||||
vec4 *vec = (vec4 *)luaL_checkudata(l, 1, "vec4_mt");
|
|
||||||
assertNotNull(vec, "Vec4 pointer cannot be NULL.");
|
|
||||||
|
|
||||||
if(stringCompare(key, "x") == 0) {
|
|
||||||
lua_pushnumber(l, (*vec)[0]);
|
|
||||||
return 1;
|
|
||||||
} else if(stringCompare(key, "y") == 0) {
|
|
||||||
lua_pushnumber(l, (*vec)[1]);
|
|
||||||
return 1;
|
|
||||||
} else if(stringCompare(key, "z") == 0) {
|
|
||||||
lua_pushnumber(l, (*vec)[2]);
|
|
||||||
return 1;
|
|
||||||
} else if(stringCompare(key, "w") == 0) {
|
|
||||||
lua_pushnumber(l, (*vec)[3]);
|
|
||||||
return 1;
|
|
||||||
} else if(stringCompare(key, "u0") == 0) {
|
|
||||||
lua_pushnumber(l, (*vec)[0]);
|
|
||||||
return 1;
|
|
||||||
} else if(stringCompare(key, "v0") == 0) {
|
|
||||||
lua_pushnumber(l, (*vec)[1]);
|
|
||||||
return 1;
|
|
||||||
} else if(stringCompare(key, "u1") == 0) {
|
|
||||||
lua_pushnumber(l, (*vec)[2]);
|
|
||||||
return 1;
|
|
||||||
} else if(stringCompare(key, "v1") == 0) {
|
|
||||||
lua_pushnumber(l, (*vec)[3]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
lua_pushnil(l);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleVec4NewIndex(lua_State *l) {
|
|
||||||
assertNotNull(l, "Lua state cannot be NULL.");
|
|
||||||
|
|
||||||
const char_t *key = luaL_checkstring(l, 2);
|
|
||||||
assertStrLenMin(key, 1, "Key cannot be empty.");
|
|
||||||
|
|
||||||
vec4 *vec = (vec4 *)luaL_checkudata(l, 1, "vec4_mt");
|
|
||||||
assertNotNull(vec, "Vec4 pointer cannot be NULL.");
|
|
||||||
|
|
||||||
if(stringCompare(key, "x") == 0) {
|
|
||||||
if(!lua_isnumber(l, 3)) {
|
|
||||||
luaL_error(l, "Vec4 x component must be a number.");
|
|
||||||
}
|
|
||||||
(*vec)[0] = (float_t)lua_tonumber(l, 3);
|
|
||||||
return 0;
|
|
||||||
} else if(stringCompare(key, "y") == 0) {
|
|
||||||
if(!lua_isnumber(l, 3)) {
|
|
||||||
luaL_error(l, "Vec4 y component must be a number.");
|
|
||||||
}
|
|
||||||
(*vec)[1] = (float_t)lua_tonumber(l, 3);
|
|
||||||
return 0;
|
|
||||||
} else if(stringCompare(key, "z") == 0) {
|
|
||||||
if(!lua_isnumber(l, 3)) {
|
|
||||||
luaL_error(l, "Vec4 z component must be a number.");
|
|
||||||
}
|
|
||||||
(*vec)[2] = (float_t)lua_tonumber(l, 3);
|
|
||||||
return 0;
|
|
||||||
} else if(stringCompare(key, "w") == 0) {
|
|
||||||
if(!lua_isnumber(l, 3)) {
|
|
||||||
luaL_error(l, "Vec4 w component must be a number.");
|
|
||||||
}
|
|
||||||
(*vec)[3] = (float_t)lua_tonumber(l, 3);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
luaL_error(l, "Invalid key for vec4: %s", key);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleVec4ToString(lua_State *l) {
|
|
||||||
assertNotNull(l, "Lua state cannot be NULL.");
|
|
||||||
|
|
||||||
vec4 *vec = (vec4 *)luaL_checkudata(l, 1, "vec4_mt");
|
|
||||||
assertNotNull(vec, "Vec4 pointer cannot be NULL.");
|
|
||||||
|
|
||||||
char buf[128];
|
|
||||||
snprintf(
|
|
||||||
buf, sizeof(buf),
|
|
||||||
"vec4(%.3f, %.3f, %.3f, %.3f)",
|
|
||||||
(*vec)[0], (*vec)[1], (*vec)[2], (*vec)[3]
|
|
||||||
);
|
|
||||||
lua_pushstring(l, buf);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
@@ -8,73 +8,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "script/scriptcontext.h"
|
#include "script/scriptcontext.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers the GLM module with the given script context.
|
|
||||||
*
|
|
||||||
* @param context The script context to register the module with.
|
|
||||||
*/
|
|
||||||
void moduleGLM(scriptcontext_t *context);
|
void moduleGLM(scriptcontext_t *context);
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new vec3 structure in Lua.
|
|
||||||
*
|
|
||||||
* @param l The Lua state.
|
|
||||||
* @return Number of return values on the Lua stack.
|
|
||||||
*/
|
|
||||||
int moduleVec3Create(lua_State *l);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lua __index metamethod for vec3 structure.
|
|
||||||
*
|
|
||||||
* @param l The Lua state.
|
|
||||||
* @return Number of return values on the Lua stack.
|
|
||||||
*/
|
|
||||||
int moduleVec3Index(lua_State *l);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lua __newindex metamethod for vec3 structure.
|
|
||||||
*
|
|
||||||
* @param l The Lua state.
|
|
||||||
* @return Number of return values on the Lua stack.
|
|
||||||
*/
|
|
||||||
int moduleVec3NewIndex(lua_State *l);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lua __tostring metamethod for vec3 structure.
|
|
||||||
*
|
|
||||||
* @param l The Lua state.
|
|
||||||
* @return Number of return values on the Lua stack.
|
|
||||||
*/
|
|
||||||
int moduleVec3ToString(lua_State *l);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new vec4 structure in Lua.
|
|
||||||
*
|
|
||||||
* @param l The Lua state.
|
|
||||||
* @return Number of return values on the Lua stack.
|
|
||||||
*/
|
|
||||||
int moduleVec4Create(lua_State *l);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lua __index metamethod for vec4 structure.
|
|
||||||
*
|
|
||||||
* @param l The Lua state.
|
|
||||||
* @return Number of return values on the Lua stack.
|
|
||||||
*/
|
|
||||||
int moduleVec4Index(lua_State *l);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lua __newindex metamethod for vec4 structure.
|
|
||||||
*
|
|
||||||
* @param l The Lua state.
|
|
||||||
* @return Number of return values on the Lua stack.
|
|
||||||
*/
|
|
||||||
int moduleVec4NewIndex(lua_State *l);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lua __tostring metamethod for vec4 structure.
|
|
||||||
*
|
|
||||||
* @param l The Lua state.
|
|
||||||
* @return Number of return values on the Lua stack.
|
|
||||||
*/
|
|
||||||
int moduleVec4ToString(lua_State *l);
|
|
||||||
@@ -9,62 +9,127 @@
|
|||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "entity/entity.h"
|
#include "entity/entity.h"
|
||||||
#include "entity/component/display/entitycamera.h"
|
#include "entity/component/display/entitycamera.h"
|
||||||
|
#include "script/module/math/modulevec2.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
entityid_t entityId;
|
||||||
|
componentid_t compId;
|
||||||
|
} entitycamera_handle_t;
|
||||||
|
|
||||||
|
static void pushEntityCameraHandle(
|
||||||
|
lua_State *L,
|
||||||
|
entityid_t entityId,
|
||||||
|
componentid_t compId
|
||||||
|
) {
|
||||||
|
entitycamera_handle_t *h = lua_newuserdata(
|
||||||
|
L, sizeof(entitycamera_handle_t)
|
||||||
|
);
|
||||||
|
h->entityId = entityId;
|
||||||
|
h->compId = compId;
|
||||||
|
luaL_getmetatable(L, "entitycamera_mt");
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityCameraIndex(lua_State *L) {
|
||||||
|
entitycamera_handle_t *h = luaL_checkudata(L, 1, "entitycamera_mt");
|
||||||
|
assertNotNull(h, "EntityCamera handle cannot be NULL");
|
||||||
|
const char *key = luaL_checkstring(L, 2);
|
||||||
|
|
||||||
|
if(strcmp(key, "zNear") == 0) {
|
||||||
|
lua_pushnumber(
|
||||||
|
L, (lua_Number)entityCameraGetZNear(h->entityId, h->compId)
|
||||||
|
);
|
||||||
|
return 1;
|
||||||
|
} else if(strcmp(key, "zFar") == 0) {
|
||||||
|
lua_pushnumber(
|
||||||
|
L, (lua_Number)entityCameraGetZFar(h->entityId, h->compId)
|
||||||
|
);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_getmetatable(L, 1);
|
||||||
|
lua_getfield(L, -1, key);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityCameraNewindex(lua_State *L) {
|
||||||
|
entitycamera_handle_t *h = luaL_checkudata(L, 1, "entitycamera_mt");
|
||||||
|
assertNotNull(h, "EntityCamera handle cannot be NULL");
|
||||||
|
const char *key = luaL_checkstring(L, 2);
|
||||||
|
|
||||||
|
if(strcmp(key, "zNear") == 0) {
|
||||||
|
entityCameraSetZNear(
|
||||||
|
h->entityId, h->compId, (float_t)luaL_checknumber(L, 3)
|
||||||
|
);
|
||||||
|
return 0;
|
||||||
|
} else if(strcmp(key, "zFar") == 0) {
|
||||||
|
entityCameraSetZFar(
|
||||||
|
h->entityId, h->compId, (float_t)luaL_checknumber(L, 3)
|
||||||
|
);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
luaL_error(L, "entitycamera: unknown property '%s'", key);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityCameraGetForwardMethod(lua_State *L) {
|
||||||
|
entitycamera_handle_t *h = luaL_checkudata(L, 1, "entitycamera_mt");
|
||||||
|
assertNotNull(h, "EntityCamera handle cannot be NULL");
|
||||||
|
vec2 fwd;
|
||||||
|
entityCameraGetForward(h->entityId, fwd);
|
||||||
|
luaVec2Push(L, fwd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityCameraGetRightMethod(lua_State *L) {
|
||||||
|
entitycamera_handle_t *h = luaL_checkudata(L, 1, "entitycamera_mt");
|
||||||
|
assertNotNull(h, "EntityCamera handle cannot be NULL");
|
||||||
|
vec2 right;
|
||||||
|
entityCameraGetRight(h->entityId, right);
|
||||||
|
luaVec2Push(L, right);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityCameraAdd(lua_State *L) {
|
||||||
|
assertNotNull(L, "Lua state cannot be NULL");
|
||||||
|
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
||||||
|
componentid_t compId = entityAddComponent(entityId, COMPONENT_TYPE_CAMERA);
|
||||||
|
pushEntityCameraHandle(L, entityId, compId);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityCameraGetCurrentGlobal(lua_State *L) {
|
||||||
|
assertNotNull(L, "Lua state cannot be NULL");
|
||||||
|
entityid_t camEnts[ENTITY_COUNT_MAX];
|
||||||
|
componentid_t camComps[ENTITY_COUNT_MAX];
|
||||||
|
entityid_t count = componentGetEntitiesWithComponent(
|
||||||
|
COMPONENT_TYPE_CAMERA, camEnts, camComps
|
||||||
|
);
|
||||||
|
if(count == 0) {
|
||||||
|
lua_pushnil(L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
pushEntityCameraHandle(L, camEnts[0], camComps[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void moduleEntityCamera(scriptcontext_t *ctx) {
|
void moduleEntityCamera(scriptcontext_t *ctx) {
|
||||||
assertNotNull(ctx, "Script context cannot be NULL");
|
assertNotNull(ctx, "Script context cannot be NULL");
|
||||||
|
|
||||||
#define REG(name, func) lua_register(ctx->luaState, name, func)
|
lua_State *L = ctx->luaState;
|
||||||
REG("entityCameraAdd", moduleEntityCameraAdd);
|
|
||||||
REG("entityCameraGetZNear", moduleEntityCameraGetZNear);
|
luaL_newmetatable(L, "entitycamera_mt");
|
||||||
REG("entityCameraSetZNear", moduleEntityCameraSetZNear);
|
lua_pushcfunction(L, entityCameraIndex);
|
||||||
REG("entityCameraGetZFar", moduleEntityCameraGetZFar);
|
lua_setfield(L, -2, "__index");
|
||||||
REG("entityCameraSetZFar", moduleEntityCameraSetZFar);
|
lua_pushcfunction(L, entityCameraNewindex);
|
||||||
#undef REG
|
lua_setfield(L, -2, "__newindex");
|
||||||
}
|
lua_pushcfunction(L, entityCameraGetForwardMethod);
|
||||||
|
lua_setfield(L, -2, "getForward");
|
||||||
int moduleEntityCameraAdd(lua_State *L) {
|
lua_pushcfunction(L, entityCameraGetRightMethod);
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
lua_setfield(L, -2, "getRight");
|
||||||
|
lua_pop(L, 1);
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
|
||||||
componentid_t compId = entityAddComponent(entityId, COMPONENT_TYPE_CAMERA);
|
lua_register(L, "entityCameraAdd", entityCameraAdd);
|
||||||
lua_pushnumber(L, (lua_Number)compId);
|
lua_register(L, "entityCameraGetCurrent", entityCameraGetCurrentGlobal);
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleEntityCameraGetZNear(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
|
||||||
componentid_t compId = (componentid_t)luaL_checknumber(L, 2);
|
|
||||||
lua_pushnumber(L, (lua_Number)entityCameraGetZNear(entityId, compId));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleEntityCameraSetZNear(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
|
||||||
componentid_t compId = (componentid_t)luaL_checknumber(L, 2);
|
|
||||||
float_t zNear = (float_t)luaL_checknumber(L, 3);
|
|
||||||
entityCameraSetZNear(entityId, compId, zNear);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleEntityCameraGetZFar(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
|
||||||
componentid_t compId = (componentid_t)luaL_checknumber(L, 2);
|
|
||||||
lua_pushnumber(L, (lua_Number)entityCameraGetZFar(entityId, compId));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleEntityCameraSetZFar(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
|
||||||
componentid_t compId = (componentid_t)luaL_checknumber(L, 2);
|
|
||||||
float_t zFar = (float_t)luaL_checknumber(L, 3);
|
|
||||||
entityCameraSetZFar(entityId, compId, zFar);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,9 +9,3 @@
|
|||||||
#include "script/scriptcontext.h"
|
#include "script/scriptcontext.h"
|
||||||
|
|
||||||
void moduleEntityCamera(scriptcontext_t *ctx);
|
void moduleEntityCamera(scriptcontext_t *ctx);
|
||||||
|
|
||||||
int moduleEntityCameraAdd(lua_State *L);
|
|
||||||
int moduleEntityCameraGetZNear(lua_State *L);
|
|
||||||
int moduleEntityCameraSetZNear(lua_State *L);
|
|
||||||
int moduleEntityCameraGetZFar(lua_State *L);
|
|
||||||
int moduleEntityCameraSetZFar(lua_State *L);
|
|
||||||
|
|||||||
@@ -10,17 +10,65 @@
|
|||||||
#include "entity/entity.h"
|
#include "entity/entity.h"
|
||||||
#include "entity/component/display/entitymaterial.h"
|
#include "entity/component/display/entitymaterial.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
entityid_t entityId;
|
||||||
|
componentid_t compId;
|
||||||
|
} entitymaterial_handle_t;
|
||||||
|
|
||||||
|
static void pushEntityMaterialHandle(
|
||||||
|
lua_State *L,
|
||||||
|
entityid_t entityId,
|
||||||
|
componentid_t compId
|
||||||
|
) {
|
||||||
|
entitymaterial_handle_t *h = lua_newuserdata(
|
||||||
|
L, sizeof(entitymaterial_handle_t)
|
||||||
|
);
|
||||||
|
h->entityId = entityId;
|
||||||
|
h->compId = compId;
|
||||||
|
luaL_getmetatable(L, "entitymaterial_mt");
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityMaterialIndex(lua_State *L) {
|
||||||
|
lua_getmetatable(L, 1);
|
||||||
|
lua_getfield(L, -1, luaL_checkstring(L, 2));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityMaterialNewindex(lua_State *L) {
|
||||||
|
entitymaterial_handle_t *h = luaL_checkudata(L, 1, "entitymaterial_mt");
|
||||||
|
assertNotNull(h, "EntityMaterial handle cannot be NULL");
|
||||||
|
const char *key = luaL_checkstring(L, 2);
|
||||||
|
|
||||||
|
if(strcmp(key, "color") == 0) {
|
||||||
|
const color_t *col = (const color_t *)luaL_checkudata(L, 3, "color_mt");
|
||||||
|
entityMaterialSetColor(h->entityId, h->compId, *col);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
luaL_error(L, "entitymaterial: unknown property '%s'", key);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityMaterialAdd(lua_State *L) {
|
||||||
|
assertNotNull(L, "Lua state cannot be NULL");
|
||||||
|
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
||||||
|
componentid_t compId = entityAddComponent(entityId, COMPONENT_TYPE_MATERIAL);
|
||||||
|
pushEntityMaterialHandle(L, entityId, compId);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void moduleEntityMaterial(scriptcontext_t *ctx) {
|
void moduleEntityMaterial(scriptcontext_t *ctx) {
|
||||||
assertNotNull(ctx, "Script context cannot be NULL");
|
assertNotNull(ctx, "Script context cannot be NULL");
|
||||||
|
|
||||||
lua_register(ctx->luaState, "entityMaterialAdd", moduleEntityMaterialAdd);
|
lua_State *L = ctx->luaState;
|
||||||
}
|
|
||||||
|
|
||||||
int moduleEntityMaterialAdd(lua_State *L) {
|
luaL_newmetatable(L, "entitymaterial_mt");
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
lua_pushcfunction(L, entityMaterialIndex);
|
||||||
|
lua_setfield(L, -2, "__index");
|
||||||
|
lua_pushcfunction(L, entityMaterialNewindex);
|
||||||
|
lua_setfield(L, -2, "__newindex");
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
lua_register(L, "entityMaterialAdd", entityMaterialAdd);
|
||||||
componentid_t compId = entityAddComponent(entityId, COMPONENT_TYPE_MATERIAL);
|
|
||||||
lua_pushnumber(L, (lua_Number)compId);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,5 +9,3 @@
|
|||||||
#include "script/scriptcontext.h"
|
#include "script/scriptcontext.h"
|
||||||
|
|
||||||
void moduleEntityMaterial(scriptcontext_t *ctx);
|
void moduleEntityMaterial(scriptcontext_t *ctx);
|
||||||
|
|
||||||
int moduleEntityMaterialAdd(lua_State *L);
|
|
||||||
|
|||||||
@@ -10,17 +10,76 @@
|
|||||||
#include "entity/entity.h"
|
#include "entity/entity.h"
|
||||||
#include "entity/component/display/entitymesh.h"
|
#include "entity/component/display/entitymesh.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
entityid_t entityId;
|
||||||
|
componentid_t compId;
|
||||||
|
} entitymesh_handle_t;
|
||||||
|
|
||||||
|
static void pushEntityMeshHandle(
|
||||||
|
lua_State *L,
|
||||||
|
entityid_t entityId,
|
||||||
|
componentid_t compId
|
||||||
|
) {
|
||||||
|
entitymesh_handle_t *h = lua_newuserdata(L, sizeof(entitymesh_handle_t));
|
||||||
|
h->entityId = entityId;
|
||||||
|
h->compId = compId;
|
||||||
|
luaL_getmetatable(L, "entitymesh_mt");
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityMeshIndex(lua_State *L) {
|
||||||
|
lua_getmetatable(L, 1);
|
||||||
|
lua_getfield(L, -1, luaL_checkstring(L, 2));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityMeshGeneratePlaneMethod(lua_State *L) {
|
||||||
|
entitymesh_handle_t *h = luaL_checkudata(L, 1, "entitymesh_mt");
|
||||||
|
assertNotNull(h, "EntityMesh handle cannot be NULL");
|
||||||
|
float_t width = (float_t)luaL_checknumber(L, 2);
|
||||||
|
float_t height = (float_t)luaL_checknumber(L, 3);
|
||||||
|
errorret_t err = entityMeshGeneratePlane(h->entityId, h->compId, width, height);
|
||||||
|
if(err.code != ERROR_OK) {
|
||||||
|
luaL_error(L, "Failed to generate plane mesh");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityMeshGenerateCapsuleMethod(lua_State *L) {
|
||||||
|
entitymesh_handle_t *h = luaL_checkudata(L, 1, "entitymesh_mt");
|
||||||
|
assertNotNull(h, "EntityMesh handle cannot be NULL");
|
||||||
|
float_t radius = (float_t)luaL_checknumber(L, 2);
|
||||||
|
float_t halfHeight = (float_t)luaL_checknumber(L, 3);
|
||||||
|
errorret_t err = entityMeshGenerateCapsule(
|
||||||
|
h->entityId, h->compId, radius, halfHeight
|
||||||
|
);
|
||||||
|
if(err.code != ERROR_OK) {
|
||||||
|
luaL_error(L, "Failed to generate capsule mesh");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityMeshAdd(lua_State *L) {
|
||||||
|
assertNotNull(L, "Lua state cannot be NULL");
|
||||||
|
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
||||||
|
componentid_t compId = entityAddComponent(entityId, COMPONENT_TYPE_MESH);
|
||||||
|
pushEntityMeshHandle(L, entityId, compId);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void moduleEntityMesh(scriptcontext_t *ctx) {
|
void moduleEntityMesh(scriptcontext_t *ctx) {
|
||||||
assertNotNull(ctx, "Script context cannot be NULL");
|
assertNotNull(ctx, "Script context cannot be NULL");
|
||||||
|
|
||||||
lua_register(ctx->luaState, "entityMeshAdd", moduleEntityMeshAdd);
|
lua_State *L = ctx->luaState;
|
||||||
}
|
|
||||||
|
|
||||||
int moduleEntityMeshAdd(lua_State *L) {
|
luaL_newmetatable(L, "entitymesh_mt");
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
lua_pushcfunction(L, entityMeshIndex);
|
||||||
|
lua_setfield(L, -2, "__index");
|
||||||
|
lua_pushcfunction(L, entityMeshGeneratePlaneMethod);
|
||||||
|
lua_setfield(L, -2, "generatePlane");
|
||||||
|
lua_pushcfunction(L, entityMeshGenerateCapsuleMethod);
|
||||||
|
lua_setfield(L, -2, "generateCapsule");
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
lua_register(L, "entityMeshAdd", entityMeshAdd);
|
||||||
componentid_t compId = entityAddComponent(entityId, COMPONENT_TYPE_MESH);
|
|
||||||
lua_pushnumber(L, (lua_Number)compId);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,5 +9,3 @@
|
|||||||
#include "script/scriptcontext.h"
|
#include "script/scriptcontext.h"
|
||||||
|
|
||||||
void moduleEntityMesh(scriptcontext_t *ctx);
|
void moduleEntityMesh(scriptcontext_t *ctx);
|
||||||
|
|
||||||
int moduleEntityMeshAdd(lua_State *L);
|
|
||||||
|
|||||||
@@ -9,132 +9,145 @@
|
|||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "entity/entity.h"
|
#include "entity/entity.h"
|
||||||
#include "entity/component/display/entityposition.h"
|
#include "entity/component/display/entityposition.h"
|
||||||
|
#include "script/module/math/modulevec3.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
entityid_t entityId;
|
||||||
|
componentid_t compId;
|
||||||
|
} entityposition_handle_t;
|
||||||
|
|
||||||
|
static void pushEntityPositionHandle(
|
||||||
|
lua_State *L,
|
||||||
|
entityid_t entityId,
|
||||||
|
componentid_t compId
|
||||||
|
) {
|
||||||
|
entityposition_handle_t *h = lua_newuserdata(
|
||||||
|
L, sizeof(entityposition_handle_t)
|
||||||
|
);
|
||||||
|
h->entityId = entityId;
|
||||||
|
h->compId = compId;
|
||||||
|
luaL_getmetatable(L, "entityposition_mt");
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityPositionIndex(lua_State *L) {
|
||||||
|
entityposition_handle_t *h = luaL_checkudata(L, 1, "entityposition_mt");
|
||||||
|
assertNotNull(h, "EntityPosition handle cannot be NULL");
|
||||||
|
const char *key = luaL_checkstring(L, 2);
|
||||||
|
|
||||||
|
if(strcmp(key, "x") == 0) {
|
||||||
|
vec3 v; entityPositionGetPosition(h->entityId, h->compId, v);
|
||||||
|
lua_pushnumber(L, v[0]); return 1;
|
||||||
|
} else if(strcmp(key, "y") == 0) {
|
||||||
|
vec3 v; entityPositionGetPosition(h->entityId, h->compId, v);
|
||||||
|
lua_pushnumber(L, v[1]); return 1;
|
||||||
|
} else if(strcmp(key, "z") == 0) {
|
||||||
|
vec3 v; entityPositionGetPosition(h->entityId, h->compId, v);
|
||||||
|
lua_pushnumber(L, v[2]); return 1;
|
||||||
|
} else if(strcmp(key, "rotX") == 0) {
|
||||||
|
vec3 v; entityPositionGetRotation(h->entityId, h->compId, v);
|
||||||
|
lua_pushnumber(L, v[0]); return 1;
|
||||||
|
} else if(strcmp(key, "rotY") == 0) {
|
||||||
|
vec3 v; entityPositionGetRotation(h->entityId, h->compId, v);
|
||||||
|
lua_pushnumber(L, v[1]); return 1;
|
||||||
|
} else if(strcmp(key, "rotZ") == 0) {
|
||||||
|
vec3 v; entityPositionGetRotation(h->entityId, h->compId, v);
|
||||||
|
lua_pushnumber(L, v[2]); return 1;
|
||||||
|
} else if(strcmp(key, "scaleX") == 0) {
|
||||||
|
vec3 v; entityPositionGetScale(h->entityId, h->compId, v);
|
||||||
|
lua_pushnumber(L, v[0]); return 1;
|
||||||
|
} else if(strcmp(key, "scaleY") == 0) {
|
||||||
|
vec3 v; entityPositionGetScale(h->entityId, h->compId, v);
|
||||||
|
lua_pushnumber(L, v[1]); return 1;
|
||||||
|
} else if(strcmp(key, "scaleZ") == 0) {
|
||||||
|
vec3 v; entityPositionGetScale(h->entityId, h->compId, v);
|
||||||
|
lua_pushnumber(L, v[2]); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_getmetatable(L, 1);
|
||||||
|
lua_getfield(L, -1, key);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityPositionNewindex(lua_State *L) {
|
||||||
|
entityposition_handle_t *h = luaL_checkudata(L, 1, "entityposition_mt");
|
||||||
|
assertNotNull(h, "EntityPosition handle cannot be NULL");
|
||||||
|
const char *key = luaL_checkstring(L, 2);
|
||||||
|
|
||||||
|
if(strcmp(key, "x") == 0) {
|
||||||
|
vec3 v; entityPositionGetPosition(h->entityId, h->compId, v);
|
||||||
|
v[0] = (float_t)luaL_checknumber(L, 3);
|
||||||
|
entityPositionSetPosition(h->entityId, h->compId, v); return 0;
|
||||||
|
} else if(strcmp(key, "y") == 0) {
|
||||||
|
vec3 v; entityPositionGetPosition(h->entityId, h->compId, v);
|
||||||
|
v[1] = (float_t)luaL_checknumber(L, 3);
|
||||||
|
entityPositionSetPosition(h->entityId, h->compId, v); return 0;
|
||||||
|
} else if(strcmp(key, "z") == 0) {
|
||||||
|
vec3 v; entityPositionGetPosition(h->entityId, h->compId, v);
|
||||||
|
v[2] = (float_t)luaL_checknumber(L, 3);
|
||||||
|
entityPositionSetPosition(h->entityId, h->compId, v); return 0;
|
||||||
|
} else if(strcmp(key, "rotX") == 0) {
|
||||||
|
vec3 v; entityPositionGetRotation(h->entityId, h->compId, v);
|
||||||
|
v[0] = (float_t)luaL_checknumber(L, 3);
|
||||||
|
entityPositionSetRotation(h->entityId, h->compId, v); return 0;
|
||||||
|
} else if(strcmp(key, "rotY") == 0) {
|
||||||
|
vec3 v; entityPositionGetRotation(h->entityId, h->compId, v);
|
||||||
|
v[1] = (float_t)luaL_checknumber(L, 3);
|
||||||
|
entityPositionSetRotation(h->entityId, h->compId, v); return 0;
|
||||||
|
} else if(strcmp(key, "rotZ") == 0) {
|
||||||
|
vec3 v; entityPositionGetRotation(h->entityId, h->compId, v);
|
||||||
|
v[2] = (float_t)luaL_checknumber(L, 3);
|
||||||
|
entityPositionSetRotation(h->entityId, h->compId, v); return 0;
|
||||||
|
} else if(strcmp(key, "scaleX") == 0) {
|
||||||
|
vec3 v; entityPositionGetScale(h->entityId, h->compId, v);
|
||||||
|
v[0] = (float_t)luaL_checknumber(L, 3);
|
||||||
|
entityPositionSetScale(h->entityId, h->compId, v); return 0;
|
||||||
|
} else if(strcmp(key, "scaleY") == 0) {
|
||||||
|
vec3 v; entityPositionGetScale(h->entityId, h->compId, v);
|
||||||
|
v[1] = (float_t)luaL_checknumber(L, 3);
|
||||||
|
entityPositionSetScale(h->entityId, h->compId, v); return 0;
|
||||||
|
} else if(strcmp(key, "scaleZ") == 0) {
|
||||||
|
vec3 v; entityPositionGetScale(h->entityId, h->compId, v);
|
||||||
|
v[2] = (float_t)luaL_checknumber(L, 3);
|
||||||
|
entityPositionSetScale(h->entityId, h->compId, v); return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
luaL_error(L, "entityposition: unknown property '%s'", key);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityPositionLookAtMethod(lua_State *L) {
|
||||||
|
entityposition_handle_t *h = luaL_checkudata(L, 1, "entityposition_mt");
|
||||||
|
assertNotNull(h, "EntityPosition handle cannot be NULL");
|
||||||
|
vec3 target, up, eye;
|
||||||
|
luaVec3Check(L, 2, target);
|
||||||
|
luaVec3Check(L, 3, up);
|
||||||
|
luaVec3Check(L, 4, eye);
|
||||||
|
entityPositionLookAt(h->entityId, h->compId, target, up, eye);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityPositionAdd(lua_State *L) {
|
||||||
|
assertNotNull(L, "Lua state cannot be NULL");
|
||||||
|
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
||||||
|
componentid_t compId = entityAddComponent(entityId, COMPONENT_TYPE_POSITION);
|
||||||
|
pushEntityPositionHandle(L, entityId, compId);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void moduleEntityPosition(scriptcontext_t *ctx) {
|
void moduleEntityPosition(scriptcontext_t *ctx) {
|
||||||
assertNotNull(ctx, "Script context cannot be NULL");
|
assertNotNull(ctx, "Script context cannot be NULL");
|
||||||
|
|
||||||
#define REG(name, func) lua_register(ctx->luaState, name, func)
|
lua_State *L = ctx->luaState;
|
||||||
REG("entityPositionAdd", moduleEntityPositionAdd);
|
|
||||||
REG("entityPositionSetPosition", moduleEntityPositionSetPosition);
|
luaL_newmetatable(L, "entityposition_mt");
|
||||||
REG("entityPositionGetPosition", moduleEntityPositionGetPosition);
|
lua_pushcfunction(L, entityPositionIndex);
|
||||||
REG("entityPositionSetRotation", moduleEntityPositionSetRotation);
|
lua_setfield(L, -2, "__index");
|
||||||
REG("entityPositionGetRotation", moduleEntityPositionGetRotation);
|
lua_pushcfunction(L, entityPositionNewindex);
|
||||||
REG("entityPositionSetScale", moduleEntityPositionSetScale);
|
lua_setfield(L, -2, "__newindex");
|
||||||
REG("entityPositionGetScale", moduleEntityPositionGetScale);
|
lua_pushcfunction(L, entityPositionLookAtMethod);
|
||||||
REG("entityPositionLookAt", moduleEntityPositionLookAt);
|
lua_setfield(L, -2, "lookAt");
|
||||||
#undef REG
|
lua_pop(L, 1);
|
||||||
}
|
|
||||||
|
lua_register(L, "entityPositionAdd", entityPositionAdd);
|
||||||
int moduleEntityPositionAdd(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
|
||||||
componentid_t compId = entityAddComponent(entityId, COMPONENT_TYPE_POSITION);
|
|
||||||
lua_pushnumber(L, (lua_Number)compId);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleEntityPositionSetPosition(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
|
||||||
componentid_t compId = (componentid_t)luaL_checknumber(L, 2);
|
|
||||||
vec3 pos = {
|
|
||||||
(float_t)luaL_checknumber(L, 3),
|
|
||||||
(float_t)luaL_checknumber(L, 4),
|
|
||||||
(float_t)luaL_checknumber(L, 5)
|
|
||||||
};
|
|
||||||
entityPositionSetPosition(entityId, compId, pos);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleEntityPositionGetPosition(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
|
||||||
componentid_t compId = (componentid_t)luaL_checknumber(L, 2);
|
|
||||||
vec3 pos;
|
|
||||||
entityPositionGetPosition(entityId, compId, pos);
|
|
||||||
lua_pushnumber(L, pos[0]);
|
|
||||||
lua_pushnumber(L, pos[1]);
|
|
||||||
lua_pushnumber(L, pos[2]);
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleEntityPositionSetRotation(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
|
||||||
componentid_t compId = (componentid_t)luaL_checknumber(L, 2);
|
|
||||||
vec3 rot = {
|
|
||||||
(float_t)luaL_checknumber(L, 3),
|
|
||||||
(float_t)luaL_checknumber(L, 4),
|
|
||||||
(float_t)luaL_checknumber(L, 5)
|
|
||||||
};
|
|
||||||
entityPositionSetRotation(entityId, compId, rot);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleEntityPositionGetRotation(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
|
||||||
componentid_t compId = (componentid_t)luaL_checknumber(L, 2);
|
|
||||||
vec3 rot;
|
|
||||||
entityPositionGetRotation(entityId, compId, rot);
|
|
||||||
lua_pushnumber(L, rot[0]);
|
|
||||||
lua_pushnumber(L, rot[1]);
|
|
||||||
lua_pushnumber(L, rot[2]);
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleEntityPositionSetScale(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
|
||||||
componentid_t compId = (componentid_t)luaL_checknumber(L, 2);
|
|
||||||
vec3 scale = {
|
|
||||||
(float_t)luaL_checknumber(L, 3),
|
|
||||||
(float_t)luaL_checknumber(L, 4),
|
|
||||||
(float_t)luaL_checknumber(L, 5)
|
|
||||||
};
|
|
||||||
entityPositionSetScale(entityId, compId, scale);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleEntityPositionGetScale(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
|
||||||
componentid_t compId = (componentid_t)luaL_checknumber(L, 2);
|
|
||||||
vec3 scale;
|
|
||||||
entityPositionGetScale(entityId, compId, scale);
|
|
||||||
lua_pushnumber(L, scale[0]);
|
|
||||||
lua_pushnumber(L, scale[1]);
|
|
||||||
lua_pushnumber(L, scale[2]);
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleEntityPositionLookAt(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
|
||||||
componentid_t compId = (componentid_t)luaL_checknumber(L, 2);
|
|
||||||
vec3 target = {
|
|
||||||
(float_t)luaL_checknumber(L, 3),
|
|
||||||
(float_t)luaL_checknumber(L, 4),
|
|
||||||
(float_t)luaL_checknumber(L, 5)
|
|
||||||
};
|
|
||||||
vec3 up = {
|
|
||||||
(float_t)luaL_checknumber(L, 6),
|
|
||||||
(float_t)luaL_checknumber(L, 7),
|
|
||||||
(float_t)luaL_checknumber(L, 8)
|
|
||||||
};
|
|
||||||
vec3 eye = {
|
|
||||||
(float_t)luaL_checknumber(L, 9),
|
|
||||||
(float_t)luaL_checknumber(L, 10),
|
|
||||||
(float_t)luaL_checknumber(L, 11)
|
|
||||||
};
|
|
||||||
entityPositionLookAt(entityId, compId, target, up, eye);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,3 @@
|
|||||||
#include "script/scriptcontext.h"
|
#include "script/scriptcontext.h"
|
||||||
|
|
||||||
void moduleEntityPosition(scriptcontext_t *ctx);
|
void moduleEntityPosition(scriptcontext_t *ctx);
|
||||||
|
|
||||||
int moduleEntityPositionAdd(lua_State *L);
|
|
||||||
int moduleEntityPositionSetPosition(lua_State *L);
|
|
||||||
int moduleEntityPositionGetPosition(lua_State *L);
|
|
||||||
int moduleEntityPositionSetRotation(lua_State *L);
|
|
||||||
int moduleEntityPositionGetRotation(lua_State *L);
|
|
||||||
int moduleEntityPositionSetScale(lua_State *L);
|
|
||||||
int moduleEntityPositionGetScale(lua_State *L);
|
|
||||||
int moduleEntityPositionLookAt(lua_State *L);
|
|
||||||
|
|||||||
@@ -9,132 +9,187 @@
|
|||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "entity/entity.h"
|
#include "entity/entity.h"
|
||||||
#include "entity/component/physics/entityphysics.h"
|
#include "entity/component/physics/entityphysics.h"
|
||||||
|
#include "physics/physicsbodytype.h"
|
||||||
|
#include "script/module/math/modulevec3.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
entityid_t entityId;
|
||||||
|
componentid_t compId;
|
||||||
|
} entityphysics_handle_t;
|
||||||
|
|
||||||
|
static void pushEntityPhysicsHandle(
|
||||||
|
lua_State *L,
|
||||||
|
entityid_t entityId,
|
||||||
|
componentid_t compId
|
||||||
|
) {
|
||||||
|
entityphysics_handle_t *h = lua_newuserdata(
|
||||||
|
L, sizeof(entityphysics_handle_t)
|
||||||
|
);
|
||||||
|
h->entityId = entityId;
|
||||||
|
h->compId = compId;
|
||||||
|
luaL_getmetatable(L, "entityphysics_mt");
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityPhysicsIndex(lua_State *L) {
|
||||||
|
entityphysics_handle_t *h = luaL_checkudata(L, 1, "entityphysics_mt");
|
||||||
|
assertNotNull(h, "EntityPhysics handle cannot be NULL");
|
||||||
|
const char *key = luaL_checkstring(L, 2);
|
||||||
|
|
||||||
|
if(strcmp(key, "bodyType") == 0) {
|
||||||
|
lua_pushnumber(
|
||||||
|
L, (lua_Number)entityPhysicsGetBodyType(h->entityId, h->compId)
|
||||||
|
);
|
||||||
|
return 1;
|
||||||
|
} else if(strcmp(key, "velocityX") == 0) {
|
||||||
|
vec3 v; entityPhysicsGetVelocity(h->entityId, h->compId, v);
|
||||||
|
lua_pushnumber(L, v[0]); return 1;
|
||||||
|
} else if(strcmp(key, "velocityY") == 0) {
|
||||||
|
vec3 v; entityPhysicsGetVelocity(h->entityId, h->compId, v);
|
||||||
|
lua_pushnumber(L, v[1]); return 1;
|
||||||
|
} else if(strcmp(key, "velocityZ") == 0) {
|
||||||
|
vec3 v; entityPhysicsGetVelocity(h->entityId, h->compId, v);
|
||||||
|
lua_pushnumber(L, v[2]); return 1;
|
||||||
|
} else if(strcmp(key, "velocity") == 0) {
|
||||||
|
vec3 v; entityPhysicsGetVelocity(h->entityId, h->compId, v);
|
||||||
|
luaVec3Push(L, v); return 1;
|
||||||
|
} else if(strcmp(key, "onGround") == 0) {
|
||||||
|
lua_pushboolean(
|
||||||
|
L, (int)entityPhysicsIsOnGround(h->entityId, h->compId)
|
||||||
|
);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_getmetatable(L, 1);
|
||||||
|
lua_getfield(L, -1, key);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityPhysicsNewindex(lua_State *L) {
|
||||||
|
entityphysics_handle_t *h = luaL_checkudata(L, 1, "entityphysics_mt");
|
||||||
|
assertNotNull(h, "EntityPhysics handle cannot be NULL");
|
||||||
|
const char *key = luaL_checkstring(L, 2);
|
||||||
|
|
||||||
|
if(strcmp(key, "bodyType") == 0) {
|
||||||
|
physicsbodytype_t t = (physicsbodytype_t)luaL_checknumber(L, 3);
|
||||||
|
entityPhysicsSetBodyType(h->entityId, h->compId, t);
|
||||||
|
return 0;
|
||||||
|
} else if(strcmp(key, "velocityX") == 0) {
|
||||||
|
vec3 v; entityPhysicsGetVelocity(h->entityId, h->compId, v);
|
||||||
|
v[0] = (float_t)luaL_checknumber(L, 3);
|
||||||
|
entityPhysicsSetVelocity(h->entityId, h->compId, v); return 0;
|
||||||
|
} else if(strcmp(key, "velocityY") == 0) {
|
||||||
|
vec3 v; entityPhysicsGetVelocity(h->entityId, h->compId, v);
|
||||||
|
v[1] = (float_t)luaL_checknumber(L, 3);
|
||||||
|
entityPhysicsSetVelocity(h->entityId, h->compId, v); return 0;
|
||||||
|
} else if(strcmp(key, "velocityZ") == 0) {
|
||||||
|
vec3 v; entityPhysicsGetVelocity(h->entityId, h->compId, v);
|
||||||
|
v[2] = (float_t)luaL_checknumber(L, 3);
|
||||||
|
entityPhysicsSetVelocity(h->entityId, h->compId, v); return 0;
|
||||||
|
} else if(strcmp(key, "velocity") == 0) {
|
||||||
|
vec3 v; luaVec3Check(L, 3, v);
|
||||||
|
entityPhysicsSetVelocity(h->entityId, h->compId, v); return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
luaL_error(L, "entityphysics: unknown property '%s'", key);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityPhysicsSetShapeCapsuleMethod(lua_State *L) {
|
||||||
|
entityphysics_handle_t *h = luaL_checkudata(L, 1, "entityphysics_mt");
|
||||||
|
assertNotNull(h, "EntityPhysics handle cannot be NULL");
|
||||||
|
physicsshape_t shape;
|
||||||
|
shape.type = PHYSICS_SHAPE_CAPSULE;
|
||||||
|
shape.data.capsule.radius = (float_t)luaL_checknumber(L, 2);
|
||||||
|
shape.data.capsule.halfHeight = (float_t)luaL_checknumber(L, 3);
|
||||||
|
entityPhysicsSetShape(h->entityId, h->compId, shape);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityPhysicsSetShapePlaneMethod(lua_State *L) {
|
||||||
|
entityphysics_handle_t *h = luaL_checkudata(L, 1, "entityphysics_mt");
|
||||||
|
assertNotNull(h, "EntityPhysics handle cannot be NULL");
|
||||||
|
physicsshape_t shape;
|
||||||
|
shape.type = PHYSICS_SHAPE_PLANE;
|
||||||
|
shape.data.plane.normal[0] = (float_t)luaL_checknumber(L, 2);
|
||||||
|
shape.data.plane.normal[1] = (float_t)luaL_checknumber(L, 3);
|
||||||
|
shape.data.plane.normal[2] = (float_t)luaL_checknumber(L, 4);
|
||||||
|
shape.data.plane.distance = (float_t)luaL_checknumber(L, 5);
|
||||||
|
entityPhysicsSetShape(h->entityId, h->compId, shape);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityPhysicsSetShapeSphereMethod(lua_State *L) {
|
||||||
|
entityphysics_handle_t *h = luaL_checkudata(L, 1, "entityphysics_mt");
|
||||||
|
assertNotNull(h, "EntityPhysics handle cannot be NULL");
|
||||||
|
physicsshape_t shape;
|
||||||
|
shape.type = PHYSICS_SHAPE_SPHERE;
|
||||||
|
shape.data.sphere.radius = (float_t)luaL_checknumber(L, 2);
|
||||||
|
entityPhysicsSetShape(h->entityId, h->compId, shape);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityPhysicsSetShapeCubeMethod(lua_State *L) {
|
||||||
|
entityphysics_handle_t *h = luaL_checkudata(L, 1, "entityphysics_mt");
|
||||||
|
assertNotNull(h, "EntityPhysics handle cannot be NULL");
|
||||||
|
physicsshape_t shape;
|
||||||
|
shape.type = PHYSICS_SHAPE_CUBE;
|
||||||
|
shape.data.cube.halfExtents[0] = (float_t)luaL_checknumber(L, 2);
|
||||||
|
shape.data.cube.halfExtents[1] = (float_t)luaL_checknumber(L, 3);
|
||||||
|
shape.data.cube.halfExtents[2] = (float_t)luaL_checknumber(L, 4);
|
||||||
|
entityPhysicsSetShape(h->entityId, h->compId, shape);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityPhysicsApplyImpulseMethod(lua_State *L) {
|
||||||
|
entityphysics_handle_t *h = luaL_checkudata(L, 1, "entityphysics_mt");
|
||||||
|
assertNotNull(h, "EntityPhysics handle cannot be NULL");
|
||||||
|
vec3 impulse = {
|
||||||
|
(float_t)luaL_checknumber(L, 2),
|
||||||
|
(float_t)luaL_checknumber(L, 3),
|
||||||
|
(float_t)luaL_checknumber(L, 4)
|
||||||
|
};
|
||||||
|
entityPhysicsApplyImpulse(h->entityId, h->compId, impulse);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entityPhysicsAdd(lua_State *L) {
|
||||||
|
assertNotNull(L, "Lua state cannot be NULL");
|
||||||
|
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
||||||
|
componentid_t compId = entityAddComponent(entityId, COMPONENT_TYPE_PHYSICS);
|
||||||
|
pushEntityPhysicsHandle(L, entityId, compId);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void moduleEntityPhysics(scriptcontext_t *ctx) {
|
void moduleEntityPhysics(scriptcontext_t *ctx) {
|
||||||
assertNotNull(ctx, "Script context cannot be NULL");
|
assertNotNull(ctx, "Script context cannot be NULL");
|
||||||
|
|
||||||
#define REG(name, func) lua_register(ctx->luaState, name, func)
|
lua_State *L = ctx->luaState;
|
||||||
REG("entityPhysicsAdd", moduleEntityPhysicsAdd);
|
|
||||||
REG("entityPhysicsSetVelocity", moduleEntityPhysicsSetVelocity);
|
#define SET(name, val) \
|
||||||
REG("entityPhysicsGetVelocity", moduleEntityPhysicsGetVelocity);
|
lua_pushnumber(L, (lua_Number)(val)); \
|
||||||
REG("entityPhysicsApplyImpulse", moduleEntityPhysicsApplyImpulse);
|
lua_setglobal(L, name)
|
||||||
REG("entityPhysicsIsOnGround", moduleEntityPhysicsIsOnGround);
|
SET("PHYSICS_BODY_STATIC", PHYSICS_BODY_STATIC);
|
||||||
REG("entityPhysicsSetShapeCube", moduleEntityPhysicsSetShapeCube);
|
SET("PHYSICS_BODY_DYNAMIC", PHYSICS_BODY_DYNAMIC);
|
||||||
REG("entityPhysicsSetShapeSphere", moduleEntityPhysicsSetShapeSphere);
|
SET("PHYSICS_BODY_KINEMATIC", PHYSICS_BODY_KINEMATIC);
|
||||||
REG("entityPhysicsSetShapeCapsule", moduleEntityPhysicsSetShapeCapsule);
|
#undef SET
|
||||||
REG("entityPhysicsSetShapePlane", moduleEntityPhysicsSetShapePlane);
|
|
||||||
#undef REG
|
luaL_newmetatable(L, "entityphysics_mt");
|
||||||
}
|
lua_pushcfunction(L, entityPhysicsIndex);
|
||||||
|
lua_setfield(L, -2, "__index");
|
||||||
int moduleEntityPhysicsAdd(lua_State *L) {
|
lua_pushcfunction(L, entityPhysicsNewindex);
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
lua_setfield(L, -2, "__newindex");
|
||||||
|
lua_pushcfunction(L, entityPhysicsSetShapeCapsuleMethod);
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
lua_setfield(L, -2, "setShapeCapsule");
|
||||||
componentid_t compId = entityAddComponent(entityId, COMPONENT_TYPE_PHYSICS);
|
lua_pushcfunction(L, entityPhysicsSetShapePlaneMethod);
|
||||||
lua_pushnumber(L, (lua_Number)compId);
|
lua_setfield(L, -2, "setShapePlane");
|
||||||
return 1;
|
lua_pushcfunction(L, entityPhysicsSetShapeSphereMethod);
|
||||||
}
|
lua_setfield(L, -2, "setShapeSphere");
|
||||||
|
lua_pushcfunction(L, entityPhysicsSetShapeCubeMethod);
|
||||||
int moduleEntityPhysicsSetVelocity(lua_State *L) {
|
lua_setfield(L, -2, "setShapeCube");
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
lua_pushcfunction(L, entityPhysicsApplyImpulseMethod);
|
||||||
|
lua_setfield(L, -2, "applyImpulse");
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
lua_pop(L, 1);
|
||||||
componentid_t compId = (componentid_t)luaL_checknumber(L, 2);
|
|
||||||
vec3 vel = {
|
lua_register(L, "entityPhysicsAdd", entityPhysicsAdd);
|
||||||
(float_t)luaL_checknumber(L, 3),
|
|
||||||
(float_t)luaL_checknumber(L, 4),
|
|
||||||
(float_t)luaL_checknumber(L, 5)
|
|
||||||
};
|
|
||||||
entityPhysicsSetVelocity(entityId, compId, vel);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleEntityPhysicsGetVelocity(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
|
||||||
componentid_t compId = (componentid_t)luaL_checknumber(L, 2);
|
|
||||||
vec3 vel;
|
|
||||||
entityPhysicsGetVelocity(entityId, compId, vel);
|
|
||||||
lua_pushnumber(L, vel[0]);
|
|
||||||
lua_pushnumber(L, vel[1]);
|
|
||||||
lua_pushnumber(L, vel[2]);
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleEntityPhysicsApplyImpulse(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
|
||||||
componentid_t compId = (componentid_t)luaL_checknumber(L, 2);
|
|
||||||
vec3 impulse = {
|
|
||||||
(float_t)luaL_checknumber(L, 3),
|
|
||||||
(float_t)luaL_checknumber(L, 4),
|
|
||||||
(float_t)luaL_checknumber(L, 5)
|
|
||||||
};
|
|
||||||
entityPhysicsApplyImpulse(entityId, compId, impulse);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleEntityPhysicsIsOnGround(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
|
||||||
componentid_t compId = (componentid_t)luaL_checknumber(L, 2);
|
|
||||||
lua_pushboolean(L, (int)entityPhysicsIsOnGround(entityId, compId));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleEntityPhysicsSetShapeCube(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
|
||||||
componentid_t compId = (componentid_t)luaL_checknumber(L, 2);
|
|
||||||
physicsshape_t shape;
|
|
||||||
shape.type = PHYSICS_SHAPE_CUBE;
|
|
||||||
shape.data.cube.halfExtents[0] = (float_t)luaL_checknumber(L, 3);
|
|
||||||
shape.data.cube.halfExtents[1] = (float_t)luaL_checknumber(L, 4);
|
|
||||||
shape.data.cube.halfExtents[2] = (float_t)luaL_checknumber(L, 5);
|
|
||||||
entityPhysicsSetShape(entityId, compId, shape);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleEntityPhysicsSetShapeSphere(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
|
||||||
componentid_t compId = (componentid_t)luaL_checknumber(L, 2);
|
|
||||||
physicsshape_t shape;
|
|
||||||
shape.type = PHYSICS_SHAPE_SPHERE;
|
|
||||||
shape.data.sphere.radius = (float_t)luaL_checknumber(L, 3);
|
|
||||||
entityPhysicsSetShape(entityId, compId, shape);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleEntityPhysicsSetShapeCapsule(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
|
||||||
componentid_t compId = (componentid_t)luaL_checknumber(L, 2);
|
|
||||||
physicsshape_t shape;
|
|
||||||
shape.type = PHYSICS_SHAPE_CAPSULE;
|
|
||||||
shape.data.capsule.radius = (float_t)luaL_checknumber(L, 3);
|
|
||||||
shape.data.capsule.halfHeight = (float_t)luaL_checknumber(L, 4);
|
|
||||||
entityPhysicsSetShape(entityId, compId, shape);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int moduleEntityPhysicsSetShapePlane(lua_State *L) {
|
|
||||||
assertNotNull(L, "Lua state cannot be NULL");
|
|
||||||
|
|
||||||
entityid_t entityId = (entityid_t)luaL_checknumber(L, 1);
|
|
||||||
componentid_t compId = (componentid_t)luaL_checknumber(L, 2);
|
|
||||||
physicsshape_t shape;
|
|
||||||
shape.type = PHYSICS_SHAPE_PLANE;
|
|
||||||
shape.data.plane.normal[0] = (float_t)luaL_checknumber(L, 3);
|
|
||||||
shape.data.plane.normal[1] = (float_t)luaL_checknumber(L, 4);
|
|
||||||
shape.data.plane.normal[2] = (float_t)luaL_checknumber(L, 5);
|
|
||||||
shape.data.plane.distance = (float_t)luaL_checknumber(L, 6);
|
|
||||||
entityPhysicsSetShape(entityId, compId, shape);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,13 +9,3 @@
|
|||||||
#include "script/scriptcontext.h"
|
#include "script/scriptcontext.h"
|
||||||
|
|
||||||
void moduleEntityPhysics(scriptcontext_t *ctx);
|
void moduleEntityPhysics(scriptcontext_t *ctx);
|
||||||
|
|
||||||
int moduleEntityPhysicsAdd(lua_State *L);
|
|
||||||
int moduleEntityPhysicsSetVelocity(lua_State *L);
|
|
||||||
int moduleEntityPhysicsGetVelocity(lua_State *L);
|
|
||||||
int moduleEntityPhysicsApplyImpulse(lua_State *L);
|
|
||||||
int moduleEntityPhysicsIsOnGround(lua_State *L);
|
|
||||||
int moduleEntityPhysicsSetShapeCube(lua_State *L);
|
|
||||||
int moduleEntityPhysicsSetShapeSphere(lua_State *L);
|
|
||||||
int moduleEntityPhysicsSetShapeCapsule(lua_State *L);
|
|
||||||
int moduleEntityPhysicsSetShapePlane(lua_State *L);
|
|
||||||
|
|||||||
@@ -39,7 +39,26 @@ int moduleEventSubscribe(lua_State *L) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void moduleEvent(scriptcontext_t *context) {
|
int moduleEventUnsubscribe(lua_State *L) {
|
||||||
// Reg functions
|
assertNotNull(L, "Lua state cannot be NULL");
|
||||||
lua_register(context->luaState, "eventSubscribe", moduleEventSubscribe);
|
|
||||||
|
if(!lua_islightuserdata(L, 1)) {
|
||||||
|
luaL_error(L, "eventUnsubscribe: Expected event pointer as first argument");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!lua_isnumber(L, 2)) {
|
||||||
|
luaL_error(L, "eventUnsubscribe: Expected subscription ID as second argument");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
event_t *event = (event_t *)lua_touserdata(L, 1);
|
||||||
|
assertNotNull(event, "Event cannot be NULL");
|
||||||
|
eventsub_t id = (eventsub_t)lua_tonumber(L, 2);
|
||||||
|
eventUnsubscribe(event, id);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void moduleEvent(scriptcontext_t *context) {
|
||||||
|
lua_register(context->luaState, "eventSubscribe", moduleEventSubscribe);
|
||||||
|
lua_register(context->luaState, "eventUnsubscribe", moduleEventUnsubscribe);
|
||||||
}
|
}
|
||||||
@@ -19,3 +19,8 @@ void moduleEvent(scriptcontext_t *context);
|
|||||||
* Script binding for subscribing to an event.
|
* Script binding for subscribing to an event.
|
||||||
*/
|
*/
|
||||||
int moduleEventSubscribe(lua_State *L);
|
int moduleEventSubscribe(lua_State *L);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script binding for unsubscribing from an event.
|
||||||
|
*/
|
||||||
|
int moduleEventUnsubscribe(lua_State *L);
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# Copyright (c) 2026 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||||
|
PUBLIC
|
||||||
|
modulevec2.c
|
||||||
|
modulevec3.c
|
||||||
|
modulevec4.c
|
||||||
|
modulemat4.c
|
||||||
|
modulemath.c
|
||||||
|
)
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "modulemat4.h"
|
||||||
|
#include "modulevec3.h"
|
||||||
|
#include "modulevec4.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
|
||||||
|
void luaMat4Push(lua_State *L, mat4 m) {
|
||||||
|
mat4 *u = (mat4 *)lua_newuserdata(L, sizeof(mat4));
|
||||||
|
glm_mat4_copy(m, *u);
|
||||||
|
luaL_getmetatable(L, "mat4_mt");
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void luaMat4Check(lua_State *L, int idx, mat4 out) {
|
||||||
|
mat4 *m = (mat4 *)luaL_checkudata(L, idx, "mat4_mt");
|
||||||
|
glm_mat4_copy(*m, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mat4Index(lua_State *L) {
|
||||||
|
lua_getmetatable(L, 1);
|
||||||
|
lua_getfield(L, -1, luaL_checkstring(L, 2));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mat4OpMul(lua_State *L) {
|
||||||
|
mat4 *a = (mat4 *)luaL_checkudata(L, 1, "mat4_mt");
|
||||||
|
mat4 *b = (mat4 *)luaL_checkudata(L, 2, "mat4_mt");
|
||||||
|
mat4 r; glm_mat4_mul(*a, *b, r);
|
||||||
|
luaMat4Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mat4OpToString(lua_State *L) {
|
||||||
|
lua_pushstring(L, "mat4(...)"); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mat4Transpose(lua_State *L) {
|
||||||
|
mat4 *m = (mat4 *)luaL_checkudata(L, 1, "mat4_mt");
|
||||||
|
mat4 r; glm_mat4_transpose_to(*m, r);
|
||||||
|
luaMat4Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mat4Inverse(lua_State *L) {
|
||||||
|
mat4 *m = (mat4 *)luaL_checkudata(L, 1, "mat4_mt");
|
||||||
|
mat4 r; glm_mat4_inv(*m, r);
|
||||||
|
luaMat4Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mat4MulVec3(lua_State *L) {
|
||||||
|
mat4 *m = (mat4 *)luaL_checkudata(L, 1, "mat4_mt");
|
||||||
|
vec3 v; luaVec3Check(L, 2, v);
|
||||||
|
float_t w = lua_gettop(L) >= 3 ? (float_t)luaL_checknumber(L, 3) : 1.0f;
|
||||||
|
vec3 r; glm_mat4_mulv3(*m, v, w, r);
|
||||||
|
luaVec3Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mat4MulVec4(lua_State *L) {
|
||||||
|
mat4 *m = (mat4 *)luaL_checkudata(L, 1, "mat4_mt");
|
||||||
|
vec4 v; luaVec4Check(L, 2, v);
|
||||||
|
vec4 r; glm_mat4_mulv(*m, v, r);
|
||||||
|
luaVec4Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mat4Translate(lua_State *L) {
|
||||||
|
mat4 *m = (mat4 *)luaL_checkudata(L, 1, "mat4_mt");
|
||||||
|
vec3 v; luaVec3Check(L, 2, v);
|
||||||
|
mat4 r; glm_mat4_copy(*m, r);
|
||||||
|
glm_translate(r, v);
|
||||||
|
luaMat4Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mat4Scale(lua_State *L) {
|
||||||
|
mat4 *m = (mat4 *)luaL_checkudata(L, 1, "mat4_mt");
|
||||||
|
vec3 v; luaVec3Check(L, 2, v);
|
||||||
|
mat4 r; glm_mat4_copy(*m, r);
|
||||||
|
glm_scale(r, v);
|
||||||
|
luaMat4Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mat4Identity(lua_State *L) {
|
||||||
|
mat4 r; glm_mat4_identity(r);
|
||||||
|
luaMat4Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mat4Determinant(lua_State *L) {
|
||||||
|
mat4 *m = (mat4 *)luaL_checkudata(L, 1, "mat4_mt");
|
||||||
|
lua_pushnumber(L, (lua_Number)glm_mat4_det(*m)); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mat4Create(lua_State *L) {
|
||||||
|
mat4 m; glm_mat4_identity(m);
|
||||||
|
luaMat4Push(L, m); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void moduleMathMat4(lua_State *L) {
|
||||||
|
if(!luaL_newmetatable(L, "mat4_mt")) { lua_pop(L, 1); return; }
|
||||||
|
|
||||||
|
lua_pushcfunction(L, mat4Index); lua_setfield(L, -2, "__index");
|
||||||
|
lua_pushcfunction(L, mat4OpMul); lua_setfield(L, -2, "__mul");
|
||||||
|
lua_pushcfunction(L, mat4OpToString); lua_setfield(L, -2, "__tostring");
|
||||||
|
lua_pushcfunction(L, mat4Transpose); lua_setfield(L, -2, "transpose");
|
||||||
|
lua_pushcfunction(L, mat4Inverse); lua_setfield(L, -2, "inverse");
|
||||||
|
lua_pushcfunction(L, mat4MulVec3); lua_setfield(L, -2, "mulVec3");
|
||||||
|
lua_pushcfunction(L, mat4MulVec4); lua_setfield(L, -2, "mulVec4");
|
||||||
|
lua_pushcfunction(L, mat4Translate); lua_setfield(L, -2, "translate");
|
||||||
|
lua_pushcfunction(L, mat4Scale); lua_setfield(L, -2, "scale");
|
||||||
|
lua_pushcfunction(L, mat4Identity); lua_setfield(L, -2, "identity");
|
||||||
|
lua_pushcfunction(L, mat4Determinant); lua_setfield(L, -2, "determinant");
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
lua_register(L, "mat4", mat4Create);
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "script/scriptcontext.h"
|
||||||
|
|
||||||
|
void luaMat4Push(lua_State *L, mat4 m);
|
||||||
|
void luaMat4Check(lua_State *L, int idx, mat4 out);
|
||||||
|
void moduleMathMat4(lua_State *L);
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "modulemath.h"
|
||||||
|
#include "modulevec2.h"
|
||||||
|
#include "modulevec3.h"
|
||||||
|
#include "modulevec4.h"
|
||||||
|
#include "modulemat4.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
|
||||||
|
void moduleMath(scriptcontext_t *ctx) {
|
||||||
|
assertNotNull(ctx, "Script context cannot be NULL");
|
||||||
|
lua_State *L = ctx->luaState;
|
||||||
|
moduleMathVec2(L);
|
||||||
|
moduleMathVec3(L);
|
||||||
|
moduleMathVec4(L);
|
||||||
|
moduleMathMat4(L);
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "script/scriptcontext.h"
|
||||||
|
|
||||||
|
void moduleMath(scriptcontext_t *ctx);
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "modulevec2.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
|
||||||
|
void luaVec2Push(lua_State *L, vec2 v) {
|
||||||
|
vec2 *u = (vec2 *)lua_newuserdata(L, sizeof(vec2));
|
||||||
|
glm_vec2_copy(v, *u);
|
||||||
|
luaL_getmetatable(L, "vec2_mt");
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void luaVec2Check(lua_State *L, int idx, vec2 out) {
|
||||||
|
vec2 *v = (vec2 *)luaL_checkudata(L, idx, "vec2_mt");
|
||||||
|
glm_vec2_copy(*v, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec2Index(lua_State *L) {
|
||||||
|
vec2 *v = (vec2 *)luaL_checkudata(L, 1, "vec2_mt");
|
||||||
|
const char *key = luaL_checkstring(L, 2);
|
||||||
|
if(strcmp(key, "x") == 0) { lua_pushnumber(L, (lua_Number)(*v)[0]); return 1; }
|
||||||
|
if(strcmp(key, "y") == 0) { lua_pushnumber(L, (lua_Number)(*v)[1]); return 1; }
|
||||||
|
lua_getmetatable(L, 1);
|
||||||
|
lua_getfield(L, -1, key);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec2Newindex(lua_State *L) {
|
||||||
|
vec2 *v = (vec2 *)luaL_checkudata(L, 1, "vec2_mt");
|
||||||
|
const char *key = luaL_checkstring(L, 2);
|
||||||
|
if(strcmp(key, "x") == 0) { (*v)[0] = (float_t)luaL_checknumber(L, 3); return 0; }
|
||||||
|
if(strcmp(key, "y") == 0) { (*v)[1] = (float_t)luaL_checknumber(L, 3); return 0; }
|
||||||
|
luaL_error(L, "vec2: unknown property '%s'", key);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec2OpAdd(lua_State *L) {
|
||||||
|
vec2 *a = (vec2 *)luaL_checkudata(L, 1, "vec2_mt");
|
||||||
|
vec2 *b = (vec2 *)luaL_checkudata(L, 2, "vec2_mt");
|
||||||
|
vec2 r; glm_vec2_add(*a, *b, r);
|
||||||
|
luaVec2Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec2OpSub(lua_State *L) {
|
||||||
|
vec2 *a = (vec2 *)luaL_checkudata(L, 1, "vec2_mt");
|
||||||
|
vec2 *b = (vec2 *)luaL_checkudata(L, 2, "vec2_mt");
|
||||||
|
vec2 r; glm_vec2_sub(*a, *b, r);
|
||||||
|
luaVec2Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec2OpMul(lua_State *L) {
|
||||||
|
vec2 r;
|
||||||
|
if(lua_isnumber(L, 1)) {
|
||||||
|
float_t s = (float_t)lua_tonumber(L, 1);
|
||||||
|
vec2 *v = (vec2 *)luaL_checkudata(L, 2, "vec2_mt");
|
||||||
|
glm_vec2_scale(*v, s, r);
|
||||||
|
} else {
|
||||||
|
vec2 *v = (vec2 *)luaL_checkudata(L, 1, "vec2_mt");
|
||||||
|
float_t s = (float_t)luaL_checknumber(L, 2);
|
||||||
|
glm_vec2_scale(*v, s, r);
|
||||||
|
}
|
||||||
|
luaVec2Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec2OpDiv(lua_State *L) {
|
||||||
|
vec2 *v = (vec2 *)luaL_checkudata(L, 1, "vec2_mt");
|
||||||
|
float_t s = (float_t)luaL_checknumber(L, 2);
|
||||||
|
vec2 r; glm_vec2_divs(*v, s, r);
|
||||||
|
luaVec2Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec2OpUnm(lua_State *L) {
|
||||||
|
vec2 *v = (vec2 *)luaL_checkudata(L, 1, "vec2_mt");
|
||||||
|
vec2 r; glm_vec2_negate_to(*v, r);
|
||||||
|
luaVec2Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec2OpEq(lua_State *L) {
|
||||||
|
vec2 *a = (vec2 *)luaL_checkudata(L, 1, "vec2_mt");
|
||||||
|
vec2 *b = (vec2 *)luaL_checkudata(L, 2, "vec2_mt");
|
||||||
|
lua_pushboolean(L, (*a)[0] == (*b)[0] && (*a)[1] == (*b)[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec2OpToString(lua_State *L) {
|
||||||
|
vec2 *v = (vec2 *)luaL_checkudata(L, 1, "vec2_mt");
|
||||||
|
char buf[64];
|
||||||
|
snprintf(buf, sizeof(buf), "vec2(%.3f, %.3f)", (*v)[0], (*v)[1]);
|
||||||
|
lua_pushstring(L, buf); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec2Dot(lua_State *L) {
|
||||||
|
vec2 *a = (vec2 *)luaL_checkudata(L, 1, "vec2_mt");
|
||||||
|
vec2 *b = (vec2 *)luaL_checkudata(L, 2, "vec2_mt");
|
||||||
|
lua_pushnumber(L, (lua_Number)glm_vec2_dot(*a, *b)); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec2Length(lua_State *L) {
|
||||||
|
vec2 *v = (vec2 *)luaL_checkudata(L, 1, "vec2_mt");
|
||||||
|
lua_pushnumber(L, (lua_Number)glm_vec2_norm(*v)); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec2LengthSq(lua_State *L) {
|
||||||
|
vec2 *v = (vec2 *)luaL_checkudata(L, 1, "vec2_mt");
|
||||||
|
lua_pushnumber(L, (lua_Number)glm_vec2_norm2(*v)); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec2Normalize(lua_State *L) {
|
||||||
|
vec2 *v = (vec2 *)luaL_checkudata(L, 1, "vec2_mt");
|
||||||
|
vec2 r; glm_vec2_normalize_to(*v, r);
|
||||||
|
luaVec2Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec2Lerp(lua_State *L) {
|
||||||
|
vec2 *a = (vec2 *)luaL_checkudata(L, 1, "vec2_mt");
|
||||||
|
vec2 *b = (vec2 *)luaL_checkudata(L, 2, "vec2_mt");
|
||||||
|
float_t t = (float_t)luaL_checknumber(L, 3);
|
||||||
|
vec2 r; glm_vec2_lerp(*a, *b, t, r);
|
||||||
|
luaVec2Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec2Distance(lua_State *L) {
|
||||||
|
vec2 *a = (vec2 *)luaL_checkudata(L, 1, "vec2_mt");
|
||||||
|
vec2 *b = (vec2 *)luaL_checkudata(L, 2, "vec2_mt");
|
||||||
|
lua_pushnumber(L, (lua_Number)glm_vec2_distance(*a, *b)); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec2Negate(lua_State *L) {
|
||||||
|
vec2 *v = (vec2 *)luaL_checkudata(L, 1, "vec2_mt");
|
||||||
|
vec2 r; glm_vec2_negate_to(*v, r);
|
||||||
|
luaVec2Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec2Create(lua_State *L) {
|
||||||
|
vec2 v = {0, 0};
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
if(top >= 1) v[0] = (float_t)luaL_checknumber(L, 1);
|
||||||
|
if(top >= 2) v[1] = (float_t)luaL_checknumber(L, 2);
|
||||||
|
luaVec2Push(L, v); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void moduleMathVec2(lua_State *L) {
|
||||||
|
if(!luaL_newmetatable(L, "vec2_mt")) { lua_pop(L, 1); return; }
|
||||||
|
|
||||||
|
lua_pushcfunction(L, vec2Index); lua_setfield(L, -2, "__index");
|
||||||
|
lua_pushcfunction(L, vec2Newindex); lua_setfield(L, -2, "__newindex");
|
||||||
|
lua_pushcfunction(L, vec2OpAdd); lua_setfield(L, -2, "__add");
|
||||||
|
lua_pushcfunction(L, vec2OpSub); lua_setfield(L, -2, "__sub");
|
||||||
|
lua_pushcfunction(L, vec2OpMul); lua_setfield(L, -2, "__mul");
|
||||||
|
lua_pushcfunction(L, vec2OpDiv); lua_setfield(L, -2, "__div");
|
||||||
|
lua_pushcfunction(L, vec2OpUnm); lua_setfield(L, -2, "__unm");
|
||||||
|
lua_pushcfunction(L, vec2OpEq); lua_setfield(L, -2, "__eq");
|
||||||
|
lua_pushcfunction(L, vec2OpToString); lua_setfield(L, -2, "__tostring");
|
||||||
|
lua_pushcfunction(L, vec2Dot); lua_setfield(L, -2, "dot");
|
||||||
|
lua_pushcfunction(L, vec2Length); lua_setfield(L, -2, "length");
|
||||||
|
lua_pushcfunction(L, vec2LengthSq); lua_setfield(L, -2, "lengthSq");
|
||||||
|
lua_pushcfunction(L, vec2Normalize); lua_setfield(L, -2, "normalize");
|
||||||
|
lua_pushcfunction(L, vec2Lerp); lua_setfield(L, -2, "lerp");
|
||||||
|
lua_pushcfunction(L, vec2Distance); lua_setfield(L, -2, "distance");
|
||||||
|
lua_pushcfunction(L, vec2Negate); lua_setfield(L, -2, "negate");
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
lua_register(L, "vec2", vec2Create);
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "script/scriptcontext.h"
|
||||||
|
|
||||||
|
void luaVec2Push(lua_State *L, vec2 v);
|
||||||
|
void luaVec2Check(lua_State *L, int idx, vec2 out);
|
||||||
|
void moduleMathVec2(lua_State *L);
|
||||||
@@ -0,0 +1,180 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "modulevec3.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
|
||||||
|
void luaVec3Push(lua_State *L, vec3 v) {
|
||||||
|
vec3 *u = (vec3 *)lua_newuserdata(L, sizeof(vec3));
|
||||||
|
glm_vec3_copy(v, *u);
|
||||||
|
luaL_getmetatable(L, "vec3_mt");
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void luaVec3Check(lua_State *L, int idx, vec3 out) {
|
||||||
|
vec3 *v = (vec3 *)luaL_checkudata(L, idx, "vec3_mt");
|
||||||
|
glm_vec3_copy(*v, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec3Index(lua_State *L) {
|
||||||
|
vec3 *v = (vec3 *)luaL_checkudata(L, 1, "vec3_mt");
|
||||||
|
const char *key = luaL_checkstring(L, 2);
|
||||||
|
if(strcmp(key, "x") == 0) { lua_pushnumber(L, (lua_Number)(*v)[0]); return 1; }
|
||||||
|
if(strcmp(key, "y") == 0) { lua_pushnumber(L, (lua_Number)(*v)[1]); return 1; }
|
||||||
|
if(strcmp(key, "z") == 0) { lua_pushnumber(L, (lua_Number)(*v)[2]); return 1; }
|
||||||
|
lua_getmetatable(L, 1);
|
||||||
|
lua_getfield(L, -1, key);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec3Newindex(lua_State *L) {
|
||||||
|
vec3 *v = (vec3 *)luaL_checkudata(L, 1, "vec3_mt");
|
||||||
|
const char *key = luaL_checkstring(L, 2);
|
||||||
|
if(strcmp(key, "x") == 0) { (*v)[0] = (float_t)luaL_checknumber(L, 3); return 0; }
|
||||||
|
if(strcmp(key, "y") == 0) { (*v)[1] = (float_t)luaL_checknumber(L, 3); return 0; }
|
||||||
|
if(strcmp(key, "z") == 0) { (*v)[2] = (float_t)luaL_checknumber(L, 3); return 0; }
|
||||||
|
luaL_error(L, "vec3: unknown property '%s'", key);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec3OpAdd(lua_State *L) {
|
||||||
|
vec3 *a = (vec3 *)luaL_checkudata(L, 1, "vec3_mt");
|
||||||
|
vec3 *b = (vec3 *)luaL_checkudata(L, 2, "vec3_mt");
|
||||||
|
vec3 r; glm_vec3_add(*a, *b, r);
|
||||||
|
luaVec3Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec3OpSub(lua_State *L) {
|
||||||
|
vec3 *a = (vec3 *)luaL_checkudata(L, 1, "vec3_mt");
|
||||||
|
vec3 *b = (vec3 *)luaL_checkudata(L, 2, "vec3_mt");
|
||||||
|
vec3 r; glm_vec3_sub(*a, *b, r);
|
||||||
|
luaVec3Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec3OpMul(lua_State *L) {
|
||||||
|
vec3 r;
|
||||||
|
if(lua_isnumber(L, 1)) {
|
||||||
|
float_t s = (float_t)lua_tonumber(L, 1);
|
||||||
|
vec3 *v = (vec3 *)luaL_checkudata(L, 2, "vec3_mt");
|
||||||
|
glm_vec3_scale(*v, s, r);
|
||||||
|
} else {
|
||||||
|
vec3 *v = (vec3 *)luaL_checkudata(L, 1, "vec3_mt");
|
||||||
|
float_t s = (float_t)luaL_checknumber(L, 2);
|
||||||
|
glm_vec3_scale(*v, s, r);
|
||||||
|
}
|
||||||
|
luaVec3Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec3OpDiv(lua_State *L) {
|
||||||
|
vec3 *v = (vec3 *)luaL_checkudata(L, 1, "vec3_mt");
|
||||||
|
float_t s = (float_t)luaL_checknumber(L, 2);
|
||||||
|
vec3 r; glm_vec3_divs(*v, s, r);
|
||||||
|
luaVec3Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec3OpUnm(lua_State *L) {
|
||||||
|
vec3 *v = (vec3 *)luaL_checkudata(L, 1, "vec3_mt");
|
||||||
|
vec3 r; glm_vec3_negate_to(*v, r);
|
||||||
|
luaVec3Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec3OpEq(lua_State *L) {
|
||||||
|
vec3 *a = (vec3 *)luaL_checkudata(L, 1, "vec3_mt");
|
||||||
|
vec3 *b = (vec3 *)luaL_checkudata(L, 2, "vec3_mt");
|
||||||
|
lua_pushboolean(L, (*a)[0] == (*b)[0] && (*a)[1] == (*b)[1] && (*a)[2] == (*b)[2]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec3OpToString(lua_State *L) {
|
||||||
|
vec3 *v = (vec3 *)luaL_checkudata(L, 1, "vec3_mt");
|
||||||
|
char buf[80];
|
||||||
|
snprintf(buf, sizeof(buf), "vec3(%.3f, %.3f, %.3f)", (*v)[0], (*v)[1], (*v)[2]);
|
||||||
|
lua_pushstring(L, buf); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec3Dot(lua_State *L) {
|
||||||
|
vec3 *a = (vec3 *)luaL_checkudata(L, 1, "vec3_mt");
|
||||||
|
vec3 *b = (vec3 *)luaL_checkudata(L, 2, "vec3_mt");
|
||||||
|
lua_pushnumber(L, (lua_Number)glm_vec3_dot(*a, *b)); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec3Cross(lua_State *L) {
|
||||||
|
vec3 *a = (vec3 *)luaL_checkudata(L, 1, "vec3_mt");
|
||||||
|
vec3 *b = (vec3 *)luaL_checkudata(L, 2, "vec3_mt");
|
||||||
|
vec3 r; glm_vec3_cross(*a, *b, r);
|
||||||
|
luaVec3Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec3Length(lua_State *L) {
|
||||||
|
vec3 *v = (vec3 *)luaL_checkudata(L, 1, "vec3_mt");
|
||||||
|
lua_pushnumber(L, (lua_Number)glm_vec3_norm(*v)); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec3LengthSq(lua_State *L) {
|
||||||
|
vec3 *v = (vec3 *)luaL_checkudata(L, 1, "vec3_mt");
|
||||||
|
lua_pushnumber(L, (lua_Number)glm_vec3_norm2(*v)); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec3Normalize(lua_State *L) {
|
||||||
|
vec3 *v = (vec3 *)luaL_checkudata(L, 1, "vec3_mt");
|
||||||
|
vec3 r; glm_vec3_normalize_to(*v, r);
|
||||||
|
luaVec3Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec3Lerp(lua_State *L) {
|
||||||
|
vec3 *a = (vec3 *)luaL_checkudata(L, 1, "vec3_mt");
|
||||||
|
vec3 *b = (vec3 *)luaL_checkudata(L, 2, "vec3_mt");
|
||||||
|
float_t t = (float_t)luaL_checknumber(L, 3);
|
||||||
|
vec3 r; glm_vec3_lerp(*a, *b, t, r);
|
||||||
|
luaVec3Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec3Distance(lua_State *L) {
|
||||||
|
vec3 *a = (vec3 *)luaL_checkudata(L, 1, "vec3_mt");
|
||||||
|
vec3 *b = (vec3 *)luaL_checkudata(L, 2, "vec3_mt");
|
||||||
|
lua_pushnumber(L, (lua_Number)glm_vec3_distance(*a, *b)); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec3Negate(lua_State *L) {
|
||||||
|
vec3 *v = (vec3 *)luaL_checkudata(L, 1, "vec3_mt");
|
||||||
|
vec3 r; glm_vec3_negate_to(*v, r);
|
||||||
|
luaVec3Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec3Create(lua_State *L) {
|
||||||
|
vec3 v = {0, 0, 0};
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
if(top >= 1) v[0] = (float_t)luaL_checknumber(L, 1);
|
||||||
|
if(top >= 2) v[1] = (float_t)luaL_checknumber(L, 2);
|
||||||
|
if(top >= 3) v[2] = (float_t)luaL_checknumber(L, 3);
|
||||||
|
luaVec3Push(L, v); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void moduleMathVec3(lua_State *L) {
|
||||||
|
if(!luaL_newmetatable(L, "vec3_mt")) { lua_pop(L, 1); return; }
|
||||||
|
|
||||||
|
lua_pushcfunction(L, vec3Index); lua_setfield(L, -2, "__index");
|
||||||
|
lua_pushcfunction(L, vec3Newindex); lua_setfield(L, -2, "__newindex");
|
||||||
|
lua_pushcfunction(L, vec3OpAdd); lua_setfield(L, -2, "__add");
|
||||||
|
lua_pushcfunction(L, vec3OpSub); lua_setfield(L, -2, "__sub");
|
||||||
|
lua_pushcfunction(L, vec3OpMul); lua_setfield(L, -2, "__mul");
|
||||||
|
lua_pushcfunction(L, vec3OpDiv); lua_setfield(L, -2, "__div");
|
||||||
|
lua_pushcfunction(L, vec3OpUnm); lua_setfield(L, -2, "__unm");
|
||||||
|
lua_pushcfunction(L, vec3OpEq); lua_setfield(L, -2, "__eq");
|
||||||
|
lua_pushcfunction(L, vec3OpToString); lua_setfield(L, -2, "__tostring");
|
||||||
|
lua_pushcfunction(L, vec3Dot); lua_setfield(L, -2, "dot");
|
||||||
|
lua_pushcfunction(L, vec3Cross); lua_setfield(L, -2, "cross");
|
||||||
|
lua_pushcfunction(L, vec3Length); lua_setfield(L, -2, "length");
|
||||||
|
lua_pushcfunction(L, vec3LengthSq); lua_setfield(L, -2, "lengthSq");
|
||||||
|
lua_pushcfunction(L, vec3Normalize); lua_setfield(L, -2, "normalize");
|
||||||
|
lua_pushcfunction(L, vec3Lerp); lua_setfield(L, -2, "lerp");
|
||||||
|
lua_pushcfunction(L, vec3Distance); lua_setfield(L, -2, "distance");
|
||||||
|
lua_pushcfunction(L, vec3Negate); lua_setfield(L, -2, "negate");
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
lua_register(L, "vec3", vec3Create);
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "script/scriptcontext.h"
|
||||||
|
|
||||||
|
void luaVec3Push(lua_State *L, vec3 v);
|
||||||
|
void luaVec3Check(lua_State *L, int idx, vec3 out);
|
||||||
|
void moduleMathVec3(lua_State *L);
|
||||||
@@ -0,0 +1,168 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "modulevec4.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
|
||||||
|
void luaVec4Push(lua_State *L, vec4 v) {
|
||||||
|
vec4 *u = (vec4 *)lua_newuserdata(L, sizeof(vec4));
|
||||||
|
glm_vec4_copy(v, *u);
|
||||||
|
luaL_getmetatable(L, "vec4_mt");
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void luaVec4Check(lua_State *L, int idx, vec4 out) {
|
||||||
|
vec4 *v = (vec4 *)luaL_checkudata(L, idx, "vec4_mt");
|
||||||
|
glm_vec4_copy(*v, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec4Index(lua_State *L) {
|
||||||
|
vec4 *v = (vec4 *)luaL_checkudata(L, 1, "vec4_mt");
|
||||||
|
const char *key = luaL_checkstring(L, 2);
|
||||||
|
if(strcmp(key, "x") == 0 || strcmp(key, "u0") == 0) { lua_pushnumber(L, (lua_Number)(*v)[0]); return 1; }
|
||||||
|
if(strcmp(key, "y") == 0 || strcmp(key, "v0") == 0) { lua_pushnumber(L, (lua_Number)(*v)[1]); return 1; }
|
||||||
|
if(strcmp(key, "z") == 0 || strcmp(key, "u1") == 0) { lua_pushnumber(L, (lua_Number)(*v)[2]); return 1; }
|
||||||
|
if(strcmp(key, "w") == 0 || strcmp(key, "v1") == 0) { lua_pushnumber(L, (lua_Number)(*v)[3]); return 1; }
|
||||||
|
lua_getmetatable(L, 1);
|
||||||
|
lua_getfield(L, -1, key);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec4Newindex(lua_State *L) {
|
||||||
|
vec4 *v = (vec4 *)luaL_checkudata(L, 1, "vec4_mt");
|
||||||
|
const char *key = luaL_checkstring(L, 2);
|
||||||
|
if(strcmp(key, "x") == 0 || strcmp(key, "u0") == 0) { (*v)[0] = (float_t)luaL_checknumber(L, 3); return 0; }
|
||||||
|
if(strcmp(key, "y") == 0 || strcmp(key, "v0") == 0) { (*v)[1] = (float_t)luaL_checknumber(L, 3); return 0; }
|
||||||
|
if(strcmp(key, "z") == 0 || strcmp(key, "u1") == 0) { (*v)[2] = (float_t)luaL_checknumber(L, 3); return 0; }
|
||||||
|
if(strcmp(key, "w") == 0 || strcmp(key, "v1") == 0) { (*v)[3] = (float_t)luaL_checknumber(L, 3); return 0; }
|
||||||
|
luaL_error(L, "vec4: unknown property '%s'", key);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec4OpAdd(lua_State *L) {
|
||||||
|
vec4 *a = (vec4 *)luaL_checkudata(L, 1, "vec4_mt");
|
||||||
|
vec4 *b = (vec4 *)luaL_checkudata(L, 2, "vec4_mt");
|
||||||
|
vec4 r; glm_vec4_add(*a, *b, r);
|
||||||
|
luaVec4Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec4OpSub(lua_State *L) {
|
||||||
|
vec4 *a = (vec4 *)luaL_checkudata(L, 1, "vec4_mt");
|
||||||
|
vec4 *b = (vec4 *)luaL_checkudata(L, 2, "vec4_mt");
|
||||||
|
vec4 r; glm_vec4_sub(*a, *b, r);
|
||||||
|
luaVec4Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec4OpMul(lua_State *L) {
|
||||||
|
vec4 r;
|
||||||
|
if(lua_isnumber(L, 1)) {
|
||||||
|
float_t s = (float_t)lua_tonumber(L, 1);
|
||||||
|
vec4 *v = (vec4 *)luaL_checkudata(L, 2, "vec4_mt");
|
||||||
|
glm_vec4_scale(*v, s, r);
|
||||||
|
} else {
|
||||||
|
vec4 *v = (vec4 *)luaL_checkudata(L, 1, "vec4_mt");
|
||||||
|
float_t s = (float_t)luaL_checknumber(L, 2);
|
||||||
|
glm_vec4_scale(*v, s, r);
|
||||||
|
}
|
||||||
|
luaVec4Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec4OpDiv(lua_State *L) {
|
||||||
|
vec4 *v = (vec4 *)luaL_checkudata(L, 1, "vec4_mt");
|
||||||
|
float_t s = (float_t)luaL_checknumber(L, 2);
|
||||||
|
vec4 r; glm_vec4_divs(*v, s, r);
|
||||||
|
luaVec4Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec4OpUnm(lua_State *L) {
|
||||||
|
vec4 *v = (vec4 *)luaL_checkudata(L, 1, "vec4_mt");
|
||||||
|
vec4 r; glm_vec4_negate_to(*v, r);
|
||||||
|
luaVec4Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec4OpEq(lua_State *L) {
|
||||||
|
vec4 *a = (vec4 *)luaL_checkudata(L, 1, "vec4_mt");
|
||||||
|
vec4 *b = (vec4 *)luaL_checkudata(L, 2, "vec4_mt");
|
||||||
|
lua_pushboolean(L, (*a)[0] == (*b)[0] && (*a)[1] == (*b)[1] && (*a)[2] == (*b)[2] && (*a)[3] == (*b)[3]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec4OpToString(lua_State *L) {
|
||||||
|
vec4 *v = (vec4 *)luaL_checkudata(L, 1, "vec4_mt");
|
||||||
|
char buf[96];
|
||||||
|
snprintf(buf, sizeof(buf), "vec4(%.3f, %.3f, %.3f, %.3f)", (*v)[0], (*v)[1], (*v)[2], (*v)[3]);
|
||||||
|
lua_pushstring(L, buf); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec4Dot(lua_State *L) {
|
||||||
|
vec4 *a = (vec4 *)luaL_checkudata(L, 1, "vec4_mt");
|
||||||
|
vec4 *b = (vec4 *)luaL_checkudata(L, 2, "vec4_mt");
|
||||||
|
lua_pushnumber(L, (lua_Number)glm_vec4_dot(*a, *b)); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec4Length(lua_State *L) {
|
||||||
|
vec4 *v = (vec4 *)luaL_checkudata(L, 1, "vec4_mt");
|
||||||
|
lua_pushnumber(L, (lua_Number)glm_vec4_norm(*v)); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec4LengthSq(lua_State *L) {
|
||||||
|
vec4 *v = (vec4 *)luaL_checkudata(L, 1, "vec4_mt");
|
||||||
|
lua_pushnumber(L, (lua_Number)glm_vec4_norm2(*v)); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec4Normalize(lua_State *L) {
|
||||||
|
vec4 *v = (vec4 *)luaL_checkudata(L, 1, "vec4_mt");
|
||||||
|
vec4 r; glm_vec4_normalize_to(*v, r);
|
||||||
|
luaVec4Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec4Lerp(lua_State *L) {
|
||||||
|
vec4 *a = (vec4 *)luaL_checkudata(L, 1, "vec4_mt");
|
||||||
|
vec4 *b = (vec4 *)luaL_checkudata(L, 2, "vec4_mt");
|
||||||
|
float_t t = (float_t)luaL_checknumber(L, 3);
|
||||||
|
vec4 r; glm_vec4_lerp(*a, *b, t, r);
|
||||||
|
luaVec4Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec4Negate(lua_State *L) {
|
||||||
|
vec4 *v = (vec4 *)luaL_checkudata(L, 1, "vec4_mt");
|
||||||
|
vec4 r; glm_vec4_negate_to(*v, r);
|
||||||
|
luaVec4Push(L, r); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vec4Create(lua_State *L) {
|
||||||
|
vec4 v = {0, 0, 0, 0};
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
if(top >= 1) v[0] = (float_t)luaL_checknumber(L, 1);
|
||||||
|
if(top >= 2) v[1] = (float_t)luaL_checknumber(L, 2);
|
||||||
|
if(top >= 3) v[2] = (float_t)luaL_checknumber(L, 3);
|
||||||
|
if(top >= 4) v[3] = (float_t)luaL_checknumber(L, 4);
|
||||||
|
luaVec4Push(L, v); return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void moduleMathVec4(lua_State *L) {
|
||||||
|
if(!luaL_newmetatable(L, "vec4_mt")) { lua_pop(L, 1); return; }
|
||||||
|
|
||||||
|
lua_pushcfunction(L, vec4Index); lua_setfield(L, -2, "__index");
|
||||||
|
lua_pushcfunction(L, vec4Newindex); lua_setfield(L, -2, "__newindex");
|
||||||
|
lua_pushcfunction(L, vec4OpAdd); lua_setfield(L, -2, "__add");
|
||||||
|
lua_pushcfunction(L, vec4OpSub); lua_setfield(L, -2, "__sub");
|
||||||
|
lua_pushcfunction(L, vec4OpMul); lua_setfield(L, -2, "__mul");
|
||||||
|
lua_pushcfunction(L, vec4OpDiv); lua_setfield(L, -2, "__div");
|
||||||
|
lua_pushcfunction(L, vec4OpUnm); lua_setfield(L, -2, "__unm");
|
||||||
|
lua_pushcfunction(L, vec4OpEq); lua_setfield(L, -2, "__eq");
|
||||||
|
lua_pushcfunction(L, vec4OpToString); lua_setfield(L, -2, "__tostring");
|
||||||
|
lua_pushcfunction(L, vec4Dot); lua_setfield(L, -2, "dot");
|
||||||
|
lua_pushcfunction(L, vec4Length); lua_setfield(L, -2, "length");
|
||||||
|
lua_pushcfunction(L, vec4LengthSq); lua_setfield(L, -2, "lengthSq");
|
||||||
|
lua_pushcfunction(L, vec4Normalize); lua_setfield(L, -2, "normalize");
|
||||||
|
lua_pushcfunction(L, vec4Lerp); lua_setfield(L, -2, "lerp");
|
||||||
|
lua_pushcfunction(L, vec4Negate); lua_setfield(L, -2, "negate");
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
lua_register(L, "vec4", vec4Create);
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "script/scriptcontext.h"
|
||||||
|
|
||||||
|
void luaVec4Push(lua_State *L, vec4 v);
|
||||||
|
void luaVec4Check(lua_State *L, int idx, vec4 out);
|
||||||
|
void moduleMathVec4(lua_State *L);
|
||||||
@@ -13,6 +13,9 @@ void moduleScene(scriptcontext_t *ctx) {
|
|||||||
assertNotNull(ctx, "Script context cannot be NULL");
|
assertNotNull(ctx, "Script context cannot be NULL");
|
||||||
|
|
||||||
lua_register(ctx->luaState, "sceneSet", moduleSceneSet);
|
lua_register(ctx->luaState, "sceneSet", moduleSceneSet);
|
||||||
|
|
||||||
|
lua_pushlightuserdata(ctx->luaState, &SCENE.eventUpdate);
|
||||||
|
lua_setglobal(ctx->luaState, "SCENE_EVENT_UPDATE");
|
||||||
}
|
}
|
||||||
|
|
||||||
int moduleSceneSet(lua_State *L) {
|
int moduleSceneSet(lua_State *L) {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "script/module/display/modulecolor.h"
|
#include "script/module/display/modulecolor.h"
|
||||||
#include "script/module/display/modulespritebatch.h"
|
#include "script/module/display/modulespritebatch.h"
|
||||||
#include "script/module/display/moduleglm.h"
|
#include "script/module/display/moduleglm.h"
|
||||||
|
#include "script/module/math/modulemath.h"
|
||||||
#include "script/module/display/moduleshader.h"
|
#include "script/module/display/moduleshader.h"
|
||||||
#include "script/module/ui/moduleui.h"
|
#include "script/module/ui/moduleui.h"
|
||||||
#include "script/module/display/moduletext.h"
|
#include "script/module/display/moduletext.h"
|
||||||
@@ -52,6 +53,7 @@ const scriptmodule_t SCRIPT_MODULE_LIST[] = {
|
|||||||
REG("event", moduleEvent)
|
REG("event", moduleEvent)
|
||||||
REG("spritebatch", moduleSpriteBatch)
|
REG("spritebatch", moduleSpriteBatch)
|
||||||
REG("glm", moduleGLM)
|
REG("glm", moduleGLM)
|
||||||
|
REG("math", moduleMath)
|
||||||
REG("ui", moduleUi)
|
REG("ui", moduleUi)
|
||||||
REG("text", moduleText)
|
REG("text", moduleText)
|
||||||
REG("screen", moduleScreen)
|
REG("screen", moduleScreen)
|
||||||
|
|||||||
Reference in New Issue
Block a user