demo buggy heightmap

This commit is contained in:
h4570
2022-08-01 10:04:21 +02:00
parent 47c323ec9e
commit 34b2956c08
12 changed files with 194 additions and 33 deletions
-1
View File
@@ -1,6 +1,5 @@
------------ Tyra's v2.0 roadmap to publish on GitHub ------------ ------------ Tyra's v2.0 roadmap to publish on GitHub ------------
- [General] Tyra version - [General] Tyra version
- [Renderer] Test clipper
- [Renderer] Fog - [Renderer] Fog
- [Demo] Create cool demo which will show all features of Tyra - [Demo] Create cool demo which will show all features of Tyra
- [General] CI in Github via docker image - [General] CI in Github via docker image
+1 -1
View File
@@ -31,7 +31,7 @@ class Camera {
CameraInfo3D getCameraInfo() { return CameraInfo3D(&position, &lookAt); } CameraInfo3D getCameraInfo() { return CameraInfo3D(&position, &lookAt); }
void update(const Vec4& playerPosition); void update(const Vec4& playerPosition, const float& terrainHeight);
private: private:
float circleRotation, lengthFromOrigin, height; float circleRotation, lengthFromOrigin, height;
+3 -2
View File
@@ -27,15 +27,16 @@ class Player {
Player(Engine* engine); Player(Engine* engine);
~Player(); ~Player();
const Vec4& getPosition() const { return position; }
CameraInfo3D getCameraInfo() { return camera.getCameraInfo(); } CameraInfo3D getCameraInfo() { return camera.getCameraInfo(); }
std::vector<RendererStaticPair*> staticPairs; std::vector<RendererStaticPair*> staticPairs;
std::vector<RendererDynamicPair*> dynamicPairs; std::vector<RendererDynamicPair*> dynamicPairs;
void update(); void update(const float& terrainHeight);
private: private:
void handlePlayerPosition(); void handlePlayerPosition(const float& terrainHeight);
float speed; float speed;
Pad* pad; Pad* pad;
@@ -0,0 +1,42 @@
/*
# ______ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licenced under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include "math/vec4.hpp"
#include "loaders/texture/png_loader.hpp"
using Tyra::Vec4;
namespace Demo {
class Heightmap {
public:
Heightmap(const float& minHeight, const float& maxHeight, const Vec4& leftUp,
const Vec4& rightDown);
~Heightmap();
const float& getHeightOffset(const Vec4& playerPosition);
float** map;
s16 mapWidth, mapHeight;
float minHeight, maxHeight;
Vec4 leftUp, rightDown;
private:
float getWidthPercentage(const Vec4& playerPosition);
float getHeightPercentage(const Vec4& playerPosition);
void allocateMap(const unsigned char* data, const int& width,
const int& height);
float getGameHeight(const u8& inputColor, const u8& minColor,
const u8& maxColor);
};
} // namespace Demo
+4 -1
View File
@@ -14,10 +14,12 @@
#include <renderer/3d/pipeline/static/stapip_options.hpp> #include <renderer/3d/pipeline/static/stapip_options.hpp>
#include "states/game/renderer/renderer_static_pair.hpp" #include "states/game/renderer/renderer_static_pair.hpp"
#include <renderer/renderer.hpp> #include <renderer/renderer.hpp>
#include "./heightmap.hpp"
using Tyra::StaPipOptions; using Tyra::StaPipOptions;
using Tyra::StaticMesh; using Tyra::StaticMesh;
using Tyra::TextureRepository; using Tyra::TextureRepository;
using Tyra::Vec4;
namespace Demo { namespace Demo {
@@ -26,11 +28,12 @@ class Terrain {
Terrain(TextureRepository* repo); Terrain(TextureRepository* repo);
~Terrain(); ~Terrain();
Heightmap heightmap;
StaticMesh* mesh; StaticMesh* mesh;
StaPipOptions* options; StaPipOptions* options;
RendererStaticPair* pair; RendererStaticPair* pair;
void update(); float getHeightOffset(const Vec4& playerPosition);
private: private:
void allocateOptions(); void allocateOptions();
+3 -1
View File
@@ -51,7 +51,9 @@ void GameState::update() {
auto cameraInfo = player.getCameraInfo(); auto cameraInfo = player.getCameraInfo();
engine->renderer.beginFrame(cameraInfo); engine->renderer.beginFrame(cameraInfo);
player.update(); float terrainHeight = terrain.getHeightOffset(player.getPosition());
player.update(terrainHeight);
dbgObj.setPosition(*cameraInfo.looksAt); dbgObj.setPosition(*cameraInfo.looksAt);
renderer.clear(); renderer.clear();
+2 -2
View File
@@ -21,7 +21,7 @@ Camera::Camera(Pad* t_pad) : lookAt(0.0F), position(0.0F), pad(t_pad) {
Camera::~Camera() {} Camera::~Camera() {}
void Camera::update(const Vec4& playerPosition) { void Camera::update(const Vec4& playerPosition, const float& terrainHeight) {
const float rotationOffset = 0.03F; const float rotationOffset = 0.03F;
const float heightOffset = 0.5F; const float heightOffset = 0.5F;
@@ -40,7 +40,7 @@ void Camera::update(const Vec4& playerPosition) {
} }
unitCircle.x = (sin(circleRotation) * lengthFromOrigin); unitCircle.x = (sin(circleRotation) * lengthFromOrigin);
unitCircle.y = height + playerPosition.y; unitCircle.y = height + playerPosition.y + terrainHeight;
unitCircle.z = (cos(circleRotation) * lengthFromOrigin); unitCircle.z = (cos(circleRotation) * lengthFromOrigin);
lookAt = unitCircle + playerPosition; lookAt = unitCircle + playerPosition;
+6 -5
View File
@@ -18,7 +18,7 @@ Player::Player(Engine* engine)
camera(&engine->pad) { camera(&engine->pad) {
staticPairs.push_back(new RendererStaticPair{weapon.mesh, weapon.options}); staticPairs.push_back(new RendererStaticPair{weapon.mesh, weapon.options});
pad = &engine->pad; pad = &engine->pad;
position = Vec4(3.0F, 15.0F, 0.0F); position = Vec4(3.0F, 50.0F, 0.0F);
camera.lookAt = Vec4(0.0F, 0.0F, -30.0F); camera.lookAt = Vec4(0.0F, 0.0F, -30.0F);
speed = 2.0F; speed = 2.0F;
} }
@@ -32,13 +32,13 @@ Player::~Player() {
} }
} }
void Player::update() { void Player::update(const float& terrainHeight) {
handlePlayerPosition(); handlePlayerPosition(terrainHeight);
camera.update(position); camera.update(position, terrainHeight);
weapon.update(); weapon.update();
} }
void Player::handlePlayerPosition() { void Player::handlePlayerPosition(const float& terrainHeight) {
const auto& leftJoy = pad->getLeftJoyPad(); const auto& leftJoy = pad->getLeftJoyPad();
auto normalizedCamera = Vec4(camera.unitCircle); auto normalizedCamera = Vec4(camera.unitCircle);
@@ -46,6 +46,7 @@ void Player::handlePlayerPosition() {
normalizedCamera *= speed; normalizedCamera *= speed;
Vec4 nextPosition(position); Vec4 nextPosition(position);
nextPosition.y = terrainHeight;
if (leftJoy.v <= 100) { if (leftJoy.v <= 100) {
nextPosition.x += normalizedCamera.x; nextPosition.x += normalizedCamera.x;
+110
View File
@@ -0,0 +1,110 @@
/*
# ______ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licenced under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "states/game/terrain/heightmap.hpp"
#include "file/file_utils.hpp"
#include "debug/debug.hpp"
using Tyra::FileUtils;
using Tyra::PngLoader;
using Tyra::PngPixel3;
using Tyra::Vec4;
namespace Demo {
Heightmap::Heightmap(const float& t_minHeight, const float& t_maxHeight,
const Vec4& t_leftUp, const Vec4& t_rightDown)
: minHeight(t_minHeight),
maxHeight(t_maxHeight),
leftUp(t_leftUp),
rightDown(t_rightDown) {
PngLoader loader;
auto* data =
loader.load(FileUtils::fromCwd("game/models/terrain/heightmap.png"));
allocateMap(data->data, data->width, data->height);
delete data;
}
Heightmap::~Heightmap() {
if (map) {
for (int i = 0; i < mapHeight; i++) {
delete[] map[i];
}
delete[] map;
}
}
const float& Heightmap::getHeightOffset(const Vec4& playerPosition) {
float widthPercentage = getWidthPercentage(playerPosition);
float heightPercentage = getHeightPercentage(playerPosition);
auto x = static_cast<s16>(widthPercentage * mapWidth);
auto y = static_cast<s16>(heightPercentage * mapHeight);
TYRA_ASSERT(x >= 0 && x < mapWidth, "x is out of range");
TYRA_ASSERT(y >= 0 && y < mapHeight, "y is out of range");
return map[x][y];
}
float Heightmap::getWidthPercentage(const Vec4& playerPosition) {
return (playerPosition.x - leftUp.x) / (rightDown.x - leftUp.x);
}
float Heightmap::getHeightPercentage(const Vec4& playerPosition) {
return (playerPosition.z - leftUp.z) / (rightDown.z - leftUp.z);
}
void Heightmap::allocateMap(const unsigned char* data, const int& width,
const int& height) {
auto* pixels = (struct PngPixel3*)data;
u8 min = pixels[0].r; // in grayscale every r,g,b is the same
u8 max = pixels[0].r;
// Get min and max
for (int i = 0; i < width * height; i++) {
const auto& value = pixels[i].r;
if (value < min) {
min = value;
}
if (value > max) {
max = value;
}
}
// Allocate
mapWidth = width;
mapHeight = height;
map = new float*[width];
for (int i = 0; i < width; i++) {
map[i] = new float[height];
}
// Fill
int k = 0;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
map[i][j] = getGameHeight(pixels[k++].r, min, max);
}
}
}
float Heightmap::getGameHeight(const u8& inputColor, const u8& minColor,
const u8& maxColor) {
const float mapRange = maxColor - minColor;
const float gameRange = maxHeight - minHeight;
return (inputColor - minColor) / mapRange * gameRange + minHeight;
}
} // namespace Demo
+8 -10
View File
@@ -16,8 +16,12 @@ using Tyra::FileUtils;
using Tyra::TyrobjLoader; using Tyra::TyrobjLoader;
namespace Demo { namespace Demo {
Terrain::Terrain(TextureRepository* repo)
Terrain::Terrain(TextureRepository* repo) { : heightmap(-5.0F, // Min height
70.0F, // Max height
Vec4(-196.6F, 0.0F, -412.0F, 1.0F), // Left up
Vec4(286.0F, 0.0F, 443.3F, 1.0F) // Right down
) {
TyrobjLoader loader; TyrobjLoader loader;
auto* data = loader.load( auto* data = loader.load(
FileUtils::fromCwd("game/models/terrain/terrain.obj"), 1, 25.0F, true); FileUtils::fromCwd("game/models/terrain/terrain.obj"), 1, 25.0F, true);
@@ -35,14 +39,8 @@ Terrain::Terrain(TextureRepository* repo) {
pair = new RendererStaticPair{mesh, options}; pair = new RendererStaticPair{mesh, options};
} }
// float testRotation = 0.0F; float Terrain::getHeightOffset(const Vec4& playerPosition) {
return heightmap.getHeightOffset(playerPosition);
void Terrain::update() {
// testRotation += 0.001F;
mesh->rotation.identity();
mesh->rotation.rotateZ(0.1F);
mesh->rotation.rotateY(-4.3F);
// TYRA_LOG(testRotation);
} }
Terrain::~Terrain() { Terrain::~Terrain() {
+12
View File
@@ -24,11 +24,23 @@ typedef void* png_colorp;
namespace Tyra { namespace Tyra {
struct PngPixel3 {
u8 r, g, b;
};
struct PngPixel4 {
u8 r, g, b, a;
};
class PngLoader : public TextureLoader { class PngLoader : public TextureLoader {
public: public:
PngLoader(); PngLoader();
~PngLoader(); ~PngLoader();
inline TextureBuilderData* load(const std::string& fullpath) {
return load(fullpath.c_str());
}
TextureBuilderData* load(const char* fullpath); TextureBuilderData* load(const char* fullpath);
private: private:
+2 -9
View File
@@ -107,11 +107,7 @@ void PngLoader::handle32bpp(TextureBuilderData* result, png_structp pngPtr,
png_read_image(pngPtr, rowPointers); png_read_image(pngPtr, rowPointers);
struct Pixel { struct PngPixel4* pixels = (struct PngPixel4*)result->data;
u8 r, g, b, a;
};
struct Pixel* pixels = (struct Pixel*)result->data;
int k = 0; int k = 0;
for (int i = 0; i < result->height; i++) { for (int i = 0; i < result->height; i++) {
@@ -145,10 +141,7 @@ void PngLoader::handle24bpp(TextureBuilderData* result, png_structp pngPtr,
png_read_image(pngPtr, rowPointers); png_read_image(pngPtr, rowPointers);
struct Pixel3 { struct PngPixel3* pixels = (struct PngPixel3*)result->data;
u8 r, g, b;
};
struct Pixel3* pixels = (struct Pixel3*)result->data;
int k = 0; int k = 0;
for (int i = 0; i < result->height; i++) { for (int i = 0; i < result->height; i++) {