200 lines
6.4 KiB
C
200 lines
6.4 KiB
C
/**
|
|
* Copyright (c) 2026 Dominic Masters
|
|
*
|
|
* This software is released under the MIT License.
|
|
* https://opensource.org/licenses/MIT
|
|
*/
|
|
|
|
#pragma once
|
|
#include "script/module/modulebase.h"
|
|
#include "script/module/math/modulevec3ref.h"
|
|
#include "script/scriptproto.h"
|
|
#include "entity/entity.h"
|
|
#include "entity/component/physics/entityphysics.h"
|
|
#include "moduleentityposition.h"
|
|
|
|
static scriptproto_t MODULE_ENTITY_PHYSICS_PROTO;
|
|
|
|
static entityphysics_t * moduleEntityPhysicsGet(
|
|
const jerry_call_info_t *callInfo
|
|
) {
|
|
componenthandle_t *h = scriptProtoGetValue(
|
|
&MODULE_ENTITY_PHYSICS_PROTO, callInfo->this_value
|
|
);
|
|
if(!h) return NULL;
|
|
return entityPhysicsGet(h->eid, h->cid);
|
|
}
|
|
|
|
moduleBaseFunction(moduleEntityPhysicsGetVelocity) {
|
|
entityphysics_t *phys = moduleEntityPhysicsGet(callInfo);
|
|
if(!phys) return jerry_undefined();
|
|
return moduleVec3RefPush(phys->velocity, NULL, NULL);
|
|
}
|
|
|
|
moduleBaseFunction(moduleEntityPhysicsSetVelocity) {
|
|
if(argc < 1) return moduleBaseThrow("Expected at least 1 argument");
|
|
entityphysics_t *phys = moduleEntityPhysicsGet(callInfo);
|
|
if(!phys) return jerry_undefined();
|
|
vec3 v;
|
|
if(!moduleVec3AnyCheck(args[0], v)) {
|
|
return moduleBaseThrow("expected Vec3");
|
|
}
|
|
glm_vec3_copy(v, phys->velocity);
|
|
return jerry_undefined();
|
|
}
|
|
|
|
moduleBaseFunction(moduleEntityPhysicsGetOnGround) {
|
|
entityphysics_t *phys = moduleEntityPhysicsGet(callInfo);
|
|
if(!phys) return jerry_undefined();
|
|
return jerry_boolean(phys->onGround);
|
|
}
|
|
|
|
moduleBaseFunction(moduleEntityPhysicsGetBodyType) {
|
|
entityphysics_t *phys = moduleEntityPhysicsGet(callInfo);
|
|
if(!phys) return jerry_undefined();
|
|
return jerry_number((double)phys->type);
|
|
}
|
|
|
|
moduleBaseFunction(moduleEntityPhysicsSetBodyType) {
|
|
if(argc < 1) {
|
|
return moduleBaseThrow("Expected at least 1 argument");
|
|
}
|
|
moduleBaseRequireNumber(0);
|
|
|
|
entityphysics_t *phys = moduleEntityPhysicsGet(callInfo);
|
|
if(!phys) return jerry_undefined();
|
|
phys->type = (physicsbodytype_t)(int32_t)jerry_value_as_number(args[0]);
|
|
return jerry_undefined();
|
|
}
|
|
|
|
moduleBaseFunction(moduleEntityPhysicsApplyImpulse) {
|
|
if(argc < 1) return moduleBaseThrow("Expected at least 1 argument");
|
|
entityphysics_t *phys = moduleEntityPhysicsGet(callInfo);
|
|
if(!phys) return jerry_undefined();
|
|
if(phys->type == PHYSICS_BODY_STATIC) return jerry_undefined();
|
|
vec3 impulse;
|
|
if(!moduleVec3Check(args[0], impulse)) {
|
|
return moduleBaseThrow("expected Vec3 impulse");
|
|
}
|
|
glm_vec3_add(phys->velocity, impulse, phys->velocity);
|
|
return jerry_undefined();
|
|
}
|
|
|
|
moduleBaseFunction(moduleEntityPhysicsSetShapeCube) {
|
|
if(argc < 1) return moduleBaseThrow("Expected at least 1 argument");
|
|
entityphysics_t *phys = moduleEntityPhysicsGet(callInfo);
|
|
if(!phys) return jerry_undefined();
|
|
vec3 half;
|
|
if(!moduleVec3Check(args[0], half)) {
|
|
return moduleBaseThrow("expected Vec3 halfExtents");
|
|
}
|
|
phys->shape.type = PHYSICS_SHAPE_CUBE;
|
|
glm_vec3_copy(half, phys->shape.data.cube.halfExtents);
|
|
return jerry_undefined();
|
|
}
|
|
|
|
moduleBaseFunction(moduleEntityPhysicsSetShapeSphere) {
|
|
if(argc < 1) {
|
|
return moduleBaseThrow("Expected at least 1 argument");
|
|
}
|
|
moduleBaseRequireNumber(0);
|
|
|
|
entityphysics_t *phys = moduleEntityPhysicsGet(callInfo);
|
|
if(!phys) return jerry_undefined();
|
|
phys->shape.type = PHYSICS_SHAPE_SPHERE;
|
|
phys->shape.data.sphere.radius = (float_t)jerry_value_as_number(args[0]);
|
|
return jerry_undefined();
|
|
}
|
|
|
|
moduleBaseFunction(moduleEntityPhysicsSetShapeCapsule) {
|
|
if(argc < 2) return moduleBaseThrow("Expected at least 2 arguments");
|
|
moduleBaseRequireNumber(0); moduleBaseRequireNumber(1);
|
|
entityphysics_t *phys = moduleEntityPhysicsGet(callInfo);
|
|
if(!phys) return jerry_undefined();
|
|
phys->shape.type = PHYSICS_SHAPE_CAPSULE;
|
|
phys->shape.data.capsule.radius = (float_t)jerry_value_as_number(args[0]);
|
|
phys->shape.data.capsule.halfHeight =
|
|
(float_t)jerry_value_as_number(args[1]);
|
|
return jerry_undefined();
|
|
}
|
|
|
|
moduleBaseFunction(moduleEntityPhysicsSetShapePlane) {
|
|
if(argc < 2) {
|
|
return moduleBaseThrow("Expected at least 2 arguments");
|
|
}
|
|
moduleBaseRequireNumber(1);
|
|
|
|
entityphysics_t *phys = moduleEntityPhysicsGet(callInfo);
|
|
if(!phys) return jerry_undefined();
|
|
vec3 normal;
|
|
if(!moduleVec3Check(args[0], normal)) {
|
|
return moduleBaseThrow("expected Vec3 normal");
|
|
}
|
|
phys->shape.type = PHYSICS_SHAPE_PLANE;
|
|
glm_vec3_copy(normal, phys->shape.data.plane.normal);
|
|
phys->shape.data.plane.distance = (float_t)jerry_value_as_number(args[1]);
|
|
return jerry_undefined();
|
|
}
|
|
|
|
moduleBaseFunction(moduleEntityPhysicsAdd) {
|
|
if(argc < 1) {
|
|
return moduleBaseThrow("Expected at least 1 argument");
|
|
}
|
|
moduleBaseRequireNumber(0);
|
|
|
|
entityid_t id = (entityid_t)jerry_value_as_number(args[0]);
|
|
componentid_t comp = entityAddComponent(id, COMPONENT_TYPE_PHYSICS);
|
|
componenthandle_t h = { .eid = id, .cid = comp };
|
|
return scriptProtoCreateValue(&MODULE_ENTITY_PHYSICS_PROTO, &h);
|
|
}
|
|
|
|
static void moduleEntityPHYSICS(void) {
|
|
scriptProtoInit(
|
|
&MODULE_ENTITY_PHYSICS_PROTO, NULL,
|
|
sizeof(componenthandle_t), NULL
|
|
);
|
|
|
|
scriptProtoDefineProp(
|
|
&MODULE_ENTITY_PHYSICS_PROTO, "velocity",
|
|
moduleEntityPhysicsGetVelocity, moduleEntityPhysicsSetVelocity
|
|
);
|
|
scriptProtoDefineProp(
|
|
&MODULE_ENTITY_PHYSICS_PROTO, "onGround",
|
|
moduleEntityPhysicsGetOnGround, NULL
|
|
);
|
|
scriptProtoDefineProp(
|
|
&MODULE_ENTITY_PHYSICS_PROTO, "bodyType",
|
|
moduleEntityPhysicsGetBodyType, moduleEntityPhysicsSetBodyType
|
|
);
|
|
|
|
scriptProtoDefineFunc(
|
|
&MODULE_ENTITY_PHYSICS_PROTO, "applyImpulse",
|
|
moduleEntityPhysicsApplyImpulse
|
|
);
|
|
scriptProtoDefineFunc(
|
|
&MODULE_ENTITY_PHYSICS_PROTO, "setShapeCube",
|
|
moduleEntityPhysicsSetShapeCube
|
|
);
|
|
scriptProtoDefineFunc(
|
|
&MODULE_ENTITY_PHYSICS_PROTO, "setShapeSphere",
|
|
moduleEntityPhysicsSetShapeSphere
|
|
);
|
|
scriptProtoDefineFunc(
|
|
&MODULE_ENTITY_PHYSICS_PROTO, "setShapeCapsule",
|
|
moduleEntityPhysicsSetShapeCapsule
|
|
);
|
|
scriptProtoDefineFunc(
|
|
&MODULE_ENTITY_PHYSICS_PROTO, "setShapePlane",
|
|
moduleEntityPhysicsSetShapePlane
|
|
);
|
|
|
|
moduleBaseSetInt("PHYSICS_BODY_STATIC", PHYSICS_BODY_STATIC);
|
|
moduleBaseSetInt("PHYSICS_BODY_DYNAMIC", PHYSICS_BODY_DYNAMIC);
|
|
moduleBaseSetInt("PHYSICS_BODY_KINEMATIC", PHYSICS_BODY_KINEMATIC);
|
|
|
|
moduleBaseSetInt("PHYSICS_SHAPE_CUBE", PHYSICS_SHAPE_CUBE);
|
|
moduleBaseSetInt("PHYSICS_SHAPE_SPHERE", PHYSICS_SHAPE_SPHERE);
|
|
moduleBaseSetInt("PHYSICS_SHAPE_CAPSULE", PHYSICS_SHAPE_CAPSULE);
|
|
moduleBaseSetInt("PHYSICS_SHAPE_PLANE", PHYSICS_SHAPE_PLANE);
|
|
}
|