mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-12 13:23:13 +02:00
resolve conflicts on merge with clement/baseball
This commit is contained in:
commit
8f5add3a17
9 changed files with 711 additions and 489 deletions
23
examples/baseball/audio/assets.txt
Normal file
23
examples/baseball/audio/assets.txt
Normal file
|
@ -0,0 +1,23 @@
|
|||
crowd-boos.wav
|
||||
atp:c632c92b166ade60aa16b23ff1dfdf712856caeb83bd9311980b2d5edac821af.wav
|
||||
|
||||
crowd-cheers-organ.wav
|
||||
atp:b8044401a846ed29f881a0b9b80cf1ba41f26327180c28fc9c70d144f9b70045.wav
|
||||
|
||||
crowd-medium.wav
|
||||
atp:0821bf2ac60dd2f356dfdd948e8bb89c23984dc3584612f6c815765154f02cae.wav
|
||||
|
||||
baseball-hitting-bat-1.wav
|
||||
atp:6f0b691a0c9c9ece6557d97fe242b1faec4020fe26efc9c17327993b513c5fe5.wav
|
||||
|
||||
baseball-hitting-bat-set-1.wav
|
||||
atp:5be5806205158ebdc5c3623ceb7ae73315028b51ffeae24292aff7042e3fa6a9.wav
|
||||
|
||||
baseball-hitting-bat-set-2.wav
|
||||
atp:e68661374e2145c480809c26134782aad11e0de456c7802170c7abccc4028873.wav
|
||||
|
||||
baseball-hitting-bat-set-3.wav
|
||||
atp:787e3c9af17dd3929527787176ede83d6806260e63ddd5a4cef48cd22e32c6f7.wav
|
||||
|
||||
baseball-hitting-bat-set-4.wav
|
||||
atp:fc65383431a6238c7a4749f0f6f061f75a604ed5e17d775ab1b2955609e67ebb.wav
|
8
examples/baseball/audio/attribution.txt
Normal file
8
examples/baseball/audio/attribution.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
Baseball bat hitting sounds
|
||||
https://www.freesound.org/people/SocializedArtist45/sounds/266595/
|
||||
https://www.freesound.org/people/CGEffex/sounds/93136/
|
||||
|
||||
Crowd Sounds
|
||||
http://freesound.org/people/AshFox/sounds/191925/
|
||||
http://freesound.org/people/AshFox/sounds/191928/
|
||||
http://freesound.org/people/AshFox/sounds/191929/
|
140
examples/baseball/baseball.js
Executable file
140
examples/baseball/baseball.js
Executable file
|
@ -0,0 +1,140 @@
|
|||
//
|
||||
// baseball.js
|
||||
// examples/toys
|
||||
//
|
||||
// Created by Stephen Birarda on 10/20/15.
|
||||
// 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 ROBOT_MODEL = "atp:785c81e117206c36205404beec0cc68529644fe377542dbb2d13fae4d665a5de.fbx";
|
||||
var ROBOT_POSITION = { x: -0.81, y: 0.88, z: 2.12 };
|
||||
var ROBOT_DIMENSIONS = { x: 0.95, y: 1.76, z: 0.56 };
|
||||
|
||||
var BAT_MODEL = "atp:07bdd769a57ff15ebe9331ae4e2c2eae8886a6792b4790cce03b4716eb3a81c7.fbx"
|
||||
var BAT_COLLISION_MODEL = "atp:1211ee12bc8ab0bb744e8582e15e728a00ca70a808550fc46d7284799b9a868a.obj"
|
||||
var BAT_DIMENSIONS = { x: 1.35, y: 0.10, z: 0.10 };
|
||||
var BAT_REGISTRATION_POINT = { x: 0.1, y: 0.5, z: 0.5 };
|
||||
|
||||
// add the fresh robot at home plate
|
||||
var robot = Entities.addEntity({
|
||||
name: 'Robot',
|
||||
type: 'Model',
|
||||
modelURL: ROBOT_MODEL,
|
||||
position: ROBOT_POSITION,
|
||||
// dimensions: ROBOT_DIMENSIONS,a
|
||||
animationIsPlaying: true,
|
||||
animation: {
|
||||
url: ROBOT_MODEL,
|
||||
fps: 30
|
||||
}
|
||||
});
|
||||
|
||||
// add the bat
|
||||
var bat = Entities.addEntity({
|
||||
name: 'Bat',
|
||||
/*/
|
||||
type: 'Box',
|
||||
/*/
|
||||
type: 'Model',
|
||||
modelURL: BAT_COLLISION_MODEL,
|
||||
/**/
|
||||
collisionModelURL: BAT_COLLISION_MODEL,
|
||||
// dimensions: BAT_DIMENSIONS,
|
||||
registrationPoint: BAT_REGISTRATION_POINT,
|
||||
visible: false
|
||||
})
|
||||
|
||||
var lastTriggerValue = 0.0;
|
||||
|
||||
function checkTriggers() {
|
||||
var rightTrigger = Controller.getTriggerValue(1);
|
||||
|
||||
if (rightTrigger == 0) {
|
||||
if (lastTriggerValue > 0) {
|
||||
// the trigger was just released, play out to the last frame of the swing
|
||||
Entities.editEntity(robot, {
|
||||
animation: {
|
||||
running: true,
|
||||
currentFrame: 21,
|
||||
lastFrame: 115
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (lastTriggerValue == 0) {
|
||||
// the trigger was just depressed, start the swing
|
||||
Entities.editEntity(robot, {
|
||||
animation: {
|
||||
running: true,
|
||||
currentFrame: 0,
|
||||
lastFrame: 21
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
lastTriggerValue = rightTrigger;
|
||||
}
|
||||
|
||||
var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position
|
||||
var ACTION_LIFETIME = 15; // seconds
|
||||
|
||||
var action = null;
|
||||
var factor = 0.0;
|
||||
var STEP = 0.05;
|
||||
function moveBat() {
|
||||
var JOINT_INDEX = 19;
|
||||
|
||||
var forearmPosition = Entities.getJointPosition(robot, JOINT_INDEX);
|
||||
var forearmRotation = Entities.getJointRotation(robot, JOINT_INDEX);
|
||||
|
||||
/*/
|
||||
var properties = Entities.getEntityProperties(bat, ["position", "rotation"]);
|
||||
var offsetPosition = Vec3.subtract(properties.position, forearmPosition);
|
||||
var offsetRotation = Quat.multiply(Quat.inverse(forearmRotation), properties.rotation);
|
||||
print("offsetPosition = " + JSON.stringify(offsetPosition));
|
||||
print("offsetRotation = " + JSON.stringify(Quat.safeEulerAngles(offsetRotation)));
|
||||
/*/
|
||||
Entities.editEntity(bat, {
|
||||
position: forearmPosition,
|
||||
rotation: forearmRotation,
|
||||
});
|
||||
/**/
|
||||
|
||||
// var actionProperties = {
|
||||
// relativePosition: forearmPosition,
|
||||
// relativeRotation: forearmRotation,
|
||||
//// tag: "bat-to-forearm",
|
||||
//// linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME,
|
||||
//// angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME,
|
||||
//// lifetime: ACTION_LIFETIME
|
||||
// hand: "left",
|
||||
// timeScale: 0.15
|
||||
// };
|
||||
//
|
||||
// if (action === null) {
|
||||
// Entities.addAction("hold", bat, actionProperties);
|
||||
// } else {
|
||||
// Entities.editAction(bat, action, actionProperties);
|
||||
// }
|
||||
}
|
||||
|
||||
function update() {
|
||||
// checkTriggers();
|
||||
moveBat();
|
||||
}
|
||||
|
||||
function scriptEnding() {
|
||||
Entities.deleteEntity(robot);
|
||||
Entities.deleteEntity(bat);
|
||||
if (action) {
|
||||
Entities.deleteAction(bat, action);
|
||||
}
|
||||
}
|
||||
|
||||
// hook the update so we can check controller triggers
|
||||
Script.update.connect(update);
|
||||
Script.scriptEnding.connect(scriptEnding);
|
165
examples/baseball/line.js
Normal file
165
examples/baseball/line.js
Normal file
|
@ -0,0 +1,165 @@
|
|||
function info(message) {
|
||||
print("[INFO] " + message);
|
||||
}
|
||||
|
||||
function error(message) {
|
||||
print("[ERROR] " + message);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* PolyLine
|
||||
*****************************************************************************/
|
||||
var LINE_DIMENSIONS = { x: 2000, y: 2000, z: 2000 };
|
||||
var MAX_LINE_LENGTH = 40; // This must be 2 or greater;
|
||||
var PolyLine = function(position, color, defaultStrokeWidth) {
|
||||
//info("Creating polyline");
|
||||
//Vec3.print("New line at", position);
|
||||
this.position = position;
|
||||
this.color = color;
|
||||
this.defaultStrokeWidth = 0.10;
|
||||
this.points = [
|
||||
{ x: 0, y: 0, z: 0 },
|
||||
];
|
||||
this.strokeWidths = [
|
||||
this.defaultStrokeWidth,
|
||||
]
|
||||
this.normals = [
|
||||
{ x: 1, y: 0, z: 0 },
|
||||
]
|
||||
this.entityID = Entities.addEntity({
|
||||
type: "PolyLine",
|
||||
position: position,
|
||||
linePoints: this.points,
|
||||
normals: this.normals,
|
||||
strokeWidths: this.strokeWidths,
|
||||
dimensions: LINE_DIMENSIONS,
|
||||
color: color,
|
||||
lifetime: 20,
|
||||
});
|
||||
};
|
||||
|
||||
PolyLine.prototype.enqueuePoint = function(position) {
|
||||
if (this.isFull()) {
|
||||
error("Hit max PolyLine size");
|
||||
return;
|
||||
}
|
||||
|
||||
//Vec3.print("pos", position);
|
||||
//info("Number of points: " + this.points.length);
|
||||
|
||||
position = Vec3.subtract(position, this.position);
|
||||
this.points.push(position);
|
||||
this.normals.push({ x: 1, y: 0, z: 0 });
|
||||
this.strokeWidths.push(this.defaultStrokeWidth);
|
||||
Entities.editEntity(this.entityID, {
|
||||
linePoints: this.points,
|
||||
normals: this.normals,
|
||||
strokeWidths: this.strokeWidths,
|
||||
});
|
||||
};
|
||||
|
||||
PolyLine.prototype.dequeuePoint = function() {
|
||||
if (this.points.length == 0) {
|
||||
error("Hit min PolyLine size");
|
||||
return;
|
||||
}
|
||||
|
||||
this.points = this.points.slice(1);
|
||||
this.normals = this.normals.slice(1);
|
||||
this.strokeWidths = this.strokeWidths.slice(1);
|
||||
|
||||
Entities.editEntity(this.entityID, {
|
||||
linePoints: this.points,
|
||||
normals: this.normals,
|
||||
strokeWidths: this.strokeWidths,
|
||||
});
|
||||
};
|
||||
|
||||
PolyLine.prototype.getFirstPoint = function() {
|
||||
return Vec3.sum(this.position, this.points[0]);
|
||||
};
|
||||
|
||||
PolyLine.prototype.getLastPoint = function() {
|
||||
return Vec3.sum(this.position, this.points[this.points.length - 1]);
|
||||
};
|
||||
|
||||
PolyLine.prototype.getSize = function() {
|
||||
return this.points.length;
|
||||
}
|
||||
|
||||
PolyLine.prototype.isFull = function() {
|
||||
return this.points.length >= MAX_LINE_LENGTH;
|
||||
};
|
||||
|
||||
PolyLine.prototype.destroy = function() {
|
||||
Entities.deleteEntity(this.entityID);
|
||||
this.points = [];
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* InfiniteLine
|
||||
*****************************************************************************/
|
||||
InfiniteLine = function(position, color) {
|
||||
this.position = position;
|
||||
this.color = color;
|
||||
this.lines = [new PolyLine(position, color)];
|
||||
this.size = 0;
|
||||
};
|
||||
|
||||
InfiniteLine.prototype.enqueuePoint = function(position) {
|
||||
var currentLine;
|
||||
|
||||
if (this.lines.length == 0) {
|
||||
currentLine = new PolyLine(position, this.color);
|
||||
this.lines.push(currentLine);
|
||||
} else {
|
||||
currentLine = this.lines[this.lines.length - 1];
|
||||
}
|
||||
|
||||
if (currentLine.isFull()) {
|
||||
//info("Current line is full, creating new line");
|
||||
//Vec3.print("Last line is", currentLine.getLastPoint());
|
||||
//Vec3.print("New line is", position);
|
||||
var newLine = new PolyLine(currentLine.getLastPoint(), this.color);
|
||||
this.lines.push(newLine);
|
||||
currentLine = newLine;
|
||||
}
|
||||
|
||||
currentLine.enqueuePoint(position);
|
||||
|
||||
++this.size;
|
||||
};
|
||||
|
||||
InfiniteLine.prototype.dequeuePoint = function() {
|
||||
if (this.lines.length == 0) {
|
||||
error("Trying to dequeue from InfiniteLine when no points are left");
|
||||
return;
|
||||
}
|
||||
|
||||
var lastLine = this.lines[0];
|
||||
lastLine.dequeuePoint();
|
||||
|
||||
if (lastLine.getSize() <= 1) {
|
||||
this.lines = this.lines.slice(1);
|
||||
}
|
||||
|
||||
--this.size;
|
||||
};
|
||||
|
||||
InfiniteLine.prototype.getFirstPoint = function() {
|
||||
return this.lines.length > 0 ? this.lines[0].getFirstPoint() : null;
|
||||
};
|
||||
|
||||
InfiniteLine.prototype.getLastPoint = function() {
|
||||
return this.lines.length > 0 ? this.lines[lines.length - 1].getLastPoint() : null;
|
||||
};
|
||||
|
||||
InfiniteLine.prototype.destroy = function() {
|
||||
for (var i = 0; i < this.lines.length; ++i) {
|
||||
this.lines[i].destroy();
|
||||
}
|
||||
|
||||
this.size = 0;
|
||||
};
|
352
examples/baseball/pitching.js
Normal file
352
examples/baseball/pitching.js
Normal file
|
@ -0,0 +1,352 @@
|
|||
Script.include("line.js");
|
||||
|
||||
var AUDIO = {
|
||||
crowdBoos: [
|
||||
SoundCache.getSound("atp:c632c92b166ade60aa16b23ff1dfdf712856caeb83bd9311980b2d5edac821af.wav", false)
|
||||
],
|
||||
crowdCheers: [
|
||||
SoundCache.getSound("atp:0821bf2ac60dd2f356dfdd948e8bb89c23984dc3584612f6c815765154f02cae.wav", false),
|
||||
SoundCache.getSound("atp:b8044401a846ed29f881a0b9b80cf1ba41f26327180c28fc9c70d144f9b70045.wav", false),
|
||||
],
|
||||
batHit: [
|
||||
SoundCache.getSound("atp:6f0b691a0c9c9ece6557d97fe242b1faec4020fe26efc9c17327993b513c5fe5.wav", false),
|
||||
SoundCache.getSound("atp:5be5806205158ebdc5c3623ceb7ae73315028b51ffeae24292aff7042e3fa6a9.wav", false),
|
||||
SoundCache.getSound("atp:e68661374e2145c480809c26134782aad11e0de456c7802170c7abccc4028873.wav", false),
|
||||
SoundCache.getSound("atp:787e3c9af17dd3929527787176ede83d6806260e63ddd5a4cef48cd22e32c6f7.wav", false),
|
||||
SoundCache.getSound("atp:fc65383431a6238c7a4749f0f6f061f75a604ed5e17d775ab1b2955609e67ebb.wav", false),
|
||||
]
|
||||
}
|
||||
|
||||
var PITCH_THUNK_SOUND_URL = "http://hifi-public.s3.amazonaws.com/sounds/ping_pong_gun/pong_sound.wav";
|
||||
var pitchSound = SoundCache.getSound(PITCH_THUNK_SOUND_URL, false);
|
||||
|
||||
var PITCHING_MACHINE_URL = "atp:87d4879530b698741ecc45f6f31789aac11f7865a2c3bec5fe9b061a182c80d4.fbx";
|
||||
var PITCHING_MACHINE_OUTPUT_OFFSET_PCT = {
|
||||
x: 0.0,
|
||||
y: 0.25,
|
||||
z: -1.05,
|
||||
};
|
||||
var PITCHING_MACHINE_PROPERTIES = {
|
||||
name: "Pitching Machine",
|
||||
type: "Model",
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0.8,
|
||||
z: -18.3,
|
||||
},
|
||||
velocity: {
|
||||
x: 0,
|
||||
y: -0.01,
|
||||
z: 0
|
||||
},
|
||||
gravity: {
|
||||
x: 0.0,
|
||||
y: -9.8,
|
||||
z: 0.0
|
||||
},
|
||||
registrationPoint: {
|
||||
x: 0.5,
|
||||
y: 0.5,
|
||||
z: 0.5,
|
||||
},
|
||||
rotation: Quat.fromPitchYawRollDegrees(0, 180, 0),
|
||||
modelURL: PITCHING_MACHINE_URL,
|
||||
dimensions: {
|
||||
x: 0.4,
|
||||
y: 0.61,
|
||||
z: 0.39
|
||||
},
|
||||
collisionsWillMove: false,
|
||||
shapeType: "Box",
|
||||
};
|
||||
PITCHING_MACHINE_PROPERTIES.dimensions = Vec3.multiply(2.5, PITCHING_MACHINE_PROPERTIES.dimensions);
|
||||
var DISTANCE_FROM_PLATE = PITCHING_MACHINE_PROPERTIES.position.z;
|
||||
|
||||
var PITCH_RATE = 5000;
|
||||
|
||||
var BASEBALL_MODEL_URL = "atp:7185099f1f650600ca187222573a88200aeb835454bd2f578f12c7fb4fd190fa.fbx";
|
||||
var BASEBALL_MIN_SPEED = 2.7;
|
||||
var BASEBALL_MAX_SPEED = 5.7;
|
||||
var BASEBALL_RADIUS = 0.07468;
|
||||
var BASEBALL_PROPERTIES = {
|
||||
name: "Baseball",
|
||||
type: "Model",
|
||||
modelURL: BASEBALL_MODEL_URL,
|
||||
shapeType: "Sphere",
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
},
|
||||
dimensions: {
|
||||
x: BASEBALL_RADIUS,
|
||||
y: BASEBALL_RADIUS,
|
||||
z: BASEBALL_RADIUS
|
||||
},
|
||||
collisionsWillMove: true,
|
||||
angularVelocity: {
|
||||
x: 17.0,
|
||||
y: 0,
|
||||
z: -8.0,
|
||||
|
||||
x: 0.0,
|
||||
y: 0,
|
||||
z: 0.0,
|
||||
},
|
||||
angularDamping: 0.0,
|
||||
damping: 0.0,
|
||||
restitution: 0.5,
|
||||
friction: 0.0,
|
||||
lifetime: 20,
|
||||
//collisionSoundURL: PITCH_THUNK_SOUND_URL,
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: 0,//-9.8,
|
||||
z: 0
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var pitchingMachineID = Entities.addEntity(PITCHING_MACHINE_PROPERTIES);
|
||||
|
||||
var pitchFromPosition = { x: 0, y: 1.0, z: 0 };
|
||||
var pitchDirection = { x: 0, y: 0, z: 1 };
|
||||
|
||||
function shallowCopy(obj) {
|
||||
var copy = {}
|
||||
for (var key in obj) {
|
||||
copy[key] = obj[key];
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
function randomInt(low, high) {
|
||||
return Math.floor(randomFloat(low, high));
|
||||
}
|
||||
|
||||
function randomFloat(low, high) {
|
||||
if (high === undefined) {
|
||||
high = low;
|
||||
low = 0;
|
||||
}
|
||||
return low + Math.random() * (high - low);
|
||||
}
|
||||
|
||||
function playRandomSound(sounds, options) {
|
||||
if (options === undefined) {
|
||||
options = {
|
||||
volume: 1.0,
|
||||
position: MyAvatar.position,
|
||||
}
|
||||
}
|
||||
Audio.playSound(sounds[randomInt(sounds.length)], options);
|
||||
}
|
||||
|
||||
function vec3Mult(a, b) {
|
||||
return {
|
||||
x: a.x * b.x,
|
||||
y: a.y * b.y,
|
||||
z: a.z * b.z,
|
||||
};
|
||||
}
|
||||
|
||||
function map(value, min1, max1, min2, max2) {
|
||||
return min2 + (max2 - min2) * ((value - min1) / (max1 - min1));
|
||||
}
|
||||
|
||||
function orientationOf(vector) {
|
||||
var RAD_TO_DEG = 180.0 / Math.PI;
|
||||
var Y_AXIS = { x: 0, y: 1, z: 0 };
|
||||
var X_AXIS = { x: 1, y: 0, z: 0 };
|
||||
var direction = Vec3.normalize(vector);
|
||||
|
||||
var yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS);
|
||||
var pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS);
|
||||
|
||||
return Quat.multiply(yaw, pitch);
|
||||
}
|
||||
|
||||
var injector = null;
|
||||
|
||||
var ACCELERATION_SPREAD = 10.15;
|
||||
|
||||
var trail = null;
|
||||
var trailInterval = null;
|
||||
function cleanupTrail() {
|
||||
if (trail) {
|
||||
Script.clearInterval(this.trailInterval);
|
||||
trailInterval = null;
|
||||
|
||||
trail.destroy();
|
||||
trail = null;
|
||||
}
|
||||
}
|
||||
|
||||
function setupTrail(entityID, position) {
|
||||
cleanupTrail();
|
||||
|
||||
var lastPosition = position;
|
||||
trail = new InfiniteLine(position, { red: 255, green: 128, blue: 89 });
|
||||
trailInterval = Script.setInterval(function() {
|
||||
var properties = Entities.getEntityProperties(entityID, ['position']);
|
||||
if (Vec3.distance(properties.position, lastPosition)) {
|
||||
trail.enqueuePoint(properties.position);
|
||||
lastPosition = properties.position;
|
||||
}
|
||||
}, 50);
|
||||
}
|
||||
|
||||
function Baseball(position, velocity, ballScale) {
|
||||
var self = this;
|
||||
|
||||
// Setup entity properties
|
||||
var properties = shallowCopy(BASEBALL_PROPERTIES);
|
||||
properties.position = position;
|
||||
properties.velocity = velocity;
|
||||
properties.dimensions = Vec3.multiply(ballScale, properties.dimensions);
|
||||
/*
|
||||
properties.gravity = {
|
||||
x: randomInt(-ACCELERATION_SPREAD, ACCELERATION_SPREAD),
|
||||
y: randomInt(-ACCELERATION_SPREAD, ACCELERATION_SPREAD),
|
||||
z: 0.0,
|
||||
};
|
||||
*/
|
||||
|
||||
// Create entity
|
||||
this.entityID = Entities.addEntity(properties);
|
||||
|
||||
// Listen for collision for the lifetime of the entity
|
||||
Script.addEventHandler(this.entityID, "collisionWithEntity", function(entityA, entityB, collision) {
|
||||
self.collisionCallback(entityA, entityB, collision);
|
||||
});
|
||||
/*
|
||||
if (false && Math.random() < 0.5) {
|
||||
for (var i = 0; i < 50; i++) {
|
||||
Script.setTimeout(function() {
|
||||
Entities.editEntity(entityID, {
|
||||
gravity: {
|
||||
x: randomInt(-ACCELERATION_SPREAD, ACCELERATION_SPREAD),
|
||||
y: randomInt(-ACCELERATION_SPREAD, ACCELERATION_SPREAD),
|
||||
z: 0.0,
|
||||
}
|
||||
})
|
||||
}, i * 100);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
Baseball.prototype = {
|
||||
collisionCallback: function(entityA, entityB, collision) {
|
||||
var self = this;
|
||||
var myProperties = Entities.getEntityProperties(this.entityID, ['position', 'velocity']);
|
||||
var myPosition = myProperties.position;
|
||||
var myVelocity = myProperties.velocity;
|
||||
|
||||
// Activate gravity
|
||||
Entities.editEntity(self.entityID, {
|
||||
gravity: { x: 0, y: -9.8, z: 0 }
|
||||
});
|
||||
|
||||
var name = Entities.getEntityProperties(entityB, ["name"]).name;
|
||||
print("Hit: " + name);
|
||||
if (name == "Bat") {
|
||||
print("HIT");
|
||||
|
||||
// Update ball velocity
|
||||
Entities.editEntity(self.entityID, {
|
||||
velocity: Vec3.multiply(2, myVelocity),
|
||||
});
|
||||
|
||||
// Setup line update interval
|
||||
setupTrail(self.entityID, myPosition);
|
||||
|
||||
// Setup bat hit sound
|
||||
playRandomSound(AUDIO.batHit, {
|
||||
position: myPosition,
|
||||
volume: 2.0
|
||||
});
|
||||
|
||||
// Setup crowd reaction sound
|
||||
var speed = Vec3.length(myVelocity);
|
||||
Script.setTimeout(function() {
|
||||
playRandomSound((speed < 5.0) ? AUDIO.crowdBoos : AUDIO.crowdCheers, {
|
||||
position: { x: 0 ,y: 0, z: 0 },
|
||||
volume: 1.0
|
||||
});
|
||||
}, 500);
|
||||
} else if (name == "stadium") {
|
||||
print("PARTICLES");
|
||||
entityCollisionWithGround(entityB, this.entityID, collision);
|
||||
} else if (name == "backstop") {
|
||||
print("STRIKE");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function pitchBall() {
|
||||
var machineProperties = Entities.getEntityProperties(pitchingMachineID, ["dimensions", "position", "rotation"]);
|
||||
var pitchFromPositionBase = machineProperties.position;
|
||||
var pitchFromOffset = vec3Mult(machineProperties.dimensions, PITCHING_MACHINE_OUTPUT_OFFSET_PCT);
|
||||
pitchFromOffset = Vec3.multiplyQbyV(machineProperties.rotation, pitchFromOffset);
|
||||
var pitchFromPosition = Vec3.sum(pitchFromPositionBase, pitchFromOffset);
|
||||
var pitchDirection = Quat.getFront(machineProperties.rotation);
|
||||
var ballScale = machineProperties.dimensions.x / PITCHING_MACHINE_PROPERTIES.dimensions.x;
|
||||
print("Creating baseball");
|
||||
|
||||
var speed = randomFloat(BASEBALL_MIN_SPEED, BASEBALL_MAX_SPEED)
|
||||
var timeToPassPlate = (DISTANCE_FROM_PLATE + 1.0) / speed;
|
||||
|
||||
var baseball = new Baseball(pitchFromPosition, Vec3.multiply(speed, pitchDirection), ballScale);
|
||||
|
||||
if (!injector) {
|
||||
injector = Audio.playSound(pitchSound, {
|
||||
position: pitchFromPosition,
|
||||
volume: 1.0
|
||||
});
|
||||
} else {
|
||||
injector.restart();
|
||||
}
|
||||
}
|
||||
|
||||
function entityCollisionWithGround(ground, entity, collision) {
|
||||
var ZERO_VEC = { x: 0, y: 0, z: 0 };
|
||||
var dVelocityMagnitude = Vec3.length(collision.velocityChange);
|
||||
var position = Entities.getEntityProperties(entity, "position").position;
|
||||
var particleRadius = 0.3;//map(dVelocityMagnitude, 0.05, 3, 0.5, 2);
|
||||
var speed = map(dVelocityMagnitude, 0.05, 3, 0.02, 0.09);
|
||||
var displayTime = 400;
|
||||
var orientationChange = orientationOf(collision.velocityChange);
|
||||
|
||||
var dustEffect = Entities.addEntity({
|
||||
type: "ParticleEffect",
|
||||
name: "Dust-Puff",
|
||||
position: position,
|
||||
color: {red: 195, green: 170, blue: 185},
|
||||
lifespan: 3,
|
||||
lifetime: 2,//displayTime/1000 * 2, //So we can fade particle system out gracefully
|
||||
emitRate: 5,
|
||||
emitSpeed: speed,
|
||||
emitAcceleration: ZERO_VEC,
|
||||
accelerationSpread: ZERO_VEC,
|
||||
isEmitting: true,
|
||||
polarStart: Math.PI/2,
|
||||
polarFinish: Math.PI/2,
|
||||
emitOrientation: orientationChange,
|
||||
radiusSpread: 0.1,
|
||||
radiusStart: particleRadius,
|
||||
radiusFinish: particleRadius + particleRadius / 2,
|
||||
particleRadius: particleRadius,
|
||||
alpha: 0.45,
|
||||
alphaFinish: 0.001,
|
||||
textures: "https://hifi-public.s3.amazonaws.com/alan/Playa/Particles/Particle-Sprite-Gen.png"
|
||||
});
|
||||
}
|
||||
|
||||
Script.scriptEnding.connect(function() {
|
||||
cleanupTrail();
|
||||
Entities.deleteEntity(pitchingMachineID);
|
||||
});
|
||||
|
||||
Script.setInterval(pitchBall, PITCH_RATE);
|
||||
|
|
@ -1,365 +0,0 @@
|
|||
//var PITCH_THUNK_SOUND_URL = "file:///C:/Users/Ryan/Downloads/323725__reitanna__thunk.wav";
|
||||
var PITCH_THUNK_SOUND_URL = "file:///C:/Users/Ryan/Downloads/thunk.wav";
|
||||
var PITCH_THUNK_SOUND_URL = "http://hifi-public.s3.amazonaws.com/sounds/ping_pong_gun/pong_sound.wav";
|
||||
var pitchSound = SoundCache.getSound(PITCH_THUNK_SOUND_URL, false);
|
||||
|
||||
function info(message) {
|
||||
print("[INFO] " + message);
|
||||
}
|
||||
|
||||
function error(message) {
|
||||
print("[ERROR] " + message);
|
||||
}
|
||||
|
||||
var PITCHING_MACHINE_URL = "atp:87d4879530b698741ecc45f6f31789aac11f7865a2c3bec5fe9b061a182c80d4.fbx";
|
||||
var PITCHING_MACHINE_OUTPUT_OFFSET_PCT = {
|
||||
x: 0.0,
|
||||
y: 0.25,
|
||||
z: -1.05,
|
||||
};
|
||||
var PITCHING_MACHINE_PROPERTIES = {
|
||||
name: "Pitching Machine",
|
||||
type: "Model",
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0.8,
|
||||
z: -22.3,
|
||||
},
|
||||
velocity: {
|
||||
x: 0,
|
||||
y: -0.01,
|
||||
z: 0
|
||||
},
|
||||
gravity: {
|
||||
x: 0.0,
|
||||
y: -9.8,
|
||||
z: 0.0
|
||||
},
|
||||
registrationPoint: {
|
||||
x: 0.5,
|
||||
y: 0.5,
|
||||
z: 0.5,
|
||||
},
|
||||
rotation: Quat.fromPitchYawRollDegrees(0, 180, 0),
|
||||
modelURL: PITCHING_MACHINE_URL,
|
||||
dimensions: {
|
||||
x: 0.4,
|
||||
y: 0.61,
|
||||
z: 0.39
|
||||
},
|
||||
collisionsWillMove: false,
|
||||
shapeType: "Box",
|
||||
};
|
||||
PITCHING_MACHINE_PROPERTIES.dimensions = Vec3.multiply(2.5, PITCHING_MACHINE_PROPERTIES.dimensions);
|
||||
|
||||
|
||||
var PITCH_RATE = 5000;
|
||||
|
||||
var BASEBALL_MODEL_URL = "atp:7185099f1f650600ca187222573a88200aeb835454bd2f578f12c7fb4fd190fa.fbx";
|
||||
var BASEBALL_SPEED = 2.7;
|
||||
var BASEBALL_RADIUS = 0.07468;
|
||||
var BASEBALL_PROPERTIES = {
|
||||
name: "Baseball",
|
||||
type: "Model",
|
||||
modelURL: BASEBALL_MODEL_URL,
|
||||
shapeType: "Sphere",
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
},
|
||||
dimensions: {
|
||||
x: BASEBALL_RADIUS,
|
||||
y: BASEBALL_RADIUS,
|
||||
z: BASEBALL_RADIUS
|
||||
},
|
||||
collisionsWillMove: true,
|
||||
angularVelocity: {
|
||||
x: 17.0,
|
||||
y: 0,
|
||||
z: -8.0,
|
||||
},
|
||||
angularDamping: 0.0,
|
||||
damping: 0.0,
|
||||
restitution: 0.5,
|
||||
friction: 0.0,
|
||||
lifetime: 20,
|
||||
collisionSoundURL: PITCH_THUNK_SOUND_URL,
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: 0,//-9.8,
|
||||
z: 0
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var pitchingMachineID = Entities.addEntity(PITCHING_MACHINE_PROPERTIES);
|
||||
|
||||
var pitchFromPosition = { x: 0, y: 1.0, z: 0 };
|
||||
var pitchDirection = { x: 0, y: 0, z: 1 };
|
||||
|
||||
function shallowCopy(obj) {
|
||||
var copy = {}
|
||||
for (var key in obj) {
|
||||
copy[key] = obj[key];
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
function randomInt(low, high) {
|
||||
return low + (Math.random() * (high - low));
|
||||
}
|
||||
|
||||
var ACCELERATION_SPREAD = 10.15;
|
||||
|
||||
function createBaseball(position, velocity, ballScale) {
|
||||
var properties = shallowCopy(BASEBALL_PROPERTIES);
|
||||
properties.position = position;
|
||||
properties.velocity = velocity;
|
||||
properties.acceleration = {
|
||||
x: randomInt(-ACCELERATION_SPREAD, ACCELERATION_SPREAD),
|
||||
y: randomInt(-ACCELERATION_SPREAD, ACCELERATION_SPREAD),
|
||||
z: 0.0,
|
||||
};
|
||||
properties.dimensions = Vec3.multiply(ballScale, properties.dimensions);
|
||||
var entityID = Entities.addEntity(properties);
|
||||
Script.addEventHandler(entityID, "collisionWithEntity", buildBaseballHitCallback(entityID));
|
||||
if (false && Math.random() < 0.5) {
|
||||
for (var i = 0; i < 50; i++) {
|
||||
Script.setTimeout(function() {
|
||||
Entities.editEntity(entityID, {
|
||||
gravity: {
|
||||
x: randomInt(-ACCELERATION_SPREAD, ACCELERATION_SPREAD),
|
||||
y: randomInt(-ACCELERATION_SPREAD, ACCELERATION_SPREAD),
|
||||
z: 0.0,
|
||||
}
|
||||
})
|
||||
}, i * 100);
|
||||
}
|
||||
}
|
||||
return entityID;
|
||||
}
|
||||
|
||||
var buildBaseballHitCallback = function(entityID) {
|
||||
var f = function(entityA, entityB, collision) {
|
||||
var properties = Entities.getEntityProperties(entityID, ['position', 'velocity']);
|
||||
var line = new InfiniteLine(properties.position, { red: 255, green: 128, blue: 89 });
|
||||
var lastPosition = properties.position;
|
||||
Vec3.print("Velocity", properties.velocity);
|
||||
Vec3.print("VelocityChange", collision.velocityChange);
|
||||
Script.setInterval(function() {
|
||||
var properties = Entities.getEntityProperties(entityID, ['position']);
|
||||
if (Vec3.distance(properties.position, lastPosition)) {
|
||||
line.enqueuePoint(properties.position);
|
||||
lastPosition = properties.position;
|
||||
}
|
||||
}, 50);
|
||||
Entities.editEntity(entityID, {
|
||||
velocity: Vec3.multiply(3, properties.velocity),
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: -2.8,
|
||||
z: 0
|
||||
}
|
||||
});
|
||||
print("Baseball hit!");
|
||||
Script.removeEventHandler(entityID, "collisionWithEntity", f);
|
||||
};
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
function vec3Mult(a, b) {
|
||||
return {
|
||||
x: a.x * b.x,
|
||||
y: a.y * b.y,
|
||||
z: a.z * b.z,
|
||||
};
|
||||
}
|
||||
|
||||
var injector = null;
|
||||
function pitchBall() {
|
||||
var machineProperties = Entities.getEntityProperties(pitchingMachineID, ["dimensions", "position", "rotation"]);
|
||||
var pitchFromPositionBase = machineProperties.position;
|
||||
var pitchFromOffset = vec3Mult(machineProperties.dimensions, PITCHING_MACHINE_OUTPUT_OFFSET_PCT);
|
||||
pitchFromOffset = Vec3.multiplyQbyV(machineProperties.rotation, pitchFromOffset);
|
||||
var pitchFromPosition = Vec3.sum(pitchFromPositionBase, pitchFromOffset);
|
||||
var pitchDirection = Quat.getFront(machineProperties.rotation);
|
||||
var ballScale = machineProperties.dimensions.x / PITCHING_MACHINE_PROPERTIES.dimensions.x;
|
||||
print("Creating baseball");
|
||||
var ballEntityID = createBaseball(pitchFromPosition, Vec3.multiply(BASEBALL_SPEED, pitchDirection), ballScale);
|
||||
if (!injector) {
|
||||
injector = Audio.playSound(pitchSound, {
|
||||
position: pitchFromPosition,
|
||||
volume: 1.0
|
||||
});
|
||||
} else {
|
||||
injector.restart();
|
||||
}
|
||||
}
|
||||
|
||||
Script.scriptEnding.connect(function() {
|
||||
Entities.deleteEntity(pitchingMachineID);
|
||||
})
|
||||
|
||||
Script.setInterval(pitchBall, PITCH_RATE);
|
||||
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* PolyLine
|
||||
*****************************************************************************/
|
||||
var LINE_DIMENSIONS = { x: 2000, y: 2000, z: 2000 };
|
||||
var MAX_LINE_LENGTH = 40; // This must be 2 or greater;
|
||||
var PolyLine = function(position, color, defaultStrokeWidth) {
|
||||
//info("Creating polyline");
|
||||
//Vec3.print("New line at", position);
|
||||
this.position = position;
|
||||
this.color = color;
|
||||
this.defaultStrokeWidth = 0.10;
|
||||
this.points = [
|
||||
{ x: 0, y: 0, z: 0 },
|
||||
];
|
||||
this.strokeWidths = [
|
||||
this.defaultStrokeWidth,
|
||||
]
|
||||
this.normals = [
|
||||
{ x: 1, y: 0, z: 0 },
|
||||
]
|
||||
this.entityID = Entities.addEntity({
|
||||
type: "PolyLine",
|
||||
position: position,
|
||||
linePoints: this.points,
|
||||
normals: this.normals,
|
||||
strokeWidths: this.strokeWidths,
|
||||
dimensions: LINE_DIMENSIONS,
|
||||
color: color,
|
||||
lifetime: 20,
|
||||
});
|
||||
};
|
||||
|
||||
PolyLine.prototype.enqueuePoint = function(position) {
|
||||
if (this.isFull()) {
|
||||
error("Hit max PolyLine size");
|
||||
return;
|
||||
}
|
||||
|
||||
//Vec3.print("pos", position);
|
||||
//info("Number of points: " + this.points.length);
|
||||
|
||||
position = Vec3.subtract(position, this.position);
|
||||
this.points.push(position);
|
||||
this.normals.push({ x: 1, y: 0, z: 0 });
|
||||
this.strokeWidths.push(this.defaultStrokeWidth);
|
||||
Entities.editEntity(this.entityID, {
|
||||
linePoints: this.points,
|
||||
normals: this.normals,
|
||||
strokeWidths: this.strokeWidths,
|
||||
});
|
||||
};
|
||||
|
||||
PolyLine.prototype.dequeuePoint = function() {
|
||||
if (this.points.length == 0) {
|
||||
error("Hit min PolyLine size");
|
||||
return;
|
||||
}
|
||||
|
||||
this.points = this.points.slice(1);
|
||||
this.normals = this.normals.slice(1);
|
||||
this.strokeWidths = this.strokeWidths.slice(1);
|
||||
|
||||
Entities.editEntity(this.entityID, {
|
||||
linePoints: this.points,
|
||||
normals: this.normals,
|
||||
strokeWidths: this.strokeWidths,
|
||||
});
|
||||
};
|
||||
|
||||
PolyLine.prototype.getFirstPoint = function() {
|
||||
return Vec3.sum(this.position, this.points[0]);
|
||||
};
|
||||
|
||||
PolyLine.prototype.getLastPoint = function() {
|
||||
return Vec3.sum(this.position, this.points[this.points.length - 1]);
|
||||
};
|
||||
|
||||
PolyLine.prototype.getSize = function() {
|
||||
return this.points.length;
|
||||
}
|
||||
|
||||
PolyLine.prototype.isFull = function() {
|
||||
return this.points.length >= MAX_LINE_LENGTH;
|
||||
};
|
||||
|
||||
PolyLine.prototype.destroy = function() {
|
||||
Entities.deleteEntity(this.entityID);
|
||||
this.points = [];
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* InfiniteLine
|
||||
*****************************************************************************/
|
||||
InfiniteLine = function(position, color) {
|
||||
this.position = position;
|
||||
this.color = color;
|
||||
this.lines = [new PolyLine(position, color)];
|
||||
this.size = 0;
|
||||
};
|
||||
|
||||
InfiniteLine.prototype.enqueuePoint = function(position) {
|
||||
var currentLine;
|
||||
|
||||
if (this.lines.length == 0) {
|
||||
currentLine = new PolyLine(position, this.color);
|
||||
this.lines.push(currentLine);
|
||||
} else {
|
||||
currentLine = this.lines[this.lines.length - 1];
|
||||
}
|
||||
|
||||
if (currentLine.isFull()) {
|
||||
//info("Current line is full, creating new line");
|
||||
//Vec3.print("Last line is", currentLine.getLastPoint());
|
||||
//Vec3.print("New line is", position);
|
||||
var newLine = new PolyLine(currentLine.getLastPoint(), this.color);
|
||||
this.lines.push(newLine);
|
||||
currentLine = newLine;
|
||||
}
|
||||
|
||||
currentLine.enqueuePoint(position);
|
||||
|
||||
++this.size;
|
||||
};
|
||||
|
||||
InfiniteLine.prototype.dequeuePoint = function() {
|
||||
if (this.lines.length == 0) {
|
||||
error("Trying to dequeue from InfiniteLine when no points are left");
|
||||
return;
|
||||
}
|
||||
|
||||
var lastLine = this.lines[0];
|
||||
lastLine.dequeuePoint();
|
||||
|
||||
if (lastLine.getSize() <= 1) {
|
||||
this.lines = this.lines.slice(1);
|
||||
}
|
||||
|
||||
--this.size;
|
||||
};
|
||||
|
||||
InfiniteLine.prototype.getFirstPoint = function() {
|
||||
return this.lines.length > 0 ? this.lines[0].getFirstPoint() : null;
|
||||
};
|
||||
|
||||
InfiniteLine.prototype.getLastPoint = function() {
|
||||
return this.lines.length > 0 ? this.lines[lines.length - 1].getLastPoint() : null;
|
||||
};
|
||||
|
||||
InfiniteLine.prototype.destroy = function() {
|
||||
for (var i = 0; i < this.lines.length; ++i) {
|
||||
this.lines[i].destroy();
|
||||
}
|
||||
|
||||
this.size = 0;
|
||||
};
|
|
@ -1,98 +0,0 @@
|
|||
//
|
||||
// baseball.js
|
||||
// examples/toys
|
||||
//
|
||||
// Created by Stephen Birarda on 10/20/15.
|
||||
// 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 ROBOT_MODEL = "atp:ea02100c2ee63a8b9c0495557f32041be18ec94def157592e84a816665ce2f6e.fbx";
|
||||
var ROBOT_POSITION = { x: -0.54, y: 1.21, z: 2.57 }
|
||||
|
||||
var BAT_MODEL = "atp:07bdd769a57ff15ebe9331ae4e2c2eae8886a6792b4790cce03b4716eb3a81c7.fbx"
|
||||
var BAT_COLLISION_MODEL = "atp:1211ee12bc8ab0bb744e8582e15e728a00ca70a808550fc46d7284799b9a868a.obj"
|
||||
|
||||
// add the fresh robot at home plate
|
||||
var robot = Entities.addEntity({
|
||||
name: 'Robot',
|
||||
type: 'Model',
|
||||
modelURL: ROBOT_MODEL,
|
||||
position: ROBOT_POSITION,
|
||||
animation: {
|
||||
url: ROBOT_MODEL,
|
||||
running: true
|
||||
}
|
||||
});
|
||||
|
||||
// add the bat
|
||||
var bat = Entities.addEntity({
|
||||
name: 'Bat',
|
||||
type: 'Model',
|
||||
modelURL: BAT_MODEL
|
||||
})
|
||||
|
||||
var lastTriggerValue = 0.0;
|
||||
|
||||
function checkTriggers() {
|
||||
var rightTrigger = Controller.getTriggerValue(1);
|
||||
|
||||
if (rightTrigger == 0) {
|
||||
if (lastTriggerValue > 0) {
|
||||
// the trigger was just released, play out to the last frame of the swing
|
||||
Entities.editEntity(robot, {
|
||||
animation: {
|
||||
running: true,
|
||||
currentFrame: 21,
|
||||
lastFrame: 115
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (lastTriggerValue == 0) {
|
||||
// the trigger was just depressed, start the swing
|
||||
Entities.editEntity(robot, {
|
||||
animation: {
|
||||
running: true,
|
||||
currentFrame: 0,
|
||||
lastFrame: 21
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
lastTriggerValue = rightTrigger;
|
||||
}
|
||||
|
||||
var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position
|
||||
var ACTION_LIFETIME = 15; // seconds
|
||||
|
||||
function moveBat() {
|
||||
var forearmPosition = Entities.getJointPosition(robot, 40);
|
||||
var forearmRotation = Entities.getJointRotation(robot, 40);
|
||||
|
||||
Vec3.print("forearmPosition=", forearmPosition);
|
||||
|
||||
// Entities.addAction("spring", bat, {
|
||||
// targetPosition: forearmPosition,
|
||||
// targetRotation: forearmRotation,
|
||||
// linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME,
|
||||
// angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME,
|
||||
// lifetime: ACTION_LIFETIME
|
||||
// });
|
||||
|
||||
Entities.editEntity(bat, {
|
||||
position: forearmPosition,
|
||||
rotation: forearmRotation
|
||||
});
|
||||
}
|
||||
|
||||
function update() {
|
||||
checkTriggers();
|
||||
moveBat();
|
||||
}
|
||||
|
||||
// hook the update so we can check controller triggers
|
||||
Script.update.connect(update);
|
|
@ -508,26 +508,29 @@ void ScriptEngine::addEventHandler(const EntityItemID& entityID, const QString&
|
|||
// Connect up ALL the handlers to the global entities object's signals.
|
||||
// (We could go signal by signal, or even handler by handler, but I don't think the efficiency is worth the complexity.)
|
||||
auto entities = DependencyManager::get<EntityScriptingInterface>();
|
||||
connect(entities.data(), &EntityScriptingInterface::deletingEntity, this,
|
||||
[=](const EntityItemID& entityID) {
|
||||
_registeredHandlers.remove(entityID);
|
||||
});
|
||||
|
||||
connect(entities.data(), &EntityScriptingInterface::deletingEntity, this, [this](const EntityItemID& entityID) {
|
||||
_registeredHandlers.remove(entityID);
|
||||
});
|
||||
|
||||
// Two common cases of event handler, differing only in argument signature.
|
||||
auto makeSingleEntityHandler = [=](const QString& eventName) -> std::function<void(const EntityItemID&)> {
|
||||
return [=](const EntityItemID& entityItemID) -> void {
|
||||
generalHandler(entityItemID, eventName, [=]() -> QScriptValueList {
|
||||
return QScriptValueList() << entityItemID.toScriptValue(this);
|
||||
});
|
||||
auto makeSingleEntityHandler = [&](QString eventName) {
|
||||
return [this, eventName](const EntityItemID& entityItemID) {
|
||||
forwardHandlerCall(entityItemID, eventName, { entityItemID.toScriptValue(this) });
|
||||
};
|
||||
};
|
||||
auto makeMouseHandler = [=](const QString& eventName) -> std::function<void(const EntityItemID&, const MouseEvent&)> {
|
||||
return [=](const EntityItemID& entityItemID, const MouseEvent& event) -> void {
|
||||
generalHandler(entityItemID, eventName, [=]() -> QScriptValueList {
|
||||
return QScriptValueList() << entityItemID.toScriptValue(this) << event.toScriptValue(this);
|
||||
});
|
||||
auto makeMouseHandler = [&](QString eventName) {
|
||||
return [this, eventName](const EntityItemID& entityItemID, const MouseEvent& event) {
|
||||
forwardHandlerCall(entityItemID, eventName, { entityItemID.toScriptValue(this), event.toScriptValue(this) });
|
||||
};
|
||||
};
|
||||
|
||||
auto makeCollisionHandler = [&](QString eventName) {
|
||||
return [this, eventName](const EntityItemID& idA, const EntityItemID& idB, const Collision& collision) {
|
||||
forwardHandlerCall(idA, eventName, { idA.toScriptValue(this), idB.toScriptValue(this),
|
||||
collisionToScriptValue(this, collision) });
|
||||
};
|
||||
};
|
||||
|
||||
connect(entities.data(), &EntityScriptingInterface::enterEntity, this, makeSingleEntityHandler("enterEntity"));
|
||||
connect(entities.data(), &EntityScriptingInterface::leaveEntity, this, makeSingleEntityHandler("leaveEntity"));
|
||||
|
||||
|
@ -543,12 +546,7 @@ void ScriptEngine::addEventHandler(const EntityItemID& entityID, const QString&
|
|||
connect(entities.data(), &EntityScriptingInterface::hoverOverEntity, this, makeMouseHandler("hoverOverEntity"));
|
||||
connect(entities.data(), &EntityScriptingInterface::hoverLeaveEntity, this, makeMouseHandler("hoverLeaveEntity"));
|
||||
|
||||
connect(entities.data(), &EntityScriptingInterface::collisionWithEntity, this,
|
||||
[=](const EntityItemID& idA, const EntityItemID& idB, const Collision& collision) {
|
||||
generalHandler(idA, "collisionWithEntity", [=]() {
|
||||
return QScriptValueList () << idA.toScriptValue(this) << idB.toScriptValue(this) << collisionToScriptValue(this, collision);
|
||||
});
|
||||
});
|
||||
connect(entities.data(), &EntityScriptingInterface::collisionWithEntity, this, makeCollisionHandler("collisionWithEntity"));
|
||||
}
|
||||
if (!_registeredHandlers.contains(entityID)) {
|
||||
_registeredHandlers[entityID] = RegisteredEventHandlers();
|
||||
|
@ -899,9 +897,9 @@ void ScriptEngine::load(const QString& loadFile) {
|
|||
}
|
||||
|
||||
// Look up the handler associated with eventName and entityID. If found, evalute the argGenerator thunk and call the handler with those args
|
||||
void ScriptEngine::generalHandler(const EntityItemID& entityID, const QString& eventName, std::function<QScriptValueList()> argGenerator) {
|
||||
void ScriptEngine::forwardHandlerCall(const EntityItemID& entityID, const QString& eventName, QScriptValueList eventHanderArgs) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
qDebug() << "*** ERROR *** ScriptEngine::generalHandler() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "]";
|
||||
qDebug() << "*** ERROR *** ScriptEngine::forwardHandlerCall() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "]";
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
@ -915,9 +913,8 @@ void ScriptEngine::generalHandler(const EntityItemID& entityID, const QString& e
|
|||
}
|
||||
QScriptValueList handlersForEvent = handlersOnEntity[eventName];
|
||||
if (!handlersForEvent.isEmpty()) {
|
||||
QScriptValueList args = argGenerator();
|
||||
for (int i = 0; i < handlersForEvent.count(); ++i) {
|
||||
handlersForEvent[i].call(QScriptValue(), args);
|
||||
handlersForEvent[i].call(QScriptValue(), eventHanderArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -193,7 +193,7 @@ private:
|
|||
ArrayBufferClass* _arrayBufferClass;
|
||||
|
||||
QHash<EntityItemID, RegisteredEventHandlers> _registeredHandlers;
|
||||
void generalHandler(const EntityItemID& entityID, const QString& eventName, std::function<QScriptValueList()> argGenerator);
|
||||
void forwardHandlerCall(const EntityItemID& entityID, const QString& eventName, QScriptValueList eventHanderArgs);
|
||||
Q_INVOKABLE void entityScriptContentAvailable(const EntityItemID& entityID, const QString& scriptOrURL, const QString& contents, bool isURL, bool success);
|
||||
|
||||
static QSet<ScriptEngine*> _allKnownScriptEngines;
|
||||
|
|
Loading…
Reference in a new issue