mirror of
https://github.com/lubosz/overte.git
synced 2025-04-14 14:46:55 +02:00
Merge pull request #5360 from BingShearer/Leaves
New falling leaf script based on the existing rain.js
This commit is contained in:
commit
6e41a79551
1 changed files with 331 additions and 0 deletions
331
examples/leaves.js
Executable file
331
examples/leaves.js
Executable file
|
@ -0,0 +1,331 @@
|
|||
//
|
||||
// Leaves.js
|
||||
// examples
|
||||
//
|
||||
// Created by Bing Shearer on 14 Jul 2015
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
var leafName = "scriptLeaf";
|
||||
var leafSquall = function (properties) {
|
||||
var // Properties
|
||||
squallOrigin,
|
||||
squallRadius,
|
||||
leavesPerMinute = 60,
|
||||
leafSize = {
|
||||
x: 0.1,
|
||||
y: 0.1,
|
||||
z: 0.1
|
||||
},
|
||||
leafFallSpeed = 1, // m/s
|
||||
leafLifetime = 60, // Seconds
|
||||
leafSpinMax = 0, // Maximum angular velocity per axis; deg/s
|
||||
debug = false, // Display origin circle; don't use running on Stack Manager
|
||||
// Other
|
||||
squallCircle,
|
||||
SQUALL_CIRCLE_COLOR = {
|
||||
red: 255,
|
||||
green: 0,
|
||||
blue: 0
|
||||
},
|
||||
SQUALL_CIRCLE_ALPHA = 0.5,
|
||||
SQUALL_CIRCLE_ROTATION = Quat.fromPitchYawRollDegrees(90, 0, 0),
|
||||
leafProperties,
|
||||
leaf_MODEL_URL = "https://hifi-public.s3.amazonaws.com/ozan/support/forBing/palmLeaf.fbx",
|
||||
leafTimer,
|
||||
leaves = [], // HACK: Work around leaves not always getting velocities
|
||||
leafVelocities = [], // HACK: Work around leaves not always getting velocities
|
||||
DEGREES_TO_RADIANS = Math.PI / 180,
|
||||
leafDeleteOnTearDown = true,
|
||||
maxLeaves,
|
||||
leafCount,
|
||||
nearbyEntities,
|
||||
complexMovement = false,
|
||||
movementTime = 0,
|
||||
maxSpinRadians = properties.leafSpinMax * DEGREES_TO_RADIANS,
|
||||
windFactor,
|
||||
leafDeleteOnGround = false,
|
||||
floorHeight = null;
|
||||
|
||||
|
||||
function processProperties() {
|
||||
if (!properties.hasOwnProperty("origin")) {
|
||||
print("ERROR: Leaf squall origin must be specified");
|
||||
return;
|
||||
}
|
||||
squallOrigin = properties.origin;
|
||||
|
||||
if (!properties.hasOwnProperty("radius")) {
|
||||
print("ERROR: Leaf squall radius must be specified");
|
||||
return;
|
||||
}
|
||||
squallRadius = properties.radius;
|
||||
|
||||
if (properties.hasOwnProperty("leavesPerMinute")) {
|
||||
leavesPerMinute = properties.leavesPerMinute;
|
||||
}
|
||||
|
||||
if (properties.hasOwnProperty("leafSize")) {
|
||||
leafSize = properties.leafSize;
|
||||
}
|
||||
|
||||
if (properties.hasOwnProperty("leafFallSpeed")) {
|
||||
leafFallSpeed = properties.leafFallSpeed;
|
||||
}
|
||||
|
||||
if (properties.hasOwnProperty("leafLifetime")) {
|
||||
leafLifetime = properties.leafLifetime;
|
||||
}
|
||||
|
||||
if (properties.hasOwnProperty("leafSpinMax")) {
|
||||
leafSpinMax = properties.leafSpinMax;
|
||||
}
|
||||
|
||||
if (properties.hasOwnProperty("debug")) {
|
||||
debug = properties.debug;
|
||||
}
|
||||
if (properties.hasOwnProperty("floorHeight")) {
|
||||
floorHeight = properties.floorHeight;
|
||||
}
|
||||
if (properties.hasOwnProperty("maxLeaves")) {
|
||||
maxLeaves = properties.maxLeaves;
|
||||
}
|
||||
if (properties.hasOwnProperty("complexMovement")) {
|
||||
complexMovement = properties.complexMovement;
|
||||
}
|
||||
if (properties.hasOwnProperty("leafDeleteOnGround")) {
|
||||
leafDeleteOnGround = properties.leafDeleteOnGround;
|
||||
}
|
||||
if (properties.hasOwnProperty("windFactor")) {
|
||||
windFactor = properties.windFactor;
|
||||
} else if (complexMovement == true){
|
||||
print("ERROR: Wind Factor must be defined for complex movement")
|
||||
}
|
||||
|
||||
leafProperties = {
|
||||
type: "Model",
|
||||
name: leafName,
|
||||
modelURL: leaf_MODEL_URL,
|
||||
lifetime: leafLifetime,
|
||||
dimensions: leafSize,
|
||||
velocity: {
|
||||
x: 0,
|
||||
y: -leafFallSpeed,
|
||||
z: 0
|
||||
},
|
||||
damping: 0,
|
||||
angularDamping: 0,
|
||||
ignoreForCollisions: true
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
function createleaf() {
|
||||
var angle,
|
||||
radius,
|
||||
offset,
|
||||
leaf,
|
||||
spin = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
},
|
||||
i;
|
||||
|
||||
// HACK: Work around leaves not always getting velocities set at creation
|
||||
for (i = 0; i < leaves.length; i++) {
|
||||
Entities.editEntity(leaves[i], leafVelocities[i]);
|
||||
}
|
||||
|
||||
angle = Math.random() * leafSpinMax;
|
||||
radius = Math.random() * squallRadius;
|
||||
offset = Vec3.multiplyQbyV(Quat.fromPitchYawRollDegrees(0, angle, 0), {
|
||||
x: 0,
|
||||
y: -0.1,
|
||||
z: radius
|
||||
});
|
||||
leafProperties.position = Vec3.sum(squallOrigin, offset);
|
||||
if (properties.leafSpinMax > 0 && !complexMovement) {
|
||||
spin = {
|
||||
x: Math.random() * maxSpinRadians,
|
||||
y: Math.random() * maxSpinRadians,
|
||||
z: Math.random() * maxSpinRadians
|
||||
};
|
||||
leafProperties.angularVelocity = spin;
|
||||
} else if (complexMovement) {
|
||||
spin = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
};
|
||||
leafProperties.angularVelocity = spin
|
||||
}
|
||||
leaf = Entities.addEntity(leafProperties);
|
||||
|
||||
// HACK: Work around leaves not always getting velocities set at creation
|
||||
leaves.push(leaf);
|
||||
leafVelocities.push({
|
||||
velocity: leafProperties.velocity,
|
||||
angularVelocity: spin
|
||||
});
|
||||
if (leaves.length > 5) {
|
||||
leaves.shift();
|
||||
leafVelocities.shift();
|
||||
}
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
if (debug) {
|
||||
squallCircle = Overlays.addOverlay("circle3d", {
|
||||
size: {
|
||||
x: 2 * squallRadius,
|
||||
y: 2 * squallRadius
|
||||
},
|
||||
color: SQUALL_CIRCLE_COLOR,
|
||||
alpha: SQUALL_CIRCLE_ALPHA,
|
||||
solid: true,
|
||||
visible: debug,
|
||||
position: squallOrigin,
|
||||
rotation: SQUALL_CIRCLE_ROTATION
|
||||
});
|
||||
}
|
||||
|
||||
leafTimer = Script.setInterval(function () {
|
||||
if (leafCount <= maxLeaves - 1) {
|
||||
createleaf()
|
||||
}
|
||||
}, 60000 / leavesPerMinute);
|
||||
}
|
||||
Script.setInterval(function () {
|
||||
nearbyEntities = Entities.findEntities(squallOrigin, squallRadius);
|
||||
newLeafMovement()
|
||||
}, 100);
|
||||
|
||||
function newLeafMovement() { //new additions to leaf code. Operates at 10 Hz or every 100 ms
|
||||
movementTime += 0.1;
|
||||
var currentLeaf,
|
||||
randomRotationSpeed = {
|
||||
x: maxSpinRadians * Math.sin(movementTime),
|
||||
y: maxSpinRadians * Math.random(),
|
||||
z: maxSpinRadians * Math.sin(movementTime / 7)
|
||||
};
|
||||
for (var i = 0; i < nearbyEntities.length; i++) {
|
||||
var entityProperties = Entities.getEntityProperties(nearbyEntities[i]);
|
||||
var entityName = entityProperties.name;
|
||||
if (leafName === entityName) {
|
||||
currentLeaf = nearbyEntities[i];
|
||||
var leafHeight = entityProperties.position.y;
|
||||
if (complexMovement && leafHeight > floorHeight || complexMovement && floorHeight == null) { //actual new movement code;
|
||||
var leafCurrentVel = entityProperties.velocity,
|
||||
leafCurrentRot = entityProperties.rotation,
|
||||
yVec = {
|
||||
x: 0,
|
||||
y: 1,
|
||||
z: 0
|
||||
},
|
||||
leafYinWFVec = Vec3.multiplyQbyV(leafCurrentRot, yVec),
|
||||
leafLocalHorVec = Vec3.cross(leafYinWFVec, yVec),
|
||||
leafMostDownVec = Vec3.cross(leafYinWFVec, leafLocalHorVec),
|
||||
leafDesiredVel = Vec3.multiply(leafMostDownVec, windFactor),
|
||||
leafVelDelt = Vec3.subtract(leafDesiredVel, leafCurrentVel),
|
||||
leafNewVel = Vec3.sum(leafCurrentVel, Vec3.multiply(leafVelDelt, windFactor));
|
||||
Entities.editEntity(currentLeaf, {
|
||||
angularVelocity: randomRotationSpeed,
|
||||
velocity: leafNewVel
|
||||
})
|
||||
} else if (leafHeight <= floorHeight) {
|
||||
if (!leafDeleteOnGround) {
|
||||
Entities.editEntity(nearbyEntities[i], {
|
||||
locked: false,
|
||||
velocity: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
},
|
||||
angularVelocity: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
}
|
||||
})
|
||||
} else {
|
||||
Entity.deleteEntity(currentLeaf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
getLeafCount = Script.setInterval(function () {
|
||||
leafCount = 0
|
||||
for (var i = 0; i < nearbyEntities.length; i++) {
|
||||
var entityName = Entities.getEntityProperties(nearbyEntities[i]).name;
|
||||
//Stop Leaves at floorHeight
|
||||
if (leafName === entityName) {
|
||||
leafCount++;
|
||||
if (i == nearbyEntities.length - 1) {
|
||||
//print(leafCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 1000)
|
||||
|
||||
|
||||
|
||||
function tearDown() {
|
||||
Script.clearInterval(leafTimer);
|
||||
Overlays.deleteOverlay(squallCircle);
|
||||
if (leafDeleteOnTearDown) {
|
||||
for (var i = 0; i < nearbyEntities.length; i++) {
|
||||
var entityName = Entities.getEntityProperties(nearbyEntities[i]).name;
|
||||
if (leafName === entityName) {
|
||||
//We have a match - delete this entity
|
||||
Entities.editEntity(nearbyEntities[i], {
|
||||
locked: false
|
||||
});
|
||||
Entities.deleteEntity(nearbyEntities[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
processProperties();
|
||||
setUp();
|
||||
Script.scriptEnding.connect(tearDown);
|
||||
|
||||
return {};
|
||||
};
|
||||
|
||||
var leafSquall1 = new leafSquall({
|
||||
origin: {
|
||||
x: 3071.5,
|
||||
y: 2170,
|
||||
z: 6765.3
|
||||
},
|
||||
radius: 100,
|
||||
leavesPerMinute: 30,
|
||||
leafSize: {
|
||||
x: 0.3,
|
||||
y: 0.00,
|
||||
z: 0.3
|
||||
},
|
||||
leafFallSpeed: 0.4,
|
||||
leafLifetime: 100,
|
||||
leafSpinMax: 30,
|
||||
debug: false,
|
||||
maxLeaves: 100,
|
||||
leafDeleteOnTearDown: true,
|
||||
complexMovement: true,
|
||||
floorHeight: 2143.5,
|
||||
windFactor: 0.5,
|
||||
leafDeleteOnGround: false
|
||||
});
|
||||
|
||||
// todo
|
||||
//deal with depth issue
|
Loading…
Reference in a new issue