mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 09:57:26 +02:00
merge with upstream
This commit is contained in:
commit
ab4b940d83
38 changed files with 4005 additions and 519 deletions
38
cmake/modules/FindconnexionClient.cmake
Normal file
38
cmake/modules/FindconnexionClient.cmake
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#
|
||||||
|
# FindconnexionClient.cmake
|
||||||
|
#
|
||||||
|
# Once done this will define
|
||||||
|
#
|
||||||
|
# 3DCONNEXIONCLIENT_INCLUDE_DIRS
|
||||||
|
#
|
||||||
|
# Created on 10/06/2015 by Marcel Verhagen
|
||||||
|
# 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
|
||||||
|
#
|
||||||
|
|
||||||
|
# setup hints for 3DCONNEXIONCLIENT search
|
||||||
|
include("${MACRO_DIR}/HifiLibrarySearchHints.cmake")
|
||||||
|
hifi_library_search_hints("connexionclient")
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
find_library(3DconnexionClient 3DconnexionClient)
|
||||||
|
if(EXISTS ${3DconnexionClient})
|
||||||
|
set(CONNEXIONCLIENT_FOUND true)
|
||||||
|
set(CONNEXIONCLIENT_INCLUDE_DIR ${3DconnexionClient})
|
||||||
|
set(CONNEXIONCLIENT_LIBRARY ${3DconnexionClient})
|
||||||
|
set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "-weak_framework 3DconnexionClient")
|
||||||
|
message(STATUS "Found 3Dconnexion")
|
||||||
|
mark_as_advanced(CONNEXIONCLIENT_INCLUDE_DIR CONNEXIONCLIENT_LIBRARY)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
find_path(CONNEXIONCLIENT_INCLUDE_DIRS I3dMouseParams.h PATH_SUFFIXES Inc HINTS ${CONNEXIONCLIENT_SEARCH_DIRS})
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(connexionClient DEFAULT_MSG CONNEXIONCLIENT_INCLUDE_DIRS)
|
||||||
|
|
||||||
|
mark_as_advanced(CONNEXIONCLIENT_INCLUDE_DIRS CONNEXIONCLIENT_SEARCH_DIRS)
|
||||||
|
endif()
|
28
examples/example/games/hitEffect.js
Normal file
28
examples/example/games/hitEffect.js
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
//
|
||||||
|
// hitEffect.js
|
||||||
|
// examples
|
||||||
|
//
|
||||||
|
// Created by Eric Levin on July 20, 2015
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// An example of how to toggle a screen-space hit effect using the Scene global object.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
|
||||||
|
var hitEffectEnabled = false;
|
||||||
|
|
||||||
|
toggleHitEffect();
|
||||||
|
|
||||||
|
function toggleHitEffect() {
|
||||||
|
Script.setTimeout(function() {
|
||||||
|
hitEffectEnabled = !hitEffectEnabled;
|
||||||
|
Scene.setEngineDisplayHitEffect(hitEffectEnabled);
|
||||||
|
toggleHitEffect();
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
288
examples/example/games/satellite.js
Normal file
288
examples/example/games/satellite.js
Normal file
|
@ -0,0 +1,288 @@
|
||||||
|
//
|
||||||
|
// satellite.js
|
||||||
|
// games
|
||||||
|
//
|
||||||
|
// Created by Bridget Went 7/1/2015.
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// A game to bring a satellite model into orbit around an animated earth model .
|
||||||
|
// - Double click to create a new satellite
|
||||||
|
// - Click on the satellite, drag a vector arrow to specify initial velocity
|
||||||
|
// - Release mouse to launch the active satellite
|
||||||
|
// - Orbital movement is calculated using equations of gravitational physics
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
Script.include('../utilities/tools/vector.js');
|
||||||
|
|
||||||
|
var URL = "https://s3.amazonaws.com/hifi-public/marketplace/hificontent/Scripts/planets/";
|
||||||
|
|
||||||
|
SatelliteGame = function() {
|
||||||
|
var MAX_RANGE = 50.0;
|
||||||
|
var Y_AXIS = {
|
||||||
|
x: 0,
|
||||||
|
y: 1,
|
||||||
|
z: 0
|
||||||
|
}
|
||||||
|
var LIFETIME = 6000;
|
||||||
|
var ERROR_THRESH = 20.0;
|
||||||
|
|
||||||
|
// Create the spinning earth model
|
||||||
|
var EARTH_SIZE = 20.0;
|
||||||
|
var CLOUDS_OFFSET = 0.5;
|
||||||
|
var SPIN = 0.1;
|
||||||
|
var ZONE_DIM = 100.0;
|
||||||
|
var LIGHT_INTENSITY = 1.5;
|
||||||
|
|
||||||
|
Earth = function(position, size) {
|
||||||
|
this.earth = Entities.addEntity({
|
||||||
|
type: "Model",
|
||||||
|
shapeType: 'sphere',
|
||||||
|
modelURL: URL + "earth.fbx",
|
||||||
|
position: position,
|
||||||
|
dimensions: {
|
||||||
|
x: size,
|
||||||
|
y: size,
|
||||||
|
z: size
|
||||||
|
},
|
||||||
|
rotation: Quat.angleAxis(180, {
|
||||||
|
x: 1,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
}),
|
||||||
|
angularVelocity: {
|
||||||
|
x: 0.00,
|
||||||
|
y: 0.5 * SPIN,
|
||||||
|
z: 0.00
|
||||||
|
},
|
||||||
|
angularDamping: 0.0,
|
||||||
|
damping: 0.0,
|
||||||
|
ignoreCollisions: false,
|
||||||
|
lifetime: 6000,
|
||||||
|
collisionsWillMove: false,
|
||||||
|
visible: true
|
||||||
|
});
|
||||||
|
|
||||||
|
this.clouds = Entities.addEntity({
|
||||||
|
type: "Model",
|
||||||
|
shapeType: 'sphere',
|
||||||
|
modelURL: URL + "clouds.fbx?i=2",
|
||||||
|
position: position,
|
||||||
|
dimensions: {
|
||||||
|
x: size + CLOUDS_OFFSET,
|
||||||
|
y: size + CLOUDS_OFFSET,
|
||||||
|
z: size + CLOUDS_OFFSET
|
||||||
|
},
|
||||||
|
angularVelocity: {
|
||||||
|
x: 0.00,
|
||||||
|
y: SPIN,
|
||||||
|
z: 0.00
|
||||||
|
},
|
||||||
|
angularDamping: 0.0,
|
||||||
|
damping: 0.0,
|
||||||
|
ignoreCollisions: false,
|
||||||
|
lifetime: LIFETIME,
|
||||||
|
collisionsWillMove: false,
|
||||||
|
visible: true
|
||||||
|
});
|
||||||
|
|
||||||
|
this.zone = Entities.addEntity({
|
||||||
|
type: "Zone",
|
||||||
|
position: position,
|
||||||
|
dimensions: {
|
||||||
|
x: ZONE_DIM,
|
||||||
|
y: ZONE_DIM,
|
||||||
|
z: ZONE_DIM
|
||||||
|
},
|
||||||
|
keyLightDirection: Vec3.normalize(Vec3.subtract(position, Camera.getPosition())),
|
||||||
|
keyLightIntensity: LIGHT_INTENSITY
|
||||||
|
});
|
||||||
|
|
||||||
|
this.cleanup = function() {
|
||||||
|
Entities.deleteEntity(this.clouds);
|
||||||
|
Entities.deleteEntity(this.earth);
|
||||||
|
Entities.deleteEntity(this.zone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create earth model
|
||||||
|
var center = Vec3.sum(Camera.getPosition(), Vec3.multiply(MAX_RANGE, Quat.getFront(Camera.getOrientation())));
|
||||||
|
var distance = Vec3.length(Vec3.subtract(center, Camera.getPosition()));
|
||||||
|
var earth = new Earth(center, EARTH_SIZE);
|
||||||
|
|
||||||
|
var satellites = [];
|
||||||
|
var SATELLITE_SIZE = 2.0;
|
||||||
|
var launched = false;
|
||||||
|
var activeSatellite;
|
||||||
|
|
||||||
|
var PERIOD = 4.0;
|
||||||
|
var LARGE_BODY_MASS = 16000.0;
|
||||||
|
var SMALL_BODY_MASS = LARGE_BODY_MASS * 0.000000333;
|
||||||
|
|
||||||
|
Satellite = function(position, planetCenter) {
|
||||||
|
// The Satellite class
|
||||||
|
|
||||||
|
this.launched = false;
|
||||||
|
this.startPosition = position;
|
||||||
|
this.readyToLaunch = false;
|
||||||
|
this.radius = Vec3.length(Vec3.subtract(position, planetCenter));
|
||||||
|
|
||||||
|
this.satellite = Entities.addEntity({
|
||||||
|
type: "Model",
|
||||||
|
modelURL: "https://s3.amazonaws.com/hifi-public/marketplace/hificontent/Scripts/planets/satellite/satellite.fbx",
|
||||||
|
position: this.startPosition,
|
||||||
|
dimensions: {
|
||||||
|
x: SATELLITE_SIZE,
|
||||||
|
y: SATELLITE_SIZE,
|
||||||
|
z: SATELLITE_SIZE
|
||||||
|
},
|
||||||
|
angularDamping: 0.0,
|
||||||
|
damping: 0.0,
|
||||||
|
ignoreCollisions: false,
|
||||||
|
lifetime: LIFETIME,
|
||||||
|
collisionsWillMove: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.getProperties = function() {
|
||||||
|
return Entities.getEntityProperties(this.satellite);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.launch = function() {
|
||||||
|
var prop = Entities.getEntityProperties(this.satellite);
|
||||||
|
var between = Vec3.subtract(planetCenter, prop.position);
|
||||||
|
var radius = Vec3.length(between);
|
||||||
|
this.gravity = (4.0 * Math.PI * Math.PI * Math.pow(radius, 3.0)) / (LARGE_BODY_MASS * PERIOD * PERIOD);
|
||||||
|
|
||||||
|
var initialVelocity = Vec3.normalize(Vec3.cross(between, Y_AXIS));
|
||||||
|
initialVelocity = Vec3.multiply(Math.sqrt((this.gravity * LARGE_BODY_MASS) / radius), initialVelocity);
|
||||||
|
initialVelocity = Vec3.multiply(this.arrow.magnitude, initialVelocity);
|
||||||
|
initialVelocity = Vec3.multiply(Vec3.length(initialVelocity), this.arrow.direction);
|
||||||
|
|
||||||
|
Entities.editEntity(this.satellite, {
|
||||||
|
velocity: initialVelocity
|
||||||
|
});
|
||||||
|
this.launched = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
this.update = function(deltaTime) {
|
||||||
|
var prop = Entities.getEntityProperties(this.satellite);
|
||||||
|
var between = Vec3.subtract(prop.position, planetCenter);
|
||||||
|
var radius = Vec3.length(between);
|
||||||
|
var acceleration = -(this.gravity * LARGE_BODY_MASS) * Math.pow(radius, (-2.0));
|
||||||
|
var speed = acceleration * deltaTime;
|
||||||
|
var vel = Vec3.multiply(speed, Vec3.normalize(between));
|
||||||
|
|
||||||
|
var newVelocity = Vec3.sum(prop.velocity, vel);
|
||||||
|
var newPos = Vec3.sum(prop.position, Vec3.multiply(newVelocity, deltaTime));
|
||||||
|
|
||||||
|
Entities.editEntity(this.satellite, {
|
||||||
|
velocity: newVelocity,
|
||||||
|
position: newPos
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseDoublePressEvent(event) {
|
||||||
|
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||||
|
var addVector = Vec3.multiply(pickRay.direction, distance);
|
||||||
|
var point = Vec3.sum(Camera.getPosition(), addVector);
|
||||||
|
|
||||||
|
// Create a new satellite
|
||||||
|
activeSatellite = new Satellite(point, center);
|
||||||
|
satellites.push(activeSatellite);
|
||||||
|
}
|
||||||
|
|
||||||
|
function mousePressEvent(event) {
|
||||||
|
if (!activeSatellite) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Reset label
|
||||||
|
if (activeSatellite.arrow) {
|
||||||
|
activeSatellite.arrow.deleteLabel();
|
||||||
|
}
|
||||||
|
var statsPosition = Vec3.sum(Camera.getPosition(), Vec3.multiply(MAX_RANGE * 0.4, Quat.getFront(Camera.getOrientation())));
|
||||||
|
var pickRay = Camera.computePickRay(event.x, event.y)
|
||||||
|
var rayPickResult = Entities.findRayIntersection(pickRay, true);
|
||||||
|
if (rayPickResult.entityID === activeSatellite.satellite) {
|
||||||
|
// Create a draggable vector arrow at satellite position
|
||||||
|
activeSatellite.arrow = new VectorArrow(distance, true, "INITIAL VELOCITY", statsPosition);
|
||||||
|
activeSatellite.arrow.onMousePressEvent(event);
|
||||||
|
activeSatellite.arrow.isDragging = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseMoveEvent(event) {
|
||||||
|
if (!activeSatellite || !activeSatellite.arrow || !activeSatellite.arrow.isDragging) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
activeSatellite.arrow.onMouseMoveEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseReleaseEvent(event) {
|
||||||
|
if (!activeSatellite || !activeSatellite.arrow || !activeSatellite.arrow.isDragging) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
activeSatellite.arrow.onMouseReleaseEvent(event);
|
||||||
|
activeSatellite.launch();
|
||||||
|
activeSatellite.arrow.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
var counter = 0.0;
|
||||||
|
var CHECK_ENERGY_PERIOD = 500;
|
||||||
|
|
||||||
|
function update(deltaTime) {
|
||||||
|
if (!activeSatellite) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Update all satellites
|
||||||
|
for (var i = 0; i < satellites.length; i++) {
|
||||||
|
if (!satellites[i].launched) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
satellites[i].update(deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
counter++;
|
||||||
|
if (counter % CHECK_ENERGY_PERIOD == 0) {
|
||||||
|
var prop = activeSatellite.getProperties();
|
||||||
|
var error = calcEnergyError(prop.position, Vec3.length(prop.velocity));
|
||||||
|
if (Math.abs(error) <= ERROR_THRESH) {
|
||||||
|
activeSatellite.arrow.editLabel("Nice job! The satellite has reached a stable orbit.");
|
||||||
|
} else {
|
||||||
|
activeSatellite.arrow.editLabel("Try again! The satellite is in an unstable orbit.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.endGame = function() {
|
||||||
|
for (var i = 0; i < satellites.length; i++) {
|
||||||
|
Entities.deleteEntity(satellites[i].satellite);
|
||||||
|
satellites[i].arrow.cleanup();
|
||||||
|
}
|
||||||
|
earth.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function calcEnergyError(pos, vel) {
|
||||||
|
//Calculate total energy error for active satellite's orbital motion
|
||||||
|
var radius = activeSatellite.radius;
|
||||||
|
var gravity = (4.0 * Math.PI * Math.PI * Math.pow(radius, 3.0)) / (LARGE_BODY_MASS * PERIOD * PERIOD);
|
||||||
|
var initialVelocityCalculated = Math.sqrt((gravity * LARGE_BODY_MASS) / radius);
|
||||||
|
|
||||||
|
var totalEnergy = 0.5 * LARGE_BODY_MASS * Math.pow(initialVelocityCalculated, 2.0) - ((gravity * LARGE_BODY_MASS * SMALL_BODY_MASS) / radius);
|
||||||
|
var measuredEnergy = 0.5 * LARGE_BODY_MASS * Math.pow(vel, 2.0) - ((gravity * LARGE_BODY_MASS * SMALL_BODY_MASS) / Vec3.length(Vec3.subtract(pos, center)));
|
||||||
|
var error = ((measuredEnergy - totalEnergy) / totalEnergy) * 100;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
Controller.mousePressEvent.connect(mousePressEvent);
|
||||||
|
Controller.mouseDoublePressEvent.connect(mouseDoublePressEvent);
|
||||||
|
Controller.mouseMoveEvent.connect(mouseMoveEvent);
|
||||||
|
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
|
||||||
|
Script.update.connect(update);
|
||||||
|
Script.scriptEnding.connect(this.endGame);
|
||||||
|
|
||||||
|
}
|
669
examples/example/solarsystem.js
Normal file
669
examples/example/solarsystem.js
Normal file
|
@ -0,0 +1,669 @@
|
||||||
|
//
|
||||||
|
// solarsystem.js
|
||||||
|
// games
|
||||||
|
//
|
||||||
|
// Created by Bridget Went, 5/28/15.
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// The start to a project to build a virtual physics classroom to simulate the solar system, gravity, and orbital physics.
|
||||||
|
// - A sun with oribiting planets is created in front of the user
|
||||||
|
// - UI elements allow for adjusting the period, gravity, trails, and energy recalculations
|
||||||
|
// - Click "PAUSE" to pause the animation and show planet labels
|
||||||
|
// - In this mode, double-click a planet label to zoom in on that planet
|
||||||
|
// -Double-clicking on earth label initiates satellite orbiter game
|
||||||
|
// -Press "TAB" to toggle back to solar system view
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
Script.include('../utilities/tools/cookies.js');
|
||||||
|
Script.include('games/satellite.js');
|
||||||
|
|
||||||
|
var BASE_URL = "https://s3.amazonaws.com/hifi-public/marketplace/hificontent/Scripts/planets/planets/";
|
||||||
|
|
||||||
|
var NUM_PLANETS = 8;
|
||||||
|
|
||||||
|
var trailsEnabled = true;
|
||||||
|
var energyConserved = true;
|
||||||
|
var planetView = false;
|
||||||
|
var earthView = false;
|
||||||
|
var satelliteGame;
|
||||||
|
|
||||||
|
var PANEL_X = 850;
|
||||||
|
var PANEL_Y = 600;
|
||||||
|
var BUTTON_SIZE = 20;
|
||||||
|
var PADDING = 20;
|
||||||
|
|
||||||
|
var DAMPING = 0.0;
|
||||||
|
var LIFETIME = 6000;
|
||||||
|
var ERROR_THRESH = 2.0;
|
||||||
|
var TIME_STEP = 70.0;
|
||||||
|
|
||||||
|
var MAX_POINTS_PER_LINE = 5;
|
||||||
|
var LINE_DIM = 10;
|
||||||
|
var LINE_WIDTH = 3.0;
|
||||||
|
var line;
|
||||||
|
var planetLines = [];
|
||||||
|
var trails = [];
|
||||||
|
|
||||||
|
var BOUNDS = 200;
|
||||||
|
|
||||||
|
|
||||||
|
// Alert user to move if they are too close to domain bounds
|
||||||
|
if (MyAvatar.position.x < BOUNDS || MyAvatar.position.x > TREE_SCALE - BOUNDS || MyAvatar.position.y < BOUNDS || MyAvatar.position.y > TREE_SCALE - BOUNDS || MyAvatar.position.z < BOUNDS || MyAvatar.position.z > TREE_SCALE - BOUNDS) {
|
||||||
|
Window.alert("Please move at least 200m away from domain bounds.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save intiial avatar and camera position
|
||||||
|
var startingPosition = MyAvatar.position;
|
||||||
|
var startFrame = Window.location.href;
|
||||||
|
|
||||||
|
// Place the sun
|
||||||
|
var MAX_RANGE = 80.0;
|
||||||
|
var SUN_SIZE = 8.0;
|
||||||
|
var center = Vec3.sum(startingPosition, Vec3.multiply(MAX_RANGE, Quat.getFront(Camera.getOrientation())));
|
||||||
|
|
||||||
|
var theSun = Entities.addEntity({
|
||||||
|
type: "Model",
|
||||||
|
modelURL: BASE_URL + "sun.fbx",
|
||||||
|
position: center,
|
||||||
|
dimensions: {
|
||||||
|
x: SUN_SIZE,
|
||||||
|
y: SUN_SIZE,
|
||||||
|
z: SUN_SIZE
|
||||||
|
},
|
||||||
|
angularDamping: DAMPING,
|
||||||
|
damping: DAMPING,
|
||||||
|
ignoreCollisions: false,
|
||||||
|
lifetime: LIFETIME,
|
||||||
|
collisionsWillMove: false
|
||||||
|
});
|
||||||
|
|
||||||
|
var planets = [];
|
||||||
|
var planet_properties = [];
|
||||||
|
|
||||||
|
// Reference values
|
||||||
|
var radius = 7.0;
|
||||||
|
var T_ref = 1.0;
|
||||||
|
var size = 1.0;
|
||||||
|
var M = 250.0;
|
||||||
|
var m = M * 0.000000333;
|
||||||
|
var G = (Math.pow(radius, 3.0) / Math.pow((T_ref / (2.0 * Math.PI)), 2.0)) / M;
|
||||||
|
var G_ref = G;
|
||||||
|
|
||||||
|
// Adjust size and distance as number of planets increases
|
||||||
|
var DELTA_RADIUS = 1.8;
|
||||||
|
var DELTA_SIZE = 0.2;
|
||||||
|
|
||||||
|
function initPlanets() {
|
||||||
|
for (var i = 0; i < NUM_PLANETS; ++i) {
|
||||||
|
var v0 = Math.sqrt((G * M) / radius);
|
||||||
|
var T = (2.0 * Math.PI) * Math.sqrt(Math.pow(radius, 3.0) / (G * M));
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
var color = {
|
||||||
|
red: 255,
|
||||||
|
green: 255,
|
||||||
|
blue: 255
|
||||||
|
};
|
||||||
|
} else if (i == 1) {
|
||||||
|
var color = {
|
||||||
|
red: 255,
|
||||||
|
green: 160,
|
||||||
|
blue: 110
|
||||||
|
};
|
||||||
|
} else if (i == 2) {
|
||||||
|
var color = {
|
||||||
|
red: 10,
|
||||||
|
green: 150,
|
||||||
|
blue: 160
|
||||||
|
};
|
||||||
|
} else if (i == 3) {
|
||||||
|
var color = {
|
||||||
|
red: 180,
|
||||||
|
green: 70,
|
||||||
|
blue: 10
|
||||||
|
};
|
||||||
|
} else if (i == 4) {
|
||||||
|
var color = {
|
||||||
|
red: 250,
|
||||||
|
green: 140,
|
||||||
|
blue: 0
|
||||||
|
};
|
||||||
|
} else if (i == 5) {
|
||||||
|
var color = {
|
||||||
|
red: 235,
|
||||||
|
green: 215,
|
||||||
|
blue: 0
|
||||||
|
};
|
||||||
|
} else if (i == 6) {
|
||||||
|
var color = {
|
||||||
|
red: 135,
|
||||||
|
green: 205,
|
||||||
|
blue: 240
|
||||||
|
};
|
||||||
|
} else if (i == 7) {
|
||||||
|
var color = {
|
||||||
|
red: 30,
|
||||||
|
green: 140,
|
||||||
|
blue: 255
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var prop = {
|
||||||
|
radius: radius,
|
||||||
|
position: Vec3.sum(center, {
|
||||||
|
x: radius,
|
||||||
|
y: 0.0,
|
||||||
|
z: 0.0
|
||||||
|
}),
|
||||||
|
lineColor: color,
|
||||||
|
period: T,
|
||||||
|
dimensions: size,
|
||||||
|
velocity: Vec3.multiply(v0, Vec3.normalize({
|
||||||
|
x: 0,
|
||||||
|
y: -0.2,
|
||||||
|
z: 0.9
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
planet_properties.push(prop);
|
||||||
|
|
||||||
|
planets.push(Entities.addEntity({
|
||||||
|
type: "Model",
|
||||||
|
modelURL: BASE_URL + (i + 1) + ".fbx",
|
||||||
|
position: prop.position,
|
||||||
|
dimensions: {
|
||||||
|
x: prop.dimensions,
|
||||||
|
y: prop.dimensions,
|
||||||
|
z: prop.dimensions
|
||||||
|
},
|
||||||
|
velocity: prop.velocity,
|
||||||
|
angularDamping: DAMPING,
|
||||||
|
damping: DAMPING,
|
||||||
|
ignoreCollisions: false,
|
||||||
|
lifetime: LIFETIME,
|
||||||
|
collisionsWillMove: true,
|
||||||
|
}));
|
||||||
|
|
||||||
|
radius *= DELTA_RADIUS;
|
||||||
|
size += DELTA_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize planets
|
||||||
|
initPlanets();
|
||||||
|
|
||||||
|
|
||||||
|
var labels = [];
|
||||||
|
var labelLines = [];
|
||||||
|
var labelsShowing = false;
|
||||||
|
var LABEL_X = 8.0;
|
||||||
|
var LABEL_Y = 3.0;
|
||||||
|
var LABEL_Z = 1.0;
|
||||||
|
var LABEL_DIST = 8.0;
|
||||||
|
var TEXT_HEIGHT = 1.0;
|
||||||
|
var sunLabel;
|
||||||
|
|
||||||
|
function showLabels() {
|
||||||
|
labelsShowing = true;
|
||||||
|
for (var i = 0; i < NUM_PLANETS; i++) {
|
||||||
|
var properties = planet_properties[i];
|
||||||
|
var text;
|
||||||
|
if (i == 0) {
|
||||||
|
text = "Mercury";
|
||||||
|
} else if (i == 1) {
|
||||||
|
text = "Venus";
|
||||||
|
} else if (i == 2) {
|
||||||
|
text = "Earth";
|
||||||
|
} else if (i == 3) {
|
||||||
|
text = "Mars";
|
||||||
|
} else if (i == 4) {
|
||||||
|
text = "Jupiter";
|
||||||
|
} else if (i == 5) {
|
||||||
|
text = "Saturn";
|
||||||
|
} else if (i == 6) {
|
||||||
|
text = "Uranus";
|
||||||
|
} else if (i == 7) {
|
||||||
|
text = "Neptune";
|
||||||
|
}
|
||||||
|
|
||||||
|
text = text + " Speed: " + Vec3.length(properties.velocity).toFixed(2);
|
||||||
|
|
||||||
|
var labelPos = Vec3.sum(planet_properties[i].position, {
|
||||||
|
x: 0.0,
|
||||||
|
y: LABEL_DIST,
|
||||||
|
z: LABEL_DIST
|
||||||
|
});
|
||||||
|
var linePos = planet_properties[i].position;
|
||||||
|
labelLines.push(Entities.addEntity({
|
||||||
|
type: "Line",
|
||||||
|
position: linePos,
|
||||||
|
dimensions: {
|
||||||
|
x: 20,
|
||||||
|
y: 20,
|
||||||
|
z: 20
|
||||||
|
},
|
||||||
|
lineWidth: 3.0,
|
||||||
|
color: {
|
||||||
|
red: 255,
|
||||||
|
green: 255,
|
||||||
|
blue: 255
|
||||||
|
},
|
||||||
|
linePoints: [{
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
z: 0
|
||||||
|
}, computeLocalPoint(linePos, labelPos)]
|
||||||
|
}));
|
||||||
|
|
||||||
|
labels.push(Entities.addEntity({
|
||||||
|
type: "Text",
|
||||||
|
text: text,
|
||||||
|
lineHeight: TEXT_HEIGHT,
|
||||||
|
dimensions: {
|
||||||
|
x: LABEL_X,
|
||||||
|
y: LABEL_Y,
|
||||||
|
z: LABEL_Z
|
||||||
|
},
|
||||||
|
position: labelPos,
|
||||||
|
backgroundColor: {
|
||||||
|
red: 10,
|
||||||
|
green: 10,
|
||||||
|
blue: 10
|
||||||
|
},
|
||||||
|
textColor: {
|
||||||
|
red: 255,
|
||||||
|
green: 255,
|
||||||
|
blue: 255
|
||||||
|
},
|
||||||
|
faceCamera: true
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideLabels() {
|
||||||
|
labelsShowing = false;
|
||||||
|
Entities.deleteEntity(sunLabel);
|
||||||
|
|
||||||
|
for (var i = 0; i < NUM_PLANETS; ++i) {
|
||||||
|
Entities.deleteEntity(labelLines[i]);
|
||||||
|
Entities.deleteEntity(labels[i]);
|
||||||
|
}
|
||||||
|
labels = [];
|
||||||
|
labelLines = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
var time = 0.0;
|
||||||
|
var elapsed;
|
||||||
|
var counter = 0;
|
||||||
|
var dt = 1.0 / TIME_STEP;
|
||||||
|
|
||||||
|
function update(deltaTime) {
|
||||||
|
if (paused) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
deltaTime = dt;
|
||||||
|
time++;
|
||||||
|
|
||||||
|
for (var i = 0; i < NUM_PLANETS; ++i) {
|
||||||
|
var properties = planet_properties[i];
|
||||||
|
var between = Vec3.subtract(properties.position, center);
|
||||||
|
var speed = getAcceleration(properties.radius) * deltaTime;
|
||||||
|
var vel = Vec3.multiply(speed, Vec3.normalize(between));
|
||||||
|
|
||||||
|
// Update velocity and position
|
||||||
|
properties.velocity = Vec3.sum(properties.velocity, vel);
|
||||||
|
properties.position = Vec3.sum(properties.position, Vec3.multiply(properties.velocity, deltaTime));
|
||||||
|
Entities.editEntity(planets[i], {
|
||||||
|
velocity: properties.velocity,
|
||||||
|
position: properties.position
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Create new or update current trail
|
||||||
|
if (trailsEnabled) {
|
||||||
|
var lineStack = planetLines[i];
|
||||||
|
var point = properties.position;
|
||||||
|
var prop = Entities.getEntityProperties(lineStack[lineStack.length - 1]);
|
||||||
|
var linePos = prop.position;
|
||||||
|
|
||||||
|
trails[i].push(computeLocalPoint(linePos, point));
|
||||||
|
|
||||||
|
Entities.editEntity(lineStack[lineStack.length - 1], {
|
||||||
|
linePoints: trails[i]
|
||||||
|
});
|
||||||
|
if (trails[i].length === MAX_POINTS_PER_LINE) {
|
||||||
|
trails[i] = newLine(lineStack, point, properties.period, properties.lineColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Measure total energy every 10 updates, recalibrate velocity if necessary
|
||||||
|
if (energyConserved) {
|
||||||
|
if (counter % 10 === 0) {
|
||||||
|
var error = calcEnergyError(planets[i], properties.radius, properties.v0, properties.velocity, properties.position);
|
||||||
|
if (Math.abs(error) >= ERROR_THRESH) {
|
||||||
|
var speed = adjustVelocity(planets[i], properties.position);
|
||||||
|
properties.velocity = Vec3.multiply(speed, Vec3.normalize(properties.velocity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
counter++;
|
||||||
|
if (time % TIME_STEP == 0) {
|
||||||
|
elapsed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeLocalPoint(linePos, worldPoint) {
|
||||||
|
var localPoint = Vec3.subtract(worldPoint, linePos);
|
||||||
|
return localPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAcceleration(radius) {
|
||||||
|
var acc = -(G * M) * Math.pow(radius, (-2.0));
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new trail
|
||||||
|
function resetTrails(planetIndex) {
|
||||||
|
elapsed = 0.0;
|
||||||
|
var properties = planet_properties[planetIndex];
|
||||||
|
|
||||||
|
var trail = [];
|
||||||
|
var lineStack = [];
|
||||||
|
|
||||||
|
//add the first line to both the line entity stack and the trail
|
||||||
|
trails.push(newLine(lineStack, properties.position, properties.period, properties.lineColor));
|
||||||
|
planetLines.push(lineStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new line
|
||||||
|
function newLine(lineStack, point, period, color) {
|
||||||
|
if (elapsed < period) {
|
||||||
|
var line = Entities.addEntity({
|
||||||
|
position: point,
|
||||||
|
type: "Line",
|
||||||
|
color: color,
|
||||||
|
dimensions: {
|
||||||
|
x: LINE_DIM,
|
||||||
|
y: LINE_DIM,
|
||||||
|
z: LINE_DIM
|
||||||
|
},
|
||||||
|
lifetime: LIFETIME,
|
||||||
|
lineWidth: LINE_WIDTH
|
||||||
|
});
|
||||||
|
lineStack.push(line);
|
||||||
|
} else {
|
||||||
|
// Begin overwriting first lines after one full revolution (one period)
|
||||||
|
var firstLine = lineStack.shift();
|
||||||
|
Entities.editEntity(firstLine, {
|
||||||
|
position: point,
|
||||||
|
linePoints: [{
|
||||||
|
x: 0.0,
|
||||||
|
y: 0.0,
|
||||||
|
z: 0.0
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
lineStack.push(firstLine);
|
||||||
|
|
||||||
|
}
|
||||||
|
var points = [];
|
||||||
|
points.push(computeLocalPoint(point, point));
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Measure energy error, recalculate velocity to return to initial net energy
|
||||||
|
var totalEnergy;
|
||||||
|
var measuredEnergy;
|
||||||
|
var measuredPE;
|
||||||
|
|
||||||
|
function calcEnergyError(planet, radius, v0, v, pos) {
|
||||||
|
totalEnergy = 0.5 * M * Math.pow(v0, 2.0) - ((G * M * m) / radius);
|
||||||
|
measuredEnergy = 0.5 * M * Math.pow(v, 2.0) - ((G * M * m) / Vec3.length(Vec3.subtract(center, pos)));
|
||||||
|
var error = ((measuredEnergy - totalEnergy) / totalEnergy) * 100;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
function adjustVelocity(planet, pos) {
|
||||||
|
var measuredPE = -(G * M * m) / Vec3.length(Vec3.subtract(center, pos));
|
||||||
|
return Math.sqrt(2 * (totalEnergy - measuredPE) / M);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Allow user to toggle pausing the model, switch to planet view
|
||||||
|
var pauseButton = Overlays.addOverlay("text", {
|
||||||
|
backgroundColor: {
|
||||||
|
red: 200,
|
||||||
|
green: 200,
|
||||||
|
blue: 255
|
||||||
|
},
|
||||||
|
text: "Pause",
|
||||||
|
x: PANEL_X,
|
||||||
|
y: PANEL_Y - 30,
|
||||||
|
width: 70,
|
||||||
|
height: 20,
|
||||||
|
alpha: 1.0,
|
||||||
|
backgroundAlpha: 0.5,
|
||||||
|
visible: true
|
||||||
|
});
|
||||||
|
|
||||||
|
var paused = false;
|
||||||
|
|
||||||
|
function mousePressEvent(event) {
|
||||||
|
var clickedOverlay = Overlays.getOverlayAtPoint({
|
||||||
|
x: event.x,
|
||||||
|
y: event.y
|
||||||
|
});
|
||||||
|
if (clickedOverlay == pauseButton) {
|
||||||
|
paused = !paused;
|
||||||
|
for (var i = 0; i < NUM_PLANETS; ++i) {
|
||||||
|
Entities.editEntity(planets[i], {
|
||||||
|
velocity: {
|
||||||
|
x: 0.0,
|
||||||
|
y: 0.0,
|
||||||
|
z: 0.0
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (paused && !labelsShowing) {
|
||||||
|
Overlays.editOverlay(pauseButton, {
|
||||||
|
text: "Paused",
|
||||||
|
backgroundColor: {
|
||||||
|
red: 255,
|
||||||
|
green: 50,
|
||||||
|
blue: 50
|
||||||
|
}
|
||||||
|
});
|
||||||
|
showLabels();
|
||||||
|
}
|
||||||
|
if (paused == false && labelsShowing) {
|
||||||
|
Overlays.editOverlay(pauseButton, {
|
||||||
|
text: "Pause",
|
||||||
|
backgroundColor: {
|
||||||
|
red: 200,
|
||||||
|
green: 200,
|
||||||
|
blue: 255
|
||||||
|
}
|
||||||
|
});
|
||||||
|
hideLabels();
|
||||||
|
}
|
||||||
|
planetView = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function keyPressEvent(event) {
|
||||||
|
// Jump back to solar system view
|
||||||
|
if (event.text == "TAB" && planetView) {
|
||||||
|
if (earthView) {
|
||||||
|
satelliteGame.endGame();
|
||||||
|
earthView = false;
|
||||||
|
}
|
||||||
|
MyAvatar.position = startingPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseDoublePressEvent(event) {
|
||||||
|
if (earthView) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var pickRay = Camera.computePickRay(event.x, event.y)
|
||||||
|
var rayPickResult = Entities.findRayIntersection(pickRay, true);
|
||||||
|
|
||||||
|
for (var i = 0; i < NUM_PLANETS; ++i) {
|
||||||
|
if (rayPickResult.entityID === labels[i]) {
|
||||||
|
planetView = true;
|
||||||
|
if (i == 2) {
|
||||||
|
MyAvatar.position = Vec3.sum(center, {
|
||||||
|
x: 200,
|
||||||
|
y: 200,
|
||||||
|
z: 200
|
||||||
|
});
|
||||||
|
Camera.setPosition(Vec3.sum(center, {
|
||||||
|
x: 200,
|
||||||
|
y: 200,
|
||||||
|
z: 200
|
||||||
|
}));
|
||||||
|
earthView = true;
|
||||||
|
satelliteGame = new SatelliteGame();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
MyAvatar.position = Vec3.sum({
|
||||||
|
x: 0.0,
|
||||||
|
y: 0.0,
|
||||||
|
z: 3.0
|
||||||
|
}, planet_properties[i].position);
|
||||||
|
Camera.lookAt(planet_properties[i].position);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Create UI panel
|
||||||
|
var panel = new Panel(PANEL_X, PANEL_Y);
|
||||||
|
var panelItems = [];
|
||||||
|
|
||||||
|
var g_multiplier = 1.0;
|
||||||
|
panelItems.push(panel.newSlider("Adjust Gravitational Force: ", 0.1, 5.0,
|
||||||
|
function(value) {
|
||||||
|
g_multiplier = value;
|
||||||
|
G = G_ref * g_multiplier;
|
||||||
|
},
|
||||||
|
|
||||||
|
function() {
|
||||||
|
return g_multiplier;
|
||||||
|
},
|
||||||
|
function(value) {
|
||||||
|
return value.toFixed(1) + "x";
|
||||||
|
}));
|
||||||
|
|
||||||
|
var period_multiplier = 1.0;
|
||||||
|
var last_alpha = period_multiplier;
|
||||||
|
panelItems.push(panel.newSlider("Adjust Orbital Period: ", 0.1, 3.0,
|
||||||
|
function(value) {
|
||||||
|
period_multiplier = value;
|
||||||
|
changePeriod(period_multiplier);
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
return period_multiplier;
|
||||||
|
},
|
||||||
|
function(value) {
|
||||||
|
return (value).toFixed(2) + "x";
|
||||||
|
}));
|
||||||
|
|
||||||
|
panelItems.push(panel.newCheckbox("Leave Trails: ",
|
||||||
|
function(value) {
|
||||||
|
trailsEnabled = value;
|
||||||
|
if (trailsEnabled) {
|
||||||
|
for (var i = 0; i < NUM_PLANETS; ++i) {
|
||||||
|
resetTrails(i);
|
||||||
|
}
|
||||||
|
//if trails are off and we've already created trails, remove existing trails
|
||||||
|
} else if (planetLines.length != 0) {
|
||||||
|
for (var i = 0; i < NUM_PLANETS; ++i) {
|
||||||
|
for (var j = 0; j < planetLines[i].length; ++j) {
|
||||||
|
Entities.deleteEntity(planetLines[i][j]);
|
||||||
|
}
|
||||||
|
planetLines[i] = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
return trailsEnabled;
|
||||||
|
},
|
||||||
|
function(value) {
|
||||||
|
return value;
|
||||||
|
}));
|
||||||
|
|
||||||
|
panelItems.push(panel.newCheckbox("Energy Error Calculations: ",
|
||||||
|
function(value) {
|
||||||
|
energyConserved = value;
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
return energyConserved;
|
||||||
|
},
|
||||||
|
function(value) {
|
||||||
|
return value;
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Update global G constant, period, poke velocity to new value
|
||||||
|
function changePeriod(alpha) {
|
||||||
|
var ratio = last_alpha / alpha;
|
||||||
|
G = Math.pow(ratio, 2.0) * G;
|
||||||
|
for (var i = 0; i < NUM_PLANETS; ++i) {
|
||||||
|
var properties = planet_properties[i];
|
||||||
|
properties.period = ratio * properties.period;
|
||||||
|
properties.velocity = Vec3.multiply(ratio, properties.velocity);
|
||||||
|
|
||||||
|
}
|
||||||
|
last_alpha = alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Clean up models, UI panels, lines, and button overlays
|
||||||
|
function scriptEnding() {
|
||||||
|
|
||||||
|
satelliteGame.endGame();
|
||||||
|
|
||||||
|
Entities.deleteEntity(theSun);
|
||||||
|
for (var i = 0; i < NUM_PLANETS; ++i) {
|
||||||
|
Entities.deleteEntity(planets[i]);
|
||||||
|
}
|
||||||
|
Menu.removeMenu("Developer > Scene");
|
||||||
|
panel.destroy();
|
||||||
|
Overlays.deleteOverlay(pauseButton);
|
||||||
|
|
||||||
|
var e = Entities.findEntities(MyAvatar.position, 16000);
|
||||||
|
for (i = 0; i < e.length; i++) {
|
||||||
|
var props = Entities.getEntityProperties(e[i]);
|
||||||
|
if (props.type === "Line" || props.type === "Text") {
|
||||||
|
Entities.deleteEntity(e[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Controller.mouseMoveEvent.connect(function panelMouseMoveEvent(event) {
|
||||||
|
return panel.mouseMoveEvent(event);
|
||||||
|
});
|
||||||
|
Controller.mousePressEvent.connect(function panelMousePressEvent(event) {
|
||||||
|
return panel.mousePressEvent(event);
|
||||||
|
});
|
||||||
|
Controller.mouseDoublePressEvent.connect(function panelMouseDoublePressEvent(event) {
|
||||||
|
return panel.mouseDoublePressEvent(event);
|
||||||
|
});
|
||||||
|
Controller.mouseReleaseEvent.connect(function(event) {
|
||||||
|
return panel.mouseReleaseEvent(event);
|
||||||
|
});
|
||||||
|
Controller.mousePressEvent.connect(mousePressEvent);
|
||||||
|
Controller.mouseDoublePressEvent.connect(mouseDoublePressEvent);
|
||||||
|
Controller.keyPressEvent.connect(keyPressEvent);
|
||||||
|
|
||||||
|
Script.scriptEnding.connect(scriptEnding);
|
||||||
|
Script.update.connect(update);
|
|
@ -141,7 +141,7 @@ CameraManager = function() {
|
||||||
|
|
||||||
// Pick a point INITIAL_ZOOM_DISTANCE in front of the camera to use as a focal point
|
// Pick a point INITIAL_ZOOM_DISTANCE in front of the camera to use as a focal point
|
||||||
that.zoomDistance = INITIAL_ZOOM_DISTANCE;
|
that.zoomDistance = INITIAL_ZOOM_DISTANCE;
|
||||||
that.targetZoomDistance = that.zoomDistance;
|
that.targetZoomDistance = that.zoomDistance + 3.0;
|
||||||
var focalPoint = Vec3.sum(Camera.getPosition(),
|
var focalPoint = Vec3.sum(Camera.getPosition(),
|
||||||
Vec3.multiply(that.zoomDistance, Quat.getFront(Camera.getOrientation())));
|
Vec3.multiply(that.zoomDistance, Quat.getFront(Camera.getOrientation())));
|
||||||
|
|
||||||
|
@ -150,6 +150,7 @@ CameraManager = function() {
|
||||||
var xzDist = Math.sqrt(dPos.x * dPos.x + dPos.z * dPos.z);
|
var xzDist = Math.sqrt(dPos.x * dPos.x + dPos.z * dPos.z);
|
||||||
|
|
||||||
that.targetPitch = -Math.atan2(dPos.y, xzDist) * 180 / Math.PI;
|
that.targetPitch = -Math.atan2(dPos.y, xzDist) * 180 / Math.PI;
|
||||||
|
that.targetPitch += (90 - that.targetPitch) / 3.0; // Swing camera "up" to look down at the focal point
|
||||||
that.targetYaw = Math.atan2(dPos.x, dPos.z) * 180 / Math.PI;
|
that.targetYaw = Math.atan2(dPos.x, dPos.z) * 180 / Math.PI;
|
||||||
that.pitch = that.targetPitch;
|
that.pitch = that.targetPitch;
|
||||||
that.yaw = that.targetYaw;
|
that.yaw = that.targetYaw;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
186
examples/utilities/tools/vector.js
Normal file
186
examples/utilities/tools/vector.js
Normal file
|
@ -0,0 +1,186 @@
|
||||||
|
//
|
||||||
|
// vector.js
|
||||||
|
// examples
|
||||||
|
//
|
||||||
|
// Created by Bridget Went on 7/1/15.
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// A template for creating vector arrows using line entities. A VectorArrow object creates a
|
||||||
|
// draggable vector arrow where the user clicked at a specified distance from the viewer.
|
||||||
|
// The relative magnitude and direction of the vector may be displayed.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
var LINE_DIMENSIONS = 100;
|
||||||
|
var LIFETIME = 6000;
|
||||||
|
var RAD_TO_DEG = 180.0 / Math.PI;
|
||||||
|
|
||||||
|
var LINE_WIDTH = 4;
|
||||||
|
var ARROW_WIDTH = 6;
|
||||||
|
var line, linePosition;
|
||||||
|
var arrow1, arrow2;
|
||||||
|
|
||||||
|
var SCALE = 0.15;
|
||||||
|
var ANGLE = 150.0;
|
||||||
|
|
||||||
|
|
||||||
|
VectorArrow = function(distance, showStats, statsTitle, statsPosition) {
|
||||||
|
this.magnitude = 0;
|
||||||
|
this.direction = {x: 0, y: 0, z: 0};
|
||||||
|
|
||||||
|
this.showStats = showStats;
|
||||||
|
this.isDragging = false;
|
||||||
|
|
||||||
|
this.newLine = function(position) {
|
||||||
|
linePosition = position;
|
||||||
|
var points = [];
|
||||||
|
|
||||||
|
line = Entities.addEntity({
|
||||||
|
position: linePosition,
|
||||||
|
type: "Line",
|
||||||
|
color: {red: 255, green: 255, blue: 255},
|
||||||
|
dimensions: {
|
||||||
|
x: LINE_DIMENSIONS,
|
||||||
|
y: LINE_DIMENSIONS,
|
||||||
|
z: LINE_DIMENSIONS
|
||||||
|
},
|
||||||
|
lineWidth: LINE_WIDTH,
|
||||||
|
lifetime: LIFETIME,
|
||||||
|
linePoints: []
|
||||||
|
});
|
||||||
|
|
||||||
|
arrow1 = Entities.addEntity({
|
||||||
|
position: {x: 0, y: 0, z: 0},
|
||||||
|
type: "Line",
|
||||||
|
dimensions: {
|
||||||
|
x: LINE_DIMENSIONS,
|
||||||
|
y: LINE_DIMENSIONS,
|
||||||
|
z: LINE_DIMENSIONS
|
||||||
|
},
|
||||||
|
color: {red: 255, green: 255, blue: 255},
|
||||||
|
lineWidth: ARROW_WIDTH,
|
||||||
|
linePoints: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
arrow2 = Entities.addEntity({
|
||||||
|
position: {x: 0, y: 0, z: 0},
|
||||||
|
type: "Line",
|
||||||
|
dimensions: {
|
||||||
|
x: LINE_DIMENSIONS,
|
||||||
|
y: LINE_DIMENSIONS,
|
||||||
|
z: LINE_DIMENSIONS
|
||||||
|
},
|
||||||
|
color: {red: 255, green: 255, blue: 255},
|
||||||
|
lineWidth: ARROW_WIDTH,
|
||||||
|
linePoints: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var STATS_DIMENSIONS = {
|
||||||
|
x: 4.0,
|
||||||
|
y: 1.5,
|
||||||
|
z: 0.1
|
||||||
|
};
|
||||||
|
var TEXT_HEIGHT = 0.3;
|
||||||
|
|
||||||
|
this.onMousePressEvent = function(event) {
|
||||||
|
|
||||||
|
this.newLine(computeWorldPoint(event));
|
||||||
|
|
||||||
|
if (this.showStats) {
|
||||||
|
this.label = Entities.addEntity({
|
||||||
|
type: "Text",
|
||||||
|
position: statsPosition,
|
||||||
|
dimensions: STATS_DIMENSIONS,
|
||||||
|
lineHeight: TEXT_HEIGHT,
|
||||||
|
faceCamera: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isDragging = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.onMouseMoveEvent = function(event) {
|
||||||
|
|
||||||
|
if (!this.isDragging) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var worldPoint = computeWorldPoint(event);
|
||||||
|
var localPoint = computeLocalPoint(event, linePosition);
|
||||||
|
points = [{x: 0, y: 0, z: 0}, localPoint];
|
||||||
|
Entities.editEntity(line, { linePoints: points });
|
||||||
|
|
||||||
|
var nextOffset = Vec3.multiply(SCALE, localPoint);
|
||||||
|
var normOffset = Vec3.normalize(localPoint);
|
||||||
|
var axis = Vec3.cross(normOffset, Quat.getFront(Camera.getOrientation()) );
|
||||||
|
axis = Vec3.cross(axis, normOffset);
|
||||||
|
var rotate1 = Quat.angleAxis(ANGLE, axis);
|
||||||
|
var rotate2 = Quat.angleAxis(-ANGLE, axis);
|
||||||
|
|
||||||
|
// Rotate arrow head to follow direction of the line
|
||||||
|
Entities.editEntity(arrow1, {
|
||||||
|
visible: true,
|
||||||
|
position: worldPoint,
|
||||||
|
linePoints: [{x: 0, y: 0, z: 0}, nextOffset],
|
||||||
|
rotation: rotate1
|
||||||
|
});
|
||||||
|
Entities.editEntity(arrow2, {
|
||||||
|
visible: true,
|
||||||
|
position: worldPoint,
|
||||||
|
linePoints: [{x: 0, y: 0, z: 0}, nextOffset],
|
||||||
|
rotation: rotate2
|
||||||
|
});
|
||||||
|
|
||||||
|
this.magnitude = Vec3.length(localPoint) * 0.1;
|
||||||
|
this.direction = Vec3.normalize(Vec3.subtract(worldPoint, linePosition));
|
||||||
|
|
||||||
|
if (this.showStats) {
|
||||||
|
this.editLabel(statsTitle + " Magnitude " + this.magnitude.toFixed(2) + ", Direction: " +
|
||||||
|
this.direction.x.toFixed(2) + ", " + this.direction.y.toFixed(2) + ", " + this.direction.z.toFixed(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.onMouseReleaseEvent = function() {
|
||||||
|
this.isDragging = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cleanup = function() {
|
||||||
|
Entities.deleteEntity(line);
|
||||||
|
Entities.deleteEntity(arrow1);
|
||||||
|
Entities.deleteEntity(arrow2);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.deleteLabel = function() {
|
||||||
|
Entities.deleteEntity(this.label);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.editLabel = function(str) {
|
||||||
|
if(!this.showStats) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Entities.editEntity(this.label, {
|
||||||
|
text: str
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeWorldPoint(event) {
|
||||||
|
var pickRay = Camera.computePickRay(event.x, event.y);
|
||||||
|
var addVector = Vec3.multiply(pickRay.direction, distance);
|
||||||
|
return Vec3.sum(Camera.getPosition(), addVector);
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeLocalPoint(event, linePosition) {
|
||||||
|
var localPoint = Vec3.subtract(computeWorldPoint(event), linePosition);
|
||||||
|
return localPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ set(TARGET_NAME interface)
|
||||||
project(${TARGET_NAME})
|
project(${TARGET_NAME})
|
||||||
|
|
||||||
# set a default root dir for each of our optional externals if it was not passed
|
# set a default root dir for each of our optional externals if it was not passed
|
||||||
set(OPTIONAL_EXTERNALS "Faceshift" "Sixense" "LeapMotion" "RtMidi" "SDL2" "RSSDK")
|
set(OPTIONAL_EXTERNALS "Faceshift" "Sixense" "LeapMotion" "RtMidi" "SDL2" "RSSDK" "connexionClient")
|
||||||
foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
|
foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
|
||||||
string(TOUPPER ${EXTERNAL} ${EXTERNAL}_UPPERCASE)
|
string(TOUPPER ${EXTERNAL} ${EXTERNAL}_UPPERCASE)
|
||||||
if (NOT ${${EXTERNAL}_UPPERCASE}_ROOT_DIR)
|
if (NOT ${${EXTERNAL}_UPPERCASE}_ROOT_DIR)
|
||||||
|
|
79
interface/external/connexionclient/Inc/I3dMouseParams.h
vendored
Normal file
79
interface/external/connexionclient/Inc/I3dMouseParams.h
vendored
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
//
|
||||||
|
// 3DConnexion.cpp
|
||||||
|
// hifi
|
||||||
|
//
|
||||||
|
// Created by MarcelEdward Verhagen on 09-06-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
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef I3D_MOUSE_PARAMS_H
|
||||||
|
#define I3D_MOUSE_PARAMS_H
|
||||||
|
|
||||||
|
// Parameters for the 3D mouse based on the SDK from 3Dconnexion
|
||||||
|
|
||||||
|
class I3dMouseSensor {
|
||||||
|
public:
|
||||||
|
enum Speed {
|
||||||
|
SPEED_LOW = 0,
|
||||||
|
SPEED_MID,
|
||||||
|
SPEED_HIGH
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual bool IsPanZoom() const = 0;
|
||||||
|
virtual bool IsRotate() const = 0;
|
||||||
|
virtual Speed GetSpeed() const = 0;
|
||||||
|
|
||||||
|
virtual void SetPanZoom(bool isPanZoom) = 0;
|
||||||
|
virtual void SetRotate(bool isRotate) = 0;
|
||||||
|
virtual void SetSpeed(Speed speed) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~I3dMouseSensor() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class I3dMouseNavigation {
|
||||||
|
public:
|
||||||
|
enum Pivot {
|
||||||
|
PIVOT_MANUAL = 0,
|
||||||
|
PIVOT_AUTO,
|
||||||
|
PIVOT_AUTO_OVERRIDE
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Navigation {
|
||||||
|
NAVIGATION_OBJECT_MODE = 0,
|
||||||
|
NAVIGATION_CAMERA_MODE,
|
||||||
|
NAVIGATION_FLY_MODE,
|
||||||
|
NAVIGATION_WALK_MODE,
|
||||||
|
NAVIGATION_HELICOPTER_MODE
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PivotVisibility {
|
||||||
|
PIVOT_HIDE = 0,
|
||||||
|
PIVOT_SHOW,
|
||||||
|
PIVOT_SHOW_MOVING
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual Navigation GetNavigationMode() const = 0;
|
||||||
|
virtual Pivot GetPivotMode() const = 0;
|
||||||
|
virtual PivotVisibility GetPivotVisibility() const = 0;
|
||||||
|
virtual bool IsLockHorizon() const = 0;
|
||||||
|
|
||||||
|
virtual void SetLockHorizon(bool bOn) = 0;
|
||||||
|
virtual void SetNavigationMode(Navigation navigation) = 0;
|
||||||
|
virtual void SetPivotMode(Pivot pivot) = 0;
|
||||||
|
virtual void SetPivotVisibility(PivotVisibility visibility) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~I3dMouseNavigation(){}
|
||||||
|
};
|
||||||
|
|
||||||
|
class I3dMouseParam : public I3dMouseSensor, public I3dMouseNavigation {
|
||||||
|
public:
|
||||||
|
virtual ~I3dMouseParam() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
4
interface/external/connexionclient/readme.txt
vendored
Normal file
4
interface/external/connexionclient/readme.txt
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
The mac version does not require any files here. 3D connexion should be installed from
|
||||||
|
http://www.3dconnexion.eu/service/drivers.html
|
||||||
|
|
||||||
|
For windows a header file is required Inc/I3dMouseParams.h
|
|
@ -115,6 +115,7 @@
|
||||||
#include "devices/MIDIManager.h"
|
#include "devices/MIDIManager.h"
|
||||||
#include "devices/OculusManager.h"
|
#include "devices/OculusManager.h"
|
||||||
#include "devices/TV3DManager.h"
|
#include "devices/TV3DManager.h"
|
||||||
|
#include "devices/3Dconnexion.h"
|
||||||
|
|
||||||
#include "scripting/AccountScriptingInterface.h"
|
#include "scripting/AccountScriptingInterface.h"
|
||||||
#include "scripting/AudioDeviceScriptingInterface.h"
|
#include "scripting/AudioDeviceScriptingInterface.h"
|
||||||
|
@ -639,6 +640,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog);
|
connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog);
|
||||||
applicationUpdater->checkForUpdate();
|
applicationUpdater->checkForUpdate();
|
||||||
|
|
||||||
|
// the 3Dconnexion device wants to be initiliazed after a window is displayed.
|
||||||
|
ConnexionClient::init();
|
||||||
|
|
||||||
auto& packetReceiver = nodeList->getPacketReceiver();
|
auto& packetReceiver = nodeList->getPacketReceiver();
|
||||||
packetReceiver.registerListener(PacketType::DomainConnectionDenied, this, "handleDomainConnectionDeniedPacket");
|
packetReceiver.registerListener(PacketType::DomainConnectionDenied, this, "handleDomainConnectionDeniedPacket");
|
||||||
}
|
}
|
||||||
|
@ -750,6 +754,7 @@ Application::~Application() {
|
||||||
|
|
||||||
Leapmotion::destroy();
|
Leapmotion::destroy();
|
||||||
RealSense::destroy();
|
RealSense::destroy();
|
||||||
|
ConnexionClient::destroy();
|
||||||
|
|
||||||
qInstallMessageHandler(NULL); // NOTE: Do this as late as possible so we continue to get our log messages
|
qInstallMessageHandler(NULL); // NOTE: Do this as late as possible so we continue to get our log messages
|
||||||
}
|
}
|
||||||
|
@ -1488,6 +1493,7 @@ void Application::focusOutEvent(QFocusEvent* event) {
|
||||||
_keyboardMouseDevice.focusOutEvent(event);
|
_keyboardMouseDevice.focusOutEvent(event);
|
||||||
SixenseManager::getInstance().focusOutEvent();
|
SixenseManager::getInstance().focusOutEvent();
|
||||||
SDL2Manager::getInstance()->focusOutEvent();
|
SDL2Manager::getInstance()->focusOutEvent();
|
||||||
|
ConnexionData::getInstance().focusOutEvent();
|
||||||
|
|
||||||
// synthesize events for keys currently pressed, since we may not get their release events
|
// synthesize events for keys currently pressed, since we may not get their release events
|
||||||
foreach (int key, _keysPressed) {
|
foreach (int key, _keysPressed) {
|
||||||
|
@ -3272,6 +3278,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
renderContext._maxDrawnOverlay3DItems = sceneInterface->getEngineMaxDrawnOverlay3DItems();
|
renderContext._maxDrawnOverlay3DItems = sceneInterface->getEngineMaxDrawnOverlay3DItems();
|
||||||
|
|
||||||
renderContext._drawItemStatus = sceneInterface->doEngineDisplayItemStatus();
|
renderContext._drawItemStatus = sceneInterface->doEngineDisplayItemStatus();
|
||||||
|
renderContext._drawHitEffect = sceneInterface->doEngineDisplayHitEffect();
|
||||||
|
|
||||||
renderContext._occlusionStatus = Menu::getInstance()->isOptionChecked(MenuOption::DebugAmbientOcclusion);
|
renderContext._occlusionStatus = Menu::getInstance()->isOptionChecked(MenuOption::DebugAmbientOcclusion);
|
||||||
|
|
||||||
|
@ -3389,7 +3396,7 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi
|
||||||
// This was removed in commit 71e59cfa88c6563749594e25494102fe01db38e9 but could be further
|
// This was removed in commit 71e59cfa88c6563749594e25494102fe01db38e9 but could be further
|
||||||
// investigated in order to adapt the technique while fixing the head rendering issue,
|
// investigated in order to adapt the technique while fixing the head rendering issue,
|
||||||
// but the complexity of the hack suggests that a better approach
|
// but the complexity of the hack suggests that a better approach
|
||||||
_mirrorCamera.setPosition(_myAvatar->getHead()->getEyePosition() +
|
_mirrorCamera.setPosition(_myAvatar->getDefaultEyePosition() +
|
||||||
_myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale());
|
_myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale());
|
||||||
}
|
}
|
||||||
_mirrorCamera.setProjection(glm::perspective(glm::radians(fov), aspect, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP));
|
_mirrorCamera.setProjection(glm::perspective(glm::radians(fov), aspect, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP));
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "devices/Faceshift.h"
|
#include "devices/Faceshift.h"
|
||||||
#include "devices/RealSense.h"
|
#include "devices/RealSense.h"
|
||||||
#include "devices/SixenseManager.h"
|
#include "devices/SixenseManager.h"
|
||||||
|
#include "devices/3Dconnexion.h"
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "scripting/MenuScriptingInterface.h"
|
#include "scripting/MenuScriptingInterface.h"
|
||||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||||
|
@ -447,6 +448,11 @@ Menu::Menu() {
|
||||||
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderLookAtVectors, 0, false);
|
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderLookAtVectors, 0, false);
|
||||||
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderFocusIndicator, 0, false);
|
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderFocusIndicator, 0, false);
|
||||||
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ShowWhosLookingAtMe, 0, false);
|
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ShowWhosLookingAtMe, 0, false);
|
||||||
|
addCheckableActionToQMenuAndActionHash(avatarDebugMenu,
|
||||||
|
MenuOption::Connexion,
|
||||||
|
0, false,
|
||||||
|
&ConnexionClient::getInstance(),
|
||||||
|
SLOT(toggleConnexion(bool)));
|
||||||
|
|
||||||
MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands");
|
MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands");
|
||||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlignForearmsWithWrists, 0, false);
|
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlignForearmsWithWrists, 0, false);
|
||||||
|
|
|
@ -160,6 +160,7 @@ namespace MenuOption {
|
||||||
const QString CenterPlayerInView = "Center Player In View";
|
const QString CenterPlayerInView = "Center Player In View";
|
||||||
const QString Chat = "Chat...";
|
const QString Chat = "Chat...";
|
||||||
const QString Collisions = "Collisions";
|
const QString Collisions = "Collisions";
|
||||||
|
const QString Connexion = "Activate 3D Connexion Devices";
|
||||||
const QString Console = "Console...";
|
const QString Console = "Console...";
|
||||||
const QString ControlWithSpeech = "Control With Speech";
|
const QString ControlWithSpeech = "Control With Speech";
|
||||||
const QString CopyAddress = "Copy Address to Clipboard";
|
const QString CopyAddress = "Copy Address to Clipboard";
|
||||||
|
|
1013
interface/src/devices/3Dconnexion.cpp
Executable file
1013
interface/src/devices/3Dconnexion.cpp
Executable file
File diff suppressed because it is too large
Load diff
244
interface/src/devices/3Dconnexion.h
Executable file
244
interface/src/devices/3Dconnexion.h
Executable file
|
@ -0,0 +1,244 @@
|
||||||
|
// 3DConnexion.h
|
||||||
|
// hifi
|
||||||
|
//
|
||||||
|
// Created by Marcel Verhagen on 09-06-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
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_ConnexionClient_h
|
||||||
|
#define hifi_ConnexionClient_h
|
||||||
|
|
||||||
|
#include <qobject.h>
|
||||||
|
#include <qlibrary.h>
|
||||||
|
#include "InterfaceLogging.h"
|
||||||
|
#include "Application.h"
|
||||||
|
|
||||||
|
#include "ui/UserInputMapper.h"
|
||||||
|
|
||||||
|
#ifndef HAVE_CONNEXIONCLIENT
|
||||||
|
class ConnexionClient : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
static ConnexionClient& getInstance();
|
||||||
|
static void init() {};
|
||||||
|
static void destroy() {};
|
||||||
|
static bool Is3dmouseAttached() { return false; };
|
||||||
|
public slots:
|
||||||
|
void toggleConnexion(bool shouldEnable) {};
|
||||||
|
};
|
||||||
|
#endif // NOT_HAVE_CONNEXIONCLIENT
|
||||||
|
|
||||||
|
#ifdef HAVE_CONNEXIONCLIENT
|
||||||
|
// the windows connexion rawinput
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#include "I3dMouseParams.h"
|
||||||
|
#include <QAbstractNativeEventFilter>
|
||||||
|
#include <QAbstractEventDispatcher>
|
||||||
|
#include <Winsock2.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
// windows rawinput parameters
|
||||||
|
class MouseParameters : public I3dMouseParam {
|
||||||
|
public:
|
||||||
|
MouseParameters();
|
||||||
|
~MouseParameters();
|
||||||
|
|
||||||
|
// I3dmouseSensor interface
|
||||||
|
bool IsPanZoom() const;
|
||||||
|
bool IsRotate() const;
|
||||||
|
Speed GetSpeed() const;
|
||||||
|
|
||||||
|
void SetPanZoom(bool isPanZoom);
|
||||||
|
void SetRotate(bool isRotate);
|
||||||
|
void SetSpeed(Speed speed);
|
||||||
|
|
||||||
|
// I3dmouseNavigation interface
|
||||||
|
Navigation GetNavigationMode() const;
|
||||||
|
Pivot GetPivotMode() const;
|
||||||
|
PivotVisibility GetPivotVisibility() const;
|
||||||
|
bool IsLockHorizon() const;
|
||||||
|
|
||||||
|
void SetLockHorizon(bool bOn);
|
||||||
|
void SetNavigationMode(Navigation navigation);
|
||||||
|
void SetPivotMode(Pivot pivot);
|
||||||
|
void SetPivotVisibility(PivotVisibility visibility);
|
||||||
|
|
||||||
|
static bool Is3dmouseAttached();
|
||||||
|
|
||||||
|
private:
|
||||||
|
MouseParameters(const MouseParameters&);
|
||||||
|
const MouseParameters& operator = (const MouseParameters&);
|
||||||
|
|
||||||
|
Navigation fNavigation;
|
||||||
|
Pivot fPivot;
|
||||||
|
PivotVisibility fPivotVisibility;
|
||||||
|
bool fIsLockHorizon;
|
||||||
|
|
||||||
|
bool fIsPanZoom;
|
||||||
|
bool fIsRotate;
|
||||||
|
Speed fSpeed;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConnexionClient : public QObject, public QAbstractNativeEventFilter {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ConnexionClient();
|
||||||
|
~ConnexionClient();
|
||||||
|
|
||||||
|
static ConnexionClient& getInstance();
|
||||||
|
|
||||||
|
ConnexionClient* client;
|
||||||
|
static void init();
|
||||||
|
static void destroy();
|
||||||
|
|
||||||
|
static bool Is3dmouseAttached();
|
||||||
|
|
||||||
|
I3dMouseParam& MouseParams();
|
||||||
|
const I3dMouseParam& MouseParams() const;
|
||||||
|
|
||||||
|
virtual void Move3d(HANDLE device, std::vector<float>& motionData);
|
||||||
|
virtual void On3dmouseKeyDown(HANDLE device, int virtualKeyCode);
|
||||||
|
virtual void On3dmouseKeyUp(HANDLE device, int virtualKeyCode);
|
||||||
|
|
||||||
|
virtual bool nativeEventFilter(const QByteArray& eventType, void* message, long* result) Q_DECL_OVERRIDE
|
||||||
|
{
|
||||||
|
MSG* msg = static_cast< MSG * >(message);
|
||||||
|
return ConnexionClient::RawInputEventFilter(message, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void toggleConnexion(bool shouldEnable);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void Move3d(std::vector<float>& motionData);
|
||||||
|
void On3dmouseKeyDown(int virtualKeyCode);
|
||||||
|
void On3dmouseKeyUp(int virtualKeyCode);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool InitializeRawInput(HWND hwndTarget);
|
||||||
|
|
||||||
|
static bool RawInputEventFilter(void* msg, long* result);
|
||||||
|
|
||||||
|
void OnRawInput(UINT nInputCode, HRAWINPUT hRawInput);
|
||||||
|
UINT GetRawInputBuffer(PRAWINPUT pData, PUINT pcbSize, UINT cbSizeHeader);
|
||||||
|
bool TranslateRawInputData(UINT nInputCode, PRAWINPUT pRawInput);
|
||||||
|
void On3dmouseInput();
|
||||||
|
|
||||||
|
class TInputData {
|
||||||
|
public:
|
||||||
|
TInputData() : fAxes(6) {}
|
||||||
|
|
||||||
|
bool IsZero() {
|
||||||
|
return (0.0f == fAxes[0] && 0.0f == fAxes[1] && 0.0f == fAxes[2] &&
|
||||||
|
0.0f == fAxes[3] && 0.0f == fAxes[4] && 0.0f == fAxes[5]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fTimeToLive; // For telling if the device was unplugged while sending data
|
||||||
|
bool fIsDirty;
|
||||||
|
std::vector<float> fAxes;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
HWND fWindow;
|
||||||
|
|
||||||
|
// Data cache to handle multiple rawinput devices
|
||||||
|
std::map< HANDLE, TInputData> fDevice2Data;
|
||||||
|
std::map< HANDLE, unsigned long> fDevice2Keystate;
|
||||||
|
|
||||||
|
// 3dmouse parameters
|
||||||
|
MouseParameters f3dMouseParams; // Rotate, Pan Zoom etc.
|
||||||
|
|
||||||
|
// use to calculate distance traveled since last event
|
||||||
|
DWORD fLast3dmouseInputTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
// the osx connexion api
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include "3DconnexionClient/ConnexionClientAPI.h"
|
||||||
|
|
||||||
|
class ConnexionClient : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
static ConnexionClient& getInstance();
|
||||||
|
static bool Is3dmouseAttached();
|
||||||
|
static void init();
|
||||||
|
static void destroy();
|
||||||
|
public slots:
|
||||||
|
void toggleConnexion(bool shouldEnable);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
|
#endif // HAVE_CONNEXIONCLIENT
|
||||||
|
|
||||||
|
|
||||||
|
// connnects to the userinputmapper
|
||||||
|
class ConnexionData : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
static ConnexionData& getInstance();
|
||||||
|
ConnexionData();
|
||||||
|
|
||||||
|
enum PositionChannel {
|
||||||
|
POSITION_AXIS_X_POS = 1,
|
||||||
|
POSITION_AXIS_X_NEG = 2,
|
||||||
|
POSITION_AXIS_Y_POS = 3,
|
||||||
|
POSITION_AXIS_Y_NEG = 4,
|
||||||
|
POSITION_AXIS_Z_POS = 5,
|
||||||
|
POSITION_AXIS_Z_NEG = 6,
|
||||||
|
ROTATION_AXIS_X_POS = 7,
|
||||||
|
ROTATION_AXIS_X_NEG = 8,
|
||||||
|
ROTATION_AXIS_Y_POS = 9,
|
||||||
|
ROTATION_AXIS_Y_NEG = 10,
|
||||||
|
ROTATION_AXIS_Z_POS = 11,
|
||||||
|
ROTATION_AXIS_Z_NEG = 12
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ButtonChannel {
|
||||||
|
BUTTON_1 = 1,
|
||||||
|
BUTTON_2 = 2,
|
||||||
|
BUTTON_3 = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::unordered_set<int> ButtonPressedMap;
|
||||||
|
typedef std::map<int, float> AxisStateMap;
|
||||||
|
|
||||||
|
float getButton(int channel) const;
|
||||||
|
float getAxis(int channel) const;
|
||||||
|
|
||||||
|
UserInputMapper::Input makeInput(ConnexionData::PositionChannel axis);
|
||||||
|
UserInputMapper::Input makeInput(ConnexionData::ButtonChannel button);
|
||||||
|
|
||||||
|
void registerToUserInputMapper(UserInputMapper& mapper);
|
||||||
|
void assignDefaultInputMapping(UserInputMapper& mapper);
|
||||||
|
|
||||||
|
void update();
|
||||||
|
void focusOutEvent();
|
||||||
|
|
||||||
|
int getDeviceID() { return _deviceID; }
|
||||||
|
void setDeviceID(int deviceID) { _deviceID = deviceID; }
|
||||||
|
|
||||||
|
QString _name;
|
||||||
|
|
||||||
|
glm::vec3 cc_position;
|
||||||
|
glm::vec3 cc_rotation;
|
||||||
|
int clientId;
|
||||||
|
|
||||||
|
void setButton(int lastButtonState);
|
||||||
|
void handleAxisEvent();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int _deviceID = 0;
|
||||||
|
|
||||||
|
ButtonPressedMap _buttonPressedMap;
|
||||||
|
AxisStateMap _axisStateMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // defined(hifi_ConnexionClient_h)
|
86
libraries/render-utils/src/HitEffect.cpp
Normal file
86
libraries/render-utils/src/HitEffect.cpp
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
//
|
||||||
|
// HitEffect.cpp
|
||||||
|
// interface/src/renderer
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 7/14/13.
|
||||||
|
// Copyright 2013 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
|
||||||
|
//
|
||||||
|
|
||||||
|
// include this before QOpenGLFramebufferObject, which includes an earlier version of OpenGL
|
||||||
|
|
||||||
|
|
||||||
|
#include <glm/gtc/random.hpp>
|
||||||
|
|
||||||
|
#include <PathUtils.h>
|
||||||
|
#include <SharedUtil.h>
|
||||||
|
|
||||||
|
#include "AbstractViewStateInterface.h"
|
||||||
|
#include "HitEffect.h"
|
||||||
|
#include "TextureCache.h"
|
||||||
|
#include "DependencyManager.h"
|
||||||
|
#include "ViewFrustum.h"
|
||||||
|
#include "GeometryCache.h"
|
||||||
|
|
||||||
|
#include <gpu/Context.h>
|
||||||
|
|
||||||
|
#include "hit_effect_vert.h"
|
||||||
|
#include "hit_effect_frag.h"
|
||||||
|
|
||||||
|
|
||||||
|
HitEffect::HitEffect() {
|
||||||
|
}
|
||||||
|
|
||||||
|
const gpu::PipelinePointer& HitEffect::getHitEffectPipeline() {
|
||||||
|
if (!_hitEffectPipeline) {
|
||||||
|
auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(hit_effect_vert)));
|
||||||
|
auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(hit_effect_frag)));
|
||||||
|
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps));
|
||||||
|
|
||||||
|
|
||||||
|
gpu::Shader::BindingSet slotBindings;
|
||||||
|
gpu::Shader::makeProgram(*program, slotBindings);
|
||||||
|
|
||||||
|
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||||
|
|
||||||
|
state->setDepthTest(false, false, gpu::LESS_EQUAL);
|
||||||
|
|
||||||
|
// Blend on transparent
|
||||||
|
state->setBlendFunction(true,
|
||||||
|
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA);
|
||||||
|
|
||||||
|
// Good to go add the brand new pipeline
|
||||||
|
_hitEffectPipeline.reset(gpu::Pipeline::create(program, state));
|
||||||
|
}
|
||||||
|
return _hitEffectPipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HitEffect::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) {
|
||||||
|
assert(renderContext->args);
|
||||||
|
assert(renderContext->args->_viewFrustum);
|
||||||
|
RenderArgs* args = renderContext->args;
|
||||||
|
gpu::Batch batch;
|
||||||
|
|
||||||
|
glm::mat4 projMat;
|
||||||
|
Transform viewMat;
|
||||||
|
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||||
|
args->_viewFrustum->evalViewTransform(viewMat);
|
||||||
|
batch.setProjectionTransform(projMat);
|
||||||
|
batch.setViewTransform(viewMat);
|
||||||
|
batch.setModelTransform(Transform());
|
||||||
|
|
||||||
|
batch.setPipeline(getHitEffectPipeline());
|
||||||
|
|
||||||
|
glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
glm::vec2 bottomLeft(-1.0f, -1.0f);
|
||||||
|
glm::vec2 topRight(1.0f, 1.0f);
|
||||||
|
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, color);
|
||||||
|
|
||||||
|
|
||||||
|
// Ready to render
|
||||||
|
args->_context->render((batch));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
33
libraries/render-utils/src/HitEffect.h
Normal file
33
libraries/render-utils/src/HitEffect.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
//
|
||||||
|
// hitEffect.h
|
||||||
|
// hifi
|
||||||
|
//
|
||||||
|
// Created by eric levin on 7/17/15.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_hitEffect_h
|
||||||
|
#define hifi_hitEffect_h
|
||||||
|
|
||||||
|
#include <DependencyManager.h>
|
||||||
|
#include "render/DrawTask.h"
|
||||||
|
|
||||||
|
class AbstractViewStateInterface;
|
||||||
|
class ProgramObject;
|
||||||
|
|
||||||
|
class HitEffect {
|
||||||
|
public:
|
||||||
|
|
||||||
|
HitEffect();
|
||||||
|
|
||||||
|
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||||
|
typedef render::Job::Model<HitEffect> JobModel;
|
||||||
|
|
||||||
|
const gpu::PipelinePointer& getHitEffectPipeline();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
gpu::PipelinePointer _hitEffectPipeline;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
//
|
//
|
||||||
// RenderDeferredTask.cpp
|
// RenderDeferredTask.cpp
|
||||||
// render-utils/src/
|
// render-utils/src/
|
||||||
|
@ -20,6 +21,7 @@
|
||||||
#include "FramebufferCache.h"
|
#include "FramebufferCache.h"
|
||||||
#include "DeferredLightingEffect.h"
|
#include "DeferredLightingEffect.h"
|
||||||
#include "TextureCache.h"
|
#include "TextureCache.h"
|
||||||
|
#include "HitEffect.h"
|
||||||
|
|
||||||
#include "render/DrawStatus.h"
|
#include "render/DrawStatus.h"
|
||||||
#include "AmbientOcclusionEffect.h"
|
#include "AmbientOcclusionEffect.h"
|
||||||
|
@ -78,6 +80,7 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
|
||||||
_jobs.push_back(Job(new DepthSortItems::JobModel("DepthSortOpaque", _jobs.back().getOutput())));
|
_jobs.push_back(Job(new DepthSortItems::JobModel("DepthSortOpaque", _jobs.back().getOutput())));
|
||||||
auto& renderedOpaques = _jobs.back().getOutput();
|
auto& renderedOpaques = _jobs.back().getOutput();
|
||||||
_jobs.push_back(Job(new DrawOpaqueDeferred::JobModel("DrawOpaqueDeferred", _jobs.back().getOutput())));
|
_jobs.push_back(Job(new DrawOpaqueDeferred::JobModel("DrawOpaqueDeferred", _jobs.back().getOutput())));
|
||||||
|
|
||||||
_jobs.push_back(Job(new DrawLight::JobModel("DrawLight")));
|
_jobs.push_back(Job(new DrawLight::JobModel("DrawLight")));
|
||||||
_jobs.push_back(Job(new RenderDeferred::JobModel("RenderDeferred")));
|
_jobs.push_back(Job(new RenderDeferred::JobModel("RenderDeferred")));
|
||||||
_jobs.push_back(Job(new ResolveDeferred::JobModel("ResolveDeferred")));
|
_jobs.push_back(Job(new ResolveDeferred::JobModel("ResolveDeferred")));
|
||||||
|
@ -105,6 +108,10 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
|
||||||
_drawStatusJobIndex = _jobs.size() - 1;
|
_drawStatusJobIndex = _jobs.size() - 1;
|
||||||
|
|
||||||
_jobs.push_back(Job(new DrawOverlay3D::JobModel("DrawOverlay3D")));
|
_jobs.push_back(Job(new DrawOverlay3D::JobModel("DrawOverlay3D")));
|
||||||
|
_jobs.push_back(Job(new HitEffect::JobModel("HitEffect")));
|
||||||
|
_jobs.back().setEnabled(false);
|
||||||
|
_drawHitEffectJobIndex = _jobs.size() -1;
|
||||||
|
|
||||||
|
|
||||||
// Give ourselves 3 frmaes of timer queries
|
// Give ourselves 3 frmaes of timer queries
|
||||||
_timerQueries.push_back(std::make_shared<gpu::Query>());
|
_timerQueries.push_back(std::make_shared<gpu::Query>());
|
||||||
|
@ -131,6 +138,10 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend
|
||||||
|
|
||||||
// Make sure we turn the displayItemStatus on/off
|
// Make sure we turn the displayItemStatus on/off
|
||||||
setDrawItemStatus(renderContext->_drawItemStatus);
|
setDrawItemStatus(renderContext->_drawItemStatus);
|
||||||
|
|
||||||
|
//Make sure we display hit effect on screen, as desired from a script
|
||||||
|
setDrawHitEffect(renderContext->_drawHitEffect);
|
||||||
|
|
||||||
|
|
||||||
// TODO: turn on/off AO through menu item
|
// TODO: turn on/off AO through menu item
|
||||||
setOcclusionStatus(renderContext->_occlusionStatus);
|
setOcclusionStatus(renderContext->_occlusionStatus);
|
||||||
|
|
|
@ -78,9 +78,13 @@ public:
|
||||||
render::Jobs _jobs;
|
render::Jobs _jobs;
|
||||||
|
|
||||||
int _drawStatusJobIndex = -1;
|
int _drawStatusJobIndex = -1;
|
||||||
|
int _drawHitEffectJobIndex = -1;
|
||||||
|
|
||||||
void setDrawItemStatus(bool draw) { if (_drawStatusJobIndex >= 0) { _jobs[_drawStatusJobIndex].setEnabled(draw); } }
|
void setDrawItemStatus(bool draw) { if (_drawStatusJobIndex >= 0) { _jobs[_drawStatusJobIndex].setEnabled(draw); } }
|
||||||
bool doDrawItemStatus() const { if (_drawStatusJobIndex >= 0) { return _jobs[_drawStatusJobIndex].isEnabled(); } else { return false; } }
|
bool doDrawItemStatus() const { if (_drawStatusJobIndex >= 0) { return _jobs[_drawStatusJobIndex].isEnabled(); } else { return false; } }
|
||||||
|
|
||||||
|
void setDrawHitEffect(bool draw) { if (_drawHitEffectJobIndex >= 0) { _jobs[_drawHitEffectJobIndex].setEnabled(draw); } }
|
||||||
|
bool doDrawHitEffect() const { if (_drawHitEffectJobIndex >=0) { return _jobs[_drawHitEffectJobIndex].isEnabled(); } else { return false; } }
|
||||||
|
|
||||||
int _occlusionJobIndex = -1;
|
int _occlusionJobIndex = -1;
|
||||||
|
|
||||||
|
|
24
libraries/render-utils/src/hit_effect.slf
Normal file
24
libraries/render-utils/src/hit_effect.slf
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<@include gpu/Config.slh@>
|
||||||
|
<$VERSION_HEADER$>
|
||||||
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
|
//
|
||||||
|
// hit_effect.frag
|
||||||
|
// fragment shader
|
||||||
|
//
|
||||||
|
// Created by Eric Levin on 7/20
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
|
||||||
|
<@include DeferredBufferWrite.slh@>
|
||||||
|
|
||||||
|
varying vec2 varQuadPosition;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
vec2 center = vec2(0.0, 0.0);
|
||||||
|
float distFromCenter = distance( vec2(0.0, 0.0), varQuadPosition);
|
||||||
|
float alpha = mix(0.0, 0.5, pow(distFromCenter,5.));
|
||||||
|
gl_FragColor = vec4(1.0, 0.0, 0.0, alpha);
|
||||||
|
}
|
24
libraries/render-utils/src/hit_effect.slv
Normal file
24
libraries/render-utils/src/hit_effect.slv
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<@include gpu/Config.slh@>
|
||||||
|
<$VERSION_HEADER$>
|
||||||
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
|
//
|
||||||
|
// hit_effect.vert
|
||||||
|
// vertex shader
|
||||||
|
//
|
||||||
|
// Created by Eric Levin on 7/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
|
||||||
|
//
|
||||||
|
|
||||||
|
<@include gpu/Transform.slh@>
|
||||||
|
|
||||||
|
<$declareStandardTransform()$>
|
||||||
|
|
||||||
|
varying vec2 varQuadPosition;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
varQuadPosition = gl_Vertex.xy;
|
||||||
|
gl_Position = gl_Vertex;
|
||||||
|
}
|
|
@ -50,6 +50,7 @@ public:
|
||||||
int _maxDrawnOverlay3DItems = -1;
|
int _maxDrawnOverlay3DItems = -1;
|
||||||
|
|
||||||
bool _drawItemStatus = false;
|
bool _drawItemStatus = false;
|
||||||
|
bool _drawHitEffect = false;
|
||||||
|
|
||||||
bool _occlusionStatus = false;
|
bool _occlusionStatus = false;
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,9 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE void setEngineDisplayItemStatus(bool display) { _drawItemStatus = display; }
|
Q_INVOKABLE void setEngineDisplayItemStatus(bool display) { _drawItemStatus = display; }
|
||||||
Q_INVOKABLE bool doEngineDisplayItemStatus() { return _drawItemStatus; }
|
Q_INVOKABLE bool doEngineDisplayItemStatus() { return _drawItemStatus; }
|
||||||
|
|
||||||
|
Q_INVOKABLE void setEngineDisplayHitEffect(bool display) { _drawHitEffect = display; }
|
||||||
|
Q_INVOKABLE bool doEngineDisplayHitEffect() { return _drawHitEffect; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void shouldRenderAvatarsChanged(bool shouldRenderAvatars);
|
void shouldRenderAvatarsChanged(bool shouldRenderAvatars);
|
||||||
|
@ -141,6 +144,8 @@ protected:
|
||||||
int _maxDrawnOverlay3DItems = -1;
|
int _maxDrawnOverlay3DItems = -1;
|
||||||
|
|
||||||
bool _drawItemStatus = false;
|
bool _drawItemStatus = false;
|
||||||
|
|
||||||
|
bool _drawHitEffect = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,16 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "BulletUtilTests.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
//#include "PhysicsTestUtil.h"
|
|
||||||
#include <BulletUtil.h>
|
#include <BulletUtil.h>
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
|
|
||||||
#include "BulletUtilTests.h"
|
// Add additional qtest functionality (the include order is important!)
|
||||||
|
#include "GlmTestUtils.h"
|
||||||
|
#include "../QTestExtensions.h"
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
const glm::vec3 origin(0.0f);
|
const glm::vec3 origin(0.0f);
|
||||||
|
|
|
@ -13,9 +13,6 @@
|
||||||
#define hifi_BulletUtilTests_h
|
#define hifi_BulletUtilTests_h
|
||||||
|
|
||||||
#include <QtTest/QtTest>
|
#include <QtTest/QtTest>
|
||||||
// Add additional qtest functionality (the include order is important!)
|
|
||||||
#include "GlmTestUtils.h"
|
|
||||||
#include "../QTestExtensions.h"
|
|
||||||
|
|
||||||
class BulletUtilTests : public QObject {
|
class BulletUtilTests : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
//
|
|
||||||
// CollisionInfoTests.cpp
|
|
||||||
// tests/physics/src
|
|
||||||
//
|
|
||||||
// Created by Andrew Meadows on 2/21/2014.
|
|
||||||
// Copyright 2014 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
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <glm/gtx/quaternion.hpp>
|
|
||||||
|
|
||||||
#include <CollisionInfo.h>
|
|
||||||
#include <SharedUtil.h>
|
|
||||||
#include <StreamUtils.h>
|
|
||||||
|
|
||||||
#include "CollisionInfoTests.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QTEST_MAIN(CollisionInfoTests)
|
|
||||||
/*
|
|
||||||
static glm::vec3 xAxis(1.0f, 0.0f, 0.0f);
|
|
||||||
static glm::vec3 xZxis(0.0f, 1.0f, 0.0f);
|
|
||||||
static glm::vec3 xYxis(0.0f, 0.0f, 1.0f);
|
|
||||||
|
|
||||||
void CollisionInfoTests::rotateThenTranslate() {
|
|
||||||
CollisionInfo collision;
|
|
||||||
collision._penetration = xAxis;
|
|
||||||
collision._contactPoint = xYxis;
|
|
||||||
collision._addedVelocity = xAxis + xYxis + xZxis;
|
|
||||||
|
|
||||||
glm::quat rotation = glm::angleAxis(PI_OVER_TWO, zAxis);
|
|
||||||
float distance = 3.0f;
|
|
||||||
glm::vec3 translation = distance * xYxis;
|
|
||||||
|
|
||||||
collision.rotateThenTranslate(rotation, translation);
|
|
||||||
QCOMPARE(collision._penetration, xYxis);
|
|
||||||
|
|
||||||
glm::vec3 expectedContactPoint = -xAxis + translation;
|
|
||||||
QCOMPARE(collision._contactPoint, expectedContactPoint);
|
|
||||||
|
|
||||||
glm::vec3 expectedAddedVelocity = xYxis - xAxis + xZxis;
|
|
||||||
QCOMPARE(collision._addedVelocity, expectedAddedVelocity);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CollisionInfoTests::translateThenRotate() {
|
|
||||||
CollisionInfo collision;
|
|
||||||
collision._penetration = xAxis;
|
|
||||||
collision._contactPoint = xYxis;
|
|
||||||
collision._addedVelocity = xAxis + xYxis + xZxis;
|
|
||||||
|
|
||||||
glm::quat rotation = glm::angleAxis( -PI_OVER_TWO, zAxis);
|
|
||||||
float distance = 3.0f;
|
|
||||||
glm::vec3 translation = distance * xYxis;
|
|
||||||
|
|
||||||
collision.translateThenRotate(translation, rotation);
|
|
||||||
QCOMPARE(collision._penetration, -xYxis);
|
|
||||||
|
|
||||||
glm::vec3 expectedContactPoint = (1.0f + distance) * xAxis;
|
|
||||||
QCOMPARE(collision._contactPoint, expectedContactPoint);
|
|
||||||
|
|
||||||
glm::vec3 expectedAddedVelocity = - xYxis + xAxis + xYxis;
|
|
||||||
QCOMPARE(collision._addedVelocity, expectedAddedVelocity);
|
|
||||||
}*/
|
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
//
|
|
||||||
// CollisionInfoTests.h
|
|
||||||
// tests/physics/src
|
|
||||||
//
|
|
||||||
// Created by Andrew Meadows on 2/21/2014.
|
|
||||||
// Copyright 2014 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
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef hifi_CollisionInfoTests_h
|
|
||||||
#define hifi_CollisionInfoTests_h
|
|
||||||
|
|
||||||
#include <QtTest/QtTest>
|
|
||||||
|
|
||||||
// Add additional qtest functionality (the include order is important!)
|
|
||||||
#include "GlmTestUtils.h"
|
|
||||||
#include "../QTestExtensions.h"
|
|
||||||
|
|
||||||
class CollisionInfoTests : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
// void rotateThenTranslate();
|
|
||||||
// void translateThenRotate();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // hifi_CollisionInfoTests_h
|
|
|
@ -9,11 +9,15 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "MeshMassPropertiesTests.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
|
||||||
#include <MeshMassProperties.h>
|
#include <MeshMassProperties.h>
|
||||||
|
|
||||||
#include "MeshMassPropertiesTests.h"
|
// Add additional qtest functionality (the include order is important!)
|
||||||
|
#include "BulletTestUtils.h"
|
||||||
|
#include "GlmTestUtils.h"
|
||||||
|
#include "../QTestExtensions.h"
|
||||||
|
|
||||||
const btScalar acceptableRelativeError(1.0e-5f);
|
const btScalar acceptableRelativeError(1.0e-5f);
|
||||||
const btScalar acceptableAbsoluteError(1.0e-4f);
|
const btScalar acceptableAbsoluteError(1.0e-4f);
|
||||||
|
|
|
@ -13,12 +13,6 @@
|
||||||
#define hifi_MeshMassPropertiesTests_h
|
#define hifi_MeshMassPropertiesTests_h
|
||||||
|
|
||||||
#include <QtTest/QtTest>
|
#include <QtTest/QtTest>
|
||||||
#include <QtGlobal>
|
|
||||||
|
|
||||||
// Add additional qtest functionality (the include order is important!)
|
|
||||||
#include "BulletTestUtils.h"
|
|
||||||
#include "GlmTestUtils.h"
|
|
||||||
#include "../QTestExtensions.h"
|
|
||||||
|
|
||||||
// Relative error macro (see errorTest in BulletTestUtils.h)
|
// Relative error macro (see errorTest in BulletTestUtils.h)
|
||||||
#define QCOMPARE_WITH_RELATIVE_ERROR(actual, expected, relativeError) \
|
#define QCOMPARE_WITH_RELATIVE_ERROR(actual, expected, relativeError) \
|
||||||
|
|
|
@ -9,12 +9,15 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "ShapeColliderTests.h"
|
||||||
|
|
||||||
//#include <stdio.h>
|
//#include <stdio.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtx/quaternion.hpp>
|
#include <glm/gtx/quaternion.hpp>
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
#include <AACubeShape.h>
|
#include <AACubeShape.h>
|
||||||
#include <CapsuleShape.h>
|
#include <CapsuleShape.h>
|
||||||
|
@ -25,7 +28,10 @@
|
||||||
#include <SphereShape.h>
|
#include <SphereShape.h>
|
||||||
#include <StreamUtils.h>
|
#include <StreamUtils.h>
|
||||||
|
|
||||||
#include "ShapeColliderTests.h"
|
// Add additional qtest functionality (the include order is important!)
|
||||||
|
#include "BulletTestUtils.h"
|
||||||
|
#include "GlmTestUtils.h"
|
||||||
|
#include "../QTestExtensions.h"
|
||||||
|
|
||||||
|
|
||||||
const glm::vec3 origin(0.0f);
|
const glm::vec3 origin(0.0f);
|
||||||
|
@ -1553,8 +1559,6 @@ void ShapeColliderTests::rayHitsCapsule() {
|
||||||
intersection._rayDirection = - xAxis;
|
intersection._rayDirection = - xAxis;
|
||||||
QCOMPARE(capsule.findRayIntersection(intersection), true);
|
QCOMPARE(capsule.findRayIntersection(intersection), true);
|
||||||
float expectedDistance = startDistance - radius * sqrtf(2.0f * delta); // using small angle approximation of cosine
|
float expectedDistance = startDistance - radius * sqrtf(2.0f * delta); // using small angle approximation of cosine
|
||||||
// float relativeError = fabsf(intersection._hitDistance - expectedDistance) / startDistance;
|
|
||||||
// for edge cases we allow a LOT of error
|
|
||||||
QCOMPARE_WITH_ABS_ERROR(intersection._hitDistance, expectedDistance, startDistance * EDGE_CASE_SLOP_FACTOR * EPSILON);
|
QCOMPARE_WITH_ABS_ERROR(intersection._hitDistance, expectedDistance, startDistance * EDGE_CASE_SLOP_FACTOR * EPSILON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1564,8 +1568,6 @@ void ShapeColliderTests::rayHitsCapsule() {
|
||||||
intersection._rayDirection = - xAxis;
|
intersection._rayDirection = - xAxis;
|
||||||
QCOMPARE(capsule.findRayIntersection(intersection), true);
|
QCOMPARE(capsule.findRayIntersection(intersection), true);
|
||||||
float expectedDistance = startDistance - radius * sqrtf(2.0f * delta); // using small angle approximation of cosine
|
float expectedDistance = startDistance - radius * sqrtf(2.0f * delta); // using small angle approximation of cosine
|
||||||
// float relativeError = fabsf(intersection._hitDistance - expectedDistance) / startDistance;
|
|
||||||
// for edge cases we allow a LOT of error
|
|
||||||
QCOMPARE_WITH_ABS_ERROR(intersection._hitDistance, expectedDistance, startDistance * EPSILON * EDGE_CASE_SLOP_FACTOR);
|
QCOMPARE_WITH_ABS_ERROR(intersection._hitDistance, expectedDistance, startDistance * EPSILON * EDGE_CASE_SLOP_FACTOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1575,8 +1577,6 @@ void ShapeColliderTests::rayHitsCapsule() {
|
||||||
intersection._rayDirection = - xAxis;
|
intersection._rayDirection = - xAxis;
|
||||||
QCOMPARE(capsule.findRayIntersection(intersection), true);
|
QCOMPARE(capsule.findRayIntersection(intersection), true);
|
||||||
float expectedDistance = startDistance - radius * sqrtf(2.0f * delta); // using small angle approximation of cosine
|
float expectedDistance = startDistance - radius * sqrtf(2.0f * delta); // using small angle approximation of cosine
|
||||||
float relativeError = fabsf(intersection._hitDistance - expectedDistance) / startDistance;
|
|
||||||
// for edge cases we allow a LOT of error
|
|
||||||
QCOMPARE_WITH_ABS_ERROR(intersection._hitDistance, expectedDistance, startDistance * EPSILON * EDGE_CASE_SLOP_FACTOR);
|
QCOMPARE_WITH_ABS_ERROR(intersection._hitDistance, expectedDistance, startDistance * EPSILON * EDGE_CASE_SLOP_FACTOR);
|
||||||
}
|
}
|
||||||
// TODO: test at steep angles near cylinder/cap junction
|
// TODO: test at steep angles near cylinder/cap junction
|
||||||
|
|
|
@ -13,13 +13,6 @@
|
||||||
#define hifi_ShapeColliderTests_h
|
#define hifi_ShapeColliderTests_h
|
||||||
|
|
||||||
#include <QtTest/QtTest>
|
#include <QtTest/QtTest>
|
||||||
#include <QtGlobal>
|
|
||||||
|
|
||||||
// Add additional qtest functionality (the include order is important!)
|
|
||||||
#include "BulletTestUtils.h"
|
|
||||||
#include "GlmTestUtils.h"
|
|
||||||
#include "../QTestExtensions.h"
|
|
||||||
|
|
||||||
|
|
||||||
class ShapeColliderTests : public QObject {
|
class ShapeColliderTests : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <StreamUtils.h>
|
#include <StreamUtils.h>
|
||||||
|
|
||||||
#include "AngularConstraintTests.h"
|
#include "AngularConstraintTests.h"
|
||||||
|
#include "../QTestExtensions.h"
|
||||||
|
|
||||||
// Computes the error value between two quaternions (using glm::dot)
|
// Computes the error value between two quaternions (using glm::dot)
|
||||||
float getErrorDifference(const glm::quat& a, const glm::quat& b) {
|
float getErrorDifference(const glm::quat& a, const glm::quat& b) {
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#ifndef hifi_AngularConstraintTests_h
|
#ifndef hifi_AngularConstraintTests_h
|
||||||
#define hifi_AngularConstraintTests_h
|
#define hifi_AngularConstraintTests_h
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
#include <QtTest/QtTest>
|
#include <QtTest/QtTest>
|
||||||
|
|
||||||
class AngularConstraintTests : public QObject {
|
class AngularConstraintTests : public QObject {
|
||||||
|
@ -21,10 +22,6 @@ private slots:
|
||||||
void testConeRollerConstraint();
|
void testConeRollerConstraint();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Use QCOMPARE_WITH_ABS_ERROR and define it for glm::quat
|
float getErrorDifference(const glm::quat& a, const glm::quat& b);
|
||||||
#include <glm/glm.hpp>
|
|
||||||
float getErrorDifference (const glm::quat& a, const glm::quat& b);
|
|
||||||
QTextStream & operator << (QTextStream& stream, const glm::quat& q);
|
|
||||||
#include "../QTestExtensions.h"
|
|
||||||
|
|
||||||
#endif // hifi_AngularConstraintTests_h
|
#endif // hifi_AngularConstraintTests_h
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <qqueue.h>
|
#include <qqueue.h>
|
||||||
|
#include <../QTestExtensions.h>
|
||||||
|
|
||||||
QTEST_MAIN(MovingPercentileTests)
|
QTEST_MAIN(MovingPercentileTests)
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#define hifi_MovingPercentileTests_h
|
#define hifi_MovingPercentileTests_h
|
||||||
|
|
||||||
#include <QtTest/QtTest>
|
#include <QtTest/QtTest>
|
||||||
#include <../QTestExtensions.h>
|
|
||||||
|
|
||||||
class MovingPercentileTests : public QObject {
|
class MovingPercentileTests : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -8,10 +8,12 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "TransformTests.h"
|
||||||
|
|
||||||
#include <Transform.h>
|
#include <Transform.h>
|
||||||
|
|
||||||
#include "TransformTests.h"
|
|
||||||
#include "SharedLogging.h"
|
#include "SharedLogging.h"
|
||||||
|
#include <../QTestExtensions.h>
|
||||||
|
|
||||||
using namespace glm;
|
using namespace glm;
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,6 @@ inline QTextStream& operator<< (QTextStream& stream, const glm::mat4& matrix) {
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <../QTestExtensions.h>
|
|
||||||
|
|
||||||
class TransformTests : public QObject {
|
class TransformTests : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private slots:
|
private slots:
|
||||||
|
|
|
@ -106,6 +106,7 @@ public:
|
||||||
CachesSize,
|
CachesSize,
|
||||||
Chat,
|
Chat,
|
||||||
Collisions,
|
Collisions,
|
||||||
|
Connexion,
|
||||||
Console,
|
Console,
|
||||||
ControlWithSpeech,
|
ControlWithSpeech,
|
||||||
CopyAddress,
|
CopyAddress,
|
||||||
|
|
Loading…
Reference in a new issue