collision with ground

This commit is contained in:
Lukas 2020-07-21 20:24:09 +02:00
parent 6ec0b76d33
commit ace545ddae
19 changed files with 587 additions and 497 deletions

394
pom.xml
View File

@ -1,22 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Codename Minosoft
~ Copyright (C) 2020 Moritz Zwerger
~
~ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
~
~ This software is not affiliated with Mojang AB, the original developer of Minecraft.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!--~ Codename Minosoft~ Copyright (C) 2020 Lukas Eisenhauer~~
This program is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.~~ This
program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.~~ You should have
received a copy of the GNU General Public License along with
this program. If not, see <https://www.gnu.org/licenses/>.~~
This software is not affiliated with Mojang AB, the original
developer of Minecraft. -->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>de.bixilon</groupId>
<artifactId>Minosoft</artifactId>
<version>0.1</version>
@ -30,42 +31,18 @@
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.4</version>
<configuration>
<mainClass>HelloFX</mainClass>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<maven.compiler.source>14</maven.compiler.source>
<maven.compiler.target>14</maven.compiler.target>
<lwjgl.version>3.2.3</lwjgl.version>
<lwjgl.natives>natives-windows</lwjgl.natives>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-bom</artifactId>
<version>${lwjgl.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1</version>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>14</version>
</dependency>
<dependency>
<groupId>org.joda</groupId>
@ -77,16 +54,6 @@
<artifactId>commons-primitives</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.l33tlabs.twl</groupId>
<artifactId>pngdecoder</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>14</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
@ -98,327 +65,60 @@
<version>1.25</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>14</version>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl</artifactId>
<classifier>natives-windows</classifier>
<version>${lwjgl.version}</version>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-assimp</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-bgfx</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-cuda</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-egl</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-glfw</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-jawt</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-jemalloc</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-libdivide</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-llvm</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-lmdb</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-lz4</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-meow</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-nanovg</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-nfd</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-nuklear</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-odbc</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-openal</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-opencl</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-opengl</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-opengles</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-openvr</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-opus</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-ovr</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-par</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-remotery</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-rpmalloc</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-shaderc</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-sse</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-stb</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-tinyexr</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-tinyfd</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-tootle</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-vma</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-vulkan</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-xxhash</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-yoga</artifactId>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-zstd</artifactId>
<classifier>natives-linux</classifier>
<version>${lwjgl.version}</version>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-assimp</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-bgfx</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-glfw</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-jemalloc</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-libdivide</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-llvm</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-lmdb</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-lz4</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-meow</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-nanovg</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-nfd</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-nuklear</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-openal</artifactId>
<classifier>${lwjgl.natives}</classifier>
<version>${lwjgl.version}</version>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-opengl</artifactId>
<classifier>${lwjgl.natives}</classifier>
<version>${lwjgl.version}</version>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-opengles</artifactId>
<classifier>${lwjgl.natives}</classifier>
<artifactId>lwjgl-opengl</artifactId>
<classifier>natives-linux</classifier>
<version>${lwjgl.version}</version>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-openvr</artifactId>
<classifier>${lwjgl.natives}</classifier>
<artifactId>lwjgl-opengl</artifactId>
<classifier>natives-windows</classifier>
<version>${lwjgl.version}</version>
</dependency>
<dependency>
<groupId>org.l33tlabs.twl</groupId>
<artifactId>pngdecoder</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-opus</artifactId>
<classifier>${lwjgl.natives}</classifier>
<artifactId>lwjgl-glfw</artifactId>
<version>${lwjgl.version}</version>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-ovr</artifactId>
<classifier>${lwjgl.natives}</classifier>
<artifactId>lwjgl-glfw</artifactId>
<classifier>natives-windows</classifier>
<version>${lwjgl.version}</version>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-par</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-remotery</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-rpmalloc</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-shaderc</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-sse</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-stb</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-tinyexr</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-tinyfd</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-tootle</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-vma</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-xxhash</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-yoga</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-zstd</artifactId>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>18.0.0</version>
<scope>compile</scope>
<artifactId>lwjgl-glfw</artifactId>
<classifier>natives-linux</classifier>
<version>${lwjgl.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -13,6 +13,8 @@
package de.bixilon.minosoft.game.datatypes.world;
import de.bixilon.minosoft.render.utility.Vec3;
public class BlockPosition {
final int x;
final int y;
@ -25,6 +27,12 @@ public class BlockPosition {
this.z = z;
}
public BlockPosition(Vec3 testPosition) {
x = (int) testPosition.x;
y = (short) testPosition.y;
z = (int) testPosition.z;
}
public int getX() {
return x;
}

View File

@ -33,6 +33,9 @@ public class Chunk {
throw new IllegalArgumentException(String.format("Invalid chunk location %s %s %s", x, y, z));
}
byte section = (byte) (y / 16);
if (nibbles.get(section) == null) {
return Blocks.AIR;
}
return nibbles.get(section).getBlock(x, y % 16, z);
}

View File

@ -57,6 +57,9 @@ public class World {
}
public Blocks getBlock(BlockPosition pos) {
if (pos.y < 1) {
return Blocks.AIR;
}
ChunkLocation loc = pos.getChunkLocation();
if (getChunk(loc) != null) {
return getChunk(loc).getBlock(pos.getInChunkLocation());

View File

@ -0,0 +1,77 @@
/*
* Codename Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.movement;
import de.bixilon.minosoft.render.utility.Vec3;
import static de.bixilon.minosoft.render.utility.Vec3.normalize;
import static java.lang.StrictMath.*;
import static org.lwjgl.opengl.GL11.glRotatef;
public class CameraMovement {
Vec3 cameraFront = new Vec3(0.0f, 0.0f, -1.0f);
private boolean firstMouse = false;
private float lastX;
private float lastY;
private float yaw;
private float pitch;
public void mouseCallback(long l, double xPos, double yPos) {
// variable l is unused but always given by openGL so we need it in the method signature
if (firstMouse) {
lastX = (float) xPos;
lastY = (float) yPos;
firstMouse = false;
}
float xoffset = (float) (xPos - lastX);
float yoffset = (float) (lastY - yPos); // reversed since y-coordinates go from bottom to top
lastX = (float) xPos;
lastY = (float) yPos;
float sensitivity = 0.1f; // change this value to your liking
xoffset *= sensitivity;
yoffset *= sensitivity;
yaw += xoffset;
pitch += yoffset;
// make sure that pitch does not get out of bounds
if (pitch > 89.0f)
pitch = 89.0f;
if (pitch < -89.0f)
pitch = -89.0f;
Vec3 front = new Vec3();
front.x = (float) -(sin(toRadians(yaw)) * cos(toRadians(pitch)));
front.y = 0;
front.z = (float) ((cos(toRadians(yaw))) * cos(toRadians(pitch)));
cameraFront = normalize(front);
}
public void loop() {
glRotatef(pitch, 1, 0, 0);
glRotatef(yaw, 0, 1, 0);
}
public void setRotation(float pitch, float yaw) {
this.pitch = pitch;
this.yaw = yaw;
}
public Vec3 getCameraFront() {
return cameraFront;
}
}

View File

@ -0,0 +1,133 @@
/*
* Codename Minosoft
* Copyright (C) 2020 Lukas Eisenhauer
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.movement;
import de.bixilon.minosoft.game.datatypes.world.BlockPosition;
import de.bixilon.minosoft.game.datatypes.world.World;
import de.bixilon.minosoft.render.blockModels.BlockModelLoader;
import de.bixilon.minosoft.render.utility.Vec3;
import java.util.ArrayList;
import java.util.List;
import static de.bixilon.minosoft.render.utility.AdditionalMath.betterRound;
import static de.bixilon.minosoft.render.utility.AdditionalMath.valuesBetween;
public class CollisionHandling {
private static Vec3 lastPosInverted;
private static Vec3 posDifference;
public static void handleCollisions(World world, PlayerController controller, BlockModelLoader modelLoader, Vec3 deltaPos) {
groundCollision(world, controller, modelLoader, deltaPos);
if (!controller.isOnGround()) {
// if we are stuck in a block, just stay there, otherwise, we would fall through the world
//topCollision(world, controller, modelLoader);
}
//xAxisCollision(world, controller, modelLoader, deltaPos);
}
private static void xAxisCollision(World world, PlayerController controller, BlockModelLoader modelLoader, Vec3 deltaPos) {
Vec3 playerPos = controller.getPlayerPos();
int xVelocityDirection = deltaPos.getXNormalized();
if (xVelocityDirection == 0) {
return;
}
BlockPosition[] testPositions = getXAxisTestPositions(controller, playerPos, xVelocityDirection);
for (BlockPosition position : testPositions) {
if (modelLoader.isFull(world.getBlock(position))) {
playerPos.x = position.getX() - xVelocityDirection * controller.getPlayerWidth();
controller.playerVelocity.x = 0;
return;
}
}
}
private static void topCollision(World world, PlayerController controller, BlockModelLoader modelLoader) {
Vec3 headTop = controller.getPlayerPos().copy();
headTop.y += controller.getPlayerHeight();
BlockPosition[] testPositions = getVerticalTestPositions(controller, headTop);
for (BlockPosition position : testPositions) {
if (modelLoader.isFull(world.getBlock(position))) {
controller.playerVelocity.y = 0;
controller.playerPos.y = position.getY() - controller.getPlayerHeight();
}
}
}
public static void groundCollision(World world, PlayerController controller, BlockModelLoader modelLoader, Vec3 deltaPos) {
Vec3 playerPos = controller.playerPos.copy();
playerPos.y++;
BlockPosition[] testPositions = getVerticalTestPositions(controller, playerPos);
for (BlockPosition position : testPositions) {
if (modelLoader.isFull(world.getBlock(position))) {
controller.playerVelocity.y = 0;
controller.playerPos.y = position.getY();
controller.onGround = true;
}
}
}
private static BlockPosition[] getVerticalTestPositions(PlayerController controller, Vec3 testPos) {
List<BlockPosition> result = new ArrayList<>();
float width = controller.getPlayerWidth();
List<Integer> xPositions = new ArrayList<>();
for (int xCoordinate : valuesBetween(betterRound(testPos.x + 0.5 * width), betterRound(testPos.x - 0.5 * width))) {
xPositions.add(xCoordinate);
}
List<Integer> zPositions = new ArrayList<>();
for (int xCoordinate : valuesBetween(betterRound(testPos.z + 0.5 * width), betterRound(testPos.z - 0.5 * width))) {
zPositions.add(xCoordinate);
}
for (int xPos : xPositions) {
for (int zPos : zPositions) {
result.add(new BlockPosition(xPos, (short) testPos.y, zPos));
}
}
return result.toArray(new BlockPosition[0]);
}
private static BlockPosition[] getXAxisTestPositions(PlayerController controller, Vec3 testPos, int xVelocityDirection) {
List<BlockPosition> result = new ArrayList<>();
float width = controller.getPlayerWidth();
List<Integer> yPositions = new ArrayList<>();
for (int yCoordinate : valuesBetween(betterRound(testPos.y + 1), betterRound(testPos.y + controller.getPlayerHeight()))) {
yPositions.add(yCoordinate);
}
List<Integer> zPositions = new ArrayList<>();
for (int zCoordinate : valuesBetween(betterRound(testPos.z + 0.5 * width), betterRound(testPos.z - 0.5 * width))) {
zPositions.add(zCoordinate);
}
for (int yPos : yPositions) {
for (int zPos : zPositions) {
result.add(new BlockPosition(betterRound(testPos.x), (short) yPos, zPos));
}
}
return result.toArray(new BlockPosition[0]);
}
}

View File

@ -0,0 +1,110 @@
/*
* Codename Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.movement;
import de.bixilon.minosoft.game.datatypes.GameMode;
import de.bixilon.minosoft.game.datatypes.world.World;
import de.bixilon.minosoft.render.MainWindow;
import de.bixilon.minosoft.render.blockModels.BlockModelLoader;
import de.bixilon.minosoft.render.utility.Vec3;
import static org.lwjgl.opengl.GL11.glTranslatef;
public class PlayerController {
private final float playerHeight = 1.8f;
private final float playerWidth = 0.5f;
CameraMovement cameraMovement;
PlayerMovement playerMovement;
Vec3 playerPos = new Vec3(0, 1, 0); // the feet position of the player
Vec3 playerVelocity = new Vec3();
float gravity = 9.81f;
boolean onGround;
private boolean enableGravity;
public PlayerController(long window) {
cameraMovement = new CameraMovement();
playerMovement = new PlayerMovement(window);
}
public void loop(float deltaTime) {
GameMode gameMode = MainWindow.getConnection().getPlayer().getGameMode();
enableGravity = gameMode == GameMode.CREATIVE || gameMode == GameMode.SPECTATOR;
handleGravity(deltaTime);
cameraMovement.loop();
playerMovement.loop(deltaTime);
applyVelocity(deltaTime);
if (gameMode == GameMode.SPECTATOR) {
return;
}
handleCollisions(MainWindow.getConnection().getPlayer().getWorld());
glTranslatef(-playerPos.x, -(playerPos.y + playerHeight - 0.2f), -playerPos.z);
}
private void handleCollisions(World world) {
onGround = false;
if (world == null) {
playerVelocity.zero();
return;
}
BlockModelLoader modelLoader = MainWindow.getRenderer().getModelLoader();
CollisionHandling.handleCollisions(world, this, modelLoader, playerMovement.deltaPos);
}
public boolean isEnableGravity() {
return enableGravity;
}
public Vec3 getPlayerPos() {
return playerPos;
}
public void setPlayerPos(Vec3 playerPos) {
this.playerPos = playerPos;
}
private void applyVelocity(float deltaTime) {
playerPos.add(Vec3.mul(playerVelocity, deltaTime));
}
private void handleGravity(float deltaTime) {
if (!enableGravity) {
return;
}
// a rather accurate model for the real world, but minecraft probably does it differently
playerVelocity.y -= gravity * deltaTime;
}
public CameraMovement getCameraMovement() {
return cameraMovement;
}
public boolean isOnGround() {
return onGround;
}
public void jump() {
playerVelocity.y = 10;
onGround = false;
}
public float getPlayerWidth() {
return playerWidth;
}
public float getPlayerHeight() {
return playerHeight;
}
}

View File

@ -0,0 +1,82 @@
/*
* Codename Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
/*
* A simple camera controller to fly around the scene
*/
package de.bixilon.minosoft.movement;
import de.bixilon.minosoft.render.MainWindow;
import de.bixilon.minosoft.render.utility.Vec3;
import static de.bixilon.minosoft.render.utility.Vec3.*;
import static org.lwjgl.glfw.GLFW.*;
public class PlayerMovement {
private final long window;
Vec3 cameraFront;
Vec3 cameraUp = new Vec3(0f, 1f, 0f);
float flySpeed = 0.1f;
Vec3 playerPos;
Vec3 deltaPos;
public PlayerMovement(long window) {
this.window = window;
}
private void processInput(float deltaTime) {
Vec3 posBefore = playerPos.copy();
float cameraSpeed = flySpeed / deltaTime;
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
MainWindow.pause();
}
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
playerPos.add(mul(cameraFront, -cameraSpeed * deltaTime));
}
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
playerPos.add(mul(cameraFront, cameraSpeed * deltaTime));
}
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
playerPos.add(mul(cross(cameraUp, cameraFront), -cameraSpeed * deltaTime));
}
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
playerPos.add(mul(cross(cameraUp, cameraFront), cameraSpeed * deltaTime));
}
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) {
if (!MainWindow.getPlayerMovement().isEnableGravity()) {
playerPos.add(0, cameraSpeed * deltaTime, 0);
}
}
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) {
if (!MainWindow.getPlayerMovement().isEnableGravity()) {
playerPos.add(0, -cameraSpeed * deltaTime, 0);
}
if (MainWindow.getPlayerMovement().isOnGround()) {
MainWindow.getPlayerMovement().jump();
}
}
deltaPos = add(playerPos, mul(posBefore, -1));
}
public void loop(float deltaTime) {
cameraFront = MainWindow.getPlayerMovement().getCameraMovement().getCameraFront();
playerPos = MainWindow.getPlayerMovement().getPlayerPos();
processInput(deltaTime);
}
}

View File

@ -35,6 +35,8 @@ import de.bixilon.minosoft.protocol.packets.serverbound.login.PacketEncryptionRe
import de.bixilon.minosoft.protocol.packets.serverbound.play.PacketKeepAliveResponse;
import de.bixilon.minosoft.protocol.packets.serverbound.play.PacketPlayerPositionAndRotationSending;
import de.bixilon.minosoft.protocol.packets.serverbound.play.PacketResourcePackStatus;
import de.bixilon.minosoft.render.MainWindow;
import de.bixilon.minosoft.render.utility.Vec3;
import javax.crypto.SecretKey;
import java.math.BigInteger;
@ -344,7 +346,10 @@ public class PacketHandler {
}
public void handle(PacketPlayerPositionAndRotation pkg) {
//ToDo handle with gui
MainWindow.getPlayerMovement().getCameraMovement().setRotation(pkg.getPitch(), pkg.getYaw());
MainWindow.getPlayerMovement().setPlayerPos(new Vec3(pkg.getLocation()));
//TODO: location
if (!connection.getPlayer().isSpawnConfirmed()) {
// oops, not spawned yet, confirming position
//ToDo feet position

View File

@ -1,115 +0,0 @@
/*
* Codename Minosoft
* Copyright (C) 2020 Lukas Eisenhauer
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
/*
* A simple camera controller to fly around the scene
*/
package de.bixilon.minosoft.render;
import de.bixilon.minosoft.render.utility.Vec3;
import static de.bixilon.minosoft.render.utility.Vec3.*;
import static java.lang.StrictMath.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
public class FlyController {
private final long window;
Vec3 cameraPos = new Vec3(0.0f, 0.0f, 0.0f);
Vec3 cameraFront = new Vec3(0.0f, 0.0f, -1.0f);
Vec3 cameraUp = new Vec3(0.0f, 1.0f, 0.0f);
float lastX;
float lastY;
float yaw = 0f;
float pitch = 0f;
float flySpeed = 0.1f;
private boolean firstMouse = true;
public FlyController(long window) {
this.window = window;
}
private void processInput(long window, float deltaTime) {
float cameraSpeed = flySpeed / deltaTime;
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
MainWindow.pause();
}
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
cameraPos.add(mul(cameraFront, cameraSpeed * deltaTime));
}
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
cameraPos.add(mul(cameraFront, -cameraSpeed * deltaTime));
}
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
cameraPos.add(mul(cross(cameraUp, cameraFront), cameraSpeed * deltaTime));
}
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
cameraPos.add(mul(cross(cameraUp, cameraFront), -cameraSpeed * deltaTime));
}
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) {
cameraPos.add(0, cameraSpeed * deltaTime, 0);
}
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) {
cameraPos.add(0, -cameraSpeed * deltaTime, 0);
}
}
public void loop(float deltaTime) {
processInput(window, deltaTime);
//glLoadIdentity();
//glTranslatef(cameraPos.x, cameraPos.y, cameraPos.z);
//glPushMatrix();
//glTranslatef(-cameraPos.x, -cameraPos.y, -cameraPos.z);
glRotatef(pitch, 1, 0, 0);
glRotatef(yaw, 0, 1, 0);
glTranslatef(cameraPos.x, cameraPos.y, cameraPos.z);
glPushMatrix();
}
public void mouseCallback(long l, double xPos, double yPos) {
if (firstMouse) {
lastX = (float) xPos;
lastY = (float) yPos;
firstMouse = false;
}
float xoffset = (float) (xPos - lastX);
float yoffset = (float) (lastY - yPos); // reversed since y-coordinates go from bottom to top
lastX = (float) xPos;
lastY = (float) yPos;
float sensitivity = 0.1f; // change this value to your liking
xoffset *= sensitivity;
yoffset *= sensitivity;
yaw += xoffset;
pitch += yoffset;
// make sure that when pitch is out of bounds, screen doesn't get flipped
if (pitch > 89.0f)
pitch = 89.0f;
if (pitch < -89.0f)
pitch = -89.0f;
Vec3 front = new Vec3();
front.x = (float) -(sin(toRadians(yaw)) * cos(toRadians(pitch)));
front.y = 0;//(float) sin(toRadians(pitch));
front.z = (float) ((cos(toRadians(yaw))) * cos(toRadians(pitch)));
cameraFront = normalize(front);
}
}

View File

@ -13,6 +13,7 @@
package de.bixilon.minosoft.render;
import de.bixilon.minosoft.movement.PlayerController;
import de.bixilon.minosoft.protocol.network.Connection;
import de.bixilon.minosoft.render.MainMenu.MainMenu;
import de.bixilon.minosoft.render.utility.RenderMode;
@ -33,7 +34,8 @@ public class MainWindow {
static MainMenu mainMenu;
static WorldRenderer renderer;
static Connection connection;
static FlyController flyController;
private static PlayerController playerMovement;
public static void start(Connection serverConnection) {
Thread guiThread = new Thread(() -> {
@ -42,15 +44,15 @@ public class MainWindow {
openGLWindow.init();
renderer = new WorldRenderer();
renderer.init();
flyController = new FlyController(openGLWindow.getWindow());
playerMovement = new PlayerController(openGLWindow.getWindow());
renderMode = MAIN_MENU;
mainMenu = new MainMenu(openGLWindow.getWidth(), openGLWindow.getHeight());
runWindow();
mainLoop();
});
guiThread.start();
}
private static void runWindow() {
private static void mainLoop() {
while (!glfwWindowShouldClose(openGLWindow.getWindow())) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
@ -67,7 +69,7 @@ public class MainWindow {
break;
case PLAY:
OpenGLWindow.gluPerspective(FOVY, (float) WIDTH / (float) HEIGHT, 0.1f, 500f);
flyController.loop(deltaTime);
playerMovement.loop(deltaTime);
renderer.draw();
break;
}
@ -89,7 +91,7 @@ public class MainWindow {
renderMode = PLAY;
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glfwSetCursorPosCallback(openGLWindow.getWindow(), flyController::mouseCallback);
glfwSetCursorPosCallback(openGLWindow.getWindow(), playerMovement.getCameraMovement()::mouseCallback);
glfwSetInputMode(openGLWindow.getWindow(), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glEnable(GL_TEXTURE_2D);
connection.connect();
@ -108,4 +110,8 @@ public class MainWindow {
public static void close() {
System.exit(1);
}
public static PlayerController getPlayerMovement() {
return playerMovement;
}
}

View File

@ -137,4 +137,8 @@ public class WorldRenderer {
public TextureLoader getTextureLoader() {
return textureLoader;
}
public BlockModelLoader getModelLoader() {
return modelLoader;
}
}

View File

@ -16,7 +16,6 @@ package de.bixilon.minosoft.render.blockModels;
import de.bixilon.minosoft.Config;
import de.bixilon.minosoft.game.datatypes.blocks.Blocks;
import org.json.JSONObject;
import org.json.simple.parser.JSONParser;
import java.io.File;
import java.io.IOException;
@ -41,7 +40,6 @@ public class BlockModelLoader {
private void loadModels(String path) throws IOException {
File[] files = new File(path).listFiles();
JSONParser parser = new JSONParser();
for (File file : files) {
String fileName = file.getName().substring(0, file.getName().lastIndexOf('.'));
@ -59,6 +57,9 @@ public class BlockModelLoader {
}
public boolean isFull(Blocks block) {
if (block == Blocks.AIR || block == null) {
return false;
}
return drawDescriptionMap.get(block).isFull();
}
}

View File

@ -34,7 +34,7 @@ public class DrawDescription {
Map<FaceOrientation, Pair<Float, Float>> faces;
boolean full; // is the block a completely filled block
boolean full = false; // is the block a completely filled block?
public DrawDescription(JSONObject json) {
if (!(json.has("parent") && json.has("textures"))) return;

View File

@ -21,6 +21,12 @@ public enum FaceOrientation {
this.id = id;
}
public static FaceOrientation[] getNotVerticalValues() {
return new FaceOrientation[]{
EAST, WEST, SOUTH, NORTH
};
}
public int getId() {
return this.id;
}

View File

@ -17,40 +17,40 @@ public class RenderConstants {
//TODO: fix rotated faces
public static final float[][][] FACE_VERTEX = new float[][][]{
{
{0.5f, 0.5f, -0.5f},
{0.5f, -0.5f, -0.5f},
{0.5f, -0.5f, 0.5f},
{0.5f, 0.5f, 0.5f}
{1, 0, 0},
{1, -1, 0},
{1, -1, 1},
{1, 0, 1}
},
{
{-0.5f, 0.5f, -0.5f},
{-0.5f, -0.5f, -0.5f},
{-0.5f, -0.5f, 0.5f},
{-0.5f, 0.5f, 0.5f}
{0, 0, 0},
{0, -1, 0},
{0, -1, 1},
{0, 0, 1}
},
{
{0.5f, 0.5f, 0.5f},
{-0.5f, 0.5f, 0.5f},
{-0.5f, 0.5f, -0.5f},
{0.5f, 0.5f, -0.5f},
{0, 0, 0},
{1, 0, 0},
{1, 0, 1},
{0, 0, 1}
},
{
{0.5f, -0.5f, 0.5f},
{-0.5f, -0.5f, 0.5f},
{-0.5f, -0.5f, -0.5f},
{0.5f, -0.5f, -0.5f},
{0, -1, 0},
{1, -1, 0},
{1, -1, 1},
{0, -1, 1}
},
{
{0.5f, 0.5f, 0.5f},
{0.5f, -0.5f, 0.5f},
{-0.5f, -0.5f, 0.5f},
{-0.5f, 0.5f, 0.5f},
{1, 0, 1},
{1, -1, 1},
{0, -1, 1},
{0, 0, 1},
},
{
{0.5f, 0.5f, -0.5f},
{0.5f, -0.5f, -0.5f},
{-0.5f, -0.5f, -0.5f},
{-0.5f, 0.5f, -0.5f},
{1, 0, 0},
{1, -1, 0},
{0, -1, 0},
{0, 0, 0}
},
};

View File

@ -109,7 +109,7 @@ public class TextureLoader {
BufferedImage img = ImageIO.read(textureInputStream);
allTextures.add(new Pair<>(img, textureName));
}
//else we have a .mcmeta file
//else we have a .mcmeta file describing animated blocks
}
// CONVERT ALL THE IMAGES INTO A SINGLE, VERY LONG IMAGE

View File

@ -0,0 +1,42 @@
/*
* Codename Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.render.utility;
import static java.lang.Math.abs;
public class AdditionalMath {
public static int[] valuesBetween(int x, int y) {
int[] result = new int[abs(x - y) + 1];
if (x > y) {
for (int z = y; z <= x; z++) {
result[x - z] = z;
}
} else if (y > x) {
for (int z = x; z <= y; z++) {
result[y - z] = z;
}
} else {
result[0] = x;
}
return result;
}
public static int betterRound(double x) {
if (x >= 0) {
return (int) x;
}
return (int) x - 1;
}
}

View File

@ -13,6 +13,8 @@
package de.bixilon.minosoft.render.utility;
import de.bixilon.minosoft.game.datatypes.entities.Location;
import static java.lang.Math.pow;
import static java.lang.Math.sqrt;
@ -29,6 +31,12 @@ public class Vec3 {
z = z_;
}
public Vec3(Location location) {
x = (float) location.getX();
y = (float) location.getY();
z = (float) location.getZ();
}
public static Vec3 add(Vec3 v1, Vec3 v2) {
return new Vec3(
v1.x + v2.x,
@ -92,4 +100,21 @@ public class Vec3 {
y /= l;
z /= l;
}
public Vec3 copy() {
return new Vec3(x, y, z);
}
public void zero() {
x = y = z = 0f;
}
public int getXNormalized() {
if (x == 0f) {
return 0;
} else if (x > 0) {
return 1;
}
return -1;
}
}