Files
Webcam/include/modules/script_squirrel/legacy/camera_binding.cpp

422 lines
13 KiB
C++

/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "binding_helpers.h"
#include "scene3d/scene.h"
#include "scene3d/mobject.h"
#include "scene3d/mcamera.h"
#include "script_squirrel/cobject/matrix_decl.h"
#include "core/renderer.h"
#include "math/vector.h"
using namespace GS;
using namespace GS::S3D;
using namespace GS::Script;
static CObjectType camera_derived_types[] = { typetag_Item, typetag_Camera, typetag_Undefined };
static CObjectType object_derived_types[] = { typetag_Item, typetag_Object, typetag_Undefined };
//------------------------------------------------------------------------------
SQInteger CameraGetItem(HSQUIRRELVM vm)
{
__SQ_GETSINGLESAFEPTR(cam, MCamera, typetag_Camera)
__SQ_RETURNSAFEPTR((MItem *)cam, typetag_Item)
}
SQInteger CameraGetFov(HSQUIRRELVM vm)
{
__SQ_GETSINGLE(__SQ_GETCOBJECTBASE(c, MCamera, camera_derived_types))
__SQ_RETURNFLOAT(c->GetFov())
}
SQInteger CameraSetFov(HSQUIRRELVM vm)
{
__SQ_GETSTART(2)
__SQ_GETCOBJECTBASE(c, MCamera, camera_derived_types)
__SQ_GETFLOAT(f)
__SQ_GETEND
c->SetFov(f);
__SQ_RETURN
}
SQInteger CameraGetZoomFactor(HSQUIRRELVM vm)
{
__SQ_GETSINGLE(__SQ_GETCOBJECTBASE(c, MCamera, camera_derived_types))
__SQ_RETURNFLOAT(c->zoom_factor)
}
SQInteger CameraSetZoomFactor(HSQUIRRELVM vm)
{
__SQ_GETSTART(2)
__SQ_GETCOBJECTBASE(c, MCamera, camera_derived_types)
__SQ_GETFLOAT(z)
__SQ_GETEND
c->SetZoomFactor(z);
__SQ_RETURN
}
SQInteger CameraSetFStop(HSQUIRRELVM vm)
{
__SQ_GETSTART(2)
__SQ_GETCOBJECTBASE(c, MCamera, camera_derived_types)
__SQ_GETFLOAT(f)
__SQ_GETEND
c->registry.CreateKey("PostProcess:Dof:FStop", f);
__SQ_RETURN
}
SQInteger CameraSetFocalDistance(HSQUIRRELVM vm)
{
__SQ_GETSTART(2)
__SQ_GETCOBJECTBASE(c, MCamera, camera_derived_types)
__SQ_GETFLOAT(f)
__SQ_GETEND
c->registry.CreateKey("PostProcess:Dof:FDist", f);
__SQ_RETURN
}
SQInteger CameraGetVisibleItems(HSQUIRRELVM vm) {
__SQ_GETSTART(2)
__SQ_GETCOBJECTBASE(c, MCamera, camera_derived_types)
__SQ_GETSAFEPTR(scene, Scene, typetag_Scene3d)
__SQ_GETEND
sq_newarray(vm, 0);
Vector4 cameraPos = c->GetMatrix().GetRow(3);
Vector4 cameraForward = c->GetMatrix().GetRow(2); // Camera's forward vector
ListForeachPtr(MItem *, item, scene->GetItemList()) {
if (item->GetItemType() == Type_Object) {
if (MObject *o = (MObject *)item) {
if (o->render_data.IsValid() && o->render_data->geometry.IsValid()) {
Vector4 objectPos = o->GetMatrix().GetRow(3);
Vector4 toObject = objectPos - cameraPos;
// Skip this object if it's too far
float distance = toObject.Len();
if (distance > 500) {
continue;
}
// Check if object is in front of the camera
float dot = toObject.x * cameraForward.x + toObject.y * cameraForward.y + toObject.z * cameraForward.z;
if (dot > 0) {
// Perform frustum culling
Frustum::Visibility vis = c->frustum.ClassifyMinMax(o->render_data->geometry->minmax, &o->GetMatrix());
if (vis != Frustum::Outside) {
CObject::Push(vm, (void *)item, typetag_Item);
sq_arrayappend(vm, -2);
}
}
}
}
}
}
return 1;
}
/*
SQInteger CameraComputeProjectionMatrix(HSQUIRRELVM vm)
{
__SQ_GETSTART(2)
__SQ_GETCOBJECTBASE(c, MCamera, camera_derived_types)
__SQ_GETFRECT(viewport)
__SQ_GETEND
Matrix4 projection_matrix;
c->ComputeProjectionMatrix(viewport, projection_matrix);
__SQ_RETURNMATRIX4(projection_matrix)
}
*/
SQInteger CameraSetAspectRatio(HSQUIRRELVM vm)
{
__SQ_GETSTART(2)
__SQ_GETCOBJECTBASE(c, MCamera, camera_derived_types)
__SQ_GETFLOAT(v)
__SQ_GETEND
c->aspect_ratio = v;
__SQ_RETURN
}
SQInteger CameraGetAspectRatio(HSQUIRRELVM vm)
{
__SQ_GETSINGLE(__SQ_GETCOBJECTBASE(c, MCamera, camera_derived_types))
__SQ_RETURNFLOAT(c->aspect_ratio)
}
SQInteger CameraSetAspectRatioRefAxis(HSQUIRRELVM vm)
{
__SQ_GETSTART(2)
__SQ_GETCOBJECTBASE(c, MCamera, camera_derived_types)
__SQ_GETBOOL(v)
__SQ_GETEND
c->aspect_ratio_ref_yaxis = asbool(v);
__SQ_RETURN
}
SQInteger CameraSetClipping(HSQUIRRELVM vm)
{
__SQ_GETSTART(3)
__SQ_GETCOBJECTBASE(c, MCamera, camera_derived_types)
__SQ_GETFLOAT(n)
__SQ_GETFLOAT(f)
__SQ_GETEND
c->z_near = n;
c->z_far = f;
__SQ_RETURN
}
SQInteger CameraGetZNear(HSQUIRRELVM vm)
{
__SQ_GETSTART(1)
__SQ_GETCOBJECTBASE(c, MCamera, camera_derived_types)
__SQ_GETEND
__SQ_RETURNFLOAT(c->z_near)
}
SQInteger CameraGetZFar(HSQUIRRELVM vm)
{
__SQ_GETSTART(1)
__SQ_GETCOBJECTBASE(c, MCamera, camera_derived_types)
__SQ_GETEND
__SQ_RETURNFLOAT(c->z_far)
}
SQInteger CameraCullObject(HSQUIRRELVM vm)
{
__SQ_GETSTART(2)
__SQ_GETCOBJECTBASE(c, MCamera, camera_derived_types)
__SQ_GETCOBJECTBASE(o, MObject, object_derived_types)
__SQ_GETEND
Frustum::Visibility vis = Frustum::Outside;
if (o->render_data.IsValid() && o->render_data->geometry.IsValid())
vis = c->frustum.ClassifyMinMax(o->render_data->geometry->minmax, &o->GetMatrix());
__SQ_RETURNINT(int(vis))
}
SQInteger CameraCullPosition(HSQUIRRELVM vm)
{
__SQ_GETSTART(2)
__SQ_GETCOBJECTBASE(c, MCamera, camera_derived_types)
__SQ_GETVECTOR(p)
__SQ_GETEND
__SQ_RETURNINT(int(c->frustum.ClassifySet(1, &p)))
}
SQInteger CameraGetFrustumVertices(HSQUIRRELVM vm)
{
__SQ_GETSTART(1)
__SQ_GETCOBJECTBASE(c, MCamera, camera_derived_types)
__SQ_GETEND
const Vector4* vtx = c->frustum.GetVertices();
sq_newarray(vm, 0);
for (int i = 0; i < 8; ++i)
{
PushVector(vm, vtx[i], false);
sq_arrayappend(vm, -2);
}
return 1;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
SQInteger CameraWorldToScreen(HSQUIRRELVM vm)
{
__SQ_GETSTART(3)
__SQ_GETCOBJECTBASE(c, MCamera, camera_derived_types)
__SQ_GETSAFEPTR(renderer, Renderer, typetag_Renderer)
__SQ_GETVECTOR(world)
__SQ_GETEND
Vector4 screen;
if (!c->WorldToScreen(renderer->GetViewport(), world, screen))
screen.Set(-1, -1, -1, -1);
__SQ_RETURNVECTOR(screen)
}
SQInteger CameraScreenToWorld(HSQUIRRELVM vm)
{
__SQ_GETSTART(4)
__SQ_GETCOBJECTBASE(c, MCamera, camera_derived_types)
__SQ_GETSAFEPTR(renderer, Renderer, typetag_Renderer)
__SQ_GETFLOAT(x)
__SQ_GETFLOAT(y)
__SQ_GETEND
__SQ_RETURNVECTOR(c->ScreenToWorld(renderer->GetViewport(), x, y))
}
SQInteger CameraScreenToWorldPlane(HSQUIRRELVM vm)
{
__SQ_GETSTART(5)
__SQ_GETCOBJECTBASE(c, MCamera, camera_derived_types)
__SQ_GETSAFEPTR(renderer, Renderer, typetag_Renderer)
__SQ_GETFLOAT(x)
__SQ_GETFLOAT(y)
__SQ_GETFLOAT(z)
__SQ_GETEND
__SQ_RETURNVECTOR(c->ScreenToWorld(renderer->GetViewport(), x, y, z))
}
//------------------------------------------------------------------------------
//-------------------------------------------------------
void RegisterCameraBinding(HSQUIRRELVM vm)
//-------------------------------------------------------
{
/*#
Topic: Camera
Type: Camera
Related: Item
#*/
/*#
Section: CameraGeneric
Desc: Generic functions
#*/
/*#
Func: CameraGetItem
Proto: Item:Camera
Example: local camera_item = CameraGetItem(camera)
Desc: Return camera item.
#*/
sq_register(vm, CameraGetItem, "CameraGetItem", _SC(".x"));
/*#
Section: CameraAR
Desc: Aspect ratio functions.
#*/
/*#
Func: CameraSetAspectRatio
Proto: void:Camera,float aspect_ratio
Desc: Set camera aspect ratio.
#*/
sq_register(vm, CameraSetAspectRatio, "CameraSetAspectRatio", _SC(".xn"));
/*#
Func: CameraGetAspectRatio
Proto: float:Camera
Desc: Get camera aspect ratio.
#*/
sq_register(vm, CameraGetAspectRatio, "CameraGetAspectRatio", _SC(".x"));
/*#
Func: CameraSetAspectRatioRefAxis
Proto: void:Camera,bool use_Y_axis
Desc: Set camera aspect ratio correction to be done on the vertical screen axis (Y) instead of the horizontal axis (X).
#*/
sq_register(vm, CameraSetAspectRatioRefAxis, "CameraSetAspectRatioRefAxis", _SC(".xb"));
/*#
Section: CameraViewport
Desc: Viewport functions
#*/
/*#
Func: CameraCullObject
Proto: VisibilityFlags:Camera camera_to_cull_against,Object object_to_cull
Desc: Cull an object against the camera frustum. Returns a visibility flag mask.
#*/
sq_register(vm, CameraCullObject, "CameraCullObject", _SC(".xx"));
/*#
Func: CameraCullPosition
Proto: VisibilityFlags:Camera camera_to_cull_against,Vector world_position
Desc: Cull a position in world space against the camera frustum. Returns a visibility flag mask.
#*/
sq_register(vm, CameraCullPosition, "CameraCullPosition", _SC(".xx"));
sq_register(vm, CameraGetFrustumVertices, "CameraGetFrustumVertices", _SC(".x"));
sq_register(vm, CameraGetZNear, "CameraGetZNear", _SC(".x"));
sq_register(vm, CameraGetZFar, "CameraGetZFar", _SC(".x"));
/*#
Func: CameraGetFov
Proto: float:Camera
Desc: Get camera fov in radian.
#*/
sq_register(vm, CameraGetFov, "CameraGetFov", _SC(".x"));
/*#
Func: CameraSetFov
Proto: void:Camera,float fov_in_radian
Example: CameraSetFov(camera, Deg(60))
Desc: Get camera fov in radian.
#*/
sq_register(vm, CameraSetFov, "CameraSetFov", _SC(".xn"));
/*#
Func: CameraGetZoomFactor
Proto: float:Camera
Desc: Get camera zoom.
#*/
sq_register(vm, CameraGetZoomFactor, "CameraGetZoomFactor", _SC(".x"));
/*#
Func: CameraSetZoomFactor
Proto: void:Camera,float zoom_factor
Example: CameraSetZoomFactor(camera, 3.2)
Desc: Set camera zoom.
#*/
sq_register(vm, CameraSetZoomFactor, "CameraSetZoomFactor", _SC(".xn"));
/*#
Func: CameraSetFocalDistance
Proto: void:Camera,float distance_in_meters
Example:
// Set focus 10 meters from camera. Objects closer or father than 10 meters will appear out of focus.
CameraSetFocalDistance(camera, Mtr(10))
Desc: Set camera focal distance, set to 0 or less to disable depth of field on the camera.
#*/
sq_register(vm, CameraSetFocalDistance, "CameraSetFocalDistance", _SC(".xn"));
/*#
Func: CameraSetFStop
Proto: void:Camera,float fstop_in_meters
Example: CameraSetFStop(camera, Mtr(4))
Desc: Set camera f-stop, set to 0 or less to disable depth of field on the camera.
#*/
sq_register(vm, CameraSetFStop, "CameraSetFStop", _SC(".xn"));
/*#
Func: CameraSetClipping
Proto: void:camera,float near, float far
Example: CameraSetClipping(camera, Cm(1), Mtr(100))
Desc: Set camera near and far clipping planes.
#*/
sq_register(vm, CameraSetClipping, "CameraSetClipping", _SC(".xnn"));
/*#
Func: CameraWorldToScreen
Proto: vector:Camera,Renderer,Vector world_position
Example:
// Project world position {10,5,1} on the screen.
local p2d = CameraWorldToScreen(camera, g_render, Vector(10, 5, 1))
Desc: Transform a world space position to a normalized screen space position, in the range { [0;1], [0;1] }.
#*/
sq_register(vm, CameraWorldToScreen, "CameraWorldToScreen", _SC(".xxx"));
/*#
Func: CameraScreenToWorld
Proto: vector:Camera,Renderer,float x,float y
Example:
// Transform the middle of the screen to a 3d world position 1 meter away from the camera.
local wp = CameraScreenToWorld(camera, g_render, 0.5, 0.5)
Desc: Transform a normalized screen space position to a world space position.<br>
The screen space position is the result of a projection on the Z=1 imaginary plane, situated 1 meter in front of the camera.
See: CameraScreenToWorldPlane
#*/
sq_register(vm, CameraScreenToWorld, "CameraScreenToWorld", _SC(".xxnn"));
/*#
Func: CameraScreenToWorldPlane
Proto: vector:Camera,Renderer,float x,float y,float plane_distance_in_meters
Desc: Transform a normalized screen space position to a world space position.<br>
The screen space position is the result of a projection on an imaginary plane situated in front of the camera.
#*/
sq_register(vm, CameraScreenToWorldPlane, "CameraScreenToWorldPlane", _SC(".xxnnn"));
sq_pushroottable(vm);
/*#
Enum: VisibilityFlags
Desc: Reported by the visibility functions, visibility can be total, partial or null.
Values: VisibilityOutside,VisibilityClipped,VisibilityInside
#*/
sq_pushstring(vm, "VisibilityOutside", -1); sq_pushinteger(vm, Frustum::Outside); sq_newslot(vm, -3, true);
sq_pushstring(vm, "VisibilityClipped", -1); sq_pushinteger(vm, Frustum::Clipped); sq_newslot(vm, -3, true);
sq_pushstring(vm, "VisibilityInside", -1); sq_pushinteger(vm, Frustum::Inside); sq_newslot(vm, -3, true);
/*#
Func: CameraGetVisibleItems
Proto: array:Camera,Scene3d
Desc: Get all visible items in the camera frustum.
#*/
sq_register(vm, CameraGetVisibleItems, "CameraGetVisibleItems", _SC(".xx"));
sq_pop(vm, 1);
}