Index: source/graphics/scripting/JSInterface_GameView.h =================================================================== --- source/graphics/scripting/JSInterface_GameView.h +++ source/graphics/scripting/JSInterface_GameView.h @@ -18,6 +18,8 @@ #ifndef INCLUDED_JSINTERFACE_GAMEVIEW #define INCLUDED_JSINTERFACE_GAMEVIEW +#include "scriptinterface/ScriptTypes.h" + class ScriptRequest; namespace JSI_GameView Index: source/graphics/scripting/JSInterface_GameView.cpp =================================================================== --- source/graphics/scripting/JSInterface_GameView.cpp +++ source/graphics/scripting/JSInterface_GameView.cpp @@ -17,6 +17,8 @@ #include "precompiled.h" +#include "jsapi.h" + #include "JSInterface_GameView.h" #include "graphics/Camera.h" @@ -55,7 +57,6 @@ IMPLEMENT_BOOLEAN_SCRIPT_SETTING(Culling); IMPLEMENT_BOOLEAN_SCRIPT_SETTING(LockCullCamera); IMPLEMENT_BOOLEAN_SCRIPT_SETTING(ConstrainCamera); - #undef IMPLEMENT_BOOLEAN_SCRIPT_SETTING @@ -72,6 +73,171 @@ #undef REGISTER_BOOLEAN_SCRIPT_SETTING +bool getPivot(JSContext* ctx, unsigned argc, JS::Value *vp) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + CVector3D current(-1, -1, -1); + if (g_Game && g_Game->GetView()) + current = g_Game->GetView()->GetCameraPivot(); + JS::RootedObject r(ctx, JS_NewPlainObject(ctx)); + JS::RootedValue rX(ctx, JS_NumberValue(current.X)), + rY(ctx, JS_NumberValue(current.Y)); + JS_SetProperty(ctx, r, "x", rX); + JS_SetProperty(ctx, r, "y", rY); + args.rval().setObject(*r); + return true; +} + +bool setPivot(JSContext* ctx, unsigned argc, JS::Value *vp) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + args.rval().setNull(); + return true; +} + +bool getPhi(JSContext* ctx, unsigned argc, JS::Value *vp) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + CVector3D currentRotation(-1, -1, -1); + if (g_Game && g_Game->GetView()) + currentRotation = g_Game->GetView()->GetCameraRotation(); + args.rval().setNumber(currentRotation.X); + return true; +} + +bool setPhi(JSContext* ctx, unsigned argc, JS::Value *vp) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + double inputPhi; + JS::ToNumber(ctx, args.get(0), &inputPhi); + CVector3D currentCameraPosition = CVector3D(-1,-1,-1); + CVector3D currentCameraRotation = CVector3D(-1,-1,-1); + float currentZoom = -1; + if (g_Game && g_Game->GetView()) { + currentCameraPosition = g_Game->GetView()->GetCameraPosition(); + currentCameraRotation = g_Game->GetView()->GetCameraRotation(); + currentZoom = g_Game->GetView()->GetCameraZoom(); + g_Game->GetView()->SetCamera( + currentCameraPosition, + inputPhi, + currentCameraRotation.Y, + currentZoom + ); + } + args.rval().setNull(); + return true; +} + +bool getPsi(JSContext* ctx, unsigned argc, JS::Value *vp) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + args.rval().setNull(); + CVector3D currentRotation(-1, -1, -1); + if (g_Game && g_Game->GetView()) + currentRotation = g_Game->GetView()->GetCameraRotation(); + args.rval().setNumber(currentRotation.Y); + return true; +} + +bool setPsi(JSContext* ctx, unsigned argc, JS::Value *vp) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + double inputPsi; + JS::ToNumber(ctx, args.get(0), &inputPsi); + CVector3D currentCameraPosition = CVector3D(-1,-1,-1); + CVector3D currentCameraRotation = CVector3D(-1,-1,-1); + float currentZoom = -1; + if (g_Game && g_Game->GetView()) { + currentCameraPosition = g_Game->GetView()->GetCameraPosition(); + currentCameraRotation = g_Game->GetView()->GetCameraRotation(); + currentZoom = g_Game->GetView()->GetCameraZoom(); + g_Game->GetView()->SetCamera( + currentCameraPosition, + currentCameraRotation.X, + inputPsi, + currentZoom + ); + } + args.rval().setNull(); + return true; +} + +bool getZoom(JSContext* ctx, unsigned argc, JS::Value *vp) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + float currentZoom = -1; + if (g_Game && g_Game->GetView()) + currentZoom = g_Game->GetView()->GetCameraZoom(); + args.rval().setNumber(currentZoom); + return true; +} + +bool setZoom(JSContext* ctx, unsigned argc, JS::Value *vp) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + + double input_zoom; + JS::ToNumber(ctx, args.get(0), &input_zoom); + + CVector3D currentCameraPosition = CVector3D(-1,-1,-1); + CVector3D currentCameraRotation = CVector3D(-1,-1,-1); + if (g_Game && g_Game->GetView()) { + currentCameraPosition = g_Game->GetView()->GetCameraPosition(); + currentCameraRotation = g_Game->GetView()->GetCameraRotation(); + g_Game->GetView()->SetCamera( + currentCameraPosition, + currentCameraRotation.X, + currentCameraRotation.Y, + float(input_zoom) + ); + } + args.rval().setNull(); + return true; +} + +JSPropertySpec camera_properties[] = { + JS_PSGS("pivot", &getPivot, &setPivot, 0), + JS_PSGS("phi", &getPhi, &setPhi, 0), + JS_PSGS("psi", &getPsi, &setPsi, 0), + JS_PSGS("zoom", &getZoom, &setZoom, 0), + JS_PS_END, +}; + +bool moveTo(JSContext* ctx, unsigned argc, JS::Value *vp) { + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); + if (!g_Game || !g_Game->GetWorld() || !g_Game->GetView() || !g_Game->GetWorld()->GetTerrain()) { + return false; + } + JS::HandleValue input_pos = args.get(0); + JS::RootedObject target_pos(ctx); + JS_ValueToObject(ctx, input_pos, &target_pos); + bool isArray; + JS::IsArrayObject(ctx, target_pos, &isArray); + uint32_t arrayLength; + JS::GetArrayLength(ctx, target_pos, &arrayLength); + if (!isArray || arrayLength < 2) return false; + JS::RootedValue js_x(ctx), js_z(ctx); + if (!JS_GetElement(ctx, target_pos, 0, &js_x)) return false; + if (!JS_GetElement(ctx, target_pos, 1, &js_z)) return false; + double x, z; + JS::ToNumber(ctx, js_x, &x); + JS::ToNumber(ctx, js_z, &z); + // + CTerrain* terrain = g_Game->GetWorld()->GetTerrain(); + CVector3D target; + target.X = float(x); + target.Z = float(z); + target.Y = terrain->GetExactGroundLevel(target.X, target.Z); + g_Game->GetView()->MoveCameraTarget(target); + args.rval().setNull(); + return true; +} + +JSFunctionSpec camera_methods[] = +{ + JS_FN("moveTo", &moveTo, 1, 0), + JS_FS_END +}; + +JS::Value getCamera(const ScriptRequest& rq) { + JS::RootedObject camera(rq.cx, JS_NewPlainObject(rq.cx)); + JS_DefineProperties(rq.cx, camera, camera_properties); + JS_DefineFunctions(rq.cx, camera, camera_methods); + return JS::ObjectValue(*camera.get()); +} + JS::Value GetCameraPivot(const ScriptRequest& rq) { CVector3D pivot(-1, -1, -1); @@ -166,6 +332,8 @@ { RegisterScriptFunctions_Settings(rq); + ScriptFunction::Register<&getCamera>(rq, "getCamera"); + ScriptFunction::Register<&GetCameraPivot>(rq, "GetCameraPivot"); ScriptFunction::Register<&CameraMoveTo>(rq, "CameraMoveTo"); ScriptFunction::Register<&SetCameraTarget>(rq, "SetCameraTarget"); @@ -175,4 +343,3 @@ ScriptFunction::Register<&GetFollowedEntity>(rq, "GetFollowedEntity"); ScriptFunction::Register<&GetTerrainAtScreenPoint>(rq, "GetTerrainAtScreenPoint"); } -}