Skip to content

Commit

Permalink
added character on planet
Browse files Browse the repository at this point in the history
The walking is a bit weird though
  • Loading branch information
BarthPaleologue committed Nov 13, 2023
1 parent b1ce408 commit d3d97fc
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 26 deletions.
6 changes: 4 additions & 2 deletions src/ts/butterfly/butterflyMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import butterflyTexture from "../../assets/butterfly.png";
import { Texture } from "@babylonjs/core/Materials/Textures/texture";
import { TransformNode } from "@babylonjs/core/Meshes/transformNode";
import { DirectionalLight } from "@babylonjs/core/Lights/directionalLight";
import { Vector3 } from "@babylonjs/core/Maths/math.vector";

export function createButterflyMaterial(player: TransformNode, light: DirectionalLight, scene: Scene) {
export function createButterflyMaterial(light: DirectionalLight, scene: Scene, player?: TransformNode) {
const shaderName = "butterflyMaterial";
Effect.ShadersStore[`${shaderName}FragmentShader`] = butterflyFragment;
Effect.ShadersStore[`${shaderName}VertexShader`] = butterflyVertex;
Expand All @@ -28,7 +29,8 @@ export function createButterflyMaterial(player: TransformNode, light: Directiona
let elapsedSeconds = 0;
scene.onBeforeRenderObservable.add(() => {
elapsedSeconds += scene.getEngine().getDeltaTime() / 1000;
butterflyMaterial.setVector3("playerPosition", player.position);
const playerPosition = player?.position ?? new Vector3(0, 500, 0);
butterflyMaterial.setVector3("playerPosition", playerPosition);
butterflyMaterial.setFloat("time", elapsedSeconds);
});

Expand Down
2 changes: 1 addition & 1 deletion src/ts/flatfield.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ const butterfly = createButterfly(scene);
butterfly.position.y = 1;
butterfly.isVisible = false;

const butterflyMaterial = createButterflyMaterial(character, light, scene);
const butterflyMaterial = createButterflyMaterial(light, scene, character);
butterfly.material = butterflyMaterial;

const butterflyPatch = ThinInstancePatch.CreateSquare(Vector3.Zero(), patchSize * fieldRadius * 2, 100);
Expand Down
7 changes: 4 additions & 3 deletions src/ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,20 @@ import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera";

import windSound from "../assets/wind.mp3";

import "@babylonjs/core/Collisions/collisionCoordinator";
import "@babylonjs/core/Audio/audioSceneComponent";
import "@babylonjs/core/Audio/audioEngine";
import { Sound } from "@babylonjs/core/Audio/sound";
import { Engine } from "@babylonjs/core/Engines/engine";

import "@babylonjs/core/Physics/physicsEngineComponent";
import { PatchManager } from "./instancing/patchManager";
import { downSample, randomDownSample } from "./utils/matrixBuffer";
import { Terrain } from "./terrain/terrain";

import "@babylonjs/core/Collisions/collisionCoordinator";
import "@babylonjs/core/Physics/physicsEngineComponent";
import HavokPhysics from "@babylonjs/havok";
import { HavokPlugin } from "@babylonjs/core/Physics/v2/Plugins/havokPlugin";

import { IPatch } from "./instancing/iPatch";
import { InstancePatch } from "./instancing/instancePatch";
import { TerrainChunk } from "./terrain/terrainChunk";
Expand Down Expand Up @@ -92,7 +93,7 @@ const butterfly = createButterfly(scene);
butterfly.position.y = 1;
butterfly.isVisible = false;

const butterflyMaterial = createButterflyMaterial(character, light, scene);
const butterflyMaterial = createButterflyMaterial(light, scene, character);
butterfly.material = butterflyMaterial;

const tree = await createTree(scene);
Expand Down
27 changes: 25 additions & 2 deletions src/ts/planet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ import "@babylonjs/core/Misc/screenshotTools";
import { Tools } from "@babylonjs/core/Misc/tools";
import { HemisphericLight } from "@babylonjs/core/Lights/hemisphericLight";

import "@babylonjs/core/Collisions/collisionCoordinator";
import "@babylonjs/core/Physics/physicsEngineComponent";
import HavokPhysics from "@babylonjs/havok";
import { HavokPlugin } from "@babylonjs/core/Physics/v2/Plugins/havokPlugin";
import { createCharacterController } from "./utils/character";
import { setUpVector } from "./utils/algebra";

// Init babylonjs
const canvas = document.getElementById("renderer") as HTMLCanvasElement;
canvas.width = window.innerWidth;
Expand All @@ -24,9 +31,15 @@ canvas.height = window.innerHeight;
const engine = new Engine(canvas, true);
engine.displayLoadingUI();

const havokInstance = await HavokPhysics();
const havokPlugin = new HavokPlugin(true, havokInstance);

const scene = new Scene(engine);
scene.enablePhysics(Vector3.Zero(), havokPlugin);

const camera = new ArcRotateCamera("camera", 0, 1.4, 10, Vector3.Zero(), scene);
const planetRadius = 10;

const camera = new ArcRotateCamera("camera", 0, 1.4, 6, Vector3.Zero(), scene);
camera.attachControl();

const light = new DirectionalLight("light", new Vector3(1, -2, -2).normalize(), scene);
Expand All @@ -35,8 +48,18 @@ ambient.intensity = 0.2;

createSkybox(scene, light.direction.scale(-1));

const character = await createCharacterController(scene, camera);
scene.onAfterPhysicsObservable.add(() => {
setUpVector(character, character.position.subtract(planet.node.position).normalize());

camera.upVector = character.up;

character.computeWorldMatrix(true);
camera.getViewMatrix(true);
});

// Interesting part starts here
const planet = new Planet(4, scene);
const planet = new Planet(planetRadius, scene);

document.addEventListener("keypress", (e) => {
if (e.key === "p") {
Expand Down
29 changes: 21 additions & 8 deletions src/ts/planet/planetChunk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@ import { createGrassMaterial } from "../grass/grassMaterial";
import { DirectionalLight } from "@babylonjs/core/Lights/directionalLight";
import { ThinInstancePatch } from "../instancing/thinInstancePatch";
import { MeshBuilder } from "@babylonjs/core/Meshes/meshBuilder";
import { downSample, randomDownSample } from "../utils/matrixBuffer";
import { downSample } from "../utils/matrixBuffer";
import { createTree } from "../utils/tree";
import { createButterfly } from "../butterfly/butterfly";
import { createButterflyMaterial } from "../butterfly/butterflyMaterial";
import { PhysicsAggregate } from "@babylonjs/core/Physics/v2/physicsAggregate";
import { PhysicsShapeType } from "@babylonjs/core/Physics/v2/IPhysicsEnginePlugin";
import { InstancePatch } from "../instancing/instancePatch";

export enum Direction {
Expand Down Expand Up @@ -163,39 +167,48 @@ export class PlanetChunk {

vertexData.applyToMesh(this.mesh);

new PhysicsAggregate(this.mesh, PhysicsShapeType.MESH, { mass: 0 }, scene);

this.scatterAssets(scene);
}

scatterAssets(scene: Scene) {
const grassBlade = createGrassBlade(scene, 2);
grassBlade.isVisible = false;
const grassMaterial = createGrassMaterial(scene.lights[0] as DirectionalLight, scene);
grassBlade.material = grassMaterial;
grassBlade.material = createGrassMaterial(scene.lights[0] as DirectionalLight, scene);

const patch = new ThinInstancePatch(this.mesh.position, this.alignedInstancesMatrixBuffer);
patch.createInstances(grassBlade);

createTree(scene).then((tree) => {
/*createTree(scene).then((tree) => {
tree.scaling.scaleInPlace(3);
tree.position.y = -1;
tree.bakeCurrentTransformIntoVertices();
tree.isVisible = false;
const treePatch = new ThinInstancePatch(this.mesh.position, downSample(this.instancesMatrixBuffer, 10000));
const treePatch = new ThinInstancePatch(this.mesh.position, downSample(this.instancesMatrixBuffer, 20000));
treePatch.createInstances(tree);
});
});*/

const cube = MeshBuilder.CreateBox("cube", { size: 1 }, scene);
cube.position.y = 0.5;
cube.bakeCurrentTransformIntoVertices();
cube.isVisible = false;
const cubePatch = new ThinInstancePatch(this.mesh.position, downSample(this.instancesMatrixBuffer, 3000));
cube.checkCollisions = true;
const cubePatch = new InstancePatch(this.mesh.position, downSample(this.instancesMatrixBuffer, 5000));
cubePatch.createInstances(cube);

/*const butterfly = createButterfly(scene);
//butterfly.position.y = 1;
//butterfly.bakeCurrentTransformIntoVertices();
butterfly.material = createButterflyMaterial(scene.lights[0] as DirectionalLight, scene);
butterfly.isVisible = false;
const butterflyPatch = new ThinInstancePatch(this.mesh.position, downSample(this.instancesMatrixBuffer, 1000));
butterflyPatch.createInstances(butterfly);*/
}
}

function terrainFunction(position: Vector3): [height: number, grad: Vector3] {
const heightMultiplier = 0.2;
const heightMultiplier = 0.2 * 0;
const frequency = 3;
const height = Math.cos(position.x * frequency) * Math.sin(position.y * frequency) * Math.cos(position.z * frequency) * heightMultiplier;
const gradX = -Math.sin(position.x * frequency) * Math.sin(position.y * frequency) * Math.cos(position.z * frequency) * frequency * heightMultiplier;
Expand Down
8 changes: 8 additions & 0 deletions src/ts/utils/algebra.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import { Quaternion, Vector3 } from "@babylonjs/core/Maths/math.vector";
import { TransformNode } from "@babylonjs/core/Meshes/transformNode";

export function getTransformationQuaternion(from: Vector3, to: Vector3): Quaternion {
const rotationAxis = Vector3.Cross(from, to);
const angle = Math.acos(Vector3.Dot(from, to));
return Quaternion.RotationAxis(rotationAxis, angle);
}

export function setUpVector(transformNode: TransformNode, newUpVector: Vector3) {
const currentUpVector = transformNode.up;
const rotationQuaternion = getTransformationQuaternion(currentUpVector, newUpVector);
if(transformNode.rotationQuaternion === null) transformNode.rotationQuaternion = rotationQuaternion;
else transformNode.rotationQuaternion = rotationQuaternion.multiply(transformNode.rotationQuaternion);
}
13 changes: 3 additions & 10 deletions src/ts/utils/character.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { TransformNode } from "@babylonjs/core/Meshes/transformNode";
import { PhysicsRaycastResult } from "@babylonjs/core/Physics/physicsRaycastResult";
import { PhysicsEngineV2 } from "@babylonjs/core/Physics/v2";
import { ActionManager, ExecuteCodeAction } from "@babylonjs/core/Actions";
import { setUpVector } from "./algebra";

export async function createCharacterController(scene: Scene, camera: ArcRotateCamera): Promise<AbstractMesh> {
const result = await SceneLoader.ImportMeshAsync("", "", character, scene);
Expand Down Expand Up @@ -115,20 +116,12 @@ export async function createCharacterController(scene: Scene, camera: ArcRotateC
}

// downward raycast
const start = hero.position.add(Vector3.Up().scale(50));
const end = hero.position.add(Vector3.Down().scale(50));
const start = hero.position.add(hero.up.scale(50));
const end = hero.position.add(hero.up.scale(-50));
(scene.getPhysicsEngine() as PhysicsEngineV2).raycastToRef(start, end, raycastResult);
if (raycastResult.hasHit) {
hero.position.y = raycastResult.hitPointWorld.y + 0.01;
}

// camera down raycast
const cameraStart = camera.position.add(Vector3.Up().scale(50));
const cameraEnd = camera.position.add(Vector3.Down().scale(50));
(scene.getPhysicsEngine() as PhysicsEngineV2).raycastToRef(cameraStart, cameraEnd, raycastResult);
if (raycastResult.hasHit) {
camera.position.y = raycastResult.hitPointWorld.y + 0.01;
}
});

return hero;
Expand Down

0 comments on commit d3d97fc

Please sign in to comment.