From 95d5c06773324099dac21baee21c419920a9e2d5 Mon Sep 17 00:00:00 2001 From: Alexander Klingenbeck Date: Fri, 26 May 2023 08:10:27 +0200 Subject: [PATCH] Add bindings for rcamera, add 1st person cam example --- bindings/raylib_math_api.json | 1 - bindings/src/index.ts | 35 +++- bindings/src/raylib-header.ts | 2 +- examples/core/core_3d_camera_first_person.c | 206 ------------------- examples/core/core_3d_camera_first_person.js | 195 ++++++++++++++++++ examples/lib.raylib.d.ts | 28 +++ generate-bindings.js | 31 ++- src/bindings/js_raylib_core.h | 151 ++++++++++++++ 8 files changed, 430 insertions(+), 219 deletions(-) delete mode 100644 bindings/raylib_math_api.json delete mode 100644 examples/core/core_3d_camera_first_person.c create mode 100644 examples/core/core_3d_camera_first_person.js diff --git a/bindings/raylib_math_api.json b/bindings/raylib_math_api.json deleted file mode 100644 index 7dd1586..0000000 --- a/bindings/raylib_math_api.json +++ /dev/null @@ -1 +0,0 @@ -[{"name":"Clamp","returnType":"float","params":[{"name":"value","type":"float"},{"name":"min","type":"float"},{"name":"max","type":"float"}],"description":"Clamp float value"},{"name":"Lerp","returnType":"float","params":[{"name":"start","type":"float"},{"name":"end","type":"float"},{"name":"amount","type":"float"}],"description":"Calculate linear interpolation between two floats"},{"name":"Normalize","returnType":"float","params":[{"name":"value","type":"float"},{"name":"start","type":"float"},{"name":"end","type":"float"}],"description":"Normalize input value within input range"},{"name":"Remap","returnType":"float","params":[{"name":"value","type":"float"},{"name":"inputStart","type":"float"},{"name":"inputEnd","type":"float"},{"name":"outputStart","type":"float"},{"name":"outputEnd","type":"float"}],"description":"Remap input value within input range to output range"},{"name":"Wrap","returnType":"float","params":[{"name":"value","type":"float"},{"name":"min","type":"float"},{"name":"max","type":"float"}],"description":"Wrap input value from min to max"},{"name":"FloatEquals","returnType":"int","params":[{"name":"x","type":"float"},{"name":"y","type":"float"}],"description":"Check whether two given floats are almost equal"},{"name":"Vector2Zero","returnType":"Vector2","params":[],"description":"Vector with components value 0.0f"},{"name":"Vector2One","returnType":"Vector2","params":[],"description":"Vector with components value 1.0f"},{"name":"Vector2Add","returnType":"Vector2","params":[{"name":"v1","type":"Vector2"},{"name":"v2","type":"Vector2"}],"description":"Add two vectors (v1 + v2)"},{"name":"Vector2AddValue","returnType":"Vector2","params":[{"name":"v","type":"Vector2"},{"name":"add","type":"float"}],"description":"Add vector and float value"},{"name":"Vector2Subtract","returnType":"Vector2","params":[{"name":"v1","type":"Vector2"},{"name":"v2","type":"Vector2"}],"description":"Subtract two vectors (v1 - v2)"},{"name":"Vector2SubtractValue","returnType":"Vector2","params":[{"name":"v","type":"Vector2"},{"name":"sub","type":"float"}],"description":"Subtract vector by float value"},{"name":"Vector2Length","returnType":"float","params":[{"name":"v","type":"Vector2"}],"description":"Calculate vector length"},{"name":"Vector2LengthSqr","returnType":"float","params":[{"name":"v","type":"Vector2"}],"description":"Calculate vector square length"},{"name":"Vector2DotProduct","returnType":"float","params":[{"name":"v1","type":"Vector2"},{"name":"v2","type":"Vector2"}],"description":"Calculate two vectors dot product"},{"name":"Vector2Distance","returnType":"float","params":[{"name":"v1","type":"Vector2"},{"name":"v2","type":"Vector2"}],"description":"Calculate distance between two vectors"},{"name":"Vector2DistanceSqr","returnType":"float","params":[{"name":"v1","type":"Vector2"},{"name":"v2","type":"Vector2"}],"description":"Calculate square distance between two vectors"},{"name":"Vector2Angle","returnType":"float","params":[{"name":"v1","type":"Vector2"},{"name":"v2","type":"Vector2"}],"description":"Calculate angle between two vectors\nNOTE: Angle is calculated from origin point (0, 0)"},{"name":"Vector2LineAngle","returnType":"float","params":[{"name":"start","type":"Vector2"},{"name":"end","type":"Vector2"}],"description":"Calculate angle defined by a two vectors line\nNOTE: Parameters need to be normalized\nCurrent implementation should be aligned with glm::angle"},{"name":"Vector2Scale","returnType":"Vector2","params":[{"name":"v","type":"Vector2"},{"name":"scale","type":"float"}],"description":"Scale vector (multiply by value)"},{"name":"Vector2Multiply","returnType":"Vector2","params":[{"name":"v1","type":"Vector2"},{"name":"v2","type":"Vector2"}],"description":"Multiply vector by vector"},{"name":"Vector2Negate","returnType":"Vector2","params":[{"name":"v","type":"Vector2"}],"description":"Negate vector"},{"name":"Vector2Divide","returnType":"Vector2","params":[{"name":"v1","type":"Vector2"},{"name":"v2","type":"Vector2"}],"description":"Divide vector by vector"},{"name":"Vector2Normalize","returnType":"Vector2","params":[{"name":"v","type":"Vector2"}],"description":"Normalize provided vector"},{"name":"Vector2Transform","returnType":"Vector2","params":[{"name":"v","type":"Vector2"},{"name":"mat","type":"Matrix"}],"description":"Transforms a Vector2 by a given Matrix"},{"name":"Vector2Lerp","returnType":"Vector2","params":[{"name":"v1","type":"Vector2"},{"name":"v2","type":"Vector2"},{"name":"amount","type":"float"}],"description":"Calculate linear interpolation between two vectors"},{"name":"Vector2Reflect","returnType":"Vector2","params":[{"name":"v","type":"Vector2"},{"name":"normal","type":"Vector2"}],"description":"Calculate reflected vector to normal"},{"name":"Vector2Rotate","returnType":"Vector2","params":[{"name":"v","type":"Vector2"},{"name":"angle","type":"float"}],"description":"Rotate vector by angle"},{"name":"Vector2MoveTowards","returnType":"Vector2","params":[{"name":"v","type":"Vector2"},{"name":"target","type":"Vector2"},{"name":"maxDistance","type":"float"}],"description":"Move Vector towards target"},{"name":"Vector2Invert","returnType":"Vector2","params":[{"name":"v","type":"Vector2"}],"description":"Invert the given vector"},{"name":"Vector2Clamp","returnType":"Vector2","params":[{"name":"v","type":"Vector2"},{"name":"min","type":"Vector2"},{"name":"max","type":"Vector2"}],"description":"Clamp the components of the vector between\nmin and max values specified by the given vectors"},{"name":"Vector2ClampValue","returnType":"Vector2","params":[{"name":"v","type":"Vector2"},{"name":"min","type":"float"},{"name":"max","type":"float"}],"description":"Clamp the magnitude of the vector between two min and max values"},{"name":"Vector2Equals","returnType":"int","params":[{"name":"p","type":"Vector2"},{"name":"q","type":"Vector2"}],"description":"Check whether two given vectors are almost equal"},{"name":"Vector3Zero","returnType":"Vector3","params":[],"description":"Vector with components value 0.0f"},{"name":"Vector3One","returnType":"Vector3","params":[],"description":"Vector with components value 1.0f"},{"name":"Vector3Add","returnType":"Vector3","params":[{"name":"v1","type":"Vector3"},{"name":"v2","type":"Vector3"}],"description":"Add two vectors"},{"name":"Vector3AddValue","returnType":"Vector3","params":[{"name":"v","type":"Vector3"},{"name":"add","type":"float"}],"description":"Add vector and float value"},{"name":"Vector3Subtract","returnType":"Vector3","params":[{"name":"v1","type":"Vector3"},{"name":"v2","type":"Vector3"}],"description":"Subtract two vectors"},{"name":"Vector3SubtractValue","returnType":"Vector3","params":[{"name":"v","type":"Vector3"},{"name":"sub","type":"float"}],"description":"Subtract vector by float value"},{"name":"Vector3Scale","returnType":"Vector3","params":[{"name":"v","type":"Vector3"},{"name":"scalar","type":"float"}],"description":"Multiply vector by scalar"},{"name":"Vector3Multiply","returnType":"Vector3","params":[{"name":"v1","type":"Vector3"},{"name":"v2","type":"Vector3"}],"description":"Multiply vector by vector"},{"name":"Vector3CrossProduct","returnType":"Vector3","params":[{"name":"v1","type":"Vector3"},{"name":"v2","type":"Vector3"}],"description":"Calculate two vectors cross product"},{"name":"Vector3Perpendicular","returnType":"Vector3","params":[{"name":"v","type":"Vector3"}],"description":"Calculate one vector perpendicular vector"},{"name":"Vector3Length","returnType":"float","params":[{"name":"v","type":"const Vector3"}],"description":"Calculate vector length"},{"name":"Vector3LengthSqr","returnType":"float","params":[{"name":"v","type":"const Vector3"}],"description":"Calculate vector square length"},{"name":"Vector3DotProduct","returnType":"float","params":[{"name":"v1","type":"Vector3"},{"name":"v2","type":"Vector3"}],"description":"Calculate two vectors dot product"},{"name":"Vector3Distance","returnType":"float","params":[{"name":"v1","type":"Vector3"},{"name":"v2","type":"Vector3"}],"description":"Calculate distance between two vectors"},{"name":"Vector3DistanceSqr","returnType":"float","params":[{"name":"v1","type":"Vector3"},{"name":"v2","type":"Vector3"}],"description":"Calculate square distance between two vectors"},{"name":"Vector3Angle","returnType":"float","params":[{"name":"v1","type":"Vector3"},{"name":"v2","type":"Vector3"}],"description":"Calculate angle between two vectors"},{"name":"Vector3Negate","returnType":"Vector3","params":[{"name":"v","type":"Vector3"}],"description":"Negate provided vector (invert direction)"},{"name":"Vector3Divide","returnType":"Vector3","params":[{"name":"v1","type":"Vector3"},{"name":"v2","type":"Vector3"}],"description":"Divide vector by vector"},{"name":"Vector3Normalize","returnType":"Vector3","params":[{"name":"v","type":"Vector3"}],"description":"Normalize provided vector"},{"name":"Vector3OrthoNormalize","returnType":"void","params":[{"name":"v1","type":"Vector3 *"},{"name":"v2","type":"Vector3 *"}],"description":"Orthonormalize provided vectors\nMakes vectors normalized and orthogonal to each other\nGram-Schmidt function implementation"},{"name":"Vector3Transform","returnType":"Vector3","params":[{"name":"v","type":"Vector3"},{"name":"mat","type":"Matrix"}],"description":"Transforms a Vector3 by a given Matrix"},{"name":"Vector3RotateByQuaternion","returnType":"Vector3","params":[{"name":"v","type":"Vector3"},{"name":"q","type":"Quaternion"}],"description":"Transform a vector by quaternion rotation"},{"name":"Vector3RotateByAxisAngle","returnType":"Vector3","params":[{"name":"v","type":"Vector3"},{"name":"axis","type":"Vector3"},{"name":"angle","type":"float"}],"description":"Rotates a vector around an axis"},{"name":"Vector3Lerp","returnType":"Vector3","params":[{"name":"v1","type":"Vector3"},{"name":"v2","type":"Vector3"},{"name":"amount","type":"float"}],"description":"Calculate linear interpolation between two vectors"},{"name":"Vector3Reflect","returnType":"Vector3","params":[{"name":"v","type":"Vector3"},{"name":"normal","type":"Vector3"}],"description":"Calculate reflected vector to normal"},{"name":"Vector3Min","returnType":"Vector3","params":[{"name":"v1","type":"Vector3"},{"name":"v2","type":"Vector3"}],"description":"Get min value for each pair of components"},{"name":"Vector3Max","returnType":"Vector3","params":[{"name":"v1","type":"Vector3"},{"name":"v2","type":"Vector3"}],"description":"Get max value for each pair of components"},{"name":"Vector3Barycenter","returnType":"Vector3","params":[{"name":"p","type":"Vector3"},{"name":"a","type":"Vector3"},{"name":"b","type":"Vector3"},{"name":"c","type":"Vector3"}],"description":"Compute barycenter coordinates (u, v, w) for point p with respect to triangle (a, b, c)\nNOTE: Assumes P is on the plane of the triangle"},{"name":"Vector3Unproject","returnType":"Vector3","params":[{"name":"source","type":"Vector3"},{"name":"projection","type":"Matrix"},{"name":"view","type":"Matrix"}],"description":"Projects a Vector3 from screen space into object space\nNOTE: We are avoiding calling other raymath functions despite available"},{"name":"Vector3ToFloatV","returnType":"float3","params":[{"name":"v","type":"Vector3"}],"description":"Get Vector3 as float array"},{"name":"Vector3Invert","returnType":"Vector3","params":[{"name":"v","type":"Vector3"}],"description":"Invert the given vector"},{"name":"Vector3Clamp","returnType":"Vector3","params":[{"name":"v","type":"Vector3"},{"name":"min","type":"Vector3"},{"name":"max","type":"Vector3"}],"description":"Clamp the components of the vector between\nmin and max values specified by the given vectors"},{"name":"Vector3ClampValue","returnType":"Vector3","params":[{"name":"v","type":"Vector3"},{"name":"min","type":"float"},{"name":"max","type":"float"}],"description":"Clamp the magnitude of the vector between two values"},{"name":"Vector3Equals","returnType":"int","params":[{"name":"p","type":"Vector3"},{"name":"q","type":"Vector3"}],"description":"Check whether two given vectors are almost equal"},{"name":"Vector3Refract","returnType":"Vector3","params":[{"name":"v","type":"Vector3"},{"name":"n","type":"Vector3"},{"name":"r","type":"float"}],"description":"Compute the direction of a refracted ray where v specifies the\nnormalized direction of the incoming ray, n specifies the\nnormalized normal vector of the interface of two optical media,\nand r specifies the ratio of the refractive index of the medium\nfrom where the ray comes to the refractive index of the medium\non the other side of the surface"},{"name":"MatrixDeterminant","returnType":"float","params":[{"name":"mat","type":"Matrix"}],"description":"Compute matrix determinant"},{"name":"MatrixTrace","returnType":"float","params":[{"name":"mat","type":"Matrix"}],"description":"Get the trace of the matrix (sum of the values along the diagonal)"},{"name":"MatrixTranspose","returnType":"Matrix","params":[{"name":"mat","type":"Matrix"}],"description":"Transposes provided matrix"},{"name":"MatrixInvert","returnType":"Matrix","params":[{"name":"mat","type":"Matrix"}],"description":"Invert provided matrix"},{"name":"MatrixIdentity","returnType":"Matrix","params":[],"description":"Get identity matrix"},{"name":"MatrixAdd","returnType":"Matrix","params":[{"name":"left","type":"Matrix"},{"name":"right","type":"Matrix"}],"description":"Add two matrices"},{"name":"MatrixSubtract","returnType":"Matrix","params":[{"name":"left","type":"Matrix"},{"name":"right","type":"Matrix"}],"description":"Subtract two matrices (left - right)"},{"name":"MatrixMultiply","returnType":"Matrix","params":[{"name":"left","type":"Matrix"},{"name":"right","type":"Matrix"}],"description":"Get two matrix multiplication\nNOTE: When multiplying matrices... the order matters!"},{"name":"MatrixTranslate","returnType":"Matrix","params":[{"name":"x","type":"float"},{"name":"y","type":"float"},{"name":"z","type":"float"}],"description":"Get translation matrix"},{"name":"MatrixRotate","returnType":"Matrix","params":[{"name":"axis","type":"Vector3"},{"name":"angle","type":"float"}],"description":"Create rotation matrix from axis and angle\nNOTE: Angle should be provided in radians"},{"name":"MatrixRotateX","returnType":"Matrix","params":[{"name":"angle","type":"float"}],"description":"Get x-rotation matrix\nNOTE: Angle must be provided in radians"},{"name":"MatrixRotateY","returnType":"Matrix","params":[{"name":"angle","type":"float"}],"description":"Get y-rotation matrix\nNOTE: Angle must be provided in radians"},{"name":"MatrixRotateZ","returnType":"Matrix","params":[{"name":"angle","type":"float"}],"description":"Get z-rotation matrix\nNOTE: Angle must be provided in radians"},{"name":"MatrixRotateXYZ","returnType":"Matrix","params":[{"name":"angle","type":"Vector3"}],"description":"Get xyz-rotation matrix\nNOTE: Angle must be provided in radians"},{"name":"MatrixRotateZYX","returnType":"Matrix","params":[{"name":"angle","type":"Vector3"}],"description":"Get zyx-rotation matrix\nNOTE: Angle must be provided in radians"},{"name":"MatrixScale","returnType":"Matrix","params":[{"name":"x","type":"float"},{"name":"y","type":"float"},{"name":"z","type":"float"}],"description":"Get scaling matrix"},{"name":"MatrixFrustum","returnType":"Matrix","params":[{"name":"left","type":"double"},{"name":"right","type":"double"},{"name":"bottom","type":"double"},{"name":"top","type":"double"},{"name":"near","type":"double"},{"name":"far","type":"double"}],"description":"Get perspective projection matrix"},{"name":"MatrixPerspective","returnType":"Matrix","params":[{"name":"fovy","type":"double"},{"name":"aspect","type":"double"},{"name":"near","type":"double"},{"name":"far","type":"double"}],"description":"Get perspective projection matrix\nNOTE: Fovy angle must be provided in radians"},{"name":"MatrixOrtho","returnType":"Matrix","params":[{"name":"left","type":"double"},{"name":"right","type":"double"},{"name":"bottom","type":"double"},{"name":"top","type":"double"},{"name":"near","type":"double"},{"name":"far","type":"double"}],"description":"Get orthographic projection matrix"},{"name":"MatrixLookAt","returnType":"Matrix","params":[{"name":"eye","type":"Vector3"},{"name":"target","type":"Vector3"},{"name":"up","type":"Vector3"}],"description":"Get camera look-at matrix (view matrix)"},{"name":"MatrixToFloatV","returnType":"float16","params":[{"name":"mat","type":"Matrix"}],"description":"Get float array of matrix data"},{"name":"QuaternionAdd","returnType":"Quaternion","params":[{"name":"q1","type":"Quaternion"},{"name":"q2","type":"Quaternion"}],"description":"Add two quaternions"},{"name":"QuaternionAddValue","returnType":"Quaternion","params":[{"name":"q","type":"Quaternion"},{"name":"add","type":"float"}],"description":"Add quaternion and float value"},{"name":"QuaternionSubtract","returnType":"Quaternion","params":[{"name":"q1","type":"Quaternion"},{"name":"q2","type":"Quaternion"}],"description":"Subtract two quaternions"},{"name":"QuaternionSubtractValue","returnType":"Quaternion","params":[{"name":"q","type":"Quaternion"},{"name":"sub","type":"float"}],"description":"Subtract quaternion and float value"},{"name":"QuaternionIdentity","returnType":"Quaternion","params":[],"description":"Get identity quaternion"},{"name":"QuaternionLength","returnType":"float","params":[{"name":"q","type":"Quaternion"}],"description":"Computes the length of a quaternion"},{"name":"QuaternionNormalize","returnType":"Quaternion","params":[{"name":"q","type":"Quaternion"}],"description":"Normalize provided quaternion"},{"name":"QuaternionInvert","returnType":"Quaternion","params":[{"name":"q","type":"Quaternion"}],"description":"Invert provided quaternion"},{"name":"QuaternionMultiply","returnType":"Quaternion","params":[{"name":"q1","type":"Quaternion"},{"name":"q2","type":"Quaternion"}],"description":"Calculate two quaternion multiplication"},{"name":"QuaternionScale","returnType":"Quaternion","params":[{"name":"q","type":"Quaternion"},{"name":"mul","type":"float"}],"description":"Scale quaternion by float value"},{"name":"QuaternionDivide","returnType":"Quaternion","params":[{"name":"q1","type":"Quaternion"},{"name":"q2","type":"Quaternion"}],"description":"Divide two quaternions"},{"name":"QuaternionLerp","returnType":"Quaternion","params":[{"name":"q1","type":"Quaternion"},{"name":"q2","type":"Quaternion"},{"name":"amount","type":"float"}],"description":"Calculate linear interpolation between two quaternions"},{"name":"QuaternionNlerp","returnType":"Quaternion","params":[{"name":"q1","type":"Quaternion"},{"name":"q2","type":"Quaternion"},{"name":"amount","type":"float"}],"description":"Calculate slerp-optimized interpolation between two quaternions"},{"name":"QuaternionSlerp","returnType":"Quaternion","params":[{"name":"q1","type":"Quaternion"},{"name":"q2","type":"Quaternion"},{"name":"amount","type":"float"}],"description":"Calculates spherical linear interpolation between two quaternions"},{"name":"QuaternionFromVector3ToVector3","returnType":"Quaternion","params":[{"name":"from","type":"Vector3"},{"name":"to","type":"Vector3"}],"description":"Calculate quaternion based on the rotation from one vector to another"},{"name":"QuaternionFromMatrix","returnType":"Quaternion","params":[{"name":"mat","type":"Matrix"}],"description":"Get a quaternion for a given rotation matrix"},{"name":"QuaternionToMatrix","returnType":"Matrix","params":[{"name":"q","type":"Quaternion"}],"description":"Get a matrix for a given quaternion"},{"name":"QuaternionFromAxisAngle","returnType":"Quaternion","params":[{"name":"axis","type":"Vector3"},{"name":"angle","type":"float"}],"description":"Get rotation quaternion for an angle and axis\nNOTE: Angle must be provided in radians"},{"name":"QuaternionToAxisAngle","returnType":"void","params":[{"name":"q","type":"Quaternion"},{"name":"outAxis","type":"Vector3 *"},{"name":"outAngle","type":"float *"}],"description":"Get the rotation angle and axis for a given quaternion"},{"name":"QuaternionFromEuler","returnType":"Quaternion","params":[{"name":"pitch","type":"float"},{"name":"yaw","type":"float"},{"name":"roll","type":"float"}],"description":"Get the quaternion equivalent to Euler angles\nNOTE: Rotation order is ZYX"},{"name":"QuaternionToEuler","returnType":"Vector3","params":[{"name":"q","type":"Quaternion"}],"description":"Get the Euler angles equivalent to quaternion (roll, pitch, yaw)\nNOTE: Angles are returned in a Vector3 struct in radians"},{"name":"QuaternionTransform","returnType":"Quaternion","params":[{"name":"q","type":"Quaternion"},{"name":"mat","type":"Matrix"}],"description":"Transform a quaternion given a transformation matrix"},{"name":"QuaternionEquals","returnType":"int","params":[{"name":"p","type":"Quaternion"},{"name":"q","type":"Quaternion"}],"description":"Check whether two given quaternions are almost equal"}] \ No newline at end of file diff --git a/bindings/src/index.ts b/bindings/src/index.ts index fa34866..f87a0fc 100644 --- a/bindings/src/index.ts +++ b/bindings/src/index.ts @@ -3,9 +3,10 @@ import { RayLibApi, RayLibFunction, RayLibType } from "./interfaces"; import { ApiDescription, ApiFunction } from "./api"; import { RayLibHeader } from "./raylib-header"; -function parseMathHeader(): RayLibFunction[] { - const i = readFileSync("thirdparty/raylib/src/raymath.h", 'utf8') - const m = [...i.matchAll(/((?:\/\/ .+\n)*)RMAPI\s+([\w<>]+)\s+([\w<>]+)\((.*)\)/gm)] +function parseHeader(path: string, prefix: string): RayLibFunction[] { + const i = readFileSync(path, 'utf8') + const regex = new RegExp(`((?:\\/\\/ .+\\n)*)${prefix}\\s+([\\w<>]+)\\s+([\\w<>]+)\\((.*)\\)`, 'gm') + const m = [...i.matchAll(regex)] const res = m.map(groups => { const args = groups[4].split(',').filter(x => x !== 'void').map(arg => { arg = arg.trim().replace(" *", "* ") @@ -37,12 +38,20 @@ function main(){ returnType: "void", params: [{type: "Model *",name:"model"},{type:"int",name:"materialIndex"},{type:"Material",name:"material"}] }) - const mathApi = parseMathHeader(); - writeFileSync("bindings/raylib_math_api.json", JSON.stringify(mathApi)) + + const mathApi = parseHeader("thirdparty/raylib/src/raymath.h", "RMAPI"); mathApi.forEach(x => api.functions.push(x)) + + const cameraApi = parseHeader("thirdparty/raylib/src/rcamera.h", "RLAPI"); + //cameraApi.forEach(x => console.log(`core.addApiFunctionByName("${x.name}")`)) + cameraApi.forEach(x => api.functions.push(x)) const apiDesc = new ApiDescription(api) + const core = new RayLibHeader("raylib_core", apiDesc) + core.includes.include("raymath.h") + core.includes.include("rcamera.h") + core.addApiStructByName("Color", { properties: { r: { get: true, set: true }, @@ -1013,6 +1022,22 @@ function main(){ core.addApiFunctionByName("QuaternionToEuler") core.addApiFunctionByName("QuaternionTransform") core.addApiFunctionByName("QuaternionEquals") + core.exportGlobalConstant("DEG2RAD", "(PI/180.0)") + core.exportGlobalConstant("RAD2DEG", "(180.0/PI)") + + // module: rcamera + core.addApiFunctionByName("GetCameraForward") + core.addApiFunctionByName("GetCameraUp") + core.addApiFunctionByName("GetCameraRight") + core.addApiFunctionByName("CameraMoveForward") + core.addApiFunctionByName("CameraMoveUp") + core.addApiFunctionByName("CameraMoveRight") + core.addApiFunctionByName("CameraMoveToTarget") + core.addApiFunctionByName("CameraYaw") + core.addApiFunctionByName("CameraPitch") + core.addApiFunctionByName("CameraRoll") + core.addApiFunctionByName("GetCameraViewMatrix") + core.addApiFunctionByName("GetCameraProjectionMatrix") api.defines.filter(x => x.type === "COLOR").map(x => ({ name: x.name, description: x.description, values: (x.value.match(/\{([^}]+)\}/) || "")[1].split(',').map(x => x.trim()) })).forEach(x => { core.exportGlobalStruct("Color", x.name, x.values, x.description) diff --git a/bindings/src/raylib-header.ts b/bindings/src/raylib-header.ts index 60ee4fc..aa47cf2 100644 --- a/bindings/src/raylib-header.ts +++ b/bindings/src/raylib-header.ts @@ -26,7 +26,7 @@ export class RayLibHeader extends QuickJsHeader { super(name) this.includes.include("raylib.h") //this.includes.line("#define RAYMATH_IMPLEMENTATION") - this.includes.include("raymath.h") + } addApiFunction(api: ApiFunction, jsName: string | null = null, options: FuncBindingOptions = {}){ diff --git a/examples/core/core_3d_camera_first_person.c b/examples/core/core_3d_camera_first_person.c deleted file mode 100644 index 6a2a115..0000000 --- a/examples/core/core_3d_camera_first_person.c +++ /dev/null @@ -1,206 +0,0 @@ -/******************************************************************************************* -* -* raylib [core] example - 3d camera first person -* -* Example originally created with raylib 1.3, last time updated with raylib 1.3 -* -* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, -* BSD-like license that allows static linking with closed source software -* -* Copyright (c) 2015-2023 Ramon Santamaria (@raysan5) -* -********************************************************************************************/ - -#include "raylib.h" -#include "rcamera.h" - -#define MAX_COLUMNS 20 - -//------------------------------------------------------------------------------------ -// Program main entry point -//------------------------------------------------------------------------------------ -int main(void) -{ - // Initialization - //-------------------------------------------------------------------------------------- - const int screenWidth = 800; - const int screenHeight = 450; - - InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera first person"); - - // Define the camera to look into our 3d world (position, target, up vector) - Camera camera = { 0 }; - camera.position = (Vector3){ 0.0f, 2.0f, 4.0f }; // Camera position - camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; // Camera looking at point - camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) - camera.fovy = 60.0f; // Camera field-of-view Y - camera.projection = CAMERA_PERSPECTIVE; // Camera projection type - - int cameraMode = CAMERA_FIRST_PERSON; - - // Generates some random columns - float heights[MAX_COLUMNS] = { 0 }; - Vector3 positions[MAX_COLUMNS] = { 0 }; - Color colors[MAX_COLUMNS] = { 0 }; - - for (int i = 0; i < MAX_COLUMNS; i++) - { - heights[i] = (float)GetRandomValue(1, 12); - positions[i] = (Vector3){ (float)GetRandomValue(-15, 15), heights[i]/2.0f, (float)GetRandomValue(-15, 15) }; - colors[i] = (Color){ GetRandomValue(20, 255), GetRandomValue(10, 55), 30, 255 }; - } - - DisableCursor(); // Limit cursor to relative movement inside the window - - SetTargetFPS(60); // Set our game to run at 60 frames-per-second - //-------------------------------------------------------------------------------------- - - // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key - { - // Update - //---------------------------------------------------------------------------------- - // Switch camera mode - if (IsKeyPressed(KEY_ONE)) - { - cameraMode = CAMERA_FREE; - camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Reset roll - } - - if (IsKeyPressed(KEY_TWO)) - { - cameraMode = CAMERA_FIRST_PERSON; - camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Reset roll - } - - if (IsKeyPressed(KEY_THREE)) - { - cameraMode = CAMERA_THIRD_PERSON; - camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Reset roll - } - - if (IsKeyPressed(KEY_FOUR)) - { - cameraMode = CAMERA_ORBITAL; - camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Reset roll - } - - // Switch camera projection - if (IsKeyPressed(KEY_P)) - { - if (camera.projection == CAMERA_PERSPECTIVE) - { - // Create isometric view - cameraMode = CAMERA_THIRD_PERSON; - // Note: The target distance is related to the render distance in the orthographic projection - camera.position = (Vector3){ 0.0f, 2.0f, -100.0f }; - camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; - camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; - camera.projection = CAMERA_ORTHOGRAPHIC; - camera.fovy = 20.0f; // near plane width in CAMERA_ORTHOGRAPHIC - CameraYaw(&camera, -135 * DEG2RAD, true); - CameraPitch(&camera, -45 * DEG2RAD, true, true, false); - } - else if (camera.projection == CAMERA_ORTHOGRAPHIC) - { - // Reset to default view - cameraMode = CAMERA_THIRD_PERSON; - camera.position = (Vector3){ 0.0f, 2.0f, 10.0f }; - camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; - camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; - camera.projection = CAMERA_PERSPECTIVE; - camera.fovy = 60.0f; - } - } - - // Update camera computes movement internally depending on the camera mode - // Some default standard keyboard/mouse inputs are hardcoded to simplify use - // For advance camera controls, it's reecommended to compute camera movement manually - UpdateCamera(&camera, cameraMode); // Update camera - -/* - // Camera PRO usage example (EXPERIMENTAL) - // This new camera function allows custom movement/rotation values to be directly provided - // as input parameters, with this approach, rcamera module is internally independent of raylib inputs - UpdateCameraPro(&camera, - (Vector3){ - (IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - // Move forward-backward - (IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f, - (IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - // Move right-left - (IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f, - 0.0f // Move up-down - }, - (Vector3){ - GetMouseDelta().x*0.05f, // Rotation: yaw - GetMouseDelta().y*0.05f, // Rotation: pitch - 0.0f // Rotation: roll - }, - GetMouseWheelMove()*2.0f); // Move to target (zoom) -*/ - //---------------------------------------------------------------------------------- - - // Draw - //---------------------------------------------------------------------------------- - BeginDrawing(); - - ClearBackground(RAYWHITE); - - BeginMode3D(camera); - - DrawPlane((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector2){ 32.0f, 32.0f }, LIGHTGRAY); // Draw ground - DrawCube((Vector3){ -16.0f, 2.5f, 0.0f }, 1.0f, 5.0f, 32.0f, BLUE); // Draw a blue wall - DrawCube((Vector3){ 16.0f, 2.5f, 0.0f }, 1.0f, 5.0f, 32.0f, LIME); // Draw a green wall - DrawCube((Vector3){ 0.0f, 2.5f, 16.0f }, 32.0f, 5.0f, 1.0f, GOLD); // Draw a yellow wall - - // Draw some cubes around - for (int i = 0; i < MAX_COLUMNS; i++) - { - DrawCube(positions[i], 2.0f, heights[i], 2.0f, colors[i]); - DrawCubeWires(positions[i], 2.0f, heights[i], 2.0f, MAROON); - } - - // Draw player cube - if (cameraMode == CAMERA_THIRD_PERSON) - { - DrawCube(camera.target, 0.5f, 0.5f, 0.5f, PURPLE); - DrawCubeWires(camera.target, 0.5f, 0.5f, 0.5f, DARKPURPLE); - } - - EndMode3D(); - - // Draw info boxes - DrawRectangle(5, 5, 330, 100, Fade(SKYBLUE, 0.5f)); - DrawRectangleLines(5, 5, 330, 100, BLUE); - - DrawText("Camera controls:", 15, 15, 10, BLACK); - DrawText("- Move keys: W, A, S, D, Space, Left-Ctrl", 15, 30, 10, BLACK); - DrawText("- Look around: arrow keys or mouse", 15, 45, 10, BLACK); - DrawText("- Camera mode keys: 1, 2, 3, 4", 15, 60, 10, BLACK); - DrawText("- Zoom keys: num-plus, num-minus or mouse scroll", 15, 75, 10, BLACK); - DrawText("- Camera projection key: P", 15, 90, 10, BLACK); - - DrawRectangle(600, 5, 195, 100, Fade(SKYBLUE, 0.5f)); - DrawRectangleLines(600, 5, 195, 100, BLUE); - - DrawText("Camera status:", 610, 15, 10, BLACK); - DrawText(TextFormat("- Mode: %s", (cameraMode == CAMERA_FREE) ? "FREE" : - (cameraMode == CAMERA_FIRST_PERSON) ? "FIRST_PERSON" : - (cameraMode == CAMERA_THIRD_PERSON) ? "THIRD_PERSON" : - (cameraMode == CAMERA_ORBITAL) ? "ORBITAL" : "CUSTOM"), 610, 30, 10, BLACK); - DrawText(TextFormat("- Projection: %s", (camera.projection == CAMERA_PERSPECTIVE) ? "PERSPECTIVE" : - (camera.projection == CAMERA_ORTHOGRAPHIC) ? "ORTHOGRAPHIC" : "CUSTOM"), 610, 45, 10, BLACK); - DrawText(TextFormat("- Position: (%06.3f, %06.3f, %06.3f)", camera.position.x, camera.position.y, camera.position.z), 610, 60, 10, BLACK); - DrawText(TextFormat("- Target: (%06.3f, %06.3f, %06.3f)", camera.target.x, camera.target.y, camera.target.z), 610, 75, 10, BLACK); - DrawText(TextFormat("- Up: (%06.3f, %06.3f, %06.3f)", camera.up.x, camera.up.y, camera.up.z), 610, 90, 10, BLACK); - - EndDrawing(); - //---------------------------------------------------------------------------------- - } - - // De-Initialization - //-------------------------------------------------------------------------------------- - CloseWindow(); // Close window and OpenGL context - //-------------------------------------------------------------------------------------- - - return 0; -} \ No newline at end of file diff --git a/examples/core/core_3d_camera_first_person.js b/examples/core/core_3d_camera_first_person.js new file mode 100644 index 0000000..74a33b9 --- /dev/null +++ b/examples/core/core_3d_camera_first_person.js @@ -0,0 +1,195 @@ +/******************************************************************************************* +* +* raylib [core] example - 3d camera first person +* +* Example originally created with raylib 1.3, last time updated with raylib 1.3 +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2015-2023 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +const MAX_COLUMNS = 20; + +// Initialization +//-------------------------------------------------------------------------------------- +const screenWidth = 800; +const screenHeight = 450; + +initWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera first person"); + +// Define the camera to look into our 3d world (position, target, up vector) +const position = new Vector3(0.0, 2.0, 4.0); // Camera position +const target = new Vector3(0.0, 2.0, 0.0); // Camera looking at point +const up = new Vector3(0.0, 1.0, 0.0); // Camera up vector (rotation towards target) +const fovy = 60.0; // Camera field-of-view Y +const projection = CAMERA_PERSPECTIVE; // Camera projection type +const camera = new Camera3D(position,target, up, fovy, projection); + +let cameraMode = CAMERA_FIRST_PERSON; + +// Generates some random columns +const heights = new Array(MAX_COLUMNS); +const positions = new Array(MAX_COLUMNS); +const colors = new Array(MAX_COLUMNS); + +for (let i = 0; i < MAX_COLUMNS; i++) +{ + heights[i] = getRandomValue(1, 12); + positions[i] = new Vector3(getRandomValue(-15, 15), heights[i]/2.0, getRandomValue(-15, 15)); + colors[i] = new Color(getRandomValue(20, 255), getRandomValue(10, 55), 30, 255); +} + +disableCursor(); // Limit cursor to relative movement inside the window + +setTargetFPS(60); // Set our game to run at 60 frames-per-second +//-------------------------------------------------------------------------------------- + +// Main game loop +while (!windowShouldClose()) // Detect window close button or ESC key +{ + // Update + //---------------------------------------------------------------------------------- + // Switch camera mode + if (isKeyPressed(KEY_ONE)) + { + cameraMode = CAMERA_FREE; + camera.up = new Vector3(0.0, 1.0, 0.0); // Reset roll + } + + if (isKeyPressed(KEY_TWO)) + { + cameraMode = CAMERA_FIRST_PERSON; + camera.up = new Vector3(0.0, 1.0, 0.0); // Reset roll + } + + if (isKeyPressed(KEY_THREE)) + { + cameraMode = CAMERA_THIRD_PERSON; + camera.up = new Vector3(0.0, 1.0, 0.0); // Reset roll + } + + if (isKeyPressed(KEY_FOUR)) + { + cameraMode = CAMERA_ORBITAL; + camera.up = new Vector3(0.0, 1.0, 0.0); // Reset roll + } + + // Switch camera projection + if (isKeyPressed(KEY_P)) + { + if (camera.projection == CAMERA_PERSPECTIVE) + { + // Create isometric view + cameraMode = CAMERA_THIRD_PERSON; + // Note: The target distance is related to the render distance in the orthographic projection + camera.position = new Vector3(0.0, 2.0, -100.0); + camera.target = new Vector3(0.0, 2.0, 0.0); + camera.up = new Vector3(0.0, 1.0, 0.0); + camera.projection = CAMERA_ORTHOGRAPHIC; + camera.fovy = 20.0; // near plane width in CAMERA_ORTHOGRAPHIC + cameraYaw(camera, -135 * DEG2RAD, true); + cameraPitch(camera, -45 * DEG2RAD, true, true, false); + } + else if (camera.projection == CAMERA_ORTHOGRAPHIC) + { + // Reset to default view + cameraMode = CAMERA_THIRD_PERSON; + camera.position = new Vector3(0.0, 2.0, 10.0); + camera.target = new Vector3(0.0, 2.0, 0.0); + camera.up = new Vector3(0.0, 1.0, 0.0); + camera.projection = CAMERA_PERSPECTIVE; + camera.fovy = 60.0; + } + } + + // Update camera computes movement internally depending on the camera mode + // Some default standard keyboard/mouse inputs are hardcoded to simplify use + // For advance camera controls, it's recommended to compute camera movement manually + updateCamera(camera, cameraMode); // Update camera + +/* + // Camera PRO usage example (EXPERIMENTAL) + // This new camera function allows custom movement/rotation values to be directly provided + // as input parameters, with this approach, rcamera module is internally independent of raylib inputs + UpdateCameraPro(&camera, + (Vector3){ + (IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - // Move forward-backward + (IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f, + (IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - // Move right-left + (IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f, + 0.0f // Move up-down + }, + (Vector3){ + GetMouseDelta().x*0.05f, // Rotation: yaw + GetMouseDelta().y*0.05f, // Rotation: pitch + 0.0f // Rotation: roll + }, + GetMouseWheelMove()*2.0f); // Move to target (zoom) +*/ + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + beginDrawing(); + + clearBackground(RAYWHITE); + + beginMode3D(camera); + + drawPlane(new Vector3(0.0, 0.0, 0.0), new Vector2(32.0, 32.0), LIGHTGRAY); // Draw ground + drawCube(new Vector3(-16.0, 2.5, 0.0), 1.0, 5.0, 32.0, BLUE); // Draw a blue wall + drawCube(new Vector3(16.0, 2.5, 0.0), 1.0, 5.0, 32.0, LIME); // Draw a green wall + drawCube(new Vector3(0.0, 2.5, 16.0), 32.0, 5.0, 1.0, GOLD); // Draw a yellow wall + + // Draw some cubes around + for (let i = 0; i < MAX_COLUMNS; i++) + { + drawCube(positions[i], 2.0, heights[i], 2.0, colors[i]); + drawCubeWires(positions[i], 2.0, heights[i], 2.0, MAROON); + } + + // Draw player cube + if (cameraMode == CAMERA_THIRD_PERSON) + { + drawCube(camera.target, 0.5, 0.5, 0.5, PURPLE); + drawCubeWires(camera.target, 0.5, 0.5, 0.5, DARKPURPLE); + } + + endMode3D(); + + // Draw info boxes + drawRectangle(5, 5, 330, 100, fade(SKYBLUE, 0.5)); + drawRectangleLines(5, 5, 330, 100, BLUE); + + drawText("Camera controls:", 15, 15, 10, BLACK); + drawText("- Move keys: W, A, S, D, Space, Left-Ctrl", 15, 30, 10, BLACK); + drawText("- Look around: arrow keys or mouse", 15, 45, 10, BLACK); + drawText("- Camera mode keys: 1, 2, 3, 4", 15, 60, 10, BLACK); + drawText("- Zoom keys: num-plus, num-minus or mouse scroll", 15, 75, 10, BLACK); + drawText("- Camera projection key: P", 15, 90, 10, BLACK); + + drawRectangle(600, 5, 195, 100, fade(SKYBLUE, 0.5)); + drawRectangleLines(600, 5, 195, 100, BLUE); + + drawText("Camera status:", 610, 15, 10, BLACK); + drawText("- Mode: " + (cameraMode == CAMERA_FREE) ? "FREE" : + (cameraMode == CAMERA_FIRST_PERSON) ? "FIRST_PERSON" : + (cameraMode == CAMERA_THIRD_PERSON) ? "THIRD_PERSON" : + (cameraMode == CAMERA_ORBITAL) ? "ORBITAL" : "CUSTOM", 610, 30, 10, BLACK); + drawText("- Projection: " + (camera.projection == CAMERA_PERSPECTIVE) ? "PERSPECTIVE" : + (camera.projection == CAMERA_ORTHOGRAPHIC) ? "ORTHOGRAPHIC" : "CUSTOM", 610, 45, 10, BLACK); + drawText(`- Position: ${camera.position.x}, ${camera.position.y}, ${camera.position.z}`, 610, 60, 10, BLACK); + //DrawText(TextFormat("- Target: (%06.3f, %06.3f, %06.3f)", camera.target.x, camera.target.y, camera.target.z), 610, 75, 10, BLACK); + //DrawText(TextFormat("- Up: (%06.3f, %06.3f, %06.3f)", camera.up.x, camera.up.y, camera.up.z), 610, 90, 10, BLACK); + + endDrawing(); + //---------------------------------------------------------------------------------- +} + +// De-Initialization +//-------------------------------------------------------------------------------------- +closeWindow(); // Close window and OpenGL context +//-------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/examples/lib.raylib.d.ts b/examples/lib.raylib.d.ts index 05d892c..8a342e1 100644 --- a/examples/lib.raylib.d.ts +++ b/examples/lib.raylib.d.ts @@ -1360,6 +1360,34 @@ declare function quaternionToEuler(q: Vector4): Vector3; declare function quaternionTransform(q: Vector4, mat: Matrix): Vector4; /** Check whether two given quaternions are almost equal */ declare function quaternionEquals(p: Vector4, q: Vector4): number; +/** */ +declare function getCameraForward(camera: Camera3D): Vector3; +/** */ +declare function getCameraUp(camera: Camera3D): Vector3; +/** */ +declare function getCameraRight(camera: Camera3D): Vector3; +/** Camera movement */ +declare function cameraMoveForward(camera: Camera3D, distance: number, moveInWorldPlane: boolean): void; +/** */ +declare function cameraMoveUp(camera: Camera3D, distance: number): void; +/** */ +declare function cameraMoveRight(camera: Camera3D, distance: number, moveInWorldPlane: boolean): void; +/** */ +declare function cameraMoveToTarget(camera: Camera3D, delta: number): void; +/** Camera rotation */ +declare function cameraYaw(camera: Camera3D, angle: number, rotateAroundTarget: boolean): void; +/** */ +declare function cameraPitch(camera: Camera3D, angle: number, lockView: boolean, rotateAroundTarget: boolean, rotateUp: boolean): void; +/** */ +declare function cameraRoll(camera: Camera3D, angle: number): void; +/** */ +declare function getCameraViewMatrix(camera: Camera3D): Matrix; +/** */ +declare function getCameraProjectionMatrix(camera: Camera3D, aspect: number): Matrix; +/** (PI/180.0) */ +declare var DEG2RAD: number; +/** (180.0/PI) */ +declare var RAD2DEG: number; /** Light Gray */ declare var LIGHTGRAY: Color; /** Gray */ diff --git a/generate-bindings.js b/generate-bindings.js index 0d81e8b..3f04a63 100644 --- a/generate-bindings.js +++ b/generate-bindings.js @@ -620,7 +620,6 @@ class RayLibHeader extends quickjs_1.QuickJsHeader { this.typings = new typescript_1.TypeScriptDeclaration(); this.includes.include("raylib.h"); //this.includes.line("#define RAYMATH_IMPLEMENTATION") - this.includes.include("raymath.h"); } addApiFunction(api, jsName = null, options = {}) { const jName = jsName || api.name.charAt(0).toLowerCase() + api.name.slice(1); @@ -896,9 +895,10 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); const fs_1 = __webpack_require__(/*! fs */ "fs"); const api_1 = __webpack_require__(/*! ./api */ "./src/api.ts"); const raylib_header_1 = __webpack_require__(/*! ./raylib-header */ "./src/raylib-header.ts"); -function parseMathHeader() { - const i = (0, fs_1.readFileSync)("thirdparty/raylib/src/raymath.h", 'utf8'); - const m = [...i.matchAll(/((?:\/\/ .+\n)*)RMAPI\s+([\w<>]+)\s+([\w<>]+)\((.*)\)/gm)]; +function parseHeader(path, prefix) { + const i = (0, fs_1.readFileSync)(path, 'utf8'); + const regex = new RegExp(`((?:\\/\\/ .+\\n)*)${prefix}\\s+([\\w<>]+)\\s+([\\w<>]+)\\((.*)\\)`, 'gm'); + const m = [...i.matchAll(regex)]; const res = m.map(groups => { const args = groups[4].split(',').filter(x => x !== 'void').map(arg => { arg = arg.trim().replace(" *", "* "); @@ -926,11 +926,15 @@ function main() { returnType: "void", params: [{ type: "Model *", name: "model" }, { type: "int", name: "materialIndex" }, { type: "Material", name: "material" }] }); - const mathApi = parseMathHeader(); - (0, fs_1.writeFileSync)("bindings/raylib_math_api.json", JSON.stringify(mathApi)); + const mathApi = parseHeader("thirdparty/raylib/src/raymath.h", "RMAPI"); mathApi.forEach(x => api.functions.push(x)); + const cameraApi = parseHeader("thirdparty/raylib/src/rcamera.h", "RLAPI"); + //cameraApi.forEach(x => console.log(`core.addApiFunctionByName("${x.name}")`)) + cameraApi.forEach(x => api.functions.push(x)); const apiDesc = new api_1.ApiDescription(api); const core = new raylib_header_1.RayLibHeader("raylib_core", apiDesc); + core.includes.include("raymath.h"); + core.includes.include("rcamera.h"); core.addApiStructByName("Color", { properties: { r: { get: true, set: true }, @@ -1846,6 +1850,21 @@ function main() { core.addApiFunctionByName("QuaternionToEuler"); core.addApiFunctionByName("QuaternionTransform"); core.addApiFunctionByName("QuaternionEquals"); + core.exportGlobalConstant("DEG2RAD", "(PI/180.0)"); + core.exportGlobalConstant("RAD2DEG", "(180.0/PI)"); + // module: rcamera + core.addApiFunctionByName("GetCameraForward"); + core.addApiFunctionByName("GetCameraUp"); + core.addApiFunctionByName("GetCameraRight"); + core.addApiFunctionByName("CameraMoveForward"); + core.addApiFunctionByName("CameraMoveUp"); + core.addApiFunctionByName("CameraMoveRight"); + core.addApiFunctionByName("CameraMoveToTarget"); + core.addApiFunctionByName("CameraYaw"); + core.addApiFunctionByName("CameraPitch"); + core.addApiFunctionByName("CameraRoll"); + core.addApiFunctionByName("GetCameraViewMatrix"); + core.addApiFunctionByName("GetCameraProjectionMatrix"); api.defines.filter(x => x.type === "COLOR").map(x => ({ name: x.name, description: x.description, values: (x.value.match(/\{([^}]+)\}/) || "")[1].split(',').map(x => x.trim()) })).forEach(x => { core.exportGlobalStruct("Color", x.name, x.values, x.description); }); diff --git a/src/bindings/js_raylib_core.h b/src/bindings/js_raylib_core.h index 164ec54..faa796d 100644 --- a/src/bindings/js_raylib_core.h +++ b/src/bindings/js_raylib_core.h @@ -8,6 +8,7 @@ #include #include #include +#include #ifndef countof #define countof(x) (sizeof(x) / sizeof((x)[0])) @@ -8327,6 +8328,140 @@ static JSValue js_quaternionEquals(JSContext * ctx, JSValueConst this_val, int a return ret; } +static JSValue js_getCameraForward(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Camera* camera = (Camera*)JS_GetOpaque2(ctx, argv[0], js_Camera3D_class_id); + if(camera == NULL) return JS_EXCEPTION; + Vector3 returnVal = GetCameraForward(camera); + Vector3* ret_ptr = (Vector3*)js_malloc(ctx, sizeof(Vector3)); + *ret_ptr = returnVal; + JSValue ret = JS_NewObjectClass(ctx, js_Vector3_class_id); + JS_SetOpaque(ret, ret_ptr); + return ret; +} + +static JSValue js_getCameraUp(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Camera* camera = (Camera*)JS_GetOpaque2(ctx, argv[0], js_Camera3D_class_id); + if(camera == NULL) return JS_EXCEPTION; + Vector3 returnVal = GetCameraUp(camera); + Vector3* ret_ptr = (Vector3*)js_malloc(ctx, sizeof(Vector3)); + *ret_ptr = returnVal; + JSValue ret = JS_NewObjectClass(ctx, js_Vector3_class_id); + JS_SetOpaque(ret, ret_ptr); + return ret; +} + +static JSValue js_getCameraRight(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Camera* camera = (Camera*)JS_GetOpaque2(ctx, argv[0], js_Camera3D_class_id); + if(camera == NULL) return JS_EXCEPTION; + Vector3 returnVal = GetCameraRight(camera); + Vector3* ret_ptr = (Vector3*)js_malloc(ctx, sizeof(Vector3)); + *ret_ptr = returnVal; + JSValue ret = JS_NewObjectClass(ctx, js_Vector3_class_id); + JS_SetOpaque(ret, ret_ptr); + return ret; +} + +static JSValue js_cameraMoveForward(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Camera* camera = (Camera*)JS_GetOpaque2(ctx, argv[0], js_Camera3D_class_id); + if(camera == NULL) return JS_EXCEPTION; + double _double_distance; + JS_ToFloat64(ctx, &_double_distance, argv[1]); + float distance = (float)_double_distance; + bool moveInWorldPlane = JS_ToBool(ctx, argv[2]); + CameraMoveForward(camera, distance, moveInWorldPlane); + return JS_UNDEFINED; +} + +static JSValue js_cameraMoveUp(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Camera* camera = (Camera*)JS_GetOpaque2(ctx, argv[0], js_Camera3D_class_id); + if(camera == NULL) return JS_EXCEPTION; + double _double_distance; + JS_ToFloat64(ctx, &_double_distance, argv[1]); + float distance = (float)_double_distance; + CameraMoveUp(camera, distance); + return JS_UNDEFINED; +} + +static JSValue js_cameraMoveRight(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Camera* camera = (Camera*)JS_GetOpaque2(ctx, argv[0], js_Camera3D_class_id); + if(camera == NULL) return JS_EXCEPTION; + double _double_distance; + JS_ToFloat64(ctx, &_double_distance, argv[1]); + float distance = (float)_double_distance; + bool moveInWorldPlane = JS_ToBool(ctx, argv[2]); + CameraMoveRight(camera, distance, moveInWorldPlane); + return JS_UNDEFINED; +} + +static JSValue js_cameraMoveToTarget(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Camera* camera = (Camera*)JS_GetOpaque2(ctx, argv[0], js_Camera3D_class_id); + if(camera == NULL) return JS_EXCEPTION; + double _double_delta; + JS_ToFloat64(ctx, &_double_delta, argv[1]); + float delta = (float)_double_delta; + CameraMoveToTarget(camera, delta); + return JS_UNDEFINED; +} + +static JSValue js_cameraYaw(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Camera* camera = (Camera*)JS_GetOpaque2(ctx, argv[0], js_Camera3D_class_id); + if(camera == NULL) return JS_EXCEPTION; + double _double_angle; + JS_ToFloat64(ctx, &_double_angle, argv[1]); + float angle = (float)_double_angle; + bool rotateAroundTarget = JS_ToBool(ctx, argv[2]); + CameraYaw(camera, angle, rotateAroundTarget); + return JS_UNDEFINED; +} + +static JSValue js_cameraPitch(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Camera* camera = (Camera*)JS_GetOpaque2(ctx, argv[0], js_Camera3D_class_id); + if(camera == NULL) return JS_EXCEPTION; + double _double_angle; + JS_ToFloat64(ctx, &_double_angle, argv[1]); + float angle = (float)_double_angle; + bool lockView = JS_ToBool(ctx, argv[2]); + bool rotateAroundTarget = JS_ToBool(ctx, argv[3]); + bool rotateUp = JS_ToBool(ctx, argv[4]); + CameraPitch(camera, angle, lockView, rotateAroundTarget, rotateUp); + return JS_UNDEFINED; +} + +static JSValue js_cameraRoll(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Camera* camera = (Camera*)JS_GetOpaque2(ctx, argv[0], js_Camera3D_class_id); + if(camera == NULL) return JS_EXCEPTION; + double _double_angle; + JS_ToFloat64(ctx, &_double_angle, argv[1]); + float angle = (float)_double_angle; + CameraRoll(camera, angle); + return JS_UNDEFINED; +} + +static JSValue js_getCameraViewMatrix(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Camera* camera = (Camera*)JS_GetOpaque2(ctx, argv[0], js_Camera3D_class_id); + if(camera == NULL) return JS_EXCEPTION; + Matrix returnVal = GetCameraViewMatrix(camera); + Matrix* ret_ptr = (Matrix*)js_malloc(ctx, sizeof(Matrix)); + *ret_ptr = returnVal; + JSValue ret = JS_NewObjectClass(ctx, js_Matrix_class_id); + JS_SetOpaque(ret, ret_ptr); + return ret; +} + +static JSValue js_getCameraProjectionMatrix(JSContext * ctx, JSValueConst this_val, int argc, JSValueConst * argv) { + Camera* camera = (Camera*)JS_GetOpaque2(ctx, argv[0], js_Camera3D_class_id); + if(camera == NULL) return JS_EXCEPTION; + double _double_aspect; + JS_ToFloat64(ctx, &_double_aspect, argv[1]); + float aspect = (float)_double_aspect; + Matrix returnVal = GetCameraProjectionMatrix(camera, aspect); + Matrix* ret_ptr = (Matrix*)js_malloc(ctx, sizeof(Matrix)); + *ret_ptr = returnVal; + JSValue ret = JS_NewObjectClass(ctx, js_Matrix_class_id); + JS_SetOpaque(ret, ret_ptr); + return ret; +} + static const JSCFunctionListEntry js_raylib_core_funcs[] = { JS_CFUNC_DEF("initWindow",3,js_initWindow), JS_CFUNC_DEF("windowShouldClose",0,js_windowShouldClose), @@ -8850,6 +8985,18 @@ static const JSCFunctionListEntry js_raylib_core_funcs[] = { JS_CFUNC_DEF("quaternionToEuler",1,js_quaternionToEuler), JS_CFUNC_DEF("quaternionTransform",2,js_quaternionTransform), JS_CFUNC_DEF("quaternionEquals",2,js_quaternionEquals), + JS_CFUNC_DEF("getCameraForward",1,js_getCameraForward), + JS_CFUNC_DEF("getCameraUp",1,js_getCameraUp), + JS_CFUNC_DEF("getCameraRight",1,js_getCameraRight), + JS_CFUNC_DEF("cameraMoveForward",3,js_cameraMoveForward), + JS_CFUNC_DEF("cameraMoveUp",2,js_cameraMoveUp), + JS_CFUNC_DEF("cameraMoveRight",3,js_cameraMoveRight), + JS_CFUNC_DEF("cameraMoveToTarget",2,js_cameraMoveToTarget), + JS_CFUNC_DEF("cameraYaw",3,js_cameraYaw), + JS_CFUNC_DEF("cameraPitch",5,js_cameraPitch), + JS_CFUNC_DEF("cameraRoll",2,js_cameraRoll), + JS_CFUNC_DEF("getCameraViewMatrix",1,js_getCameraViewMatrix), + JS_CFUNC_DEF("getCameraProjectionMatrix",2,js_getCameraProjectionMatrix), }; static int js_raylib_core_init(JSContext * ctx, JSModuleDef * m) { @@ -8900,6 +9047,8 @@ static int js_raylib_core_init(JSContext * ctx, JSModuleDef * m) { js_declare_RenderTexture(ctx, m); js_declare_MaterialMap(ctx, m); js_declare_Material(ctx, m); + JS_SetModuleExport(ctx, m, "DEG2RAD", JS_NewInt32(ctx, DEG2RAD)); + JS_SetModuleExport(ctx, m, "RAD2DEG", JS_NewInt32(ctx, RAD2DEG)); Color LIGHTGRAY_struct = { 200, 200, 200, 255 }; Color* LIGHTGRAY_js_ptr = (Color*)js_malloc(ctx, sizeof(Color)); *LIGHTGRAY_js_ptr = LIGHTGRAY_struct; @@ -9310,6 +9459,8 @@ JSModuleDef * js_init_module_raylib_core(JSContext * ctx, const char * module_na JS_AddModuleExport(ctx, m, "BoundingBox"); JS_AddModuleExport(ctx, m, "NPatchInfo"); JS_AddModuleExport(ctx, m, "Mesh"); + JS_AddModuleExport(ctx, m, "DEG2RAD"); + JS_AddModuleExport(ctx, m, "RAD2DEG"); JS_AddModuleExport(ctx, m, "LIGHTGRAY"); JS_AddModuleExport(ctx, m, "GRAY"); JS_AddModuleExport(ctx, m, "DARKGRAY");