Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
let endRight = buffer.data.subarray(
(pos + 1) * 9 + 3, (pos + 1) * 9 + 6);
let endUp = buffer.data.subarray(
(pos + 1) * 9 + 6, (pos + 1) * 9 + 9);
// Then lerp... kinda.
let right = vec3.create();
vec3.lerp(right, startRight, endRight, lerpTimer % 1);
let up = vec3.create();
vec3.lerp(up, startUp, endUp, lerpTimer % 1);
let eye = vec3.create();
vec3.lerp(eye, start, end, lerpTimer % 1);
vec3.add(eye, eye, up);
let front = vec3.create();
vec3.cross(front, up, right);
vec3.normalize(front, front);
let center = vec3.create();
vec3.add(center, front, eye);
// console.log(start, end);
// Last, create view matrix from these three vectors.
mat4.lookAt(context.cameraObj.viewMatrix, eye, center, up);
// context.cameraObj.transform.position.set(eye);
// context.cameraObj.transform.invalidate();
let slope = vec3.dot(front, [0, -1, 0]);
lerpAccel *= 0.98;
lerpAccel += slope / 30;
lerpAccel = Math.max(0.5, Math.min(1.5, lerpAccel));
lerpTimer += delta * 5 * (lerpAccel + Math.max(0, slope + 1));
if ((lerpTimer + 1) >= buffer.data.length / 9) {
lerpTimer = -1;
}
}
renderer.render({
function quatLookAt(out, front, up) {
let zFront = vec3.create();
vec3.normalize(zFront, front);
// vec3.scale(zFront, zFront, -1);
let right = vec3.create();
vec3.cross(right, up, zFront);
vec3.normalize(right, right);
if (vec3.length(right) < 0.0001) {
right = [1, 0, 0];
}
let yUp = vec3.create();
vec3.cross(yUp, zFront, right);
let mat = [
right[0], right[1], right[2],
yUp[0], yUp[1], yUp[2],
zFront[0], zFront[1], zFront[2]
/* right[0], yUp[0], zFront[0],
right[1], yUp[1], zFront[1],
import {VEC3_UNIT_Z} from '../../../common/gl-matrix-addon';
import {degToRad, randomInRange, lerp} from '../../../common/math';
import {uint8ToUint24} from '../../../common/typecast';
// Heap allocations needed for this module.
let rotationHeap = quat.create();
let locationHeap = vec3.create();
let colorHeap = new Uint8Array(4);
let widthHeap = new Float32Array(1);
let lengthHeap = new Float32Array(1);
let latitudeHeap = new Float32Array(1);
let variationHeap = new Float32Array(1);
let speedHeap = new Float32Array(1);
let gravityHeap = new Float32Array(1);
let mat3Heap = new Float32Array(9);
let vec3Heap = [vec3.create(), vec3.create(), vec3.create(), vec3.create(), vec3.create(), vec3.create()];
/**
* A type 2 particle.
*/
export default class Particle2 {
/**
* @param {MdxParticle2Emitter} emitter
*/
constructor(emitter) {
this.emitter = emitter;
this.emitterView = null;
this.health = 0;
this.head = true;
this.location = vec3.create();
this.velocity = vec3.create();
this.gravity = 0;
calculateNormals() {
if (this.vertices === null) throw new Error('Vertices array is null');
let indices = this.vertexIndices;
if (indices == null) throw new Error('Position indices is null');
// One vec3 per one face. so indices / 3 * 3.
let normals = new Float32Array(indices.length);
let normalIndices = createIndicesArray(indices.length / 3, indices.length);
let normalId = 0;
for (let faceId = 0; faceId < indices.length; faceId += 3) {
const vertexId1 = indices[faceId];
const vertexId2 = indices[faceId + 1];
const vertexId3 = indices[faceId + 2];
// Calculate normal vector.
let origin = this.vertices.slice(vertexId1 * 3, vertexId1 * 3 + 3);
let p1 = vec3.create(), p2 = vec3.create();
let uv = vec3.create();
vec3.subtract(p1, this.vertices.slice(vertexId2 * 3, vertexId2 * 3 + 3),
origin);
vec3.subtract(p2, this.vertices.slice(vertexId3 * 3, vertexId3 * 3 + 3),
origin);
vec3.cross(uv, p1, p2);
vec3.normalize(uv, uv);
// Done. Store them in normals buffer, and set indices to it.
normals.set(uv, normalId * 3);
normalIndices[faceId] = normalId;
normalIndices[faceId + 1] = normalId;
normalIndices[faceId + 2] = normalId;
normalId ++;
}
this.normals = normals;
this.normalIndices = normalIndices;
}
case 0x046: return new ShinyObject(geometryData, emitters, .015, 230); // jiggy
case 0x047: return new ShinyObject(geometryData, emitters, .03, 200); // empty honeycomb
case 0x1d8: return new ShinyObject(geometryData, emitters, 1 / 60, 0, SparkleColor.DarkBlue);
case 0x1d9: return new ShinyObject(geometryData, emitters, 1 / 60, 0, SparkleColor.Red);
case 0x1da: return new ShinyObject(geometryData, emitters, 1 / 60);
case 0x0e6: return new Gloop(geometryData, emitters);
case 0x0f1: return new RailRider(geometryData); //swamp leaf
case 0x123: return new MagicCarpet(geometryData);
case 0x348: return new Brentilda(geometryData, emitters);
}
return new GeometryRenderer(geometryData);
}
const movementScratch = vec3.create();
class Bobber implements MovementController {
private speed = 80 + 20 * Math.random();
private basePos = vec3.create();
private baseYaw = 0;
private baseRoll = 0;
private baseScale = 1;
protected amplitudes = nArray(3, () => 0);
constructor(obj: GeometryRenderer) {
mat4.getTranslation(this.basePos, obj.modelMatrix);
mat4.getScaling(movementScratch, obj.modelMatrix);
this.baseScale = movementScratch[0]; // assume uniform
// BK uses a slightly different convention than the existing logic
this.baseRoll = Math.atan2(obj.modelMatrix[1], obj.modelMatrix[5]);
this.baseYaw = -Math.atan2(obj.modelMatrix[2], obj.modelMatrix[0]);
// nothing sets pitch, so ignore
newArray[buffer.data.length + 1] = pos[1];
newArray[buffer.data.length + 2] = pos[2];
if (buffer.data.length >= 18) {
let currentFront = vec3.create();
getFront(currentFront, newArray.subarray(buffer.data.length - 9),
newArray.subarray(buffer.data.length));
let prevFront = vec3.create();
getFront(prevFront, newArray.subarray(buffer.data.length - 18),
newArray.subarray(buffer.data.length - 9));
let currentRight = vec3.create();
let prevRight = vec3.create();
getRight(currentRight, currentFront);
getRight(prevRight, prevFront);
let currentUp = vec3.create();
let prevUp = vec3.create();
getUp(currentUp, currentFront, currentRight);
getUp(prevUp, prevFront, prevRight);
vec3.lerp(prevRight, prevRight, currentRight, 0.5);
vec3.lerp(prevUp, prevUp, currentUp, 0.5);
newArray.set(prevRight, buffer.data.length - 6);
newArray.set(currentRight, buffer.data.length + 3);
newArray.set(prevUp, buffer.data.length - 3);
newArray.set(currentUp, buffer.data.length + 6);
} else if (buffer.data.length >= 9) {
let front = vec3.create();
getFront(front, newArray.subarray(buffer.data.length - 9),
newArray.subarray(buffer.data.length));
getRight(newArray.subarray(buffer.data.length - 6), front);
selectUnit(x, y, toggle) {
let ray = new Float32Array(6);
this.camera.screenToWorldRay(ray, [x, y]);
let dir = normalHeap1;
dir[0] = ray[3] - ray[0];
dir[1] = ray[4] - ray[1];
dir[2] = ray[5] - ray[2];
vec3.normalize(dir, dir);
let eMid = vec3.create(), eSize = vec3.create(), rDir = vec3.create();
let entity = null;
let entDist = 1e+6;
this.units.forEach(ent => {
let {instance, location, radius} = ent;
vec3.set(eMid, 0, 0, radius / 2);
vec3.set(eSize, radius, radius, radius);
vec3.add(eMid, eMid, location);
vec3.sub(eMid, eMid, ray);
vec3.div(eMid, eMid, eSize);
vec3.div(rDir, dir, eSize);
let dlen = vec3.sqrLen(rDir);
let dp = Math.max(0, vec3.dot(rDir, eMid)) / dlen;
if (dp > entDist) return;
import { SceneObjHolder } from "./Main";
import { JMapInfoIter, getJMapInfoScale } from "./JMapInfo";
import { DrawType, DrawBufferType, CalcAnimType, MovementType, NameObj } from "./NameObj";
import { assertExists } from "../util";
import { BTIData, BTI } from "../Common/JSYSTEM/JUTTexture";
import { RARC } from "../j3d/rarc";
import { getRes, XanimePlayer } from "./Animation";
import { vec3, vec2, mat4 } from "gl-matrix";
import { HitSensor } from "./HitSensor";
import { RailDirection } from "./RailRider";
import { isNearZero, isNearZeroVec3 } from "../MathHelpers";
import { Camera, texProjCameraSceneTex } from "../Camera";
import { NormalizedViewportCoords } from "../gfx/helpers/RenderTargetHelpers";
import { GravityInfo, GravityTypeMask } from "./Gravity";
const scratchVec3 = vec3.create();
export function connectToScene(sceneObjHolder: SceneObjHolder, nameObj: NameObj, movementType: MovementType, calcAnimType: CalcAnimType, drawBufferType: DrawBufferType, drawType: DrawType): void {
sceneObjHolder.sceneNameObjListExecutor.registerActor(nameObj, movementType, calcAnimType, drawBufferType, drawType);
}
export function connectToSceneMapObjMovement(sceneObjHolder: SceneObjHolder, nameObj: NameObj): void {
sceneObjHolder.sceneNameObjListExecutor.registerActor(nameObj, 0x22, -1, -1, -1);
}
export function connectToSceneNpc(sceneObjHolder: SceneObjHolder, nameObj: NameObj): void {
sceneObjHolder.sceneNameObjListExecutor.registerActor(nameObj, 0x28, 0x06, DrawBufferType.NPC, -1);
}
export function connectToSceneIndirectNpc(sceneObjHolder: SceneObjHolder, nameObj: NameObj): void {
sceneObjHolder.sceneNameObjListExecutor.registerActor(nameObj, 0x28, 0x06, DrawBufferType.INDIRECT_NPC, -1);
}
private createParticle (emitter: ParticleEmitterWrapper, emitterMatrix: mat4) {
let particle: Particle;
if (particleStorage.length) {
particle = particleStorage.pop();
} else {
particle = {
emitter: null,
pos: vec3.create(),
angle: 0,
speed: vec3.create(),
gravity: null,
lifeSpan: null
};
}
let width: number = this.interp.animVectorVal(emitter.props.Width, 0);
let length: number = this.interp.animVectorVal(emitter.props.Length, 0);
let speedScale: number = this.interp.animVectorVal(emitter.props.Speed, 0);
let variation: number = this.interp.animVectorVal(emitter.props.Variation, 0);
let latitude: number = degToRad(this.interp.animVectorVal(emitter.props.Latitude, 0));
particle.emitter = emitter;
particle.pos[0] = emitter.props.PivotPoint[0] + rand(-width, width);
particle.pos[1] = emitter.props.PivotPoint[1] + rand(-length, length);
particle.pos[2] = emitter.props.PivotPoint[2];
getInitialDeformedVertices(featurePoints) {
let displacement = featurePoints.map((c, i) => {
let fp = this.getPosition(this.data.face.featurePoint[i])
let scale = (500 - fp[2] * 200) / 500
let p = vec3.clone(fp)
p[0] = (c[0] - 0.5) * scale
p[1] = (c[1] - 0.5) * scale
return vec3.sub(p, p, fp)
})
let n = this.data.face.position.length / 3
let position = new Float32Array(n * 3)
for (let i = 0; i < n; i++) {
let p = vec3.create()
let b = 0
this.data.face.weight[i].forEach((w) => {
vec3.add(p, p, vec3.scale(vec3.create(), displacement[w[0]], w[1]))
b += w[1]
})
vec3.scale(p, p, 1 / b)
vec3.add(p, p, this.getPosition(i))
position[i * 3 + 0] = p[0]
position[i * 3 + 1] = p[1]
position[i * 3 + 2] = p[2]
}
return new THREE.BufferAttribute(position, 3)
}