demo buggy heightmap
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -27,17 +27,18 @@ 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;
|
||||||
Vec4 position;
|
Vec4 position;
|
||||||
Weapon weapon;
|
Weapon weapon;
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user