mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 00:57:24 +02:00
branch
This commit is contained in:
parent
19a72871ac
commit
03a4de4f92
3 changed files with 60 additions and 213 deletions
|
@ -1,13 +1,13 @@
|
||||||
var fishtank;
|
var fishtank;
|
||||||
|
|
||||||
var TANK_DIMENSIONS = {
|
var TANK_DIMENSIONS = {
|
||||||
x: 1,
|
x: 1.3393,
|
||||||
y: 1,
|
y: 1.3515,
|
||||||
z: 2
|
z: 3.5914
|
||||||
};
|
};
|
||||||
|
|
||||||
var TANK_WIDTH = 3.0;
|
var TANK_WIDTH = TANK_DIMENSIONS.z;
|
||||||
var TANK_HEIGHT = 1.0;
|
var TANK_HEIGHT = TANK_DIMENSIONS.y;
|
||||||
|
|
||||||
var DEBUG_COLOR = {
|
var DEBUG_COLOR = {
|
||||||
red: 255,
|
red: 255,
|
||||||
|
@ -21,10 +21,13 @@ var TANK_POSITION = center;
|
||||||
|
|
||||||
var TANK_SCRIPT = Script.resolvePath('tank.js?' + Math.random())
|
var TANK_SCRIPT = Script.resolvePath('tank.js?' + Math.random())
|
||||||
|
|
||||||
|
var TANK_MODEL_URL = "http://hifi-content.s3.amazonaws.com/DomainContent/Home/fishTank/aquarium-6.fbx";
|
||||||
|
|
||||||
function createFishTank() {
|
function createFishTank() {
|
||||||
var tankProperties = {
|
var tankProperties = {
|
||||||
name: 'hifi-home-fishtank',
|
name: 'hifi-home-fishtank',
|
||||||
type: 'Box',
|
type: 'Model',
|
||||||
|
modelURL:TANK_MODEL_URL,
|
||||||
dimensions: TANK_DIMENSIONS,
|
dimensions: TANK_DIMENSIONS,
|
||||||
position: TANK_POSITION,
|
position: TANK_POSITION,
|
||||||
color: DEBUG_COLOR,
|
color: DEBUG_COLOR,
|
||||||
|
@ -38,7 +41,7 @@ function createFishTank() {
|
||||||
grabbable: false
|
grabbable: false
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
visible:false
|
visible:true
|
||||||
}
|
}
|
||||||
|
|
||||||
fishTank = Entities.addEntity(tankProperties);
|
fishTank = Entities.addEntity(tankProperties);
|
||||||
|
|
|
@ -1,182 +0,0 @@
|
||||||
//
|
|
||||||
// flockOfFish.js
|
|
||||||
// examples
|
|
||||||
//
|
|
||||||
// Philip Rosedale
|
|
||||||
// Copyright 2016 High Fidelity, Inc.
|
|
||||||
// Fish smimming around in a space in front of you
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
|
|
||||||
|
|
||||||
var LIFETIME = 300; // Fish live for 5 minutes
|
|
||||||
var NUM_FISH = 20;
|
|
||||||
var TANK_WIDTH = 3.0;
|
|
||||||
var TANK_HEIGHT = 1.0;
|
|
||||||
var FISH_WIDTH = 0.03;
|
|
||||||
var FISH_LENGTH = 0.15;
|
|
||||||
var MAX_SIGHT_DISTANCE = 0.8;
|
|
||||||
var MIN_SEPARATION = 0.15;
|
|
||||||
var AVOIDANCE_FORCE = 0.2;
|
|
||||||
var COHESION_FORCE = 0.05;
|
|
||||||
var ALIGNMENT_FORCE = 0.05;
|
|
||||||
var SWIMMING_FORCE = 0.05;
|
|
||||||
var SWIMMING_SPEED = 1.5;
|
|
||||||
|
|
||||||
var fishLoaded = false;
|
|
||||||
var fish = [];
|
|
||||||
|
|
||||||
var lowerCorner = { x: 0, y: 0, z: 0 };
|
|
||||||
var upperCorner = { x: 0, y: 0, z: 0 };
|
|
||||||
|
|
||||||
function randomVector(scale) {
|
|
||||||
return { x: Math.random() * scale - scale / 2.0, y: Math.random() * scale - scale / 2.0, z: Math.random() * scale - scale / 2.0 };
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateFish(deltaTime) {
|
|
||||||
if (!Entities.serversExist() || !Entities.canRez()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!fishLoaded) {
|
|
||||||
loadFish(NUM_FISH);
|
|
||||||
fishLoaded = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var averageVelocity = { x: 0, y: 0, z: 0 };
|
|
||||||
var averagePosition = { x: 0, y: 0, z: 0 };
|
|
||||||
var birdPositionsCounted = 0;
|
|
||||||
var birdVelocitiesCounted = 0;
|
|
||||||
|
|
||||||
// First pre-load an array with properties on all the other fish so our per-fish loop
|
|
||||||
// isn't doing it.
|
|
||||||
var flockProperties = [];
|
|
||||||
for (var i = 0; i < fish.length; i++) {
|
|
||||||
var otherProps = Entities.getEntityProperties(fish[i].entityId, ["position", "velocity", "rotation"]);
|
|
||||||
flockProperties.push(otherProps);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < fish.length; i++) {
|
|
||||||
if (fish[i].entityId) {
|
|
||||||
// Get only the properties we need, because that is faster
|
|
||||||
var properties = flockProperties[i];
|
|
||||||
// If fish has been deleted, bail
|
|
||||||
if (properties.id != fish[i].entityId) {
|
|
||||||
fish[i].entityId = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store old values so we can check if they have changed enough to update
|
|
||||||
var velocity = { x: properties.velocity.x, y: properties.velocity.y, z: properties.velocity.z };
|
|
||||||
var position = { x: properties.position.x, y: properties.position.y, z: properties.position.z };
|
|
||||||
averageVelocity = { x: 0, y: 0, z: 0 };
|
|
||||||
averagePosition = { x: 0, y: 0, z: 0 };
|
|
||||||
|
|
||||||
var othersCounted = 0;
|
|
||||||
for (var j = 0; j < fish.length; j++) {
|
|
||||||
if (i != j) {
|
|
||||||
// Get only the properties we need, because that is faster
|
|
||||||
var otherProps = flockProperties[j];
|
|
||||||
var separation = Vec3.distance(properties.position, otherProps.position);
|
|
||||||
if (separation < MAX_SIGHT_DISTANCE) {
|
|
||||||
averageVelocity = Vec3.sum(averageVelocity, otherProps.velocity);
|
|
||||||
averagePosition = Vec3.sum(averagePosition, otherProps.position);
|
|
||||||
othersCounted++;
|
|
||||||
}
|
|
||||||
if (separation < MIN_SEPARATION) {
|
|
||||||
var pushAway = Vec3.multiply(Vec3.normalize(Vec3.subtract(properties.position, otherProps.position)), AVOIDANCE_FORCE);
|
|
||||||
velocity = Vec3.sum(velocity, pushAway);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (othersCounted > 0) {
|
|
||||||
averageVelocity = Vec3.multiply(averageVelocity, 1.0 / othersCounted);
|
|
||||||
averagePosition = Vec3.multiply(averagePosition, 1.0 / othersCounted);
|
|
||||||
// Alignment: Follow group's direction and speed
|
|
||||||
velocity = Vec3.mix(velocity, Vec3.multiply(Vec3.normalize(averageVelocity), Vec3.length(velocity)), ALIGNMENT_FORCE);
|
|
||||||
// Cohesion: Steer towards center of flock
|
|
||||||
var towardCenter = Vec3.subtract(averagePosition, position);
|
|
||||||
velocity = Vec3.mix(velocity, Vec3.multiply(Vec3.normalize(towardCenter), Vec3.length(velocity)), COHESION_FORCE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to swim at a constant speed
|
|
||||||
velocity = Vec3.mix(velocity, Vec3.multiply(Vec3.normalize(velocity), SWIMMING_SPEED), SWIMMING_FORCE);
|
|
||||||
|
|
||||||
// Keep fish in their 'tank'
|
|
||||||
if (position.x < lowerCorner.x) {
|
|
||||||
position.x = lowerCorner.x;
|
|
||||||
velocity.x *= -1.0;
|
|
||||||
} else if (position.x > upperCorner.x) {
|
|
||||||
position.x = upperCorner.x;
|
|
||||||
velocity.x *= -1.0;
|
|
||||||
}
|
|
||||||
if (position.y < lowerCorner.y) {
|
|
||||||
position.y = lowerCorner.y;
|
|
||||||
velocity.y *= -1.0;
|
|
||||||
} else if (position.y > upperCorner.y) {
|
|
||||||
position.y = upperCorner.y;
|
|
||||||
velocity.y *= -1.0;
|
|
||||||
}
|
|
||||||
if (position.z < lowerCorner.z) {
|
|
||||||
position.z = lowerCorner.z;
|
|
||||||
velocity.z *= -1.0;
|
|
||||||
} else if (position.z > upperCorner.z) {
|
|
||||||
position.z = upperCorner.z;
|
|
||||||
velocity.z *= -1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Orient in direction of velocity
|
|
||||||
var rotation = Quat.rotationBetween(Vec3.UNIT_NEG_Z, velocity);
|
|
||||||
var VELOCITY_FOLLOW_RATE = 0.30;
|
|
||||||
|
|
||||||
// Only update properties if they have changed, to save bandwidth
|
|
||||||
var MIN_POSITION_CHANGE_FOR_UPDATE = 0.001;
|
|
||||||
if (Vec3.distance(properties.position, position) < MIN_POSITION_CHANGE_FOR_UPDATE) {
|
|
||||||
Entities.editEntity(fish[i].entityId, { velocity: velocity, rotation: Quat.mix(properties.rotation, rotation, VELOCITY_FOLLOW_RATE) });
|
|
||||||
} else {
|
|
||||||
Entities.editEntity(fish[i].entityId, { position: position, velocity: velocity, rotation: Quat.slerp(properties.rotation, rotation, VELOCITY_FOLLOW_RATE) });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect a call back that happens every frame
|
|
||||||
Script.update.connect(updateFish);
|
|
||||||
|
|
||||||
// Delete our little friends if script is stopped
|
|
||||||
Script.scriptEnding.connect(function() {
|
|
||||||
for (var i = 0; i < fish.length; i++) {
|
|
||||||
Entities.deleteEntity(fish[i].entityId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var STARTING_FRACTION = 0.25;
|
|
||||||
function loadFish(howMany) {
|
|
||||||
var center = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), 2 * TANK_WIDTH));
|
|
||||||
lowerCorner = { x: center.x - TANK_WIDTH / 2, y: center.y, z: center.z - TANK_WIDTH / 2 };
|
|
||||||
upperCorner = { x: center.x + TANK_WIDTH / 2, y: center.y + TANK_HEIGHT, z: center.z + TANK_WIDTH / 2 };
|
|
||||||
|
|
||||||
for (var i = 0; i < howMany; i++) {
|
|
||||||
var position = {
|
|
||||||
x: lowerCorner.x + (upperCorner.x - lowerCorner.x) / 2.0 + (Math.random() - 0.5) * (upperCorner.x - lowerCorner.x) * STARTING_FRACTION,
|
|
||||||
y: lowerCorner.y + (upperCorner.y - lowerCorner.y) / 2.0 + (Math.random() - 0.5) * (upperCorner.y - lowerCorner.y) * STARTING_FRACTION,
|
|
||||||
z: lowerCorner.z + (upperCorner.z - lowerCorner.x) / 2.0 + (Math.random() - 0.5) * (upperCorner.z - lowerCorner.z) * STARTING_FRACTION
|
|
||||||
};
|
|
||||||
|
|
||||||
fish.push({
|
|
||||||
entityId: Entities.addEntity({
|
|
||||||
type: "Box",
|
|
||||||
position: position,
|
|
||||||
rotation: { x: 0, y: 0, z: 0, w: 1 },
|
|
||||||
dimensions: { x: FISH_WIDTH, y: FISH_WIDTH, z: FISH_LENGTH },
|
|
||||||
velocity: { x: SWIMMING_SPEED, y: SWIMMING_SPEED, z: SWIMMING_SPEED },
|
|
||||||
damping: 0.0,
|
|
||||||
dynamic: false,
|
|
||||||
lifetime: LIFETIME,
|
|
||||||
color: { red: 0, green: 255, blue: 255 }
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -29,7 +29,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
FishTank.prototype = {
|
FishTank.prototype = {
|
||||||
fish:null,
|
fish: null,
|
||||||
findFishInTank: function() {
|
findFishInTank: function() {
|
||||||
|
|
||||||
// print('looking for a fish. in the tank')
|
// print('looking for a fish. in the tank')
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
}, 1000)
|
}, 1000)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
print('JBP userdata before parse attempt' + properties.userData)
|
print('JBP userdata before parse attempt' + properties.userData)
|
||||||
_this.userData = null;
|
_this.userData = null;
|
||||||
try {
|
try {
|
||||||
|
@ -121,8 +121,14 @@
|
||||||
|
|
||||||
var LIFETIME = 300; // Fish live for 5 minutes
|
var LIFETIME = 300; // Fish live for 5 minutes
|
||||||
var NUM_FISH = 20;
|
var NUM_FISH = 20;
|
||||||
var TANK_WIDTH = 3.0;
|
var TANK_DIMENSIONS = {
|
||||||
var TANK_HEIGHT = 1.0;
|
x: 1.3393,
|
||||||
|
y: 1.3515,
|
||||||
|
z: 3.5914
|
||||||
|
};
|
||||||
|
|
||||||
|
var TANK_WIDTH = TANK_DIMENSIONS.z;
|
||||||
|
var TANK_HEIGHT = TANK_DIMENSIONS.y;
|
||||||
var FISH_WIDTH = 0.03;
|
var FISH_WIDTH = 0.03;
|
||||||
var FISH_LENGTH = 0.15;
|
var FISH_LENGTH = 0.15;
|
||||||
var MAX_SIGHT_DISTANCE = 0.8;
|
var MAX_SIGHT_DISTANCE = 0.8;
|
||||||
|
@ -133,14 +139,18 @@
|
||||||
var SWIMMING_FORCE = 0.05;
|
var SWIMMING_FORCE = 0.05;
|
||||||
var SWIMMING_SPEED = 1.5;
|
var SWIMMING_SPEED = 1.5;
|
||||||
|
|
||||||
|
var FISH_MODEL_URL = "http://hifi-content.s3.amazonaws.com/DomainContent/Home/fishTank/Fish-1.fbx";
|
||||||
|
|
||||||
|
var FISH_MODEL_TWO_URL = "http://hifi-content.s3.amazonaws.com/DomainContent/Home/fishTank/Fish-2.fbx";
|
||||||
|
|
||||||
var fishLoaded = false;
|
var fishLoaded = false;
|
||||||
var fish = [];
|
|
||||||
|
|
||||||
var lowerCorner = {
|
var lowerCorner = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
z: 0
|
z: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
var upperCorner = {
|
var upperCorner = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
|
@ -160,9 +170,13 @@
|
||||||
if (!Entities.serversExist() || !Entities.canRez()) {
|
if (!Entities.serversExist() || !Entities.canRez()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
print('has fish??' + _this.userData['hifi-home-fishtank'].fishLoaded)
|
|
||||||
|
print('has userdata fish??' + _this.userData['hifi-home-fishtank'].fishLoaded)
|
||||||
|
|
||||||
|
|
||||||
if (_this.userData['hifi-home-fishtank'].fishLoaded === false) {
|
if (_this.userData['hifi-home-fishtank'].fishLoaded === false) {
|
||||||
print('NO FISH NO FISH NO FISH')
|
//no fish in the user data
|
||||||
|
|
||||||
loadFish(NUM_FISH);
|
loadFish(NUM_FISH);
|
||||||
setEntityCustomData(FISHTANK_USERDATA_KEY, _this.entityID, {
|
setEntityCustomData(FISHTANK_USERDATA_KEY, _this.entityID, {
|
||||||
fishLoaded: true
|
fishLoaded: true
|
||||||
|
@ -170,38 +184,51 @@
|
||||||
_this.userData['hifi-home-fishtank'].fishLoaded = true;
|
_this.userData['hifi-home-fishtank'].fishLoaded = true;
|
||||||
_this.fish = _this.findFishInTank();
|
_this.fish = _this.findFishInTank();
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
if(this.fish===null){
|
//fish in userdata already
|
||||||
|
if (_this.fish === null) {
|
||||||
|
|
||||||
_this.fish = _this.findFishInTank();
|
_this.fish = _this.findFishInTank();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// if (!fishLoaded) {
|
|
||||||
// fishLoaded = true;
|
|
||||||
// loadFish(NUM_FISH);
|
|
||||||
// setEntityCustomData(FISHTANK_USERDATA_KEY, _this.entityID, {
|
|
||||||
// fishLoaded: true
|
|
||||||
// });
|
|
||||||
// _this.userData['hifi-home-fishtank'].fishLoaded=true;
|
|
||||||
// _this.fish = _this.findFishInTank();
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
var fish = _this.fish;
|
var fish = _this.fish;
|
||||||
|
print('how many fish do i find?'+fish.length)
|
||||||
|
|
||||||
|
if (fish.length === 0) {
|
||||||
|
print('no fish...')
|
||||||
|
return
|
||||||
|
};
|
||||||
|
|
||||||
var averageVelocity = {
|
var averageVelocity = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
z: 0
|
z: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
var averagePosition = {
|
var averagePosition = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
z: 0
|
z: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
var birdPositionsCounted = 0;
|
var birdPositionsCounted = 0;
|
||||||
var birdVelocitiesCounted = 0;
|
var birdVelocitiesCounted = 0;
|
||||||
|
var center = _this.currentProperties.position;
|
||||||
|
|
||||||
|
lowerCorner = {
|
||||||
|
x: center.x - (TANK_WIDTH / 2),
|
||||||
|
y: center.y,
|
||||||
|
z: center.z - (TANK_WIDTH / 2)
|
||||||
|
};
|
||||||
|
upperCorner = {
|
||||||
|
x: center.x + (TANK_WIDTH / 2),
|
||||||
|
y: center.y + TANK_HEIGHT,
|
||||||
|
z: center.z + (TANK_WIDTH / 2)
|
||||||
|
};
|
||||||
|
|
||||||
// First pre-load an array with properties on all the other fish so our per-fish loop
|
// First pre-load an array with properties on all the other fish so our per-fish loop
|
||||||
// isn't doing it.
|
// isn't doing it.
|
||||||
|
@ -323,8 +350,6 @@
|
||||||
|
|
||||||
function loadFish(howMany) {
|
function loadFish(howMany) {
|
||||||
print('LOADING FISH: ' + howMany)
|
print('LOADING FISH: ' + howMany)
|
||||||
// var center = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), 2 * TANK_WIDTH));
|
|
||||||
|
|
||||||
|
|
||||||
var center = _this.currentProperties.position;
|
var center = _this.currentProperties.position;
|
||||||
|
|
||||||
|
@ -352,7 +377,8 @@
|
||||||
fish.push(
|
fish.push(
|
||||||
Entities.addEntity({
|
Entities.addEntity({
|
||||||
name: 'hifi-fishtank-fish' + _this.entityID,
|
name: 'hifi-fishtank-fish' + _this.entityID,
|
||||||
type: "Box",
|
type: "Model",
|
||||||
|
modelURL: fish.length % 2 === 0 ? FISH_MODEL_URL : FISH_MODEL_TWO_URL,
|
||||||
position: position,
|
position: position,
|
||||||
rotation: {
|
rotation: {
|
||||||
x: 0,
|
x: 0,
|
||||||
|
|
Loading…
Reference in a new issue