mirror of
https://github.com/overte-org/overte.git
synced 2025-04-26 07:16:25 +02:00
154 lines
5.3 KiB
JavaScript
154 lines
5.3 KiB
JavaScript
//
|
|
// planky.js
|
|
// examples
|
|
//
|
|
// Created by Thijs Wenker on 5/2/14.
|
|
// Copyright 2015 High Fidelity, Inc.
|
|
//
|
|
// Pull blocks off the bottom and put them on the top using the grab.js script.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
|
|
|
const NUM_LAYERS = 16;
|
|
const BASE_DIMENSION = { x: 7, y: 2, z: 7 };
|
|
const BLOCKS_PER_LAYER = 3;
|
|
const BLOCK_SIZE = {x: 0.2, y: 0.1, z: 0.8};
|
|
const BLOCK_SPACING = BLOCK_SIZE.x / 3;
|
|
// BLOCK_HEIGHT_VARIATION removes a random percentages of the default block height per block. (for example 0.001 %)
|
|
const BLOCK_HEIGHT_VARIATION = 0.001;
|
|
const GRAVITY = {x: 0, y: -2.8, z: 0};
|
|
const DENSITY = 2000;
|
|
const DAMPING_FACTOR = 0.98;
|
|
const ANGULAR_DAMPING_FACTOR = 0.8;
|
|
const FRICTION = 0.99;
|
|
const RESTITUTION = 0.0;
|
|
const SPAWN_DISTANCE = 3;
|
|
const BLOCK_YAW_OFFSET = 45;
|
|
const BUTTON_DIMENSIONS = {width: 49, height: 49};
|
|
const MAXIMUM_PERCENTAGE = 100.0;
|
|
|
|
var windowWidth = Window.innerWidth;
|
|
var size;
|
|
var pieces = [];
|
|
var ground = false;
|
|
var layerRotated = false;
|
|
|
|
function grabLowestJointY() {
|
|
var jointNames = MyAvatar.getJointNames();
|
|
var floorY = MyAvatar.position.y;
|
|
for (var jointName in jointNames) {
|
|
if (MyAvatar.getJointPosition(jointNames[jointName]).y < floorY) {
|
|
floorY = MyAvatar.getJointPosition(jointNames[jointName]).y;
|
|
}
|
|
}
|
|
return floorY;
|
|
}
|
|
|
|
function getButtonPosX() {
|
|
return windowWidth - ((BUTTON_DIMENSIONS.width / 2) + BUTTON_DIMENSIONS.width);
|
|
}
|
|
|
|
var button = Overlays.addOverlay('image', {
|
|
x: getButtonPosX(),
|
|
y: 10,
|
|
width: BUTTON_DIMENSIONS.width,
|
|
height: BUTTON_DIMENSIONS.height,
|
|
imageURL: HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/planky_button.svg',
|
|
alpha: 0.8
|
|
});
|
|
|
|
|
|
function resetBlocks() {
|
|
pieces.forEach(function(piece) {
|
|
Entities.deleteEntity(piece);
|
|
});
|
|
pieces = [];
|
|
var avatarRot = Quat.fromPitchYawRollDegrees(0.0, MyAvatar.bodyYaw, 0.0);
|
|
basePosition = Vec3.sum(MyAvatar.position, Vec3.multiply(SPAWN_DISTANCE, Quat.getFront(avatarRot)));
|
|
basePosition.y = grabLowestJointY() - (BASE_DIMENSION.y / 2);
|
|
if (!ground) {
|
|
ground = Entities.addEntity({
|
|
type: 'Model',
|
|
modelURL: HIFI_PUBLIC_BUCKET + 'eric/models/woodFloor.fbx',
|
|
dimensions: BASE_DIMENSION,
|
|
position: basePosition,
|
|
rotation: avatarRot,
|
|
shapeType: 'box'
|
|
});
|
|
} else {
|
|
Entities.editEntity(ground, {position: basePosition, rotation: avatarRot});
|
|
}
|
|
var offsetRot = Quat.multiply(avatarRot, Quat.fromPitchYawRollDegrees(0.0, BLOCK_YAW_OFFSET, 0.0));
|
|
basePosition.y += (BASE_DIMENSION.y / 2);
|
|
for (var layerIndex = 0; layerIndex < NUM_LAYERS; layerIndex++) {
|
|
var layerRotated = layerIndex % 2 === 0;
|
|
var offset = -(BLOCK_SPACING);
|
|
var layerRotation = Quat.fromPitchYawRollDegrees(0, layerRotated ? 0 : 90, 0.0);
|
|
for (var blockIndex = 0; blockIndex < BLOCKS_PER_LAYER; blockIndex++) {
|
|
var blockPositionXZ = BLOCK_SIZE.x * blockIndex - (BLOCK_SIZE.x * 3 / 2 - BLOCK_SIZE.x / 2);
|
|
var localTransform = Vec3.multiplyQbyV(offsetRot, {
|
|
x: (layerRotated ? blockPositionXZ + offset: 0),
|
|
y: (BLOCK_SIZE.y / 2) + (BLOCK_SIZE.y * layerIndex),
|
|
z: (layerRotated ? 0 : blockPositionXZ + offset)
|
|
});
|
|
pieces.push(Entities.addEntity({
|
|
type: 'Model',
|
|
modelURL: HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/block.fbx',
|
|
shapeType: 'box',
|
|
name: 'PlankyBlock' + ((layerIndex * BLOCKS_PER_LAYER) + blockIndex),
|
|
dimensions: {
|
|
x: BLOCK_SIZE.x,
|
|
y: BLOCK_SIZE.y - ((BLOCK_SIZE.y * (BLOCK_HEIGHT_VARIATION / MAXIMUM_PERCENTAGE)) * Math.random()),
|
|
z: BLOCK_SIZE.z
|
|
},
|
|
position: {
|
|
x: basePosition.x + localTransform.x,
|
|
y: basePosition.y + localTransform.y,
|
|
z: basePosition.z + localTransform.z
|
|
},
|
|
rotation: Quat.multiply(layerRotation, offsetRot),
|
|
collisionsWillMove: true,
|
|
damping: DAMPING_FACTOR,
|
|
restitution: RESTITUTION,
|
|
friction: FRICTION,
|
|
angularDamping: ANGULAR_DAMPING_FACTOR,
|
|
gravity: GRAVITY,
|
|
density: DENSITY
|
|
}));
|
|
offset += BLOCK_SPACING;
|
|
}
|
|
}
|
|
}
|
|
|
|
function mousePressEvent(event) {
|
|
var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y});
|
|
if (clickedOverlay === button) {
|
|
resetBlocks();
|
|
}
|
|
}
|
|
|
|
Controller.mousePressEvent.connect(mousePressEvent);
|
|
|
|
function cleanup() {
|
|
Overlays.deleteOverlay(button);
|
|
if (ground) {
|
|
Entities.deleteEntity(ground);
|
|
}
|
|
pieces.forEach(function(piece) {
|
|
Entities.deleteEntity(piece);
|
|
});
|
|
pieces = [];
|
|
}
|
|
|
|
function onUpdate() {
|
|
if (windowWidth != Window.innerWidth) {
|
|
windowWidth = Window.innerWidth;
|
|
Overlays.editOverlay(button, {x: getButtonPosX()});
|
|
}
|
|
}
|
|
|
|
Script.update.connect(onUpdate)
|
|
Script.scriptEnding.connect(cleanup);
|