Adds DrawModelPro() and DrawModelWiresPro(), accepting Matrixes as input
This allows us to easily draw the same model with multiple transformations, in particular rotation around multiple axises without having to change the attributes of the model itself (which the Yaw, Pitch, Roll example does). This is particularly useful when loading one model and drawing it multiple times, such as in a game where you fight multiple enemies who all use the same model, but move and behave independently.
This commit is contained in:
parent
bc15c19518
commit
ddcbcbe7a6
190
examples/models/models_transformations.c
Normal file
190
examples/models/models_transformations.c
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [models] example - Draw some basic geometric shapes (cube, sphere, cylinder...)
|
||||
*
|
||||
* Example originally created with raylib 1.0, last time updated with raylib 3.5
|
||||
*
|
||||
* 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) 2014-2023 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "raymath.h"
|
||||
|
||||
// Transforms of the cube
|
||||
Vector3 position = (Vector3){0.0f, 0.0f, 0.0f};
|
||||
Vector3 scale = (Vector3){1.0f, 1.0f, 1.0f};
|
||||
Vector3 rotation = (Vector3){0.0f, 0.0f, 0.0f};
|
||||
|
||||
// Define movement speed
|
||||
const float translationSpeed = 0.2f;
|
||||
const float scaleSpeed = 0.1f;
|
||||
const float rotationSpeed = 2.0f;
|
||||
|
||||
bool left()
|
||||
{
|
||||
return IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT);
|
||||
}
|
||||
|
||||
bool right()
|
||||
{
|
||||
return IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT);
|
||||
}
|
||||
|
||||
bool up()
|
||||
{
|
||||
return IsKeyDown(KEY_W) || IsKeyDown(KEY_UP);
|
||||
}
|
||||
|
||||
bool down()
|
||||
{
|
||||
return IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN);
|
||||
}
|
||||
|
||||
bool in()
|
||||
{
|
||||
return IsKeyDown(KEY_E) || IsKeyDown(KEY_PAGE_DOWN);
|
||||
}
|
||||
|
||||
bool out()
|
||||
{
|
||||
return IsKeyDown(KEY_Q) || IsKeyDown(KEY_PAGE_UP);
|
||||
}
|
||||
|
||||
bool shouldScale()
|
||||
{
|
||||
return IsKeyDown(KEY_LEFT_CONTROL);
|
||||
}
|
||||
|
||||
bool shouldMove()
|
||||
{
|
||||
return IsKeyDown(KEY_LEFT_SHIFT);
|
||||
}
|
||||
|
||||
void handleInput()
|
||||
{
|
||||
if (shouldMove())
|
||||
{
|
||||
if (left())
|
||||
position.x -= translationSpeed;
|
||||
else if (right())
|
||||
position.x += translationSpeed;
|
||||
if (down())
|
||||
position.y -= translationSpeed;
|
||||
else if (up())
|
||||
position.y += translationSpeed;
|
||||
if (out())
|
||||
position.z += translationSpeed;
|
||||
else if (in())
|
||||
position.z -= translationSpeed;
|
||||
}
|
||||
else if (shouldScale())
|
||||
{
|
||||
if (left())
|
||||
scale.x -= scaleSpeed;
|
||||
else if (right())
|
||||
scale.x += scaleSpeed;
|
||||
if (down())
|
||||
scale.y -= scaleSpeed;
|
||||
else if (up())
|
||||
scale.y += scaleSpeed;
|
||||
if (out())
|
||||
scale.z += scaleSpeed;
|
||||
else if (in())
|
||||
scale.z -= scaleSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (left())
|
||||
rotation.x -= rotationSpeed;
|
||||
else if (right())
|
||||
rotation.x += rotationSpeed;
|
||||
if (down())
|
||||
rotation.y -= rotationSpeed;
|
||||
else if (up())
|
||||
rotation.y += rotationSpeed;
|
||||
if (out())
|
||||
rotation.z += rotationSpeed;
|
||||
else if (in())
|
||||
rotation.z -= rotationSpeed;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - model transformations");
|
||||
|
||||
// Generate a cube shaped model to play with
|
||||
Model cube = LoadModelFromMesh(GenMeshCube(2.0f, 2.0f, 2.0f));
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
Camera camera = {0};
|
||||
camera.position = (Vector3){0.0f, 10.0f, 10.0f};
|
||||
camera.target = (Vector3){0.0f, 0.0f, 0.0f};
|
||||
camera.up = (Vector3){0.0f, 1.0f, 0.0f};
|
||||
camera.fovy = 45.0f;
|
||||
camera.projection = CAMERA_PERSPECTIVE;
|
||||
|
||||
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
|
||||
handleInput();
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode3D(camera);
|
||||
|
||||
// Set translation matrix
|
||||
Matrix matTranslation = MatrixTranslate(position.x, position.y, position.z);
|
||||
|
||||
// Multiply rotation matrices with each other, to rotate around each axis.
|
||||
Matrix matRotX = MatrixRotate((Vector3){1.0f, 0.0f, 0.0f}, rotation.x * DEG2RAD);
|
||||
Matrix matRotY = MatrixRotate((Vector3){0.0f, 1.0f, 0.0f}, rotation.y * DEG2RAD);
|
||||
Matrix matRotZ = MatrixRotate((Vector3){0.0f, 0.0f, 1.0f}, rotation.z * DEG2RAD);
|
||||
Matrix matRotCombined = MatrixMultiply(matRotX, matRotY);
|
||||
matRotCombined = MatrixMultiply(matRotCombined, matRotZ);
|
||||
|
||||
// Set scale matrix
|
||||
Matrix matScale = MatrixScale(scale.x, scale.y, scale.z);
|
||||
|
||||
DrawModelPro(cube, matTranslation, matRotCombined, matScale, RED);
|
||||
DrawModelWiresPro(cube, matTranslation, matRotCombined, matScale, BLUE);
|
||||
DrawGrid(10, 1.0f); // Draw a grid
|
||||
|
||||
EndMode3D();
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
DrawText("Left Shift + W/A/S/D to translate", 10, 40, 20, BLUE);
|
||||
DrawText("Left Ctrl + W/A/S/D to scale", 10, 70, 20, BLUE);
|
||||
DrawText("W/A/S/D to rotate", 10, 100, 20, BLUE);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
examples/models/models_transformations.png
Normal file
BIN
examples/models/models_transformations.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
|
|
@ -1469,8 +1469,10 @@ RLAPI BoundingBox GetModelBoundingBox(Model model);
|
|||
// Model drawing functions
|
||||
RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
|
||||
RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
|
||||
RLAPI void DrawModelPro(Model model, Matrix translation, Matrix rotation, Matrix scale, Color tint); // Draw a model with pro parameters
|
||||
RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
|
||||
RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
|
||||
RLAPI void DrawModelWiresPro(Model model, Matrix translation, Matrix rotation, Matrix scale, Color tint); // Draw a model wires (with texture if set) with pro parameters
|
||||
RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
|
||||
RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float size, Color tint); // Draw a billboard texture
|
||||
RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source
|
||||
|
|
|
|||
|
|
@ -3430,7 +3430,13 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota
|
|||
Matrix matRotation = MatrixRotate(rotationAxis, rotationAngle*DEG2RAD);
|
||||
Matrix matTranslation = MatrixTranslate(position.x, position.y, position.z);
|
||||
|
||||
Matrix matTransform = MatrixMultiply(MatrixMultiply(matScale, matRotation), matTranslation);
|
||||
DrawModelPro(model, matTranslation, matRotation, matScale, tint);
|
||||
}
|
||||
|
||||
// Draw a model with pro parameters
|
||||
void DrawModelPro(Model model, Matrix translation, Matrix rotation, Matrix scale, Color tint)
|
||||
{
|
||||
Matrix matTransform = MatrixMultiply(MatrixMultiply(scale, rotation), translation);
|
||||
|
||||
// Combine model transformation matrix (model.transform) with matrix generated by function parameters (matTransform)
|
||||
model.transform = MatrixMultiply(model.transform, matTransform);
|
||||
|
|
@ -3471,6 +3477,16 @@ void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float
|
|||
rlDisableWireMode();
|
||||
}
|
||||
|
||||
// Draw a model wires (with texture if set) with pro parameters
|
||||
void DrawModelWiresPro(Model model, Matrix translation, Matrix rotation, Matrix scale, Color tint)
|
||||
{
|
||||
rlEnableWireMode();
|
||||
|
||||
DrawModelPro(model, translation, rotation, scale, tint);
|
||||
|
||||
rlDisableWireMode();
|
||||
}
|
||||
|
||||
// Draw a billboard
|
||||
void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float size, Color tint)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user