add test data, fix makefile
This commit is contained in:
		
							parent
							
								
									0cdfc7e786
								
							
						
					
					
						commit
						37164dc33c
					
				
							
								
								
									
										29
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										29
									
								
								Makefile
								
								
								
								
							| 
						 | 
				
			
			@ -29,11 +29,11 @@
 | 
			
		|||
PLATFORM              ?= PLATFORM_DESKTOP
 | 
			
		||||
 | 
			
		||||
# Define project variables
 | 
			
		||||
PROJECT_NAME          ?= raylib_game
 | 
			
		||||
PROJECT_NAME          ?= raylib_test
 | 
			
		||||
PROJECT_VERSION       ?= 1.0
 | 
			
		||||
PROJECT_BUILD_PATH    ?= .
 | 
			
		||||
 | 
			
		||||
RAYLIB_PATH           ?= ../../raylib
 | 
			
		||||
RAYLIB_PATH           ?=  ~/lib/raylib
 | 
			
		||||
 | 
			
		||||
# Locations of raylib.h and libraylib.a/libraylib.so
 | 
			
		||||
# NOTE: Those variables are only used for PLATFORM_OS: LINUX, BSD
 | 
			
		||||
| 
						 | 
				
			
			@ -51,7 +51,7 @@ BUILD_MODE            ?= RELEASE
 | 
			
		|||
USE_WAYLAND_DISPLAY   ?= FALSE
 | 
			
		||||
 | 
			
		||||
# PLATFORM_WEB: Default properties
 | 
			
		||||
BUILD_WEB_ASYNCIFY    ?= FALSE
 | 
			
		||||
BUILD_WEB_ASYNCIFY    ?= TRUE
 | 
			
		||||
BUILD_WEB_SHELL       ?= minshell.html
 | 
			
		||||
BUILD_WEB_HEAP_SIZE   ?= 134217728
 | 
			
		||||
BUILD_WEB_RESOURCES   ?= TRUE
 | 
			
		||||
| 
						 | 
				
			
			@ -149,18 +149,6 @@ endif
 | 
			
		|||
# Define raylib release directory for compiled library
 | 
			
		||||
RAYLIB_RELEASE_PATH 	?= $(RAYLIB_PATH)/src
 | 
			
		||||
 | 
			
		||||
ifeq ($(OS),Windows_NT)
 | 
			
		||||
    ifeq ($(PLATFORM),PLATFORM_WEB)
 | 
			
		||||
        # Emscripten required variables
 | 
			
		||||
        EMSDK_PATH         ?= C:/emsdk
 | 
			
		||||
        EMSCRIPTEN_PATH    ?= $(EMSDK_PATH)/upstream/emscripten
 | 
			
		||||
        CLANG_PATH          = $(EMSDK_PATH)/upstream/bin
 | 
			
		||||
        PYTHON_PATH         = $(EMSDK_PATH)/python/3.9.2-nuget_64bit
 | 
			
		||||
        NODE_PATH           = $(EMSDK_PATH)/node/14.15.5_64bit/bin
 | 
			
		||||
        export PATH         = $(EMSDK_PATH);$(EMSCRIPTEN_PATH);$(CLANG_PATH);$(NODE_PATH);$(PYTHON_PATH):$$(PATH)
 | 
			
		||||
    endif
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
# Define default C compiler: CC
 | 
			
		||||
#------------------------------------------------------------------------------------------------
 | 
			
		||||
CC = gcc
 | 
			
		||||
| 
						 | 
				
			
			@ -310,7 +298,7 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
 | 
			
		|||
    # --memory-init-file 0       # to avoid an external memory initialization code file (.mem)
 | 
			
		||||
    # --preload-file resources   # specify a resources folder for data compilation
 | 
			
		||||
    # --source-map-base          # allow debugging in browser with source map
 | 
			
		||||
    LDFLAGS += -s USE_GLFW=3 -s TOTAL_MEMORY=$(BUILD_WEB_HEAP_SIZE) -s FORCE_FILESYSTEM=1
 | 
			
		||||
    LDFLAGS += -s USE_GLFW=3 -s TOTAL_MEMORY=$(BUILD_WEB_HEAP_SIZE) -s FORCE_FILESYSTEM=1 -s ALLOW_MEMORY_GROWTH=1
 | 
			
		||||
    
 | 
			
		||||
    # Build using asyncify
 | 
			
		||||
    ifeq ($(BUILD_WEB_ASYNCIFY),TRUE)
 | 
			
		||||
| 
						 | 
				
			
			@ -401,6 +389,11 @@ endif
 | 
			
		|||
#------------------------------------------------------------------------------------------------
 | 
			
		||||
PROJECT_SOURCE_FILES ?= \
 | 
			
		||||
    main.c \
 | 
			
		||||
    #screen_logo.c \
 | 
			
		||||
    #screen_title.c \
 | 
			
		||||
    #screen_options.c \
 | 
			
		||||
    #screen_gameplay.c \
 | 
			
		||||
    #screen_ending.c
 | 
			
		||||
 | 
			
		||||
# Define all object files from source files
 | 
			
		||||
OBJS = $(patsubst %.c, %.o, $(PROJECT_SOURCE_FILES))
 | 
			
		||||
| 
						 | 
				
			
			@ -481,6 +474,6 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
 | 
			
		|||
endif
 | 
			
		||||
 | 
			
		||||
# Set specific target variable
 | 
			
		||||
clean_shell_cmd: SHELL=cmd
 | 
			
		||||
clean_shell_cmd: SHELL=sh
 | 
			
		||||
clean_shell_cmd:
 | 
			
		||||
	del *.o *.exe $(PROJECT_NAME).data $(PROJECT_NAME).html $(PROJECT_NAME).js $(PROJECT_NAME).wasm /s
 | 
			
		||||
	rm *.o *.exe $(PROJECT_NAME).data $(PROJECT_NAME).html $(PROJECT_NAME).js $(PROJECT_NAME).wasm /s
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										87
									
								
								basic-web.c
								
								
								
								
							
							
						
						
									
										87
									
								
								basic-web.c
								
								
								
								
							| 
						 | 
				
			
			@ -1,87 +0,0 @@
 | 
			
		|||
/*******************************************************************************************
 | 
			
		||||
*
 | 
			
		||||
*   raylib [core] example - Basic window (adapted for HTML5 platform)
 | 
			
		||||
*
 | 
			
		||||
*   NOTE: This example is prepared to compile for PLATFORM_WEB, and PLATFORM_DESKTOP
 | 
			
		||||
*   As you will notice, code structure is slightly diferent to the other examples...
 | 
			
		||||
*   To compile it for PLATFORM_WEB just uncomment #define PLATFORM_WEB at beginning
 | 
			
		||||
*
 | 
			
		||||
*   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"
 | 
			
		||||
 | 
			
		||||
//#define PLATFORM_WEB
 | 
			
		||||
 | 
			
		||||
#if defined(PLATFORM_WEB)
 | 
			
		||||
    #include <emscripten/emscripten.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
// Global Variables Definition
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
const int screenWidth = 800;
 | 
			
		||||
const int screenHeight = 450;
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
// Module functions declaration
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
void UpdateDrawFrame(void);     // Update and Draw one frame
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------------
 | 
			
		||||
// Program main entry point
 | 
			
		||||
//------------------------------------------------------------------------------------
 | 
			
		||||
int main(void)
 | 
			
		||||
{
 | 
			
		||||
    // Initialization
 | 
			
		||||
    //--------------------------------------------------------------------------------------
 | 
			
		||||
    InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window");
 | 
			
		||||
 | 
			
		||||
#if defined(PLATFORM_WEB)
 | 
			
		||||
    emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
 | 
			
		||||
#else
 | 
			
		||||
    SetTargetFPS(60);   // Set our game to run at 60 frames-per-second
 | 
			
		||||
    //--------------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
    // Main game loop
 | 
			
		||||
    while (!WindowShouldClose())    // Detect window close button or ESC key
 | 
			
		||||
    {
 | 
			
		||||
        UpdateDrawFrame();
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // De-Initialization
 | 
			
		||||
    //--------------------------------------------------------------------------------------
 | 
			
		||||
    CloseWindow();        // Close window and OpenGL context
 | 
			
		||||
    //--------------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
// Module Functions Definition
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
void UpdateDrawFrame(void)
 | 
			
		||||
{
 | 
			
		||||
    // Update
 | 
			
		||||
    //----------------------------------------------------------------------------------
 | 
			
		||||
    // TODO: Update your variables here
 | 
			
		||||
    //----------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
    // Draw
 | 
			
		||||
    //----------------------------------------------------------------------------------
 | 
			
		||||
    BeginDrawing();
 | 
			
		||||
 | 
			
		||||
        ClearBackground(RAYWHITE);
 | 
			
		||||
 | 
			
		||||
        DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY);
 | 
			
		||||
 | 
			
		||||
    EndDrawing();
 | 
			
		||||
    //----------------------------------------------------------------------------------
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,2 +0,0 @@
 | 
			
		|||
#!/bin/sh
 | 
			
		||||
gcc main.c $(pkg-config --libs --cflags raylib) -o parthanon
 | 
			
		||||
							
								
								
									
										120
									
								
								main.c
								
								
								
								
							
							
						
						
									
										120
									
								
								main.c
								
								
								
								
							| 
						 | 
				
			
			@ -1,34 +1,84 @@
 | 
			
		|||
#include "raylib.h"
 | 
			
		||||
#include "raymath.h"
 | 
			
		||||
#include "rcamera.h"
 | 
			
		||||
 | 
			
		||||
int main(int argc, char **argv) {
 | 
			
		||||
  const int screen_width = 800;
 | 
			
		||||
  const int screen_height = 450;
 | 
			
		||||
#if defined(PLATFORM_WEB)
 | 
			
		||||
    #include <emscripten/emscripten.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
const int screen_width = 800;
 | 
			
		||||
const int screen_height = 450;
 | 
			
		||||
 | 
			
		||||
Camera camera = {0};
 | 
			
		||||
Ray ray = {0};
 | 
			
		||||
Model parth;
 | 
			
		||||
Texture2D texture;
 | 
			
		||||
Vector3 parth_pos = {0.0f, 0.0f, 0.0f};
 | 
			
		||||
BoundingBox parth_bound_box;
 | 
			
		||||
 | 
			
		||||
void MainGameLoop(void);
 | 
			
		||||
 | 
			
		||||
int main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
  InitWindow(screen_width, screen_height, "Parthanon 3D");
 | 
			
		||||
 | 
			
		||||
  Camera camera = {0}; // camera location places is about the center.
 | 
			
		||||
  camera.position = (Vector3){-9.0f, 9.0f, 4.0f};
 | 
			
		||||
  camera.target = (Vector3){9.0f, 9.0f, 0.0f};
 | 
			
		||||
  camera.up = (Vector3){0.0f, 1.0f, 0.0f};
 | 
			
		||||
  camera.fovy = 60.0f;
 | 
			
		||||
  camera.projection = CAMERA_PERSPECTIVE;
 | 
			
		||||
 | 
			
		||||
  Ray ray = {0};
 | 
			
		||||
 | 
			
		||||
  Model parth = LoadModel("parthanon.obj");
 | 
			
		||||
  Texture2D texture = LoadTexture("parthanon.png");
 | 
			
		||||
  parth = LoadModel("resources/parthanon.obj");
 | 
			
		||||
  texture = LoadTexture("resources/parthanon.png");
 | 
			
		||||
  parth.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture;
 | 
			
		||||
 | 
			
		||||
  Vector3 parthPos = {0.0f, 0.0f, 0.0f};
 | 
			
		||||
  BoundingBox parthBB = GetMeshBoundingBox(parth.meshes[0]);
 | 
			
		||||
  parth_bound_box = GetMeshBoundingBox(parth.meshes[0]);
 | 
			
		||||
 | 
			
		||||
  DisableCursor();
 | 
			
		||||
  SetTargetFPS(60);
 | 
			
		||||
#if defined(PLATFORM_WEB)
 | 
			
		||||
    emscripten_set_main_loop(MainGameLoop, 0, 1);
 | 
			
		||||
#else
 | 
			
		||||
    SetTargetFPS(60);   // Set our game to run at 60 frames-per-second
 | 
			
		||||
 | 
			
		||||
  while (!WindowShouldClose()) {
 | 
			
		||||
    DisableCursor();
 | 
			
		||||
 | 
			
		||||
    UpdateCamera(&camera, CAMERA_FIRST_PERSON);
 | 
			
		||||
    while (!WindowShouldClose())
 | 
			
		||||
    {
 | 
			
		||||
        MainGameLoop();
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  UnloadModel(parth);
 | 
			
		||||
  UnloadTexture(texture);
 | 
			
		||||
 | 
			
		||||
  CloseWindow();
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Main game loop
 | 
			
		||||
 */
 | 
			
		||||
void MainGameLoop(void)
 | 
			
		||||
{
 | 
			
		||||
    // Lock mouse cursor if mouse click on canvas
 | 
			
		||||
    if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) DisableCursor();
 | 
			
		||||
    if (IsKeyPressed(KEY_ESCAPE)) EnableCursor();
 | 
			
		||||
 | 
			
		||||
    /* UpdateCamera(&camera, CAMERA_FIRST_PERSON); */
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
 | 
			
		||||
    RayCollision collision = {0};
 | 
			
		||||
    collision.distance = 10000000.0f; // arbitrary reasonable distance.
 | 
			
		||||
| 
						 | 
				
			
			@ -37,24 +87,28 @@ int main(int argc, char **argv) {
 | 
			
		|||
    // ray pointing down so we are always just above the floor.
 | 
			
		||||
    ray = (Ray){camera.position, (Vector3){0.0f, -1.0f, 0.0f}};
 | 
			
		||||
 | 
			
		||||
    RayCollision boxHitInfo = GetRayCollisionBox(ray, parthBB);
 | 
			
		||||
    if ((boxHitInfo.hit) && (boxHitInfo.distance < collision.distance)) {
 | 
			
		||||
      collision = boxHitInfo;
 | 
			
		||||
    RayCollision bb_hit = GetRayCollisionBox(ray, parth_bound_box);
 | 
			
		||||
    if ((bb_hit.hit) && (bb_hit.distance < collision.distance))
 | 
			
		||||
    {
 | 
			
		||||
      collision = bb_hit;
 | 
			
		||||
 | 
			
		||||
      RayCollision meshHitInfo = {0};
 | 
			
		||||
      for (int m = 0; m < parth.meshCount; m++) {
 | 
			
		||||
        meshHitInfo =
 | 
			
		||||
            GetRayCollisionMesh(ray, parth.meshes[m], parth.transform);
 | 
			
		||||
        if (meshHitInfo.hit) {
 | 
			
		||||
          if ((!collision.hit) || (collision.distance > meshHitInfo.distance)) {
 | 
			
		||||
            collision = meshHitInfo;
 | 
			
		||||
      RayCollision mesh_collide = {0};
 | 
			
		||||
      for (int m = 0; m < parth.meshCount; m++)
 | 
			
		||||
      {
 | 
			
		||||
        mesh_collide = GetRayCollisionMesh(ray, parth.meshes[m], parth.transform);
 | 
			
		||||
        if (mesh_collide.hit)
 | 
			
		||||
	{
 | 
			
		||||
          if ((!collision.hit) || (collision.distance > mesh_collide.distance))
 | 
			
		||||
	  {
 | 
			
		||||
            collision = mesh_collide;
 | 
			
		||||
          }
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (meshHitInfo.hit) {
 | 
			
		||||
        collision = meshHitInfo;
 | 
			
		||||
      if (mesh_collide.hit)
 | 
			
		||||
      {
 | 
			
		||||
        collision = mesh_collide;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -64,11 +118,13 @@ int main(int argc, char **argv) {
 | 
			
		|||
 | 
			
		||||
    BeginMode3D(camera);
 | 
			
		||||
 | 
			
		||||
    DrawModel(parth, parthPos, 1.0f, WHITE);
 | 
			
		||||
    DrawModel(parth, parth_pos, 1.0f, WHITE);
 | 
			
		||||
 | 
			
		||||
    if (collision.hit) {
 | 
			
		||||
    if (collision.hit)
 | 
			
		||||
    {
 | 
			
		||||
      camera.position.y = collision.point.y + 0.4; // Camera position
 | 
			
		||||
      if (camera.position.y < 0.0f) {
 | 
			
		||||
      if (camera.position.y < 0.0f)
 | 
			
		||||
      {
 | 
			
		||||
        camera.position.y = 0.4f;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -80,10 +136,4 @@ int main(int argc, char **argv) {
 | 
			
		|||
    DrawFPS(10, 10);
 | 
			
		||||
 | 
			
		||||
    EndDrawing();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  UnloadModel(parth);
 | 
			
		||||
  UnloadTexture(texture);
 | 
			
		||||
  CloseWindow();
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										114
									
								
								minshell.html
								
								
								
								
							
							
						
						
									
										114
									
								
								minshell.html
								
								
								
								
							| 
						 | 
				
			
			@ -1,57 +1,77 @@
 | 
			
		|||
<!doctype html>
 | 
			
		||||
<html lang="en-us">
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta charset="utf-8">
 | 
			
		||||
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 | 
			
		||||
    <meta charset="utf-8" />
 | 
			
		||||
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 | 
			
		||||
    <title>raylib web game</title>
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    <style>
 | 
			
		||||
        body { margin: 0px; }
 | 
			
		||||
        canvas.emscripten { border: 0px none; background-color: black; }
 | 
			
		||||
      body {
 | 
			
		||||
        margin: 0px;
 | 
			
		||||
      }
 | 
			
		||||
      canvas.emscripten {
 | 
			
		||||
        border: 0px none;
 | 
			
		||||
        background-color: black;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
    <script type='text/javascript' src="https://cdn.jsdelivr.net/gh/eligrey/FileSaver.js/dist/FileSaver.min.js"> </script>
 | 
			
		||||
    <script type='text/javascript'>
 | 
			
		||||
        function saveFileFromMEMFSToDisk(memoryFSname, localFSname)     // This can be called by C/C++ code
 | 
			
		||||
        {
 | 
			
		||||
            var isSafari = false; // Not supported, navigator.userAgent access is being restricted
 | 
			
		||||
            //var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
 | 
			
		||||
            var data = FS.readFile(memoryFSname);
 | 
			
		||||
            var blob;
 | 
			
		||||
    <script
 | 
			
		||||
      type="text/javascript"
 | 
			
		||||
      src="https://cdn.jsdelivr.net/gh/eligrey/FileSaver.js/dist/FileSaver.min.js"
 | 
			
		||||
    ></script>
 | 
			
		||||
    <script type="text/javascript">
 | 
			
		||||
      function saveFileFromMEMFSToDisk(memoryFSname, localFSname) {
 | 
			
		||||
        // This can be called by C/C++ code
 | 
			
		||||
        var isSafari = false; // Not supported, navigator.userAgent access is being restricted
 | 
			
		||||
        //var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
 | 
			
		||||
        var data = FS.readFile(memoryFSname);
 | 
			
		||||
        var blob;
 | 
			
		||||
 | 
			
		||||
            if (isSafari) blob = new Blob([data.buffer], { type: "application/octet-stream" });
 | 
			
		||||
            else blob = new Blob([data.buffer], { type: "application/octet-binary" });
 | 
			
		||||
        if (isSafari)
 | 
			
		||||
          blob = new Blob([data.buffer], { type: "application/octet-stream" });
 | 
			
		||||
        else
 | 
			
		||||
          blob = new Blob([data.buffer], { type: "application/octet-binary" });
 | 
			
		||||
 | 
			
		||||
            // NOTE: SaveAsDialog is a browser setting. For example, in Google Chrome,
 | 
			
		||||
            // in Settings/Advanced/Downloads section you have a setting:
 | 
			
		||||
            // 'Ask where to save each file before downloading' - which you can set true/false.
 | 
			
		||||
            // If you enable this setting it would always ask you and bring the SaveAsDialog
 | 
			
		||||
            saveAs(blob, localFSname);
 | 
			
		||||
        }
 | 
			
		||||
        // NOTE: SaveAsDialog is a browser setting. For example, in Google Chrome,
 | 
			
		||||
        // in Settings/Advanced/Downloads section you have a setting:
 | 
			
		||||
        // 'Ask where to save each file before downloading' - which you can set true/false.
 | 
			
		||||
        // If you enable this setting it would always ask you and bring the SaveAsDialog
 | 
			
		||||
        saveAs(blob, localFSname);
 | 
			
		||||
      }
 | 
			
		||||
    </script>
 | 
			
		||||
    </head>
 | 
			
		||||
    <body>
 | 
			
		||||
        <canvas class=emscripten id=canvas oncontextmenu=event.preventDefault() tabindex=-1></canvas>
 | 
			
		||||
        <p id="output" />
 | 
			
		||||
        <script>
 | 
			
		||||
            var Module = {
 | 
			
		||||
                print: (function() {
 | 
			
		||||
                    var element = document.getElementById('output');
 | 
			
		||||
                    if (element) element.value = ''; // clear browser cache
 | 
			
		||||
                    return function(text) {
 | 
			
		||||
                        if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
 | 
			
		||||
                        console.log(text);
 | 
			
		||||
                        if (element) {
 | 
			
		||||
                          element.value += text + "\n";
 | 
			
		||||
                          element.scrollTop = element.scrollHeight; // focus on bottom
 | 
			
		||||
                        }
 | 
			
		||||
                    };
 | 
			
		||||
                })(),            
 | 
			
		||||
                canvas: (function() {
 | 
			
		||||
                    var canvas = document.getElementById('canvas');
 | 
			
		||||
                    return canvas;
 | 
			
		||||
                })()
 | 
			
		||||
            };
 | 
			
		||||
        </script>
 | 
			
		||||
        {{{ SCRIPT }}}
 | 
			
		||||
    </body>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <canvas
 | 
			
		||||
      class="emscripten"
 | 
			
		||||
      id="canvas"
 | 
			
		||||
      oncontextmenu="event.preventDefault()"
 | 
			
		||||
      tabindex="-1"
 | 
			
		||||
    ></canvas>
 | 
			
		||||
    <p id="output" />
 | 
			
		||||
    <script>
 | 
			
		||||
      var Module = {
 | 
			
		||||
        print: (function () {
 | 
			
		||||
          let element = document.getElementById("output");
 | 
			
		||||
          if (element) element.value = ""; // clear browser cache
 | 
			
		||||
          return function (text) {
 | 
			
		||||
            if (arguments.length > 1)
 | 
			
		||||
              text = Array.prototype.slice.call(arguments).join(" ");
 | 
			
		||||
            console.log(text);
 | 
			
		||||
            if (element) {
 | 
			
		||||
              element.value += text + "\n";
 | 
			
		||||
              element.scrollTop = element.scrollHeight; // focus on bottom
 | 
			
		||||
            }
 | 
			
		||||
          };
 | 
			
		||||
        })(),
 | 
			
		||||
        canvas: (function () {
 | 
			
		||||
          let canvas = document.getElementById("canvas");
 | 
			
		||||
          canvas.width = document.body.clientWidth; //document.width is obsolete
 | 
			
		||||
          canvas.height = document.body.clientHeight; //document.height is obsolete
 | 
			
		||||
          canvasW = canvas.width;
 | 
			
		||||
          canvasH = canvas.height;
 | 
			
		||||
          return canvas;
 | 
			
		||||
        })(),
 | 
			
		||||
      };
 | 
			
		||||
    </script>
 | 
			
		||||
    {{{ SCRIPT }}}
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										
											BIN
										
									
								
								parthanon.png
								
								
								
								
							
							
						
						
									
										
											BIN
										
									
								
								parthanon.png
								
								
								
								
							
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 587 KiB  | 
| 
						 | 
				
			
			@ -0,0 +1,558 @@
 | 
			
		|||
/*******************************************************************************************
 | 
			
		||||
*
 | 
			
		||||
*   rcamera - Basic camera system with support for multiple camera modes
 | 
			
		||||
*
 | 
			
		||||
*   CONFIGURATION:
 | 
			
		||||
*       #define RCAMERA_IMPLEMENTATION
 | 
			
		||||
*           Generates the implementation of the library into the included file.
 | 
			
		||||
*           If not defined, the library is in header only mode and can be included in other headers
 | 
			
		||||
*           or source files without problems. But only ONE file should hold the implementation.
 | 
			
		||||
*
 | 
			
		||||
*       #define RCAMERA_STANDALONE
 | 
			
		||||
*           If defined, the library can be used as standalone as a camera system but some
 | 
			
		||||
*           functions must be redefined to manage inputs accordingly.
 | 
			
		||||
*
 | 
			
		||||
*   CONTRIBUTORS:
 | 
			
		||||
*       Ramon Santamaria:   Supervision, review, update and maintenance
 | 
			
		||||
*       Christoph Wagner:   Complete redesign, using raymath (2022)
 | 
			
		||||
*       Marc Palau:         Initial implementation (2014)
 | 
			
		||||
*
 | 
			
		||||
*
 | 
			
		||||
*   LICENSE: zlib/libpng
 | 
			
		||||
*
 | 
			
		||||
*   Copyright (c) 2022-2023 Christoph Wagner (@Crydsch) & Ramon Santamaria (@raysan5)
 | 
			
		||||
*
 | 
			
		||||
*   This software is provided "as-is", without any express or implied warranty. In no event
 | 
			
		||||
*   will the authors be held liable for any damages arising from the use of this software.
 | 
			
		||||
*
 | 
			
		||||
*   Permission is granted to anyone to use this software for any purpose, including commercial
 | 
			
		||||
*   applications, and to alter it and redistribute it freely, subject to the following restrictions:
 | 
			
		||||
*
 | 
			
		||||
*     1. The origin of this software must not be misrepresented; you must not claim that you
 | 
			
		||||
*     wrote the original software. If you use this software in a product, an acknowledgment
 | 
			
		||||
*     in the product documentation would be appreciated but is not required.
 | 
			
		||||
*
 | 
			
		||||
*     2. Altered source versions must be plainly marked as such, and must not be misrepresented
 | 
			
		||||
*     as being the original software.
 | 
			
		||||
*
 | 
			
		||||
*     3. This notice may not be removed or altered from any source distribution.
 | 
			
		||||
*
 | 
			
		||||
**********************************************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifndef RCAMERA_H
 | 
			
		||||
#define RCAMERA_H
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
// Defines and Macros
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
// Function specifiers definition
 | 
			
		||||
 | 
			
		||||
// Function specifiers in case library is build/used as a shared library (Windows)
 | 
			
		||||
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
#if defined(BUILD_LIBTYPE_SHARED)
 | 
			
		||||
#if defined(__TINYC__)
 | 
			
		||||
#define __declspec(x) __attribute__((x))
 | 
			
		||||
#endif
 | 
			
		||||
#define RLAPI __declspec(dllexport)     // We are building the library as a Win32 shared library (.dll)
 | 
			
		||||
#elif defined(USE_LIBTYPE_SHARED)
 | 
			
		||||
#define RLAPI __declspec(dllimport)     // We are using the library as a Win32 shared library (.dll)
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef RLAPI
 | 
			
		||||
    #define RLAPI       // Functions defined as 'extern' by default (implicit specifiers)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(RCAMERA_STANDALONE)
 | 
			
		||||
    #define CAMERA_CULL_DISTANCE_NEAR      0.01
 | 
			
		||||
    #define CAMERA_CULL_DISTANCE_FAR    1000.0
 | 
			
		||||
#else
 | 
			
		||||
    #define CAMERA_CULL_DISTANCE_NEAR   RL_CULL_DISTANCE_NEAR
 | 
			
		||||
    #define CAMERA_CULL_DISTANCE_FAR    RL_CULL_DISTANCE_FAR
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
// Types and Structures Definition
 | 
			
		||||
// NOTE: Below types are required for standalone usage
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
#if defined(RCAMERA_STANDALONE)
 | 
			
		||||
    // Vector2, 2 components
 | 
			
		||||
    typedef struct Vector2 {
 | 
			
		||||
        float x;                // Vector x component
 | 
			
		||||
        float y;                // Vector y component
 | 
			
		||||
    } Vector2;
 | 
			
		||||
 | 
			
		||||
    // Vector3, 3 components
 | 
			
		||||
    typedef struct Vector3 {
 | 
			
		||||
        float x;                // Vector x component
 | 
			
		||||
        float y;                // Vector y component
 | 
			
		||||
        float z;                // Vector z component
 | 
			
		||||
    } Vector3;
 | 
			
		||||
 | 
			
		||||
    // Matrix, 4x4 components, column major, OpenGL style, right-handed
 | 
			
		||||
    typedef struct Matrix {
 | 
			
		||||
        float m0, m4, m8, m12;  // Matrix first row (4 components)
 | 
			
		||||
        float m1, m5, m9, m13;  // Matrix second row (4 components)
 | 
			
		||||
        float m2, m6, m10, m14; // Matrix third row (4 components)
 | 
			
		||||
        float m3, m7, m11, m15; // Matrix fourth row (4 components)
 | 
			
		||||
    } Matrix;
 | 
			
		||||
 | 
			
		||||
    // Camera type, defines a camera position/orientation in 3d space
 | 
			
		||||
    typedef struct Camera3D {
 | 
			
		||||
        Vector3 position;       // Camera position
 | 
			
		||||
        Vector3 target;         // Camera target it looks-at
 | 
			
		||||
        Vector3 up;             // Camera up vector (rotation over its axis)
 | 
			
		||||
        float fovy;             // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic
 | 
			
		||||
        int projection;         // Camera projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC
 | 
			
		||||
    } Camera3D;
 | 
			
		||||
 | 
			
		||||
    typedef Camera3D Camera;    // Camera type fallback, defaults to Camera3D
 | 
			
		||||
 | 
			
		||||
    // Camera projection
 | 
			
		||||
    typedef enum {
 | 
			
		||||
        CAMERA_PERSPECTIVE = 0, // Perspective projection
 | 
			
		||||
        CAMERA_ORTHOGRAPHIC     // Orthographic projection
 | 
			
		||||
    } CameraProjection;
 | 
			
		||||
 | 
			
		||||
    // Camera system modes
 | 
			
		||||
    typedef enum {
 | 
			
		||||
        CAMERA_CUSTOM = 0,      // Camera custom, controlled by user (UpdateCamera() does nothing)
 | 
			
		||||
        CAMERA_FREE,            // Camera free mode
 | 
			
		||||
        CAMERA_ORBITAL,         // Camera orbital, around target, zoom supported
 | 
			
		||||
        CAMERA_FIRST_PERSON,    // Camera first person
 | 
			
		||||
        CAMERA_THIRD_PERSON     // Camera third person
 | 
			
		||||
    } CameraMode;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
// Global Variables Definition
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
//...
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
// Module Functions Declaration
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
extern "C" {            // Prevents name mangling of functions
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
RLAPI Vector3 GetCameraForward(Camera *camera);
 | 
			
		||||
RLAPI Vector3 GetCameraUp(Camera *camera);
 | 
			
		||||
RLAPI Vector3 GetCameraRight(Camera *camera);
 | 
			
		||||
 | 
			
		||||
// Camera movement
 | 
			
		||||
RLAPI void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane);
 | 
			
		||||
RLAPI void CameraMoveUp(Camera *camera, float distance);
 | 
			
		||||
RLAPI void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane);
 | 
			
		||||
RLAPI void CameraMoveToTarget(Camera *camera, float delta);
 | 
			
		||||
 | 
			
		||||
// Camera rotation
 | 
			
		||||
RLAPI void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget);
 | 
			
		||||
RLAPI void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp);
 | 
			
		||||
RLAPI void CameraRoll(Camera *camera, float angle);
 | 
			
		||||
 | 
			
		||||
RLAPI Matrix GetCameraViewMatrix(Camera *camera);
 | 
			
		||||
RLAPI Matrix GetCameraProjectionMatrix(Camera* camera, float aspect);
 | 
			
		||||
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // RCAMERA_H
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/***********************************************************************************
 | 
			
		||||
*
 | 
			
		||||
*   CAMERA IMPLEMENTATION
 | 
			
		||||
*
 | 
			
		||||
************************************************************************************/
 | 
			
		||||
 | 
			
		||||
#if defined(RCAMERA_IMPLEMENTATION)
 | 
			
		||||
 | 
			
		||||
#include "raymath.h"        // Required for vector maths:
 | 
			
		||||
                            // Vector3Add()
 | 
			
		||||
                            // Vector3Subtract()
 | 
			
		||||
                            // Vector3Scale()
 | 
			
		||||
                            // Vector3Normalize()
 | 
			
		||||
                            // Vector3Distance()
 | 
			
		||||
                            // Vector3CrossProduct()
 | 
			
		||||
                            // Vector3RotateByAxisAngle()
 | 
			
		||||
                            // Vector3Angle()
 | 
			
		||||
                            // Vector3Negate()
 | 
			
		||||
                            // MatrixLookAt()
 | 
			
		||||
                            // MatrixPerspective()
 | 
			
		||||
                            // MatrixOrtho()
 | 
			
		||||
                            // MatrixIdentity()
 | 
			
		||||
 | 
			
		||||
// raylib required functionality:
 | 
			
		||||
                            // GetMouseDelta()
 | 
			
		||||
                            // GetMouseWheelMove()
 | 
			
		||||
                            // IsKeyDown()
 | 
			
		||||
                            // IsKeyPressed()
 | 
			
		||||
                            // GetFrameTime()
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
// Defines and Macros
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
#define CAMERA_MOVE_SPEED                               0.09f
 | 
			
		||||
#define CAMERA_ROTATION_SPEED                           0.03f
 | 
			
		||||
#define CAMERA_PAN_SPEED                                0.2f
 | 
			
		||||
 | 
			
		||||
// Camera mouse movement sensitivity
 | 
			
		||||
#define CAMERA_MOUSE_MOVE_SENSITIVITY                   0.003f     // TODO: it should be independant of framerate
 | 
			
		||||
#define CAMERA_MOUSE_SCROLL_SENSITIVITY                 1.5f
 | 
			
		||||
 | 
			
		||||
#define CAMERA_ORBITAL_SPEED                            0.5f       // Radians per second
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER  8.0f
 | 
			
		||||
#define CAMERA_FIRST_PERSON_STEP_DIVIDER                30.0f
 | 
			
		||||
#define CAMERA_FIRST_PERSON_WAVING_DIVIDER              200.0f
 | 
			
		||||
 | 
			
		||||
// PLAYER (used by camera)
 | 
			
		||||
#define PLAYER_MOVEMENT_SENSITIVITY                     20.0f
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
// Types and Structures Definition
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
//...
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
// Global Variables Definition
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
//...
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
// Module specific Functions Declaration
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
//...
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
// Module Functions Definition
 | 
			
		||||
//----------------------------------------------------------------------------------
 | 
			
		||||
// Returns the cameras forward vector (normalized)
 | 
			
		||||
Vector3 GetCameraForward(Camera *camera)
 | 
			
		||||
{
 | 
			
		||||
    return Vector3Normalize(Vector3Subtract(camera->target, camera->position));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Returns the cameras up vector (normalized)
 | 
			
		||||
// Note: The up vector might not be perpendicular to the forward vector
 | 
			
		||||
Vector3 GetCameraUp(Camera *camera)
 | 
			
		||||
{
 | 
			
		||||
    return Vector3Normalize(camera->up);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Returns the cameras right vector (normalized)
 | 
			
		||||
Vector3 GetCameraRight(Camera *camera)
 | 
			
		||||
{
 | 
			
		||||
    Vector3 forward = GetCameraForward(camera);
 | 
			
		||||
    Vector3 up = GetCameraUp(camera);
 | 
			
		||||
 | 
			
		||||
    return Vector3CrossProduct(forward, up);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Moves the camera in its forward direction
 | 
			
		||||
void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane)
 | 
			
		||||
{
 | 
			
		||||
    Vector3 forward = GetCameraForward(camera);
 | 
			
		||||
 | 
			
		||||
    if (moveInWorldPlane)
 | 
			
		||||
    {
 | 
			
		||||
        // Project vector onto world plane
 | 
			
		||||
        forward.y = 0;
 | 
			
		||||
        forward = Vector3Normalize(forward);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Scale by distance
 | 
			
		||||
    forward = Vector3Scale(forward, distance);
 | 
			
		||||
 | 
			
		||||
    // Move position and target
 | 
			
		||||
    camera->position = Vector3Add(camera->position, forward);
 | 
			
		||||
    camera->target = Vector3Add(camera->target, forward);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Moves the camera in its up direction
 | 
			
		||||
void CameraMoveUp(Camera *camera, float distance)
 | 
			
		||||
{
 | 
			
		||||
    Vector3 up = GetCameraUp(camera);
 | 
			
		||||
 | 
			
		||||
    // Scale by distance
 | 
			
		||||
    up = Vector3Scale(up, distance);
 | 
			
		||||
 | 
			
		||||
    // Move position and target
 | 
			
		||||
    camera->position = Vector3Add(camera->position, up);
 | 
			
		||||
    camera->target = Vector3Add(camera->target, up);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Moves the camera target in its current right direction
 | 
			
		||||
void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane)
 | 
			
		||||
{
 | 
			
		||||
    Vector3 right = GetCameraRight(camera);
 | 
			
		||||
 | 
			
		||||
    if (moveInWorldPlane)
 | 
			
		||||
    {
 | 
			
		||||
        // Project vector onto world plane
 | 
			
		||||
        right.y = 0;
 | 
			
		||||
        right = Vector3Normalize(right);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Scale by distance
 | 
			
		||||
    right = Vector3Scale(right, distance);
 | 
			
		||||
 | 
			
		||||
    // Move position and target
 | 
			
		||||
    camera->position = Vector3Add(camera->position, right);
 | 
			
		||||
    camera->target = Vector3Add(camera->target, right);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Moves the camera position closer/farther to/from the camera target
 | 
			
		||||
void CameraMoveToTarget(Camera *camera, float delta)
 | 
			
		||||
{
 | 
			
		||||
    float distance = Vector3Distance(camera->position, camera->target);
 | 
			
		||||
 | 
			
		||||
    // Apply delta
 | 
			
		||||
    distance += delta;
 | 
			
		||||
 | 
			
		||||
    // Distance must be greater than 0
 | 
			
		||||
    if (distance <= 0) distance = 0.001f;
 | 
			
		||||
 | 
			
		||||
    // Set new distance by moving the position along the forward vector
 | 
			
		||||
    Vector3 forward = GetCameraForward(camera);
 | 
			
		||||
    camera->position = Vector3Add(camera->target, Vector3Scale(forward, -distance));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Rotates the camera around its up vector
 | 
			
		||||
// Yaw is "looking left and right"
 | 
			
		||||
// If rotateAroundTarget is false, the camera rotates around its position
 | 
			
		||||
// Note: angle must be provided in radians
 | 
			
		||||
void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget)
 | 
			
		||||
{
 | 
			
		||||
    // Rotation axis
 | 
			
		||||
    Vector3 up = GetCameraUp(camera);
 | 
			
		||||
 | 
			
		||||
    // View vector
 | 
			
		||||
    Vector3 targetPosition = Vector3Subtract(camera->target, camera->position);
 | 
			
		||||
 | 
			
		||||
    // Rotate view vector around up axis
 | 
			
		||||
    targetPosition = Vector3RotateByAxisAngle(targetPosition, up, angle);
 | 
			
		||||
 | 
			
		||||
    if (rotateAroundTarget)
 | 
			
		||||
    {
 | 
			
		||||
        // Move position relative to target
 | 
			
		||||
        camera->position = Vector3Subtract(camera->target, targetPosition);
 | 
			
		||||
    }
 | 
			
		||||
    else // rotate around camera.position
 | 
			
		||||
    {
 | 
			
		||||
        // Move target relative to position
 | 
			
		||||
        camera->target = Vector3Add(camera->position, targetPosition);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Rotates the camera around its right vector, pitch is "looking up and down"
 | 
			
		||||
//  - lockView prevents camera overrotation (aka "somersaults")
 | 
			
		||||
//  - rotateAroundTarget defines if rotation is around target or around its position
 | 
			
		||||
//  - rotateUp rotates the up direction as well (typically only usefull in CAMERA_FREE)
 | 
			
		||||
// NOTE: angle must be provided in radians
 | 
			
		||||
void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp)
 | 
			
		||||
{
 | 
			
		||||
    // Up direction
 | 
			
		||||
    Vector3 up = GetCameraUp(camera);
 | 
			
		||||
 | 
			
		||||
    // View vector
 | 
			
		||||
    Vector3 targetPosition = Vector3Subtract(camera->target, camera->position);
 | 
			
		||||
 | 
			
		||||
    if (lockView)
 | 
			
		||||
    {
 | 
			
		||||
        // In these camera modes we clamp the Pitch angle
 | 
			
		||||
        // to allow only viewing straight up or down.
 | 
			
		||||
 | 
			
		||||
        // Clamp view up
 | 
			
		||||
        float maxAngleUp = Vector3Angle(up, targetPosition);
 | 
			
		||||
        maxAngleUp -= 0.001f; // avoid numerical errors
 | 
			
		||||
        if (angle > maxAngleUp) angle = maxAngleUp;
 | 
			
		||||
 | 
			
		||||
        // Clamp view down
 | 
			
		||||
        float maxAngleDown = Vector3Angle(Vector3Negate(up), targetPosition);
 | 
			
		||||
        maxAngleDown *= -1.0f; // downwards angle is negative
 | 
			
		||||
        maxAngleDown += 0.001f; // avoid numerical errors
 | 
			
		||||
        if (angle < maxAngleDown) angle = maxAngleDown;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Rotation axis
 | 
			
		||||
    Vector3 right = GetCameraRight(camera);
 | 
			
		||||
 | 
			
		||||
    // Rotate view vector around right axis
 | 
			
		||||
    targetPosition = Vector3RotateByAxisAngle(targetPosition, right, angle);
 | 
			
		||||
 | 
			
		||||
    if (rotateAroundTarget)
 | 
			
		||||
    {
 | 
			
		||||
        // Move position relative to target
 | 
			
		||||
        camera->position = Vector3Subtract(camera->target, targetPosition);
 | 
			
		||||
    }
 | 
			
		||||
    else // rotate around camera.position
 | 
			
		||||
    {
 | 
			
		||||
        // Move target relative to position
 | 
			
		||||
        camera->target = Vector3Add(camera->position, targetPosition);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (rotateUp)
 | 
			
		||||
    {
 | 
			
		||||
        // Rotate up direction around right axis
 | 
			
		||||
        camera->up = Vector3RotateByAxisAngle(camera->up, right, angle);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Rotates the camera around its forward vector
 | 
			
		||||
// Roll is "turning your head sideways to the left or right"
 | 
			
		||||
// Note: angle must be provided in radians
 | 
			
		||||
void CameraRoll(Camera *camera, float angle)
 | 
			
		||||
{
 | 
			
		||||
    // Rotation axis
 | 
			
		||||
    Vector3 forward = GetCameraForward(camera);
 | 
			
		||||
 | 
			
		||||
    // Rotate up direction around forward axis
 | 
			
		||||
    camera->up = Vector3RotateByAxisAngle(camera->up, forward, angle);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Returns the camera view matrix
 | 
			
		||||
Matrix GetCameraViewMatrix(Camera *camera)
 | 
			
		||||
{
 | 
			
		||||
    return MatrixLookAt(camera->position, camera->target, camera->up);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Returns the camera projection matrix
 | 
			
		||||
Matrix GetCameraProjectionMatrix(Camera *camera, float aspect)
 | 
			
		||||
{
 | 
			
		||||
    if (camera->projection == CAMERA_PERSPECTIVE)
 | 
			
		||||
    {
 | 
			
		||||
        return MatrixPerspective(camera->fovy*DEG2RAD, aspect, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR);
 | 
			
		||||
    }
 | 
			
		||||
    else if (camera->projection == CAMERA_ORTHOGRAPHIC)
 | 
			
		||||
    {
 | 
			
		||||
        double top = camera->fovy/2.0;
 | 
			
		||||
        double right = top*aspect;
 | 
			
		||||
 | 
			
		||||
        return MatrixOrtho(-right, right, -top, top, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return MatrixIdentity();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if !defined(RCAMERA_STANDALONE)
 | 
			
		||||
// Update camera position for selected mode
 | 
			
		||||
// Camera mode: CAMERA_FREE, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON, CAMERA_ORBITAL or CUSTOM
 | 
			
		||||
void UpdateCamera(Camera *camera, int mode)
 | 
			
		||||
{
 | 
			
		||||
    Vector2 mousePositionDelta = GetMouseDelta();
 | 
			
		||||
 | 
			
		||||
    bool moveInWorldPlane = ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON));
 | 
			
		||||
    bool rotateAroundTarget = ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL));
 | 
			
		||||
    bool lockView = ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL));
 | 
			
		||||
    bool rotateUp = false;
 | 
			
		||||
 | 
			
		||||
    if (mode == CAMERA_ORBITAL)
 | 
			
		||||
    {
 | 
			
		||||
        // Orbital can just orbit
 | 
			
		||||
        Matrix rotation = MatrixRotate(GetCameraUp(camera), CAMERA_ORBITAL_SPEED*GetFrameTime());
 | 
			
		||||
        Vector3 view = Vector3Subtract(camera->position, camera->target);
 | 
			
		||||
        view = Vector3Transform(view, rotation);
 | 
			
		||||
        camera->position = Vector3Add(camera->target, view);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        // Camera rotation
 | 
			
		||||
        if (IsKeyDown(KEY_DOWN)) CameraPitch(camera, -CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp);
 | 
			
		||||
        if (IsKeyDown(KEY_UP)) CameraPitch(camera, CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp);
 | 
			
		||||
        if (IsKeyDown(KEY_RIGHT)) CameraYaw(camera, -CAMERA_ROTATION_SPEED, rotateAroundTarget);
 | 
			
		||||
        if (IsKeyDown(KEY_LEFT)) CameraYaw(camera, CAMERA_ROTATION_SPEED, rotateAroundTarget);
 | 
			
		||||
        if (IsKeyDown(KEY_Q)) CameraRoll(camera, -CAMERA_ROTATION_SPEED);
 | 
			
		||||
        if (IsKeyDown(KEY_E)) CameraRoll(camera, CAMERA_ROTATION_SPEED);
 | 
			
		||||
 | 
			
		||||
        // Camera movement
 | 
			
		||||
        if (!IsGamepadAvailable(0))
 | 
			
		||||
        {
 | 
			
		||||
            // Camera pan (for CAMERA_FREE)
 | 
			
		||||
            if ((mode == CAMERA_FREE) && (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE)))
 | 
			
		||||
            {
 | 
			
		||||
                const Vector2 mouseDelta = GetMouseDelta();
 | 
			
		||||
                if (mouseDelta.x > 0.0f) CameraMoveRight(camera, CAMERA_PAN_SPEED, moveInWorldPlane);
 | 
			
		||||
                if (mouseDelta.x < 0.0f) CameraMoveRight(camera, -CAMERA_PAN_SPEED, moveInWorldPlane);
 | 
			
		||||
                if (mouseDelta.y > 0.0f) CameraMoveUp(camera, -CAMERA_PAN_SPEED);
 | 
			
		||||
                if (mouseDelta.y < 0.0f) CameraMoveUp(camera, CAMERA_PAN_SPEED);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                // Mouse support
 | 
			
		||||
                CameraYaw(camera, -mousePositionDelta.x*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget);
 | 
			
		||||
                CameraPitch(camera, -mousePositionDelta.y*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Keyboard support
 | 
			
		||||
            if (IsKeyDown(KEY_W)) CameraMoveForward(camera, CAMERA_MOVE_SPEED, moveInWorldPlane);
 | 
			
		||||
            if (IsKeyDown(KEY_A)) CameraMoveRight(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane);
 | 
			
		||||
            if (IsKeyDown(KEY_S)) CameraMoveForward(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane);
 | 
			
		||||
            if (IsKeyDown(KEY_D)) CameraMoveRight(camera, CAMERA_MOVE_SPEED, moveInWorldPlane);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            // Gamepad controller support
 | 
			
		||||
            CameraYaw(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X) * 2)*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget);
 | 
			
		||||
            CameraPitch(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y) * 2)*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp);
 | 
			
		||||
 | 
			
		||||
            if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) <= -0.25f) CameraMoveForward(camera, CAMERA_MOVE_SPEED, moveInWorldPlane);
 | 
			
		||||
            if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) <= -0.25f) CameraMoveRight(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane);
 | 
			
		||||
            if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) >= 0.25f) CameraMoveForward(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane);
 | 
			
		||||
            if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) >= 0.25f) CameraMoveRight(camera, CAMERA_MOVE_SPEED, moveInWorldPlane);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mode == CAMERA_FREE)
 | 
			
		||||
        {
 | 
			
		||||
            if (IsKeyDown(KEY_SPACE)) CameraMoveUp(camera, CAMERA_MOVE_SPEED);
 | 
			
		||||
            if (IsKeyDown(KEY_LEFT_CONTROL)) CameraMoveUp(camera, -CAMERA_MOVE_SPEED);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL) || (mode == CAMERA_FREE))
 | 
			
		||||
    {
 | 
			
		||||
        // Zoom target distance
 | 
			
		||||
        CameraMoveToTarget(camera, -GetMouseWheelMove());
 | 
			
		||||
        if (IsKeyPressed(KEY_KP_SUBTRACT)) CameraMoveToTarget(camera, 2.0f);
 | 
			
		||||
        if (IsKeyPressed(KEY_KP_ADD)) CameraMoveToTarget(camera, -2.0f);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#endif // !RCAMERA_STANDALONE
 | 
			
		||||
 | 
			
		||||
// Update camera movement, movement/rotation values should be provided by user
 | 
			
		||||
void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, float zoom)
 | 
			
		||||
{
 | 
			
		||||
    // Required values
 | 
			
		||||
    // movement.x - Move forward/backward
 | 
			
		||||
    // movement.y - Move right/left
 | 
			
		||||
    // movement.z - Move up/down
 | 
			
		||||
    // rotation.x - yaw
 | 
			
		||||
    // rotation.y - pitch
 | 
			
		||||
    // rotation.z - roll
 | 
			
		||||
    // zoom - Move towards target
 | 
			
		||||
 | 
			
		||||
    bool lockView = true;
 | 
			
		||||
    bool rotateAroundTarget = false;
 | 
			
		||||
    bool rotateUp = false;
 | 
			
		||||
    bool moveInWorldPlane = true;
 | 
			
		||||
 | 
			
		||||
    // Camera rotation
 | 
			
		||||
    CameraPitch(camera, -rotation.y*DEG2RAD, lockView, rotateAroundTarget, rotateUp);
 | 
			
		||||
    CameraYaw(camera, -rotation.x*DEG2RAD, rotateAroundTarget);
 | 
			
		||||
    CameraRoll(camera, rotation.z*DEG2RAD);
 | 
			
		||||
 | 
			
		||||
    // Camera movement
 | 
			
		||||
    CameraMoveForward(camera, movement.x, moveInWorldPlane);
 | 
			
		||||
    CameraMoveRight(camera, movement.y, moveInWorldPlane);
 | 
			
		||||
    CameraMoveUp(camera, movement.z);
 | 
			
		||||
 | 
			
		||||
    // Zoom target distance
 | 
			
		||||
    CameraMoveToTarget(camera, zoom);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // RCAMERA_IMPLEMENTATION
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 1.3 MiB  | 
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
<!doctypehtml><html lang=en-us><head><meta charset=utf-8><meta content="text/html; charset=utf-8"http-equiv=Content-Type><title>raylib web game</title><style>body{margin:0}canvas.emscripten{border:0 none;background-color:#000}</style><script src=https://cdn.jsdelivr.net/gh/eligrey/FileSaver.js/dist/FileSaver.min.js></script><script>function saveFileFromMEMFSToDisk(e,a){var i,o=FS.readFile(e);i=new Blob([o.buffer],{type:"application/octet-binary"}),saveAs(i,a)}</script></head><body><canvas class=emscripten id=canvas oncontextmenu=event.preventDefault() tabindex=-1></canvas><p id=output><script>var Module={print:function(){let t=document.getElementById("output");return t&&(t.value=""),function(e){arguments.length>1&&(e=Array.prototype.slice.call(arguments).join(" ")),console.log(e),t&&(t.value+=e+"\n",t.scrollTop=t.scrollHeight)}}(),canvas:function(){let t=document.getElementById("canvas");return t.width=document.body.clientWidth,t.height=document.body.clientHeight,canvasW=t.width,canvasH=t.height,t}()}</script><script src=raylib_test.js async></script></body></html>
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Loading…
	
		Reference in New Issue