Land on a Square
Threejs Boilerplate : https://github.com/Sean-Bradley/Three.js-TypeScript-Boilerplate Threejs Course : https://sbcode.net/threejs/ Discount Coupons : https://sbcode.net/coupons#threejs
by seanwasere
HTML
<!--
Threejs Boilerplate : https://github.com/Sean-Bradley/Three.js-TypeScript-Boilerplate
Threejs Course : https://sbcode.net/threejs/
Discount Coupons : https://sbcode.net/coupons#threejs
-->
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
<script type="importmap">
{
"imports": {
"three": "https://cdn.skypack.dev/three@0.146.0/build/three.module",
"three/": "https://cdn.skypack.dev/three@0.146.0/",
"dat.gui": "https://cdn.skypack.dev/dat.gui",
"cannon-es": "https://cdn.jsdelivr.net/npm/cannon-es@0.19.0/dist/cannon-es.js"
}
}
</script>
<div id="instructions">
<u>LAND ON A SQUARE</u><br />
W,S to climb/descend<br />
A,D to yaw<br />
Numpad 8,5 to pitch<br />
Numpad 4,6 to bank
</div>
CSS
body {
overflow: hidden;
margin: 0px;
}
#instructions {
color: white;
position: absolute;
left: 100px;
top: 10px;
font-family: monospace;
}
JavaScript
import * as THREE from 'three';
import Stats from 'three/examples/jsm/libs/stats.module.js';
import {
GUI
} from 'dat.gui';
import {
OrbitControls
} from 'three/examples/jsm/controls/OrbitControls';
import {
Water
} from 'three/examples/jsm/objects/Water';
import {
Sky
} from "three/examples/jsm/objects/Sky";
import * as CANNON from 'cannon-es'
var stats;
var camera, scene, renderer;
var water, waterCompiled = false;
var light, helper, lightShift = new THREE.Vector3(0, 1, 0);
var clock, delta, numHelipads;
var world, cannonDebugRenderer;
var rotorBody, heliBody, helipadBodies;
var rotorMesh, heliBodyMesh, helipadMeshes;
var v = new THREE.Vector3();
var chaseCamPivot;
var banking = false;
var climbing = false;
var pitching = false;
var yawing = false;
var stableLift = 14.7;
var thrust = new CANNON.Vec3(0, 5, 0);
var keyMap = {};
var onDocumentKey = function(e) {
keyMap[e.key] = e.type === 'keydown';
};
document.addEventListener('keydown', onDocumentKey, false);
document.addEventListener('keyup', onDocumentKey, false);
const waves = [{
direction: 45,
steepness: 0.1,
wavelength: 7,
},
{
direction: 306,
steepness: 0.2,
wavelength: 32,
},
{
direction: 196,
steepness: 0.3,
wavelength: 59,
},
];
function getWaveInfo(x, z, time) {
const pos = new THREE.Vector3();
const tangent = new THREE.Vector3(1, 0, 0);
const binormal = new THREE.Vector3(0, 0, 1);
Object.keys(waves).forEach((wave) => {
const w = waves[wave];
const k = (Math.PI * 2) / w.wavelength;
const c = Math.sqrt(9.8 / k);
const d = new THREE.Vector2(
Math.sin((w.direction * Math.PI) / 180),
-Math.cos((w.direction * Math.PI) / 180)
);
const f = k * (d.dot(new THREE.Vector2(x, z)) - c * time);
const a = w.steepness / k;
pos.x += d.y * (a * Math.cos(f));
pos.y += a * Math.sin(f);
pos.z += d.x * (a * Math.cos(f));
tangent.x += -d.x * d.x * (w.steepness * Math.sin(f));
tangent.y += d.x *...