mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 08:15:59 -10:00
* Automatically generate the isValid() Lua API function for handle types If an ADE object's stored type has an isValid() member, ade_obj now registers an isValid function for it automatically. An explicit ADE_FUNC(isValid, ...) declared after the ADE_OBJ replaces the generated one, so types with special semantics (e.g. sound) keep their own. The 67 hand-written functions that merely delegated to the member are removed, and 26 types that previously exposed no isValid() gain one. Co-Authored-By: Claude Fable 5.1 <[email protected]> * Add ADE_OBJ_VALIDATOR for index-based Lua handles Int-index handles (shipclass, weaponclass, team, etc.) can now declare their validity predicate with a single ADE_OBJ_VALIDATOR or ADE_OBJ_VALIDATOR_RANGE line after the ADE_OBJ. The registered validator drives the generated isValid() function and is also honored by ade_set_args when the mod table asks for nil instead of invalid objects, which previously never applied to these handles. The 19 hand-written range-check functions are replaced, and loadout_ship, default_primary, default_secondary, and support_rearm_pool_team gain isValid(). Add a validator to HudGauge while we're at it. Also fully qualify the scripting namespace in LuaConvert.h so its templates can be instantiated from the unit tests. Co-Authored-By: Claude Fable 5.1 <[email protected]> --------- Co-authored-by: Claude Fable 5.1 <[email protected]>
295 lines
9.4 KiB
C++
295 lines
9.4 KiB
C++
//
|
|
//
|
|
|
|
#include <camera/camera.h>
|
|
#include "camera.h"
|
|
#include "vecmath.h"
|
|
#include "object.h"
|
|
#include "subsystem.h"
|
|
|
|
namespace scripting {
|
|
namespace api {
|
|
|
|
//**********HANDLE: Camera
|
|
ADE_OBJ(l_Camera, camid, "camera", "Camera handle");
|
|
|
|
ADE_FUNC(__tostring, l_Camera, NULL, "Camera name", "string", "Camera name, or an empty string if handle is invalid")
|
|
{
|
|
camid cid;
|
|
if(!ade_get_args(L, "o", l_Camera.Get(&cid)))
|
|
return ade_set_error(L, "s", "");
|
|
|
|
if(!cid.isValid())
|
|
return ade_set_error(L, "s", "");
|
|
|
|
return ade_set_args(L, "s", cid.getCamera()->get_name());
|
|
}
|
|
|
|
ADE_VIRTVAR(Name, l_Camera, "string", "New camera name", "string", "Camera name")
|
|
{
|
|
camid cid;
|
|
const char* s = nullptr;
|
|
if(!ade_get_args(L, "o|s", l_Camera.Get(&cid), &s))
|
|
return ade_set_error(L, "s", "");
|
|
|
|
if(!cid.isValid())
|
|
return ade_set_error(L, "s", "");
|
|
|
|
if(ADE_SETTING_VAR && s != NULL) {
|
|
cid.getCamera()->set_name(s);
|
|
}
|
|
|
|
return ade_set_args(L, "s", cid.getCamera()->get_name());
|
|
}
|
|
|
|
ADE_VIRTVAR(FOV, l_Camera, "number", "New camera FOV (in radians)", "number", "Camera FOV (in radians)")
|
|
{
|
|
camid cid;
|
|
float f = g3_get_hfov(VIEWER_ZOOM_DEFAULT);
|
|
if(!ade_get_args(L, "o|f", l_Camera.Get(&cid), &f))
|
|
return ade_set_error(L, "f", 0.0f);
|
|
|
|
if(!cid.isValid())
|
|
return ade_set_error(L, "f", 0.0f);
|
|
|
|
if(ADE_SETTING_VAR) {
|
|
cid.getCamera()->set_fov(f);
|
|
}
|
|
|
|
return ade_set_args(L, "f", g3_get_hfov(cid.getCamera()->get_fov()));
|
|
}
|
|
|
|
ADE_VIRTVAR(Orientation, l_Camera, "orientation", "New camera orientation", "orientation", "Camera orientation")
|
|
{
|
|
camid cid;
|
|
matrix_h *mh = NULL;
|
|
if(!ade_get_args(L, "o|o", l_Camera.Get(&cid), l_Matrix.GetPtr(&mh)))
|
|
return ade_set_error(L, "f", 0.0f);
|
|
|
|
if(!cid.isValid())
|
|
return ade_set_error(L, "f", 0.0f);
|
|
|
|
if(ADE_SETTING_VAR && mh != NULL) {
|
|
cid.getCamera()->set_rotation(mh->GetMatrix());
|
|
}
|
|
|
|
matrix mtx;
|
|
cid.getCamera()->get_info(NULL, &mtx);
|
|
return ade_set_args(L, "o", l_Matrix.Set(matrix_h(&mtx)));
|
|
}
|
|
|
|
ADE_VIRTVAR(Position, l_Camera, "vector", "New camera position", "vector", "Camera position")
|
|
{
|
|
camid cid;
|
|
vec3d *pos = NULL;
|
|
if(!ade_get_args(L, "o|o", l_Camera.Get(&cid), l_Vector.GetPtr(&pos)))
|
|
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
|
|
|
|
if(!cid.isValid())
|
|
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
|
|
|
|
if(ADE_SETTING_VAR && pos) {
|
|
cid.getCamera()->set_position(pos);
|
|
}
|
|
|
|
vec3d v = vmd_zero_vector;
|
|
cid.getCamera()->get_info(&v, NULL);
|
|
return ade_set_args(L, "o", l_Vector.Set(v));
|
|
}
|
|
|
|
ADE_VIRTVAR(Self, l_Camera, "object", "New mount object", "object", "Camera object")
|
|
{
|
|
camid cid;
|
|
object_h *oh = NULL;
|
|
if(!ade_get_args(L, "o|o", l_Camera.Get(&cid), l_Object.GetPtr(&oh)))
|
|
return ade_set_error(L, "o", l_Object.Set(object_h()));
|
|
|
|
if(!cid.isValid())
|
|
return ade_set_error(L, "o", l_Object.Set(object_h()));
|
|
|
|
if(ADE_SETTING_VAR && oh && oh->isValid()) {
|
|
cid.getCamera()->set_object_host(oh->objp());
|
|
}
|
|
|
|
return ade_set_object_with_breed(L, OBJ_INDEX(cid.getCamera()->get_object_host()));
|
|
}
|
|
|
|
ADE_VIRTVAR(SelfSubsystem, l_Camera, "subsystem", "New mount object subsystem", "subsystem", "Subsystem that the camera is mounted on")
|
|
{
|
|
camid cid;
|
|
ship_subsys_h *sso = NULL;
|
|
if(!ade_get_args(L, "o|o", l_Camera.Get(&cid), l_Subsystem.GetPtr(&sso)))
|
|
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
|
|
|
|
if(!cid.isValid())
|
|
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
|
|
|
|
if(ADE_SETTING_VAR && sso && sso->isValid()) {
|
|
cid.getCamera()->set_object_host(sso->objh.objp(), sso->ss->system_info->subobj_num);
|
|
}
|
|
|
|
object *objp = cid.getCamera()->get_object_host();
|
|
if(objp == NULL || objp->type != OBJ_SHIP)
|
|
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
|
|
|
|
int submodel = cid.getCamera()->get_object_host_submodel();
|
|
if(submodel < 0)
|
|
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
|
|
|
|
ship *shipp = &Ships[objp->instance];
|
|
polymodel *pm = model_get(Ship_info[shipp->ship_info_index].model_num);
|
|
|
|
if(pm == NULL)
|
|
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
|
|
|
|
bsp_info *sm = &pm->submodel[submodel];
|
|
|
|
ship_subsys *ss = ship_get_subsys(shipp, sm->name);
|
|
|
|
if(ss == NULL)
|
|
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
|
|
|
|
return ade_set_args(L, "o", l_Subsystem.Set(ship_subsys_h(objp, ss)));
|
|
}
|
|
|
|
ADE_VIRTVAR(Target, l_Camera, "object", "New target object", "object", "Camera target object")
|
|
{
|
|
camid cid;
|
|
object_h *oh = NULL;
|
|
if(!ade_get_args(L, "o|o", l_Camera.Get(&cid), l_Object.GetPtr(&oh)))
|
|
return ade_set_error(L, "o", l_Object.Set(object_h()));
|
|
|
|
if(!cid.isValid())
|
|
return ade_set_error(L, "o", l_Object.Set(object_h()));
|
|
|
|
if(ADE_SETTING_VAR && oh && oh->isValid()) {
|
|
cid.getCamera()->set_object_target(oh->objp());
|
|
}
|
|
|
|
return ade_set_object_with_breed(L, OBJ_INDEX(cid.getCamera()->get_object_target()));
|
|
}
|
|
|
|
ADE_VIRTVAR(TargetSubsystem, l_Camera, "subsystem", "New target subsystem", "subsystem", "Subsystem that the camera is pointed at")
|
|
{
|
|
camid cid;
|
|
ship_subsys_h *sso = NULL;
|
|
if(!ade_get_args(L, "o|o", l_Camera.Get(&cid), l_Subsystem.GetPtr(&sso)))
|
|
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
|
|
|
|
if(!cid.isValid())
|
|
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
|
|
|
|
if(ADE_SETTING_VAR && sso && sso->isValid()) {
|
|
cid.getCamera()->set_object_target(sso->objh.objp(), sso->ss->system_info->subobj_num);
|
|
}
|
|
|
|
object *objp = cid.getCamera()->get_object_target();
|
|
if(objp == NULL || objp->type != OBJ_SHIP)
|
|
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
|
|
|
|
int submodel = cid.getCamera()->get_object_target_submodel();
|
|
if(submodel < 0)
|
|
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
|
|
|
|
ship *shipp = &Ships[objp->instance];
|
|
polymodel *pm = model_get(Ship_info[shipp->ship_info_index].model_num);
|
|
|
|
if(pm == NULL)
|
|
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
|
|
|
|
bsp_info *sm = &pm->submodel[submodel];
|
|
|
|
ship_subsys *ss = ship_get_subsys(shipp, sm->name);
|
|
|
|
if(ss == NULL)
|
|
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
|
|
|
|
return ade_set_args(L, "o", l_Subsystem.Set(ship_subsys_h(objp, ss)));
|
|
}
|
|
|
|
ADE_FUNC(setFOV, l_Camera, "[number FOV, number ZoomTime, number ZoomAccelerationTime, number ZoomDecelerationTime]",
|
|
"Sets camera FOV"
|
|
"<br>FOV is the final field of view, in radians, of the camera."
|
|
"<br>Zoom Time is the total time to take zooming in or out."
|
|
"<br>Acceleration Time is the total time it should take the camera to get up to full zoom speed."
|
|
"<br>Deceleration Time is the total time it should take the camera to slow down from full zoom speed.",
|
|
"boolean", "true if successful, false or nil otherwise")
|
|
{
|
|
camid cid;
|
|
float n_fov = g3_get_hfov(VIEWER_ZOOM_DEFAULT);
|
|
float time=0.0f;
|
|
float acc_time=0.0f;
|
|
float dec_time=0.0f;
|
|
if(!ade_get_args(L, "o|ffff", l_Camera.Get(&cid), &n_fov, &time, &acc_time, &dec_time))
|
|
return ADE_RETURN_NIL;
|
|
|
|
if(!cid.isValid())
|
|
return ADE_RETURN_NIL;
|
|
|
|
cid.getCamera()->set_fov(n_fov, time, acc_time, dec_time);
|
|
|
|
return ADE_RETURN_TRUE;
|
|
}
|
|
|
|
ADE_FUNC(setOrientation, l_Camera, "[orientation WorldOrientation, number RotationTime, number AccelerationTime, number DecelerationTime]",
|
|
"Sets camera orientation and velocity data."
|
|
"<br>Orientation is the final orientation for the camera, after it has finished moving. If not specified, the camera will simply stop at its current orientation."
|
|
"<br>Rotation time (seconds) is how long total, including acceleration, the camera should take to rotate. If it is not specified, the camera will jump to the specified orientation."
|
|
"<br>Acceleration time (seconds) is how long it should take the camera to get 'up to speed'. If not specified, the camera will instantly start moving."
|
|
"<br>Deceleration time (seconds) is how long it should take the camera to slow down. If not specified, the camera will instantly stop moving.",
|
|
"boolean", "true if successful, false or nil otherwise")
|
|
{
|
|
camid cid;
|
|
matrix_h *mh=NULL;
|
|
float time=0.0f;
|
|
float acc_time=0.0f;
|
|
float dec_time=0.0f;
|
|
if(!ade_get_args(L, "o|offf", l_Camera.Get(&cid), l_Matrix.GetPtr(&mh), &time, &acc_time, &dec_time))
|
|
return ADE_RETURN_NIL;
|
|
|
|
if(!cid.isValid())
|
|
return ADE_RETURN_NIL;
|
|
|
|
camera *cam = cid.getCamera();
|
|
|
|
if(mh != NULL)
|
|
{
|
|
cam->set_rotation(mh->GetMatrix(), time, acc_time, dec_time);
|
|
}
|
|
else
|
|
{
|
|
cam->set_rotation();
|
|
}
|
|
|
|
return ADE_RETURN_TRUE;
|
|
}
|
|
|
|
ADE_FUNC(setPosition, l_Camera, "[vector Position, number TranslationTime, number AccelerationTime, number DecelerationTime]",
|
|
"Sets camera position and velocity data."
|
|
"<br>Position is the final position for the camera. If not specified, the camera will simply stop at its current position."
|
|
"<br>Translation time (seconds) is how long total, including acceleration, the camera should take to move. If it is not specified, the camera will jump to the specified position."
|
|
"<br>Acceleration time (seconds) is how long it should take the camera to get 'up to speed'. If not specified, the camera will instantly start moving."
|
|
"<br>Deceleration time (seconds) is how long it should take the camera to slow down. If not specified, the camera will instantly stop moving.",
|
|
"boolean", "true if successful, false or nil otherwise")
|
|
{
|
|
camid cid;
|
|
vec3d *pos=NULL;
|
|
float time=0.0f;
|
|
float acc_time=0.0f;
|
|
float dec_time=0.0f;
|
|
if(!ade_get_args(L, "o|offf", l_Camera.Get(&cid), l_Vector.GetPtr(&pos), &time, &acc_time, &dec_time))
|
|
return ADE_RETURN_NIL;
|
|
|
|
if(!cid.isValid())
|
|
return ADE_RETURN_NIL;
|
|
|
|
cid.getCamera()->set_position(pos, time, acc_time, dec_time);
|
|
|
|
return ADE_RETURN_TRUE;
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|