tutorial 04
This commit is contained in:
@@ -44,6 +44,8 @@ class Tutorial03 : public Game {
|
||||
* - Minecraft (this one)
|
||||
* - Static (for static 3D objects)
|
||||
* - Dynamic (for dynamic 3D objects)
|
||||
*
|
||||
* You can create your own VU1 programs and create your custom pipelines!
|
||||
*/
|
||||
MinecraftPipeline mcpip;
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
# _____ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2022, tyra - https://github.com/h4570/tyra
|
||||
# Licensed under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <tyra>
|
||||
|
||||
namespace Tyra {
|
||||
|
||||
class Camera {
|
||||
public:
|
||||
Camera(Pad* pad);
|
||||
~Camera();
|
||||
|
||||
Vec4 lookAt;
|
||||
Vec4 position;
|
||||
|
||||
/**
|
||||
* Result variable of unit circle calculation
|
||||
* This is needed for rotation about the camera lookAt
|
||||
* https://www.geogebra.org/m/cNEtsbvC
|
||||
*/
|
||||
Vec4 unitCircle;
|
||||
|
||||
CameraInfo3D getCameraInfo() { return CameraInfo3D(&position, &lookAt); }
|
||||
|
||||
void update();
|
||||
|
||||
private:
|
||||
void updatePosition();
|
||||
void updateLookAt();
|
||||
|
||||
Pad* pad;
|
||||
float circleRotation, circleLength, speed, lookAtHeight;
|
||||
};
|
||||
|
||||
} // namespace Tyra
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <tyra>
|
||||
#include <memory.h>
|
||||
#include "./camera.hpp"
|
||||
|
||||
namespace Tyra {
|
||||
|
||||
@@ -28,8 +29,16 @@ class Tutorial04 : public Game {
|
||||
|
||||
Engine* engine;
|
||||
|
||||
std::unique_ptr<StaticMesh> mesh;
|
||||
Camera camera;
|
||||
|
||||
/** 3D pipeline used for rendering static meshes */
|
||||
StaticPipeline stapip;
|
||||
|
||||
/** Options for static pipeline */
|
||||
StaPipOptions renderOptions;
|
||||
|
||||
/** Mesh with de_dust2 */
|
||||
std::unique_ptr<StaticMesh> mesh;
|
||||
};
|
||||
|
||||
} // namespace Tyra
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
# _____ ____ ___
|
||||
# | \/ ____| |___|
|
||||
# | | | \ | |
|
||||
#-----------------------------------------------------------------------
|
||||
# Copyright 2022, tyra - https://github.com/h4570/tyra
|
||||
# Licensed under Apache License 2.0
|
||||
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||
*/
|
||||
|
||||
#include "camera.hpp"
|
||||
|
||||
namespace Tyra {
|
||||
|
||||
Camera::Camera(Pad* t_pad)
|
||||
: lookAt(0.0F),
|
||||
position(-2000.0F, 0.0F, -6000.0F),
|
||||
pad(t_pad),
|
||||
circleRotation(-5.0F),
|
||||
circleLength(30.0F),
|
||||
speed(20.0F),
|
||||
lookAtHeight(-4.0F) {}
|
||||
|
||||
Camera::~Camera() {}
|
||||
|
||||
void Camera::update() {
|
||||
updatePosition();
|
||||
updateLookAt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Move camera position via left joystick
|
||||
*/
|
||||
void Camera::updatePosition() {
|
||||
const auto& leftJoy = pad->getLeftJoyPad();
|
||||
|
||||
auto direction = Vec4(unitCircle).getNormalized() * speed;
|
||||
|
||||
if (leftJoy.v <= 100) {
|
||||
position.x += direction.x;
|
||||
position.z += direction.z;
|
||||
} else if (leftJoy.v >= 200) {
|
||||
position.x += -direction.x;
|
||||
position.z += -direction.z;
|
||||
}
|
||||
|
||||
if (leftJoy.h <= 100) {
|
||||
position.x += direction.z;
|
||||
position.z += -direction.x;
|
||||
} else if (leftJoy.h >= 200) {
|
||||
position.x += -direction.z;
|
||||
position.z += direction.x;
|
||||
}
|
||||
|
||||
/** Camera height */
|
||||
position.y = 700.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move camera lookAt position via right joystick
|
||||
*/
|
||||
void Camera::updateLookAt() {
|
||||
const float rotationOffset = 0.045F;
|
||||
const float heightOffset = 2.0F;
|
||||
const auto& rightJoy = pad->getRightJoyPad();
|
||||
|
||||
if (rightJoy.h <= 100) {
|
||||
circleRotation -= rotationOffset;
|
||||
} else if (rightJoy.h >= 200) {
|
||||
circleRotation += rotationOffset;
|
||||
}
|
||||
|
||||
if (rightJoy.v <= 100) {
|
||||
lookAtHeight -= heightOffset;
|
||||
} else if (rightJoy.v >= 200) {
|
||||
lookAtHeight += heightOffset;
|
||||
}
|
||||
|
||||
unitCircle.x = Math::sin(circleRotation) * circleLength;
|
||||
unitCircle.y = lookAtHeight;
|
||||
unitCircle.z = Math::cos(circleRotation) * circleLength;
|
||||
|
||||
lookAt = unitCircle + position;
|
||||
}
|
||||
} // namespace Tyra
|
||||
@@ -13,25 +13,64 @@
|
||||
|
||||
namespace Tyra {
|
||||
|
||||
Tutorial04::Tutorial04(Engine* t_engine) : engine(t_engine) {}
|
||||
Tutorial04::Tutorial04(Engine* t_engine)
|
||||
: engine(t_engine), camera(&t_engine->pad) {}
|
||||
|
||||
Tutorial04::~Tutorial04() {
|
||||
engine->renderer.getTextureRepository().freeByMesh(mesh.get());
|
||||
}
|
||||
|
||||
void Tutorial04::init() { loadMesh(); }
|
||||
void Tutorial04::init() {
|
||||
stapip.setRenderer(&engine->renderer.core);
|
||||
loadMesh();
|
||||
}
|
||||
|
||||
void Tutorial04::loop() {}
|
||||
void Tutorial04::loop() {
|
||||
/** Update camera's lookAt and position */
|
||||
camera.update();
|
||||
|
||||
engine->renderer.beginFrame(camera.getCameraInfo());
|
||||
{
|
||||
/** Upload static pipeline's VU1 programs */
|
||||
engine->renderer.renderer3D.usePipeline(stapip);
|
||||
|
||||
/**
|
||||
* Render de_dust2.
|
||||
*
|
||||
* As you see there are clipping issues (visual glitches).
|
||||
* If you want to know how to fix it, please
|
||||
* watch video tutorial.
|
||||
*/
|
||||
stapip.render(mesh.get(), renderOptions);
|
||||
}
|
||||
engine->renderer.endFrame();
|
||||
}
|
||||
|
||||
void Tutorial04::loadMesh() {
|
||||
ObjLoader loader;
|
||||
ObjLoaderOptions options;
|
||||
options.flipUVs = true;
|
||||
options.scale = 200.0F;
|
||||
auto data = loader.load(FileUtils::fromCwd("de_dust2/de_dust2.obj"), options);
|
||||
|
||||
/**
|
||||
* Load mesh data
|
||||
* Texture names are the material names "usemtl <material name>"
|
||||
*/
|
||||
auto data =
|
||||
ObjLoader::load(FileUtils::fromCwd("de_dust2/de_dust2.obj"), options);
|
||||
|
||||
/** Create mesh with loaded data */
|
||||
mesh = std::make_unique<StaticMesh>(data.get());
|
||||
|
||||
/**
|
||||
* Disable frustum culling in render options,
|
||||
* because it not make sense to perform
|
||||
* frustum check on entire map (which will be always visible)
|
||||
*/
|
||||
renderOptions.frustumCulling = Tyra::PipelineFrustumCulling_None;
|
||||
|
||||
/**
|
||||
* Function which load all textures into texture repository,
|
||||
* based on material names.
|
||||
*/
|
||||
engine->renderer.getTextureRepository().addByMesh(
|
||||
mesh.get(), FileUtils::fromCwd("de_dust2/"), "png");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user