Add AS2
parent
85512eb243
commit
9c95672bee
|
|
@ -0,0 +1,16 @@
|
|||
cmake_minimum_required(VERSION 3.18)
|
||||
project(as2 CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
# adding this option to make clangd work
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
add_subdirectory(../raylib-cpp raylib)
|
||||
|
||||
add_executable(as2 as2.cpp)
|
||||
target_link_libraries(as2 PUBLIC raylib raylib_cpp)
|
||||
|
||||
configure_file(../assets/models/penguin.glb models/penguin.glb COPYONLY)
|
||||
configure_file(../assets/models/eagle.glb models/eagle.glb COPYONLY)
|
||||
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
# Building and Running
|
||||
|
||||
Clone the repository, navigate to the root of the project, and initialize the
|
||||
submodules:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/humanoidsandvichdispenser/cs381.git
|
||||
cd cs381
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
Navigate to the `as2` directory, create a build directory, and run CMake to
|
||||
generate the build files:
|
||||
|
||||
```sh
|
||||
cd as2
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake ..
|
||||
```
|
||||
|
||||
Compile the code using `make`:
|
||||
|
||||
```sh
|
||||
make
|
||||
```
|
||||
|
||||
This should create an executable named `as2` in the `build` directory. You can
|
||||
run the executable with the following command:
|
||||
|
||||
```sh
|
||||
./as2
|
||||
```
|
||||
|
||||
# Extra credit
|
||||
|
||||
The models spin at a rate of 10 degrees per second.
|
||||
|
||||
# Readme Question
|
||||
|
||||
The `DrawBoundedModel` function takes a model and transformer lambda function
|
||||
as parameters. We use this because the lambda defines the transformation for
|
||||
this particular draw call without affecting the model's original transformation
|
||||
matrix. This allows us to apply different transformations to the same model
|
||||
when drawing it multiple times. It also consistently draws the model with a
|
||||
bounding box that respects the transformations. The function does both of these
|
||||
operations atomically, so you don't have to worry about forgetting to apply the
|
||||
transform or draw the bounding box separately.
|
||||
|
||||
The same function could be used in the future after the model has been loaded
|
||||
to apply transforms that are not known at load time and temporary transforms
|
||||
that only apply under specific conditions. For example, we could make the model
|
||||
spin by constantly applying a transformation on the identity transform with a
|
||||
rotation value that changes over time that only applies if a specific key is
|
||||
being held.
|
||||
|
||||
The same function can also be used for transforms relative to the parent. In
|
||||
the lambda, we could multiply the transform passed to the function by a parent
|
||||
transform to get a final transform that is relative to the parent.
|
||||
|
||||
The leftmost penguin looks funny because the model only has half of the
|
||||
penguin. In its default orientation, the faces of the model are away from the
|
||||
camera (the surface normal points away), so the back faces are culled and the
|
||||
model almost appears invisible. When the model is rotated, the faces are no
|
||||
longer culled and the model looks normal.
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
#include "Color.hpp"
|
||||
#include "Keyboard.hpp"
|
||||
#include "Matrix.hpp"
|
||||
#include "Model.hpp"
|
||||
#include "raylib.h"
|
||||
#include <raylib-cpp.hpp>
|
||||
#include <iostream>
|
||||
|
||||
static bool scaleModel = false;
|
||||
|
||||
void DrawBoundedModel(raylib::Model &model, auto transformer) {
|
||||
// store the original transform to apply a different transform to the
|
||||
// model without affecting the next time we draw
|
||||
raylib::Matrix oldTransform = model.GetTransform();
|
||||
|
||||
// apply the transform that we get from whatever the transformer callback
|
||||
// gives us
|
||||
raylib::Matrix transform = transformer(model.GetTransform());
|
||||
|
||||
// default scale doesn't render correctly, so scale the model by 10 if the
|
||||
// spacebar is pressed
|
||||
if (scaleModel) {
|
||||
transform = transform.Scale(10);
|
||||
}
|
||||
|
||||
// apply the transform that we got from the transformer to the model
|
||||
model.SetTransform(transform);
|
||||
|
||||
// draw the model, passing the origin and default scale as arguments since
|
||||
// the transform is already applied to the model
|
||||
model.Draw({ 0, 0, 0 }, 1.0f, raylib::Color::White());
|
||||
|
||||
// get the bounding box of the model after applying the transform
|
||||
auto box = model.GetTransformedBoundingBox();
|
||||
|
||||
// draw the bounding box of the model using raylib's built in function
|
||||
DrawBoundingBox(box, raylib::Color::White());
|
||||
|
||||
// restore the model's transform to its original state so that the next time we
|
||||
// draw the model, it doesn't have the previous transform applied to it
|
||||
model.SetTransform(oldTransform);
|
||||
}
|
||||
|
||||
int main() {
|
||||
raylib::Window window(800, 600, "CS381 - Assignment 2");
|
||||
window.SetState(FLAG_WINDOW_RESIZABLE);
|
||||
|
||||
raylib::Model penguin("models/penguin.glb");
|
||||
raylib::Model eagle("models/eagle.glb");
|
||||
|
||||
raylib::Camera3D camera(
|
||||
{ 0, 120, 500 },
|
||||
{ 0, 0, -1 },
|
||||
{ 0, 1, 0 },
|
||||
45.0f);
|
||||
|
||||
window.SetTargetFPS(60); // save cpu cycles
|
||||
|
||||
while (!window.ShouldClose()) {
|
||||
window.BeginDrawing();
|
||||
|
||||
window.ClearBackground(raylib::Color::Gray());
|
||||
camera.BeginMode();
|
||||
|
||||
if (raylib::Keyboard::IsKeyPressed(KEY_SPACE)) {
|
||||
scaleModel = !scaleModel;
|
||||
}
|
||||
|
||||
// in addition to the required transforms, the models will rotate 10
|
||||
// degrees per second (extra credit), and the penguin is scaled by 30
|
||||
// eagle scaled by 10
|
||||
|
||||
// Draw one eagle located at (0, 0, 0), default scale, and with default
|
||||
// orientation (10 points).
|
||||
DrawBoundedModel(eagle, [](raylib::Matrix transform) {
|
||||
return transform
|
||||
.RotateY(GetTime() * raylib::Degree(10.0f))
|
||||
.Scale(10.0);
|
||||
});
|
||||
|
||||
// Draw one eagle located at (−100, 100, 0), scaled by (1, −1, 1), and
|
||||
// yawed by 180 degrees (10 points).
|
||||
DrawBoundedModel(eagle, [](raylib::Matrix transform) {
|
||||
return transform
|
||||
.Translate(-100.0f, 100.0f, 0.0f)
|
||||
.Scale(1.0f, -1.0f, 1.0f)
|
||||
.RotateY(raylib::Degree(180.0f))
|
||||
.Scale(10.0)
|
||||
.RotateY(GetTime() * raylib::Degree(10.0f));
|
||||
});
|
||||
|
||||
// Draw one penguin located at (−200, 0, 0) with default orientation (10
|
||||
// points).
|
||||
DrawBoundedModel(penguin, [](raylib::Matrix transform) {
|
||||
return transform
|
||||
.Translate(-200.0f, 0.0f, 0.0f)
|
||||
.Scale(30.0f);
|
||||
});
|
||||
|
||||
// Draw one penguin located at (200, 0, 0) and be yawed 90 degrees (10
|
||||
// points).
|
||||
DrawBoundedModel(penguin, [](raylib::Matrix transform) {
|
||||
return transform
|
||||
.Translate(200.0f, 0.0f, 0.0f)
|
||||
.RotateY(raylib::Degree(90.0f))
|
||||
.Scale(30.0)
|
||||
.RotateY(GetTime() * raylib::Degree(10.0f));
|
||||
});
|
||||
|
||||
// Penguin 3: at (100,100,0), scaled by (1,2,1) and yawed 270 degrees
|
||||
DrawBoundedModel(penguin, [](raylib::Matrix transform) {
|
||||
return transform
|
||||
.Translate(100.0f, 100.0f, 0.0f)
|
||||
.Scale(1.0f, 2.0f, 1.0f)
|
||||
.RotateY(raylib::Degree(270.0f))
|
||||
.Scale(30.0)
|
||||
.RotateY(GetTime() * raylib::Degree(10.0f));
|
||||
});
|
||||
|
||||
camera.EndMode();
|
||||
|
||||
window.EndDrawing();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue