Merge branch 'master' of github.com:highfidelity/hifi into feat/resource-prefetch
|
@ -952,6 +952,24 @@ bool OctreeServer::readOptionInt(const QString& optionName, const QJsonObject& s
|
|||
return optionAvailable;
|
||||
}
|
||||
|
||||
bool OctreeServer::readOptionInt64(const QString& optionName, const QJsonObject& settingsSectionObject, qint64& result) {
|
||||
bool optionAvailable = false;
|
||||
QString argName = "--" + optionName;
|
||||
const char* argValue = getCmdOption(_argc, _argv, qPrintable(argName));
|
||||
if (argValue) {
|
||||
optionAvailable = true;
|
||||
result = atoll(argValue);
|
||||
qDebug() << "From payload arguments: " << qPrintable(argName) << ":" << result;
|
||||
} else if (settingsSectionObject.contains(optionName)) {
|
||||
optionAvailable = true;
|
||||
result = settingsSectionObject[optionName].toString().toLongLong(&optionAvailable);
|
||||
if (optionAvailable) {
|
||||
qDebug() << "From domain settings: " << qPrintable(optionName) << ":" << result;
|
||||
}
|
||||
}
|
||||
return optionAvailable;
|
||||
}
|
||||
|
||||
bool OctreeServer::readOptionString(const QString& optionName, const QJsonObject& settingsSectionObject, QString& result) {
|
||||
bool optionAvailable = false;
|
||||
QString argName = "--" + optionName;
|
||||
|
@ -1055,10 +1073,10 @@ void OctreeServer::readConfiguration() {
|
|||
// Debug option to demonstrate that the server's local time does not
|
||||
// need to be in sync with any other network node. This forces clock
|
||||
// skew for the individual server node
|
||||
int clockSkew;
|
||||
if (readOptionInt(QString("clockSkew"), settingsSectionObject, clockSkew)) {
|
||||
qint64 clockSkew;
|
||||
if (readOptionInt64(QString("clockSkew"), settingsSectionObject, clockSkew)) {
|
||||
usecTimestampNowForceClockSkew(clockSkew);
|
||||
qDebug("clockSkew=%d", clockSkew);
|
||||
qDebug() << "clockSkew=" << clockSkew;
|
||||
}
|
||||
|
||||
// Check to see if the user passed in a command line option for setting packet send rate
|
||||
|
|
|
@ -145,6 +145,7 @@ protected:
|
|||
virtual OctreePointer createTree() = 0;
|
||||
bool readOptionBool(const QString& optionName, const QJsonObject& settingsSectionObject, bool& result);
|
||||
bool readOptionInt(const QString& optionName, const QJsonObject& settingsSectionObject, int& result);
|
||||
bool readOptionInt64(const QString& optionName, const QJsonObject& settingsSectionObject, qint64& result);
|
||||
bool readOptionString(const QString& optionName, const QJsonObject& settingsSectionObject, QString& result);
|
||||
void readConfiguration();
|
||||
virtual void readAdditionalConfiguration(const QJsonObject& settingsSectionObject) { };
|
||||
|
|
6
cmake/externals/glew/CMakeLists.txt
vendored
|
@ -7,9 +7,9 @@ endif ()
|
|||
include(ExternalProject)
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL http://hifi-public.s3.amazonaws.com/dependencies/glew_simple2.zip
|
||||
URL_MD5 f05d858e8203c32b689da208ad8b39db
|
||||
CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
|
||||
URL http://hifi-public.s3.amazonaws.com/dependencies/glew_simple_1.13.0.zip
|
||||
URL_MD5 73f833649e904257b35bf4e84f8bdfb5
|
||||
CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
|
||||
LOG_DOWNLOAD 1
|
||||
LOG_CONFIGURE 1
|
||||
LOG_BUILD 1
|
||||
|
|
|
@ -27,6 +27,10 @@ macro(SET_PACKAGING_PARAMETERS)
|
|||
set(HIGH_FIDELITY_PROTOCOL "hifi")
|
||||
set(INTERFACE_BUNDLE_NAME "Interface")
|
||||
set(INTERFACE_ICON_PREFIX "interface")
|
||||
|
||||
# add definition for this release type
|
||||
add_definitions(-DPRODUCTION_BUILD)
|
||||
|
||||
elseif (RELEASE_TYPE STREQUAL "PR")
|
||||
set(DEPLOY_PACKAGE TRUE)
|
||||
set(PR_BUILD 1)
|
||||
|
@ -34,12 +38,18 @@ macro(SET_PACKAGING_PARAMETERS)
|
|||
set(BUILD_ORGANIZATION "High Fidelity - ${BUILD_VERSION}")
|
||||
set(INTERFACE_BUNDLE_NAME "Interface")
|
||||
set(INTERFACE_ICON_PREFIX "interface-beta")
|
||||
|
||||
# add definition for this release type
|
||||
add_definitions(-DPR_BUILD)
|
||||
else ()
|
||||
set(DEV_BUILD 1)
|
||||
set(BUILD_VERSION "dev")
|
||||
set(BUILD_ORGANIZATION "High Fidelity - ${BUILD_VERSION}")
|
||||
set(INTERFACE_BUNDLE_NAME "Interface")
|
||||
set(INTERFACE_ICON_PREFIX "interface-beta")
|
||||
|
||||
# add definition for this release type
|
||||
add_definitions(-DDEV_BUILD)
|
||||
endif ()
|
||||
|
||||
if (APPLE)
|
||||
|
|
148
examples/clap.js
|
@ -1,148 +0,0 @@
|
|||
//
|
||||
// clap.js
|
||||
// examples
|
||||
//
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// This sample script watches your hydra hands and makes clapping sound when they come close together fast,
|
||||
// and also watches for the 'shift' key and claps when that key is pressed. Clapping multiple times by pressing
|
||||
// the shift key again makes the animation and sound match your pace of clapping.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
||||
|
||||
var clapAnimation = HIFI_PUBLIC_BUCKET + "animations/ClapAnimations/ClapHands_Standing.fbx";
|
||||
var ANIMATION_FRAMES_PER_CLAP = 10.0;
|
||||
var startEndFrames = [];
|
||||
startEndFrames.push({ start: 0, end: 10});
|
||||
startEndFrames.push({ start: 10, end: 20});
|
||||
startEndFrames.push({ start: 20, end: 30});
|
||||
startEndFrames.push({ start: 30, end: 40});
|
||||
startEndFrames.push({ start: 41, end: 51});
|
||||
startEndFrames.push({ start: 53, end: 0});
|
||||
|
||||
var lastClapFrame = 0;
|
||||
var lastAnimFrame = 0;
|
||||
|
||||
var claps = [];
|
||||
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap1Rvb.wav"));
|
||||
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap2Rvb.wav"));
|
||||
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap3Rvb.wav"));
|
||||
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap4Rvb.wav"));
|
||||
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap5Rvb.wav"));
|
||||
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap6Rvb.wav"));
|
||||
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap7Rvb.wav"));
|
||||
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap8Rvb.wav"));
|
||||
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap9Rvb.wav"));
|
||||
claps.push(SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap10Rvb.wav"));
|
||||
var numberOfSounds = claps.length;
|
||||
|
||||
var clappingNow = false;
|
||||
var collectedClicks = 0;
|
||||
|
||||
var clickStartTime, clickEndTime;
|
||||
var clickClappingNow = false;
|
||||
var CLAP_START_RATE = 15.0;
|
||||
var clapRate = CLAP_START_RATE;
|
||||
var startedTimer = false;
|
||||
|
||||
function maybePlaySound(deltaTime) {
|
||||
// Set the location and other info for the sound to play
|
||||
|
||||
var animationDetails = MyAvatar.getAnimationDetails(clapAnimation);
|
||||
|
||||
var frame = Math.floor(animationDetails.frameIndex);
|
||||
|
||||
if (frame != lastAnimFrame) {
|
||||
lastAnimFrame = frame;
|
||||
}
|
||||
|
||||
for (var i = 0; i < startEndFrames.length; i++) {
|
||||
if (frame == startEndFrames[i].start && (frame != lastClapFrame)) {
|
||||
playClap(1.0, Camera.getPosition());
|
||||
lastClapFrame = frame;
|
||||
}
|
||||
}
|
||||
|
||||
var palm1Position = MyAvatar.getLeftPalmPosition();
|
||||
var palm2Position = MyAvatar.getRightPalmPosition();
|
||||
var distanceBetween = Vec3.length(Vec3.subtract(palm1Position, palm2Position));
|
||||
|
||||
var palm1Velocity = Controller.getPoseValue(Controller.Standard.LeftHand).velocity;
|
||||
var palm2Velocity = Controller.getPoseValue(Controller.Standard.RightHand).velocity;
|
||||
var closingVelocity = Vec3.length(Vec3.subtract(palm1Velocity, palm2Velocity));
|
||||
|
||||
const CLAP_SPEED = 0.7;
|
||||
const CLAP_DISTANCE = 0.15;
|
||||
|
||||
if ((closingVelocity > CLAP_SPEED) && (distanceBetween < CLAP_DISTANCE) && !clappingNow) {
|
||||
var volume = closingVelocity / 2.0;
|
||||
if (volume > 1.0) volume = 1.0;
|
||||
playClap(volume, palm1Position);
|
||||
clappingNow = true;
|
||||
} else if (clappingNow && (distanceBetween > CLAP_DISTANCE * 1.2)) {
|
||||
clappingNow = false;
|
||||
}
|
||||
}
|
||||
|
||||
function playClap(volume, position) {
|
||||
var clip = Math.floor(Math.random() * numberOfSounds);
|
||||
Audio.playSound(claps[clip], {
|
||||
position: position,
|
||||
volume: volume
|
||||
});
|
||||
}
|
||||
|
||||
var FASTEST_CLAP_INTERVAL = 150.0;
|
||||
var SLOWEST_CLAP_INTERVAL = 750.0;
|
||||
|
||||
Controller.keyPressEvent.connect(function(event) {
|
||||
if(event.text == "SHIFT") {
|
||||
if (!clickClappingNow) {
|
||||
clickClappingNow = true;
|
||||
clickStartTime = new Date();
|
||||
lastClapFrame = 0;
|
||||
} else {
|
||||
// start or adjust clapping speed based on the duration between clicks
|
||||
clickEndTime = new Date();
|
||||
var milliseconds = Math.max(clickEndTime - clickStartTime, FASTEST_CLAP_INTERVAL);
|
||||
clickStartTime = new Date();
|
||||
if (milliseconds < SLOWEST_CLAP_INTERVAL) {
|
||||
clapRate = ANIMATION_FRAMES_PER_CLAP * (1000.0 / milliseconds);
|
||||
playClap(1.0, Camera.getPosition());
|
||||
MyAvatar.stopAnimation(clapAnimation);
|
||||
MyAvatar.startAnimation(clapAnimation, clapRate, 1.0, true, false);
|
||||
}
|
||||
collectedClicks = collectedClicks + 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var CLAP_END_WAIT_MSECS = 300;
|
||||
Controller.keyReleaseEvent.connect(function(event) {
|
||||
if (event.text == "SHIFT") {
|
||||
collectedClicks = 0;
|
||||
if (!startedTimer) {
|
||||
collectedClicks = 0;
|
||||
Script.setTimeout(stopClapping, CLAP_END_WAIT_MSECS);
|
||||
startedTimer = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function stopClapping() {
|
||||
if (collectedClicks == 0) {
|
||||
startedTimer = false;
|
||||
MyAvatar.stopAnimation(clapAnimation);
|
||||
clapRate = CLAP_START_RATE;
|
||||
clickClappingNow = false;
|
||||
} else {
|
||||
startedTimer = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Connect a call back that happens every frame
|
||||
Script.update.connect(maybePlaySound);
|
|
@ -1,68 +0,0 @@
|
|||
|
||||
// cowEntityScript.js
|
||||
// examples/cows
|
||||
//
|
||||
// Created by Eric Levin on 3/25/16
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// This entity script handles the logic for untipping a cow after it collides with something
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
|
||||
|
||||
(function() {
|
||||
Script.include("../libraries/utils.js");
|
||||
|
||||
var _this = this;
|
||||
_this.COLLISION_COOLDOWN_TIME = 5000;
|
||||
|
||||
|
||||
this.preload = function(entityID) {
|
||||
print("EBL Preload!!");
|
||||
_this.entityID = entityID;
|
||||
_this.mooSound = SoundCache.getSound("https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/moo.wav")
|
||||
_this.mooSoundOptions = {volume: 0.7, loop: false};
|
||||
_this.timeSinceLastCollision = 0;
|
||||
_this.shouldUntipCow = true;
|
||||
}
|
||||
|
||||
this.collisionWithEntity = function(myID, otherID, collisionInfo) {
|
||||
if(_this.shouldUntipCow) {
|
||||
Script.setTimeout(function() {
|
||||
_this.untipCow();
|
||||
_this.shouldUntipCow = true;
|
||||
}, _this.COLLISION_COOLDOWN_TIME);
|
||||
}
|
||||
|
||||
_this.shouldUntipCow = false;
|
||||
|
||||
}
|
||||
|
||||
this.untipCow = function() {
|
||||
// keep yaw but reset pitch and roll
|
||||
var cowProps = Entities.getEntityProperties(_this.entityID, ["rotation", "position"]);
|
||||
var eulerRotation = Quat.safeEulerAngles(cowProps.rotation);
|
||||
eulerRotation.x = 0;
|
||||
eulerRotation.z = 0;
|
||||
var newRotation = Quat.fromVec3Degrees(eulerRotation);
|
||||
Entities.editEntity(_this.entityID, {
|
||||
rotation: newRotation,
|
||||
velocity: {x: 0, y: 0, z: 0},
|
||||
angularVelocity: {x: 0, y: 0, z:0}
|
||||
});
|
||||
|
||||
|
||||
_this.mooSoundOptions.position = cowProps.position;
|
||||
if (!_this.soundInjector) {
|
||||
_this.soundInjector = Audio.playSound(_this.mooSound, _this.mooSoundOptions);
|
||||
} else {
|
||||
_this.soundInjector.setOptions(_this.mooSoundOptions);
|
||||
_this.soundInjector.restart();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
});
|
|
@ -1,53 +0,0 @@
|
|||
|
||||
// cowSpawner.js
|
||||
// examples/cows
|
||||
//
|
||||
// Created by Eric Levin on 3/25/16
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// This spawns a cow which will untip itself
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
var orientation = MyAvatar.orientation;
|
||||
orientation = Quat.safeEulerAngles(orientation);
|
||||
orientation.x = 0;
|
||||
orientation = Quat.fromVec3Degrees(orientation);
|
||||
var center = Vec3.sum(MyAvatar.getHeadPosition(), Vec3.multiply(2, Quat.getFront(orientation)));
|
||||
|
||||
|
||||
var SCRIPT_URL = Script.resolvePath("cowEntityScript.js?");
|
||||
var cow = Entities.addEntity({
|
||||
type: "Model",
|
||||
modelURL: "http://hifi-content.s3.amazonaws.com/DomainContent/production/cow/newMooCow.fbx",
|
||||
name: "playa_model_throwinCow",
|
||||
position: center,
|
||||
animation: {
|
||||
currentFrame: 278,
|
||||
running: true,
|
||||
url: "http://hifi-content.s3.amazonaws.com/DomainContent/Junkyard/Playa/newMooCow.fbx"
|
||||
},
|
||||
dimensions: {
|
||||
x: 0.739,
|
||||
y: 1.613,
|
||||
z: 2.529
|
||||
},
|
||||
dynamic: true,
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: -5,
|
||||
z: 0
|
||||
},
|
||||
shapeType: "box",
|
||||
script: SCRIPT_URL,
|
||||
userData: "{\"grabbableKey\":{\"grabbable\":true}}"
|
||||
});
|
||||
|
||||
|
||||
function cleanup() {
|
||||
Entities.deleteEntity(cow);
|
||||
}
|
||||
|
||||
Script.scriptEnding.connect(cleanup);
|
|
@ -1,22 +0,0 @@
|
|||
//
|
||||
// defaultScripts.js
|
||||
// examples
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
Script.load("away.js");
|
||||
Script.load("progress.js");
|
||||
Script.load("edit.js");
|
||||
Script.load("examples.js");
|
||||
Script.load("selectAudioDevice.js");
|
||||
Script.load("notifications.js");
|
||||
Script.load("controllers/handControllerGrab.js");
|
||||
Script.load("controllers/squeezeHands.js");
|
||||
Script.load("grab.js");
|
||||
Script.load("directory.js");
|
||||
Script.load("dialTone.js");
|
||||
Script.load("depthReticle.js");
|
|
@ -1,477 +0,0 @@
|
|||
//
|
||||
// pistol.js
|
||||
// examples
|
||||
//
|
||||
// Created by Eric Levin on 11/12/2015
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// This is an example script that turns the hydra controllers and mouse into a entity gun.
|
||||
// It reads the controller, watches for trigger pulls, and adds a force to any entity it hits
|
||||
|
||||
// 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("../../../libraries/utils.js");
|
||||
Script.include("../../../libraries/constants.js");
|
||||
|
||||
var GUN_FORCE =20;
|
||||
|
||||
Messages.sendMessage('Hifi-Hand-Disabler', "both");
|
||||
|
||||
var gameName = "Kill All The Rats!"
|
||||
// var HOST = "localhost:5000"
|
||||
var HOST = "desolate-bastion-1742.herokuapp.com";
|
||||
var socketClient = new WebSocket("ws://" + HOST);
|
||||
var username = GlobalServices.username;
|
||||
var currentScore = 0;
|
||||
|
||||
function score() {
|
||||
currentScore++;
|
||||
socketClient.send(JSON.stringify({
|
||||
username: username,
|
||||
score: currentScore,
|
||||
gameName: gameName
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
||||
var fireSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Guns/GUN-SHOT2.raw");
|
||||
var LASER_LENGTH = 100;
|
||||
var LASER_WIDTH = 2;
|
||||
var POSE_CONTROLS = [Controller.Standard.LeftHand, Controller.Standard.RightHand];
|
||||
var TRIGGER_CONTROLS = [Controller.Standard.LT, Controller.Standard.RT];
|
||||
var MIN_THROWER_DELAY = 1000;
|
||||
var MAX_THROWER_DELAY = 1000;
|
||||
var RELOAD_INTERVAL = 5;
|
||||
var GUN_MODEL = HIFI_PUBLIC_BUCKET + "cozza13/gun/m1911-handgun+1.fbx?v=4";
|
||||
var BULLET_VELOCITY = 10.0;
|
||||
var GUN_OFFSETS = [{
|
||||
x: 0.04,
|
||||
y: 0.26,
|
||||
z: 0.04
|
||||
}, {
|
||||
x: 0.04,
|
||||
y: 0.26,
|
||||
z: 0.04
|
||||
}];
|
||||
|
||||
var GUN_ORIENTATIONS = [Quat.fromPitchYawRollDegrees(0, 90, 90), Quat.fromPitchYawRollDegrees(0, -90, 270)];
|
||||
|
||||
//x -> y
|
||||
//y -> z
|
||||
// z -> x
|
||||
var BARREL_OFFSETS = [ {
|
||||
x: -0.12,
|
||||
y: 0.12,
|
||||
z: 0.04
|
||||
}, {
|
||||
x: 0.12,
|
||||
y: 0.12,
|
||||
z: 0.04
|
||||
} ];
|
||||
|
||||
|
||||
|
||||
var pointers = [];
|
||||
|
||||
pointers.push(Overlays.addOverlay("line3d", {
|
||||
start: ZERO_VECTOR,
|
||||
end: ZERO_VECTOR,
|
||||
color: COLORS.RED,
|
||||
alpha: 1,
|
||||
visible: true,
|
||||
lineWidth: LASER_WIDTH
|
||||
}));
|
||||
|
||||
pointers.push(Overlays.addOverlay("line3d", {
|
||||
start: ZERO_VECTOR,
|
||||
end: ZERO_VECTOR,
|
||||
color: COLORS.RED,
|
||||
alpha: 1,
|
||||
visible: true,
|
||||
lineWidth: LASER_WIDTH
|
||||
}));
|
||||
|
||||
var mapping = Controller.newMapping();
|
||||
var validPoses = [false, false];
|
||||
var barrelVectors = [0, 0];
|
||||
var barrelTips = [0, 0];
|
||||
|
||||
|
||||
// If enabled, anything can be shot, otherwise, an entity needs to have "isShootable" set in its userData
|
||||
var shootAnything = true;
|
||||
|
||||
|
||||
function update(deltaTime) {
|
||||
// FIXME we should also expose MyAvatar.handPoses[2], MyAvatar.tipPoses[2]
|
||||
var tipPoses = [MyAvatar.leftHandTipPose, MyAvatar.rightHandTipPose];
|
||||
|
||||
for (var side = 0; side < 2; side++) {
|
||||
// First check if the controller is valid
|
||||
var controllerPose = Controller.getPoseValue(POSE_CONTROLS[side]);
|
||||
validPoses[side] = controllerPose.valid;
|
||||
// Need to adjust the laser
|
||||
var tipPose = tipPoses[side];
|
||||
var handRotation = tipPoses[side].rotation;
|
||||
var barrelOffset = Vec3.multiplyQbyV(handRotation, BARREL_OFFSETS[side]);
|
||||
barrelTips[side] = Vec3.sum(tipPose.translation, barrelOffset);
|
||||
barrelVectors[side] = Vec3.multiplyQbyV(handRotation, {
|
||||
x: 0,
|
||||
y: 1,
|
||||
z: 0
|
||||
});
|
||||
|
||||
var laserTip = Vec3.sum(Vec3.multiply(LASER_LENGTH, barrelVectors[side]), barrelTips[side]);
|
||||
// Update Lasers
|
||||
Overlays.editOverlay(pointers[side], {
|
||||
start: barrelTips[side],
|
||||
end: laserTip,
|
||||
alpha: 1,
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function displayPointer(side) {
|
||||
Overlays.editOverlay(pointers[side], {
|
||||
visible: true
|
||||
});
|
||||
}
|
||||
|
||||
function hidePointer(side) {
|
||||
Overlays.editOverlay(pointers[side], {
|
||||
visible: false
|
||||
});
|
||||
}
|
||||
|
||||
function fire(side, value) {
|
||||
if (value == 0) {
|
||||
return;
|
||||
}
|
||||
Audio.playSound(fireSound, {
|
||||
position: barrelTips[side],
|
||||
volume: 0.5
|
||||
});
|
||||
|
||||
var shotDirection = Vec3.normalize(barrelVectors[side]);
|
||||
var pickRay = {
|
||||
origin: barrelTips[side],
|
||||
direction: shotDirection
|
||||
};
|
||||
createMuzzleFlash(barrelTips[side]);
|
||||
|
||||
var intersection = Entities.findRayIntersectionBlocking(pickRay, true);
|
||||
if (intersection.intersects) {
|
||||
Script.setTimeout(function() {
|
||||
createEntityHitEffect(intersection.intersection);
|
||||
if (shootAnything && intersection.properties.dynamic === 1) {
|
||||
// Any dynamic entity can be shot
|
||||
Entities.editEntity(intersection.entityID, {
|
||||
velocity: Vec3.multiply(shotDirection, GUN_FORCE)
|
||||
});
|
||||
}
|
||||
|
||||
if (intersection.properties.name === "rat") {
|
||||
score();
|
||||
createBloodSplatter(intersection.intersection);
|
||||
Entities.deleteEntity(intersection.entityID);
|
||||
|
||||
}
|
||||
//Attempt to call entity method's shot method
|
||||
var forceDirection = JSON.stringify({
|
||||
forceDirection: shotDirection
|
||||
});
|
||||
Entities.callEntityMethod(intersection.entityID, 'onShot', [forceDirection]);
|
||||
|
||||
}, 0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function scriptEnding() {
|
||||
Messages.sendMessage('Hifi-Hand-Disabler', 'none');
|
||||
mapping.disable();
|
||||
for (var i = 0; i < pointers.length; ++i) {
|
||||
Overlays.deleteOverlay(pointers[i]);
|
||||
}
|
||||
MyAvatar.detachOne(GUN_MODEL);
|
||||
MyAvatar.detachOne(GUN_MODEL);
|
||||
clearPose();
|
||||
}
|
||||
|
||||
MyAvatar.attach(GUN_MODEL, "LeftHand", GUN_OFFSETS[0], GUN_ORIENTATIONS[0], 0.40);
|
||||
MyAvatar.attach(GUN_MODEL, "RightHand", GUN_OFFSETS[1], GUN_ORIENTATIONS[1], 0.40);
|
||||
|
||||
function showPointer(side) {
|
||||
Overlays.editOverlay(pointers[side], {
|
||||
visible: true
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
mapping.from(Controller.Standard.LT).hysteresis(0.0, 0.5).to(function(value) {
|
||||
fire(0, value);
|
||||
});
|
||||
|
||||
|
||||
mapping.from(Controller.Standard.RT).hysteresis(0.0, 0.5).to(function(value) {
|
||||
fire(1, value);
|
||||
});
|
||||
mapping.enable();
|
||||
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
Script.update.connect(update);
|
||||
|
||||
|
||||
function createEntityHitEffect(position) {
|
||||
var flash = Entities.addEntity({
|
||||
type: "ParticleEffect",
|
||||
position: position,
|
||||
lifetime: 4,
|
||||
"name": "Flash Emitter",
|
||||
"color": {
|
||||
red: 228,
|
||||
green: 128,
|
||||
blue: 12
|
||||
},
|
||||
"maxParticles": 1000,
|
||||
"lifespan": 0.15,
|
||||
"emitRate": 1000,
|
||||
"emitSpeed": 1,
|
||||
"speedSpread": 0,
|
||||
"emitOrientation": {
|
||||
"x": -0.4,
|
||||
"y": 1,
|
||||
"z": -0.2,
|
||||
"w": 0.7071068286895752
|
||||
},
|
||||
"emitDimensions": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"polarStart": 0,
|
||||
"polarFinish": Math.PI,
|
||||
"azimuthStart": -3.1415927410125732,
|
||||
"azimuthFinish": 2,
|
||||
"emitAcceleration": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"accelerationSpread": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"particleRadius": 0.03,
|
||||
"radiusSpread": 0.02,
|
||||
"radiusStart": 0.02,
|
||||
"radiusFinish": 0.03,
|
||||
"colorSpread": {
|
||||
red: 100,
|
||||
green: 100,
|
||||
blue: 20
|
||||
},
|
||||
"alpha": 1,
|
||||
"alphaSpread": 0,
|
||||
"alphaStart": 0,
|
||||
"alphaFinish": 0,
|
||||
"additiveBlending": true,
|
||||
"textures": "http://ericrius1.github.io/PartiArt/assets/star.png"
|
||||
});
|
||||
|
||||
Script.setTimeout(function() {
|
||||
Entities.editEntity(flash, {
|
||||
isEmitting: false
|
||||
});
|
||||
}, 100);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function createBloodSplatter(position) {
|
||||
var splatter = Entities.addEntity({
|
||||
type: "ParticleEffect",
|
||||
position: position,
|
||||
lifetime: 4,
|
||||
"name": "Blood Splatter",
|
||||
"color": {
|
||||
red: 230,
|
||||
green: 2,
|
||||
blue: 30
|
||||
},
|
||||
"maxParticles": 1000,
|
||||
"lifespan": 0.3,
|
||||
"emitRate": 1000,
|
||||
"emitSpeed": 0.5,
|
||||
"speedSpread": 0,
|
||||
"emitOrientation": {
|
||||
"x": -0.4,
|
||||
"y": 1,
|
||||
"z": -0.2,
|
||||
"w": 0.7071068286895752
|
||||
},
|
||||
"emitDimensions": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"polarStart": 0,
|
||||
"polarFinish": Math.PI,
|
||||
"azimuthStart": -3.1415927410125732,
|
||||
"azimuthFinish": 2,
|
||||
"emitAcceleration": {
|
||||
"x": 0,
|
||||
"y": -5,
|
||||
"z": 0
|
||||
},
|
||||
"accelerationSpread": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"particleRadius": 0.05,
|
||||
"radiusSpread": 0.03,
|
||||
"radiusStart": 0.05,
|
||||
"radiusFinish": 0.05,
|
||||
"colorSpread": {
|
||||
red: 40,
|
||||
green: 0,
|
||||
blue: 30
|
||||
},
|
||||
"alpha": 1,
|
||||
"alphaSpread": 0,
|
||||
"alphaStart": 0,
|
||||
"alphaFinish": 0,
|
||||
"textures": "http://ericrius1.github.io/PartiArt/assets/star.png"
|
||||
});
|
||||
|
||||
Script.setTimeout(function() {
|
||||
Entities.editEntity(splatter, {
|
||||
isEmitting: false
|
||||
});
|
||||
}, 100)
|
||||
|
||||
}
|
||||
|
||||
|
||||
function createMuzzleFlash(position) {
|
||||
var smoke = Entities.addEntity({
|
||||
type: "ParticleEffect",
|
||||
position: position,
|
||||
lifetime: 1,
|
||||
"name": "Smoke Hit Emitter",
|
||||
"maxParticles": 1000,
|
||||
"lifespan": 4,
|
||||
"emitRate": 20,
|
||||
emitSpeed: 0,
|
||||
"speedSpread": 0,
|
||||
"emitDimensions": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"polarStart": 0,
|
||||
"polarFinish": 0,
|
||||
"azimuthStart": -3.1415927410125732,
|
||||
"azimuthFinish": 3.14,
|
||||
"emitAcceleration": {
|
||||
"x": 0,
|
||||
"y": 0.5,
|
||||
"z": 0
|
||||
},
|
||||
"accelerationSpread": {
|
||||
"x": .2,
|
||||
"y": 0,
|
||||
"z": .2
|
||||
},
|
||||
"radiusSpread": .04,
|
||||
"particleRadius": 0.07,
|
||||
"radiusStart": 0.07,
|
||||
"radiusFinish": 0.07,
|
||||
"alpha": 0.7,
|
||||
"alphaSpread": 0,
|
||||
"alphaStart": 0,
|
||||
"alphaFinish": 0,
|
||||
"additiveBlending": 0,
|
||||
"textures": "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png"
|
||||
});
|
||||
Script.setTimeout(function() {
|
||||
Entities.editEntity(smoke, {
|
||||
isEmitting: false
|
||||
});
|
||||
}, 100);
|
||||
|
||||
var flash = Entities.addEntity({
|
||||
type: "ParticleEffect",
|
||||
position: position,
|
||||
lifetime: 4,
|
||||
"name": "Muzzle Flash",
|
||||
"color": {
|
||||
red: 228,
|
||||
green: 128,
|
||||
blue: 12
|
||||
},
|
||||
"maxParticles": 1000,
|
||||
"lifespan": 0.1,
|
||||
"emitRate": 1000,
|
||||
"emitSpeed": 0.5,
|
||||
"speedSpread": 0,
|
||||
"emitOrientation": {
|
||||
"x": -0.4,
|
||||
"y": 1,
|
||||
"z": -0.2,
|
||||
"w": 0.7071068286895752
|
||||
},
|
||||
"emitDimensions": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"polarStart": 0,
|
||||
"polarFinish": Math.PI,
|
||||
"azimuthStart": -3.1415927410125732,
|
||||
"azimuthFinish": 2,
|
||||
"emitAcceleration": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"accelerationSpread": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"particleRadius": 0.05,
|
||||
"radiusSpread": 0.01,
|
||||
"radiusStart": 0.05,
|
||||
"radiusFinish": 0.05,
|
||||
"colorSpread": {
|
||||
red: 100,
|
||||
green: 100,
|
||||
blue: 20
|
||||
},
|
||||
"alpha": 1,
|
||||
"alphaSpread": 0,
|
||||
"alphaStart": 0,
|
||||
"alphaFinish": 0,
|
||||
"additiveBlending": true,
|
||||
"textures": "http://ericrius1.github.io/PartiArt/assets/star.png"
|
||||
});
|
||||
|
||||
Script.setTimeout(function() {
|
||||
Entities.editEntity(flash, {
|
||||
isEmitting: false
|
||||
});
|
||||
}, 100)
|
||||
|
||||
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
//
|
||||
// Rat.js
|
||||
// examples/toybox/entityScripts
|
||||
//
|
||||
// Created by Eric Levin on11/11/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
|
||||
/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */
|
||||
|
||||
|
||||
(function() {
|
||||
var scriptURL = Script.resolvePath('pistol.js');
|
||||
var _this;
|
||||
PistolScriptSpawner = function() {
|
||||
_this = this;
|
||||
this.forceMultiplier = 1;
|
||||
};
|
||||
|
||||
PistolScriptSpawner.prototype = {
|
||||
|
||||
enterEntity: function() {
|
||||
|
||||
Script.load(scriptURL);
|
||||
},
|
||||
|
||||
preload: function(entityID) {
|
||||
this.entityID = entityID;
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
// entity scripts always need to return a newly constructed object of our type
|
||||
return new PistolScriptSpawner();
|
||||
});
|
|
@ -1,41 +0,0 @@
|
|||
float aspect(vec2 v) {
|
||||
return v.x / v.y;
|
||||
}
|
||||
|
||||
vec3 aspectCorrectedTexture() {
|
||||
vec2 uv = _position.xy;
|
||||
uv += 0.5;
|
||||
uv.y = 1.0 - uv.y;
|
||||
|
||||
float targetAspect = iWorldScale.x / iWorldScale.y;
|
||||
float sourceAspect = aspect(iChannelResolution[0].xy);
|
||||
float aspectCorrection = sourceAspect / targetAspect;
|
||||
if (aspectCorrection > 1.0) {
|
||||
float offset = aspectCorrection - 1.0;
|
||||
float halfOffset = offset / 2.0;
|
||||
uv.y -= halfOffset;
|
||||
uv.y *= aspectCorrection;
|
||||
} else {
|
||||
float offset = 1.0 - aspectCorrection;
|
||||
float halfOffset = offset / 2.0;
|
||||
uv.x -= halfOffset;
|
||||
uv.x /= aspectCorrection;
|
||||
}
|
||||
|
||||
if (any(lessThan(uv, vec2(0.0)))) {
|
||||
return vec3(0.0);
|
||||
}
|
||||
|
||||
if (any(greaterThan(uv, vec2(1.0)))) {
|
||||
return vec3(0.0);
|
||||
}
|
||||
|
||||
vec4 color = texture(iChannel0, uv);
|
||||
return color.rgb * max(0.5, sourceAspect) * max(0.9, fract(iWorldPosition.x));
|
||||
}
|
||||
|
||||
float getProceduralColors(inout vec3 diffuse, inout vec3 specular, inout float shininess) {
|
||||
specular = aspectCorrectedTexture();
|
||||
return 1.0;
|
||||
}
|
||||
|
|
@ -269,7 +269,7 @@ endif (APPLE)
|
|||
if (SCRIPTS_INSTALL_DIR)
|
||||
# setup install of scripts beside interface executable
|
||||
install(
|
||||
DIRECTORY "${CMAKE_SOURCE_DIR}/examples/"
|
||||
DIRECTORY "${CMAKE_SOURCE_DIR}/scripts/"
|
||||
DESTINATION ${SCRIPTS_INSTALL_DIR}/scripts
|
||||
COMPONENT ${CLIENT_COMPONENT}
|
||||
)
|
||||
|
|
BIN
interface/resources/avatar/animations/fly.fbx
Normal file
BIN
interface/resources/avatar/animations/hydra_pose_closed_left.fbx
Normal file
BIN
interface/resources/avatar/animations/hydra_pose_open_left.fbx
Normal file
BIN
interface/resources/avatar/animations/hydra_pose_open_right.fbx
Normal file
BIN
interface/resources/avatar/animations/idle.fbx
Normal file
BIN
interface/resources/avatar/animations/idle_to_walk.fbx
Normal file
BIN
interface/resources/avatar/animations/jump_in_air.fbx
Normal file
BIN
interface/resources/avatar/animations/jump_land.fbx
Normal file
BIN
interface/resources/avatar/animations/jump_standing_apex.fbx
Normal file
BIN
interface/resources/avatar/animations/jump_standing_land.fbx
Normal file
BIN
interface/resources/avatar/animations/jump_standing_takeoff.fbx
Normal file
BIN
interface/resources/avatar/animations/jump_takeoff.fbx
Normal file
BIN
interface/resources/avatar/animations/run_fwd.fbx
Normal file
BIN
interface/resources/avatar/animations/side_step_left.fbx
Normal file
BIN
interface/resources/avatar/animations/side_step_right.fbx
Normal file
BIN
interface/resources/avatar/animations/side_step_short_left.fbx
Normal file
BIN
interface/resources/avatar/animations/side_step_short_right.fbx
Normal file
BIN
interface/resources/avatar/animations/talk.fbx
Normal file
BIN
interface/resources/avatar/animations/turn_left.fbx
Normal file
BIN
interface/resources/avatar/animations/turn_right.fbx
Normal file
BIN
interface/resources/avatar/animations/walk_bwd.fbx
Normal file
BIN
interface/resources/avatar/animations/walk_fwd.fbx
Normal file
BIN
interface/resources/avatar/animations/walk_short_bwd.fbx
Normal file
BIN
interface/resources/avatar/animations/walk_short_fwd.fbx
Normal file
|
@ -145,7 +145,7 @@
|
|||
"id": "rightHandGraspOpen",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/hydra_pose_open_right.fbx",
|
||||
"url": "animations/hydra_pose_open_right.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 0.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -157,7 +157,7 @@
|
|||
"id": "rightHandGraspClosed",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/hydra_pose_closed_right.fbx",
|
||||
"url": "animations/hydra_pose_closed_right.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 0.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -205,7 +205,7 @@
|
|||
"id": "leftHandGraspOpen",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/hydra_pose_open_left.fbx",
|
||||
"url": "animations/hydra_pose_open_left.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 0.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -217,7 +217,7 @@
|
|||
"id": "leftHandGraspClosed",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/hydra_pose_closed_left.fbx",
|
||||
"url": "animations/hydra_pose_closed_left.fbx",
|
||||
"startFrame": 10.0,
|
||||
"endFrame": 10.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -495,7 +495,7 @@
|
|||
"id": "idleStand",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/idle.fbx",
|
||||
"url": "animations/idle.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 90.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -507,7 +507,7 @@
|
|||
"id": "idleTalk",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/talk.fbx",
|
||||
"url": "animations/talk.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 801.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -532,7 +532,7 @@
|
|||
"id": "walkFwdShort",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/walk_short_fwd.fbx",
|
||||
"url": "animations/walk_short_fwd.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 39.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -544,7 +544,7 @@
|
|||
"id": "walkFwdNormal",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/walk_fwd.fbx",
|
||||
"url": "animations/walk_fwd.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 35.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -556,7 +556,7 @@
|
|||
"id": "walkFwdRun",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/run_fwd.fbx",
|
||||
"url": "animations/run_fwd.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 21.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -570,7 +570,7 @@
|
|||
"id": "idleToWalkFwd",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/idle_to_walk.fbx",
|
||||
"url": "animations/idle_to_walk.fbx",
|
||||
"startFrame": 1.0,
|
||||
"endFrame": 19.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -593,7 +593,7 @@
|
|||
"id": "walkBwdShort",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/walk_short_bwd.fbx",
|
||||
"url": "animations/walk_short_bwd.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 38.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -605,7 +605,7 @@
|
|||
"id": "walkBwdNormal",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/walk_bwd.fbx",
|
||||
"url": "animations/walk_bwd.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 36.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -619,7 +619,7 @@
|
|||
"id": "turnLeft",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/turn_left.fbx",
|
||||
"url": "animations/turn_left.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 28.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -631,7 +631,7 @@
|
|||
"id": "turnRight",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/turn_right.fbx",
|
||||
"url": "animations/turn_right.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 30.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -654,7 +654,7 @@
|
|||
"id": "strafeLeftShort",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/side_step_short_left.fbx",
|
||||
"url": "animations/side_step_short_left.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 28.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -666,7 +666,7 @@
|
|||
"id": "strafeLeftNormal",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/side_step_left.fbx",
|
||||
"url": "animations/side_step_left.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 30.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -691,7 +691,7 @@
|
|||
"id": "strafeRightShort",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/side_step_short_right.fbx",
|
||||
"url": "animations/side_step_short_right.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 28.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -703,7 +703,7 @@
|
|||
"id": "strafeRightNormal",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/side_step_right.fbx",
|
||||
"url": "animations/side_step_right.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 30.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -717,7 +717,7 @@
|
|||
"id": "fly",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/fly.fbx",
|
||||
"url": "animations/fly.fbx",
|
||||
"startFrame": 1.0,
|
||||
"endFrame": 80.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -729,7 +729,7 @@
|
|||
"id": "takeoffStand",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_standing_takeoff.fbx",
|
||||
"url": "animations/jump_standing_takeoff.fbx",
|
||||
"startFrame": 17.0,
|
||||
"endFrame": 25.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -741,7 +741,7 @@
|
|||
"id": "takeoffRun",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_takeoff.fbx",
|
||||
"url": "animations/jump_takeoff.fbx",
|
||||
"startFrame": 1.0,
|
||||
"endFrame": 2.5,
|
||||
"timeScale": 0.01,
|
||||
|
@ -761,7 +761,7 @@
|
|||
"id": "inAirStandPreApex",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_standing_apex.fbx",
|
||||
"url": "animations/jump_standing_apex.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 0.0,
|
||||
"timeScale": 0.0,
|
||||
|
@ -773,7 +773,7 @@
|
|||
"id": "inAirStandApex",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_standing_apex.fbx",
|
||||
"url": "animations/jump_standing_apex.fbx",
|
||||
"startFrame": 1.0,
|
||||
"endFrame": 1.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -785,7 +785,7 @@
|
|||
"id": "inAirStandPostApex",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_standing_apex.fbx",
|
||||
"url": "animations/jump_standing_apex.fbx",
|
||||
"startFrame": 2.0,
|
||||
"endFrame": 2.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -807,7 +807,7 @@
|
|||
"id": "inAirRunPreApex",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_in_air.fbx",
|
||||
"url": "animations/jump_in_air.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 0.0,
|
||||
"timeScale": 0.0,
|
||||
|
@ -819,7 +819,7 @@
|
|||
"id": "inAirRunApex",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_in_air.fbx",
|
||||
"url": "animations/jump_in_air.fbx",
|
||||
"startFrame": 6.0,
|
||||
"endFrame": 6.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -831,7 +831,7 @@
|
|||
"id": "inAirRunPostApex",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_in_air.fbx",
|
||||
"url": "animations/jump_in_air.fbx",
|
||||
"startFrame": 11.0,
|
||||
"endFrame": 11.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -845,7 +845,7 @@
|
|||
"id": "landStandImpact",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_standing_land.fbx",
|
||||
"url": "animations/jump_standing_land.fbx",
|
||||
"startFrame": 1.0,
|
||||
"endFrame": 6.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -857,7 +857,7 @@
|
|||
"id": "landStand",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_standing_land.fbx",
|
||||
"url": "animations/jump_standing_land.fbx",
|
||||
"startFrame": 6.0,
|
||||
"endFrame": 28.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -869,7 +869,7 @@
|
|||
"id": "landRun",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/jump_land.fbx",
|
||||
"url": "animations/jump_land.fbx",
|
||||
"startFrame": 1.0,
|
||||
"endFrame": 6.0,
|
||||
"timeScale": 0.65,
|
||||
|
@ -891,7 +891,7 @@
|
|||
"id": "userAnimA",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/idle.fbx",
|
||||
"url": "animations/idle.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 90.0,
|
||||
"timeScale": 1.0,
|
||||
|
@ -903,7 +903,7 @@
|
|||
"id": "userAnimB",
|
||||
"type": "clip",
|
||||
"data": {
|
||||
"url": "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/idle.fbx",
|
||||
"url": "animations/idle.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 90.0,
|
||||
"timeScale": 1.0,
|
BIN
interface/resources/meshes/being_of_light/being_of_light.fbx
Normal file
After Width: | Height: | Size: 2.6 MiB |
After Width: | Height: | Size: 2.9 MiB |
After Width: | Height: | Size: 645 KiB |
Before Width: | Height: | Size: 330 KiB |
Before Width: | Height: | Size: 142 KiB |
Before Width: | Height: | Size: 4.6 KiB |
|
@ -1,20 +0,0 @@
|
|||
filename=defaultAvatar/body.fbx
|
||||
texdir=defaultAvatar
|
||||
scale=8.666
|
||||
joint = jointRoot = jointRoot
|
||||
joint = jointLean = jointSpine
|
||||
joint = jointNeck = jointNeck
|
||||
joint = jointHead = jointHeadtop
|
||||
joint = joint_L_shoulder = joint_L_shoulder
|
||||
freeJoint = joint_L_arm
|
||||
freeJoint = joint_L_elbow
|
||||
joint = jointLeftHand = joint_L_hand
|
||||
joint = joint_R_shoulder = joint_R_shoulder
|
||||
freeJoint = joint_R_arm
|
||||
freeJoint = joint_R_elbow
|
||||
joint = jointRightHand = joint_R_hand
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,97 +1,135 @@
|
|||
name = defaultAvatar_full
|
||||
name = being_of_light
|
||||
type = body+head
|
||||
scale = 1
|
||||
filename = defaultAvatar_full/defaultAvatar_full.fbx
|
||||
texdir = defaultAvatar_full/textures
|
||||
joint = jointRightHand = RightHand
|
||||
joint = jointNeck = Head
|
||||
filename = being_of_light/being_of_light.fbx
|
||||
texdir = being_of_light/textures
|
||||
joint = jointRoot = Hips
|
||||
joint = jointLeftHand = LeftHand
|
||||
joint = jointHead = HeadTop_End
|
||||
joint = jointLean = Spine
|
||||
joint = jointLeftHand = LeftHand
|
||||
joint = jointEyeLeft = LeftEye
|
||||
joint = jointRightHand = RightHand
|
||||
joint = jointNeck = Head
|
||||
joint = jointEyeRight = RightEye
|
||||
freeJoint = LeftArm
|
||||
freeJoint = LeftForeArm
|
||||
freeJoint = RightArm
|
||||
freeJoint = RightForeArm
|
||||
bs = MouthFrown_R = Mouth.MouthFrown_R = 1
|
||||
bs = EyeOpen_L = Leye1.EyeOpen_L = 1
|
||||
bs = LipsLowerDown_L = Mouth.LipsLowerDown = 0.5
|
||||
bs = LipsStretch_L = Mouth.LipsStretch_L = 1
|
||||
bs = MouthLeft = Mouth.MouthLeft = 1
|
||||
bs = MouthSmile_L = Mouth.MouthSmile_L = 1
|
||||
bs = Sneer_R = Mouth.Sneer = 0.61
|
||||
bs = LipsPucker = Mouth.LipsPucker = 1
|
||||
bs = EyeOpen_R = Reye1.EyeOut_R = 1
|
||||
bs = LipsLowerDown_R = Mouth.LipsLowerDown = 0.43
|
||||
bs = LipsStretch_R = Mouth.LipsStretch_R = 1
|
||||
bs = MouthSmile_R = Mouth.MouthSmile_R = 1
|
||||
bs = LipsFunnel = Mouth.LipsFunnel = 1
|
||||
bs = EyeUp_L = Leye1.EyeUp_L = 1
|
||||
bs = MouthDimple_L = Mouth.MouthDimple_L = 1
|
||||
bs = Puff = Mouth.Puff = 1
|
||||
bs = EyeIn_L = Leye1.EyeIn_L = 1
|
||||
bs = EyeUp_R = Reye1.EyeUp_R = 0.99
|
||||
bs = MouthDimple_R = Mouth.MouthDimple_R = 1
|
||||
bs = MouthRight = Mouth.MouthRight = 1
|
||||
bs = EyeOut_L = Leye1.EyeOut_L = 1
|
||||
bs = JawOpen = Mouth.JawOpen = 1
|
||||
bs = EyeIn_R = Reye1.EyeIn_R = 1
|
||||
bs = BrowsD_L = Leye1.BrowsD_L = 1
|
||||
bs = EyeDown_L = Leye1.EyeDown_L = 1
|
||||
bs = EyeBlink_L = Leye1.EyeBlink_L = 1
|
||||
bs = EyeOut_R = Reye1.EyeOut_R = 1
|
||||
bs = LipsUpperUp_L = Mouth.LipsUpperUp = 0.49
|
||||
bs = MouthFrown_L = Mouth.MouthFrown_L = 1
|
||||
bs = EyeDown_R = Reye1.EyeDown_R = 1
|
||||
bs = BrowsD_R = Reye1.BrowsD_R = 1
|
||||
bs = EyeBlink_R = Reye1.EyeBlink_R = 1
|
||||
bs = LipsUpperUp_R = Mouth.LipsUpperUp = 0.47
|
||||
bs = Sneer_L = Mouth.Sneer = 0.5
|
||||
jointIndex = headphone = 7
|
||||
jointIndex = LeftUpLeg = 15
|
||||
jointIndex = Spine = 20
|
||||
jointIndex = LeftArm = 32
|
||||
jointIndex = Head = 40
|
||||
jointIndex = RightUpLeg = 10
|
||||
jointIndex = hair = 5
|
||||
jointIndex = Spine1 = 21
|
||||
jointIndex = RightHandIndex1 = 27
|
||||
jointIndex = Spine2 = 22
|
||||
jointIndex = RightHandIndex2 = 28
|
||||
jointIndex = RightHandIndex3 = 29
|
||||
jointIndex = RightHandIndex4 = 30
|
||||
jointIndex = RightToe_End = 14
|
||||
jointIndex = shield = 4
|
||||
jointIndex = LeftHandIndex1 = 35
|
||||
jointIndex = LeftHandIndex2 = 36
|
||||
jointIndex = RightHand = 26
|
||||
jointIndex = LeftHandIndex3 = 37
|
||||
jointIndex = LeftHandIndex4 = 38
|
||||
jointIndex = LeftShoulder = 31
|
||||
jointIndex = LeftHand = 34
|
||||
jointIndex = RightForeArm = 25
|
||||
jointIndex = RightLeg = 11
|
||||
jointIndex = RightFoot = 12
|
||||
jointIndex = mouth = 1
|
||||
jointIndex = LeftToe_End = 19
|
||||
jointIndex = Reye = 2
|
||||
jointIndex = Hips = 9
|
||||
jointIndex = RightToeBase = 13
|
||||
jointIndex = HeadTop_End = 41
|
||||
jointIndex = LeftFoot = 17
|
||||
jointIndex = RightShoulder = 23
|
||||
jointIndex = LeftLeg = 16
|
||||
jointIndex = Leye = 3
|
||||
jointIndex = LeftForeArm = 33
|
||||
jointIndex = face = 0
|
||||
jointIndex = body = 8
|
||||
jointIndex = LeftToeBase = 18
|
||||
jointIndex = RightArm = 24
|
||||
jointIndex = top1 = 6
|
||||
jointIndex = Neck = 39
|
||||
rx = 0
|
||||
ry = 0
|
||||
rz = 0
|
||||
tx = 0
|
||||
ty = 0
|
||||
tz = 0
|
||||
bs = MouthFrown_L = Frown_Left = 1
|
||||
bs = MouthLeft = Midmouth_Left = 1
|
||||
bs = BrowsU_R = BrowsUp_Right = 1
|
||||
bs = ChinUpperRaise = UpperLipUp_Right = 0.5
|
||||
bs = ChinUpperRaise = UpperLipUp_Left = 0.5
|
||||
bs = MouthSmile_R = Smile_Right = 1
|
||||
bs = MouthDimple_L = Smile_Left = 0.25
|
||||
bs = EyeBlink_L = Blink_Left = 1
|
||||
bs = BrowsD_L = BrowsDown_Left = 1
|
||||
bs = MouthFrown_R = Frown_Right = 1
|
||||
bs = MouthDimple_R = Smile_Right = 0.25
|
||||
bs = Sneer = Squint_Right = 0.5
|
||||
bs = Sneer = Squint_Left = 0.5
|
||||
bs = Sneer = NoseScrunch_Right = 0.75
|
||||
bs = Sneer = NoseScrunch_Left = 0.75
|
||||
bs = EyeSquint_L = Squint_Left = 1
|
||||
bs = EyeBlink_R = Blink_Right = 1
|
||||
bs = JawLeft = JawRotateY_Left = 0.5
|
||||
bs = BrowsD_R = BrowsDown_Right = 1
|
||||
bs = EyeSquint_R = Squint_Right = 1
|
||||
bs = Puff = CheekPuff_Right = 1
|
||||
bs = Puff = CheekPuff_Left = 1
|
||||
bs = LipsUpperClose = UpperLipIn = 1
|
||||
bs = JawOpen = MouthOpen = 0.69999999999999996
|
||||
bs = LipsUpperUp = UpperLipUp_Right = 0.69999999999999996
|
||||
bs = LipsUpperUp = UpperLipUp_Left = 0.69999999999999996
|
||||
bs = LipsLowerDown = LowerLipDown_Right = 0.69999999999999996
|
||||
bs = LipsLowerDown = LowerLipDown_Left = 0.69999999999999996
|
||||
bs = LipsLowerOpen = LowerLipOut = 1
|
||||
bs = EyeOpen_L = EyesWide_Left = 1
|
||||
bs = LipsPucker = MouthNarrow_Right = 1
|
||||
bs = LipsPucker = MouthNarrow_Left = 1
|
||||
bs = EyeOpen_R = EyesWide_Right = 1
|
||||
bs = JawRight = Jaw_Right = 1
|
||||
bs = MouthRight = Midmouth_Right = 1
|
||||
bs = ChinLowerRaise = Jaw_Up = 1
|
||||
bs = LipsUpperOpen = UpperLipOut = 1
|
||||
bs = BrowsU_C = BrowsUp_Right = 1
|
||||
bs = BrowsU_C = BrowsUp_Left = 1
|
||||
bs = JawFwd = JawForeward = 1
|
||||
bs = BrowsU_L = BrowsUp_Left = 1
|
||||
bs = MouthSmile_L = Smile_Left = 1
|
||||
bs = LipsLowerClose = LowerLipIn = 1
|
||||
bs = LipsFunnel = TongueUp = 1
|
||||
bs = LipsFunnel = MouthWhistle_NarrowAdjust_Right = 0.5
|
||||
bs = LipsFunnel = MouthWhistle_NarrowAdjust_Left = 0.5
|
||||
bs = LipsFunnel = MouthNarrow_Right = 1
|
||||
bs = LipsFunnel = MouthNarrow_Left = 1
|
||||
bs = LipsFunnel = Jaw_Down = 0.35999999999999999
|
||||
bs = LipsFunnel = JawForeward = 0.39000000000000001
|
||||
jointIndex = LeftHandIndex1 = 50
|
||||
jointIndex = LeftHandIndex2 = 51
|
||||
jointIndex = LeftHandIndex3 = 52
|
||||
jointIndex = LeftHandIndex4 = 53
|
||||
jointIndex = Spine1 = 12
|
||||
jointIndex = Spine2 = 13
|
||||
jointIndex = RightHandThumb1 = 18
|
||||
jointIndex = RightHandThumb2 = 19
|
||||
jointIndex = RightHandThumb3 = 20
|
||||
jointIndex = RightHandThumb4 = 21
|
||||
jointIndex = LeftFoot = 8
|
||||
jointIndex = LeftForeArm = 40
|
||||
jointIndex = Neck = 62
|
||||
jointIndex = Head = 63
|
||||
jointIndex = Hips = 0
|
||||
jointIndex = RightHandPinky1 = 30
|
||||
jointIndex = RightHandPinky2 = 31
|
||||
jointIndex = RightHandPinky3 = 32
|
||||
jointIndex = RightHandPinky4 = 33
|
||||
jointIndex = RightLeg = 2
|
||||
jointIndex = RightForeArm = 16
|
||||
jointIndex = LeftHandRing1 = 46
|
||||
jointIndex = LeftHandRing2 = 47
|
||||
jointIndex = LeftHandRing3 = 48
|
||||
jointIndex = LeftHandRing4 = 49
|
||||
jointIndex = LeftHandThumb1 = 54
|
||||
jointIndex = LeftHandThumb2 = 55
|
||||
jointIndex = LeftHandThumb3 = 56
|
||||
jointIndex = LeftHandThumb4 = 57
|
||||
jointIndex = HeadTop_End = 66
|
||||
jointIndex = LeftUpLeg = 6
|
||||
jointIndex = LeftToeBase = 9
|
||||
jointIndex = LeftHandPinky1 = 42
|
||||
jointIndex = LeftHandPinky2 = 43
|
||||
jointIndex = LeftHandPinky3 = 44
|
||||
jointIndex = LeftHandPinky4 = 45
|
||||
jointIndex = LeftLeg = 7
|
||||
jointIndex = RightEye = 65
|
||||
jointIndex = RightHand = 17
|
||||
jointIndex = RightToeBase = 4
|
||||
jointIndex = RightUpLeg = 1
|
||||
jointIndex = RightArm = 15
|
||||
jointIndex = RightHandRing1 = 26
|
||||
jointIndex = RightHandRing2 = 27
|
||||
jointIndex = RightHandRing3 = 28
|
||||
jointIndex = RightHandRing4 = 29
|
||||
jointIndex = RightHandIndex1 = 22
|
||||
jointIndex = RightHandIndex2 = 23
|
||||
jointIndex = RightHandIndex3 = 24
|
||||
jointIndex = RightHandIndex4 = 25
|
||||
jointIndex = LeftToe_End = 10
|
||||
jointIndex = LeftHandMiddle1 = 58
|
||||
jointIndex = LeftHandMiddle2 = 59
|
||||
jointIndex = LeftHandMiddle3 = 60
|
||||
jointIndex = LeftShoulder = 38
|
||||
jointIndex = LeftHandMiddle4 = 61
|
||||
jointIndex = RightFoot = 3
|
||||
jointIndex = LeftHand = 41
|
||||
jointIndex = RightHandMiddle1 = 34
|
||||
jointIndex = RightHandMiddle2 = 35
|
||||
jointIndex = RightHandMiddle3 = 36
|
||||
jointIndex = RightShoulder = 14
|
||||
jointIndex = LeftEye = 64
|
||||
jointIndex = RightHandMiddle4 = 37
|
||||
jointIndex = Body = 67
|
||||
jointIndex = LeftArm = 39
|
||||
jointIndex = RightToe_End = 5
|
||||
jointIndex = Spine = 11
|
||||
|
|
Before Width: | Height: | Size: 4.6 KiB |
|
@ -1,45 +0,0 @@
|
|||
# faceshift target mapping file
|
||||
name= defaultAvatar_head
|
||||
filename=defaultAvatar/head.fbx
|
||||
texdir=defaultAvatar
|
||||
scale=5.333
|
||||
rx=0
|
||||
ry=0
|
||||
rz=0
|
||||
tx=0
|
||||
ty=0
|
||||
tz=0
|
||||
joint = jointNeck = jointNeck
|
||||
bs = BrowsD_L = Leye1.BrowsD_L = 0.97
|
||||
bs = BrowsD_R = Reye1.BrowsD_R = 1
|
||||
bs = CheekSquint_L = Leye1.CheekSquint_L = 1
|
||||
bs = CheekSquint_R = Reye1.CheekSquint_R = 1
|
||||
bs = EyeBlink_L = Leye1.EyeBlink_L = 1
|
||||
bs = EyeBlink_R = Reye1.EyeBlink_R = 1
|
||||
bs = EyeDown_L = Leye1.EyeDown_L = 1
|
||||
bs = EyeDown_R = Reye1.EyeDown_R = 0.99
|
||||
bs = EyeIn_L = Leye1.EyeIn_L = 0.92
|
||||
bs = EyeIn_R = Reye1.EyeIn_R = 1
|
||||
bs = EyeOpen_L = Leye1.EyeOpen_L = 1
|
||||
bs = EyeOpen_R = Reye1.EyeOpen_R = 1
|
||||
bs = EyeOut_L = Leye1.EyeOut_L = 0.99
|
||||
bs = EyeOut_R = Reye1.EyeOut_R = 1
|
||||
bs = EyeUp_L = Leye1.EyeUp_L = 0.93
|
||||
bs = EyeUp_R = Reye1.EyeUp_R = 1
|
||||
bs = JawOpen = Mouth.JawOpen = 1
|
||||
bs = LipsFunnel = Mouth.LipsFunnel = 1
|
||||
bs = LipsLowerDown = Mouth.LipsLowerDown = 1
|
||||
bs = LipsPucker = Mouth.LipsPucker = 1
|
||||
bs = LipsStretch_L = Mouth.LipsStretch_L = 0.96
|
||||
bs = LipsStretch_R = Mouth.LipsStretch_R = 1
|
||||
bs = LipsUpperUp = Mouth.LipsUpperUp = 1
|
||||
bs = MouthDimple_L = Mouth.MouthDimple_L = 1
|
||||
bs = MouthDimple_R = Mouth.MouthDimple_R = 1
|
||||
bs = MouthFrown_L = Mouth.MouthFrown_L = 1
|
||||
bs = MouthFrown_R = Mouth.MouthFrown_R = 1
|
||||
bs = MouthLeft = Mouth.MouthLeft = 1
|
||||
bs = MouthRight = Mouth.MouthRight = 1
|
||||
bs = MouthSmile_L = Mouth.MouthSmile_L = 1
|
||||
bs = MouthSmile_R = Mouth.MouthSmile_R = 1
|
||||
bs = Puff = Mouth.Puff = 1
|
||||
bs = Sneer = Mouth.Sneer = 1
|
|
@ -24,7 +24,6 @@ Window {
|
|||
title: "Asset Browser"
|
||||
resizable: true
|
||||
destroyOnInvisible: true
|
||||
x: 40; y: 40
|
||||
implicitWidth: 384; implicitHeight: 640
|
||||
minSize: Qt.vector2d(200, 300)
|
||||
|
||||
|
@ -330,9 +329,10 @@ Window {
|
|||
HifiControls.ContentSection {
|
||||
id: assetDirectory
|
||||
name: "Asset Directory"
|
||||
spacing: hifi.dimensions.contentSpacing.y
|
||||
isFirst: true
|
||||
|
||||
HifiControls.VerticalSpacer {}
|
||||
|
||||
Row {
|
||||
id: buttonRow
|
||||
anchors.left: parent.left
|
||||
|
@ -343,8 +343,7 @@ Window {
|
|||
glyph: hifi.glyphs.reload
|
||||
color: hifi.buttons.white
|
||||
colorScheme: root.colorScheme
|
||||
height: 26
|
||||
width: 26
|
||||
width: hifi.dimensions.controlLineHeight
|
||||
|
||||
onClicked: root.reload()
|
||||
}
|
||||
|
@ -353,7 +352,6 @@ Window {
|
|||
text: "ADD TO WORLD"
|
||||
color: hifi.buttons.white
|
||||
colorScheme: root.colorScheme
|
||||
height: 26
|
||||
width: 120
|
||||
|
||||
enabled: canAddToWorld(assetProxyModel.data(treeView.selection.currentIndex, 0x100))
|
||||
|
@ -365,7 +363,6 @@ Window {
|
|||
text: "RENAME"
|
||||
color: hifi.buttons.white
|
||||
colorScheme: root.colorScheme
|
||||
height: 26
|
||||
width: 80
|
||||
|
||||
onClicked: root.renameFile()
|
||||
|
@ -378,7 +375,6 @@ Window {
|
|||
text: "DELETE"
|
||||
color: hifi.buttons.red
|
||||
colorScheme: root.colorScheme
|
||||
height: 26
|
||||
width: 80
|
||||
|
||||
onClicked: root.deleteFile()
|
||||
|
@ -419,7 +415,7 @@ Window {
|
|||
id: treeView
|
||||
anchors.top: assetDirectory.bottom
|
||||
anchors.bottom: uploadSection.top
|
||||
anchors.margins: 12
|
||||
anchors.margins: hifi.dimensions.contentMargin.x + 2 // Extra for border
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
|
@ -448,7 +444,7 @@ Window {
|
|||
name: "Upload A File"
|
||||
spacing: hifi.dimensions.contentSpacing.y
|
||||
anchors.bottom: parent.bottom
|
||||
height: 92
|
||||
height: 95
|
||||
|
||||
Item {
|
||||
height: parent.height
|
||||
|
|
|
@ -25,7 +25,7 @@ Hifi.AvatarInputs {
|
|||
readonly property int iconPadding: 5
|
||||
|
||||
readonly property bool shouldReposition: true
|
||||
|
||||
|
||||
Settings {
|
||||
category: "Overlay.AvatarInputs"
|
||||
property alias x: root.x
|
||||
|
|
|
@ -22,4 +22,19 @@ Windows.Window {
|
|||
url: infoView.url
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
centerWindow(root);
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
centerWindow(root);
|
||||
}
|
||||
}
|
||||
|
||||
function centerWindow() {
|
||||
desktop.centerOnVisible(root);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ Window {
|
|||
title: "Edit"
|
||||
property alias tabView: tabView
|
||||
implicitWidth: 520; implicitHeight: 695
|
||||
minSize: Qt.vector2d(412, 500)
|
||||
minSize: Qt.vector2d(456, 500)
|
||||
|
||||
HifiConstants { id: hifi }
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ Original.Button {
|
|||
property int colorScheme: hifi.colorSchemes.light
|
||||
|
||||
width: 120
|
||||
height: 28
|
||||
height: hifi.dimensions.controlLineHeight
|
||||
|
||||
style: ButtonStyle {
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ FocusScope {
|
|||
id: comboBox
|
||||
anchors.fill: parent
|
||||
visible: false
|
||||
height: hifi.fontSizes.textFieldInput + 14 // Match height of TextField control.
|
||||
height: hifi.fontSizes.textFieldInput + 13 // Match height of TextField control.
|
||||
}
|
||||
|
||||
FiraSansSemiBold {
|
||||
|
|
|
@ -46,7 +46,7 @@ Column {
|
|||
Item {
|
||||
id: leadingSpace
|
||||
width: 1
|
||||
height: isFirst ? hifi.dimensions.contentSpacing.y : 0
|
||||
height: isFirst ? 7 : 0
|
||||
anchors.top: parent.top
|
||||
}
|
||||
|
||||
|
@ -80,14 +80,14 @@ Column {
|
|||
right: parent.right
|
||||
top: topBar.bottom
|
||||
}
|
||||
height: (isCollapsible ? 3 : 2) * hifi.dimensions.contentSpacing.y
|
||||
height: isCollapsible ? 36 : 28
|
||||
|
||||
RalewayRegular {
|
||||
id: title
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
topMargin: hifi.dimensions.contentSpacing.y
|
||||
topMargin: 12
|
||||
}
|
||||
size: hifi.fontSizes.sectionName
|
||||
font.capitalization: Font.AllUppercase
|
||||
|
|
|
@ -28,7 +28,7 @@ SpinBox {
|
|||
FontLoader { id: firaSansSemiBold; source: "../../fonts/FiraSans-SemiBold.ttf"; }
|
||||
font.family: firaSansSemiBold.name
|
||||
font.pixelSize: hifi.fontSizes.textFieldInput
|
||||
height: hifi.fontSizes.textFieldInput + 14 // Match height of TextField control.
|
||||
height: hifi.fontSizes.textFieldInput + 13 // Match height of TextField control.
|
||||
|
||||
y: spinBoxLabel.visible ? spinBoxLabel.height + spinBoxLabel.anchors.bottomMargin : 0
|
||||
|
||||
|
@ -51,12 +51,13 @@ SpinBox {
|
|||
horizontalAlignment: Qt.AlignLeft
|
||||
padding.left: spinBoxLabelInside.visible ? 30 : hifi.dimensions.textPadding
|
||||
padding.right: hifi.dimensions.spinnerSize
|
||||
padding.top: 0
|
||||
|
||||
incrementControl: HiFiGlyphs {
|
||||
id: incrementButton
|
||||
text: hifi.glyphs.caratUp
|
||||
x: 6
|
||||
y: 2
|
||||
y: 1
|
||||
size: hifi.dimensions.spinnerSize
|
||||
color: styleData.upPressed ? (isLightColorScheme ? hifi.colors.black : hifi.colors.white) : hifi.colors.gray
|
||||
}
|
||||
|
|
67
interface/resources/qml/controls-uit/TextAction.qml
Normal file
|
@ -0,0 +1,67 @@
|
|||
//
|
||||
// TextField.qml
|
||||
//
|
||||
// Created by David Rowe on 21 Apr 2016
|
||||
// Copyright 2016 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
|
||||
//
|
||||
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
|
||||
import "../styles-uit"
|
||||
import "../controls-uit" as HifiControls
|
||||
|
||||
Item {
|
||||
property string icon: ""
|
||||
property int iconSize: 30
|
||||
property string text: ""
|
||||
|
||||
property int colorScheme: hifi.colorSchemes.light
|
||||
readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light
|
||||
|
||||
signal clicked()
|
||||
|
||||
height: Math.max(glyph.visible ? glyph.height - 4 : 0, string.visible ? string.height : 0)
|
||||
width: glyph.width + string.anchors.leftMargin + string.width
|
||||
|
||||
HiFiGlyphs {
|
||||
id: glyph
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: -2
|
||||
text: parent.icon
|
||||
size: parent.iconSize
|
||||
color: isLightColorScheme
|
||||
? (mouseArea.containsMouse ? hifi.colors.baseGrayHighlight : hifi.colors.lightGray)
|
||||
: (mouseArea.containsMouse ? hifi.colors.faintGray : hifi.colors.lightGrayText)
|
||||
visible: text !== ""
|
||||
width: visible ? implicitWidth : 0
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
id: string
|
||||
anchors {
|
||||
left: glyph.visible ? glyph.right : parent.left
|
||||
leftMargin: visible && glyph.visible ? hifi.dimensions.contentSpacing.x : 0
|
||||
verticalCenter: glyph.visible ? glyph.verticalCenter : undefined
|
||||
}
|
||||
text: parent.text
|
||||
size: hifi.fontSizes.inputLabel
|
||||
color: isLightColorScheme
|
||||
? (mouseArea.containsMouse ? hifi.colors.baseGrayHighlight : hifi.colors.lightGray)
|
||||
: (mouseArea.containsMouse ? hifi.colors.faintGray : hifi.colors.lightGrayText)
|
||||
font.underline: true;
|
||||
visible: text !== ""
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: parent.clicked()
|
||||
}
|
||||
}
|
|
@ -20,15 +20,17 @@ TextField {
|
|||
|
||||
property int colorScheme: hifi.colorSchemes.light
|
||||
readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light
|
||||
property bool isSearchField: false
|
||||
property string label: ""
|
||||
property real controlHeight: height + (textFieldLabel.visible ? textFieldLabel.height : 0)
|
||||
property real controlHeight: height + (textFieldLabel.visible ? textFieldLabel.height + 1 : 0)
|
||||
|
||||
placeholderText: textField.placeholderText
|
||||
|
||||
FontLoader { id: firaSansSemiBold; source: "../../fonts/FiraSans-SemiBold.ttf"; }
|
||||
font.family: firaSansSemiBold.name
|
||||
font.pixelSize: hifi.fontSizes.textFieldInput
|
||||
height: implicitHeight + 4 // Make surrounding box higher so that highlight is vertically centered.
|
||||
font.italic: textField.text == ""
|
||||
height: implicitHeight + 3 // Make surrounding box higher so that highlight is vertically centered.
|
||||
|
||||
y: textFieldLabel.visible ? textFieldLabel.height + textFieldLabel.anchors.bottomMargin : 0
|
||||
|
||||
|
@ -42,11 +44,22 @@ TextField {
|
|||
: (textField.focus ? hifi.colors.black : hifi.colors.baseGrayShadow)
|
||||
border.color: hifi.colors.primaryHighlight
|
||||
border.width: textField.focus ? 1 : 0
|
||||
radius: isSearchField ? textField.height / 2 : 0
|
||||
|
||||
HiFiGlyphs {
|
||||
text: hifi.glyphs.search
|
||||
color: textColor
|
||||
size: hifi.fontSizes.textFieldSearchIcon
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.leftMargin: hifi.dimensions.textPadding - 2
|
||||
visible: isSearchField
|
||||
}
|
||||
}
|
||||
placeholderTextColor: hifi.colors.lightGray
|
||||
selectedTextColor: hifi.colors.black
|
||||
selectionColor: hifi.colors.primaryHighlight
|
||||
padding.left: hifi.dimensions.textPadding
|
||||
padding.left: (isSearchField ? textField.height - 2 : 0) + hifi.dimensions.textPadding
|
||||
padding.right: hifi.dimensions.textPadding
|
||||
}
|
||||
|
||||
|
@ -56,7 +69,7 @@ TextField {
|
|||
colorScheme: textField.colorScheme
|
||||
anchors.left: parent.left
|
||||
anchors.bottom: parent.top
|
||||
anchors.bottomMargin: 4
|
||||
anchors.bottomMargin: 3
|
||||
visible: label != ""
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,9 @@ FocusScope {
|
|||
objectName: "desktop"
|
||||
anchors.fill: parent
|
||||
|
||||
property rect recommendedRect: rect(0,0,0,0);
|
||||
readonly property int invalid_position: -9999;
|
||||
property rect recommendedRect: Qt.rect(0,0,0,0);
|
||||
property var expectedChildren;
|
||||
|
||||
onHeightChanged: d.handleSizeChanged();
|
||||
|
||||
|
@ -55,13 +57,18 @@ FocusScope {
|
|||
|
||||
function handleSizeChanged() {
|
||||
var oldRecommendedRect = recommendedRect;
|
||||
var newRecommendedRectJS = Controller.getRecommendedOverlayRect();
|
||||
var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedOverlayRect();
|
||||
var newRecommendedRect = Qt.rect(newRecommendedRectJS.x, newRecommendedRectJS.y,
|
||||
newRecommendedRectJS.width,
|
||||
newRecommendedRectJS.height);
|
||||
|
||||
if (oldRecommendedRect != Qt.rect(0,0,0,0)
|
||||
&& oldRecommendedRect != newRecommendedRect) {
|
||||
var oldChildren = expectedChildren;
|
||||
var newChildren = d.getRepositionChildren();
|
||||
if (oldRecommendedRect != Qt.rect(0,0,0,0)
|
||||
&& (oldRecommendedRect != newRecommendedRect
|
||||
|| oldChildren != newChildren)
|
||||
) {
|
||||
expectedChildren = newChildren;
|
||||
d.repositionAll();
|
||||
}
|
||||
recommendedRect = newRecommendedRect;
|
||||
|
@ -279,13 +286,56 @@ FocusScope {
|
|||
targetWindow.focus = true;
|
||||
}
|
||||
|
||||
showDesktop();
|
||||
}
|
||||
|
||||
function centerOnVisible(item) {
|
||||
var targetWindow = d.getDesktopWindow(item);
|
||||
if (!targetWindow) {
|
||||
console.warn("Could not find top level window for " + item);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof Controller === "undefined") {
|
||||
console.warn("Controller not yet available... can't center");
|
||||
return;
|
||||
}
|
||||
|
||||
var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedOverlayRect();
|
||||
var newRecommendedRect = Qt.rect(newRecommendedRectJS.x, newRecommendedRectJS.y,
|
||||
newRecommendedRectJS.width,
|
||||
newRecommendedRectJS.height);
|
||||
var newRecommendedDimmensions = { x: newRecommendedRect.width, y: newRecommendedRect.height };
|
||||
var newX = newRecommendedRect.x + ((newRecommendedRect.width - targetWindow.width) / 2);
|
||||
var newY = newRecommendedRect.y + ((newRecommendedRect.height - targetWindow.height) / 2);
|
||||
targetWindow.x = newX;
|
||||
targetWindow.y = newY;
|
||||
|
||||
// If we've noticed that our recommended desktop rect has changed, record that change here.
|
||||
if (recommendedRect != newRecommendedRect) {
|
||||
recommendedRect = newRecommendedRect;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function repositionOnVisible(item) {
|
||||
var targetWindow = d.getDesktopWindow(item);
|
||||
if (!targetWindow) {
|
||||
console.warn("Could not find top level window for " + item);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof Controller === "undefined") {
|
||||
console.warn("Controller not yet available... can't reposition targetWindow:" + targetWindow);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var oldRecommendedRect = recommendedRect;
|
||||
var oldRecommendedDimmensions = { x: oldRecommendedRect.width, y: oldRecommendedRect.height };
|
||||
var newRecommendedRect = Controller.getRecommendedOverlayRect();
|
||||
var newRecommendedDimmensions = { x: newRecommendedRect.width, y: newRecommendedRect.height };
|
||||
repositionWindow(targetWindow, false, oldRecommendedRect, oldRecommendedDimmensions, newRecommendedRect, newRecommendedDimmensions);
|
||||
|
||||
showDesktop();
|
||||
}
|
||||
|
||||
function repositionWindow(targetWindow, forceReposition,
|
||||
|
@ -324,10 +374,8 @@ FocusScope {
|
|||
}
|
||||
var fractionX = Utils.clamp(originRelativeX / oldRecommendedDimmensions.x, 0, 1);
|
||||
var fractionY = Utils.clamp(originRelativeY / oldRecommendedDimmensions.y, 0, 1);
|
||||
|
||||
var newX = (fractionX * newRecommendedDimmensions.x) + newRecommendedRect.x;
|
||||
var newY = (fractionY * newRecommendedDimmensions.y) + newRecommendedRect.y;
|
||||
|
||||
newPosition = Qt.vector2d(newX, newY);
|
||||
}
|
||||
targetWindow.x = newPosition.x;
|
||||
|
|
|
@ -51,7 +51,11 @@ Window {
|
|||
|
||||
Rectangle {
|
||||
id: attachmentsBackground
|
||||
anchors { left: parent.left; right: parent.right; top: parent.top; bottom: newAttachmentButton.top; margins: 8 }
|
||||
anchors {
|
||||
left: parent.left; right: parent.right; top: parent.top; bottom: newAttachmentButton.top;
|
||||
margins: hifi.dimensions.contentMargin.x
|
||||
bottomMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
color: hifi.colors.baseGrayShadow
|
||||
radius: 4
|
||||
|
||||
|
@ -129,7 +133,14 @@ Window {
|
|||
|
||||
HifiControls.Button {
|
||||
id: newAttachmentButton
|
||||
anchors { left: parent.left; right: parent.right; bottom: buttonRow.top; margins: 8 }
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: buttonRow.top
|
||||
margins: hifi.dimensions.contentMargin.x;
|
||||
topMargin: hifi.dimensions.contentSpacing.y
|
||||
bottomMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
text: "New Attachment"
|
||||
color: hifi.buttons.black
|
||||
colorScheme: hifi.colorSchemes.dark
|
||||
|
@ -151,7 +162,13 @@ Window {
|
|||
Row {
|
||||
id: buttonRow
|
||||
spacing: 8
|
||||
anchors { right: parent.right; bottom: parent.bottom; margins: 8 }
|
||||
anchors {
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
margins: hifi.dimensions.contentMargin.x
|
||||
topMargin: hifi.dimensions.contentSpacing.y
|
||||
bottomMargin: hifi.dimensions.contentSpacing.y
|
||||
}
|
||||
HifiControls.Button {
|
||||
action: okAction
|
||||
color: hifi.buttons.black
|
||||
|
|
|
@ -23,8 +23,8 @@ Window {
|
|||
title: "Running Scripts"
|
||||
resizable: true
|
||||
destroyOnInvisible: true
|
||||
x: 40; y: 40
|
||||
implicitWidth: 400; implicitHeight: 695
|
||||
implicitWidth: 400
|
||||
implicitHeight: isHMD ? 695 : 728
|
||||
minSize: Qt.vector2d(200, 300)
|
||||
|
||||
HifiConstants { id: hifi }
|
||||
|
@ -32,6 +32,7 @@ Window {
|
|||
property var scripts: ScriptDiscoveryService;
|
||||
property var scriptsModel: scripts.scriptsModelFilter
|
||||
property var runningScriptsModel: ListModel { }
|
||||
property bool isHMD: false
|
||||
|
||||
Settings {
|
||||
category: "Overlay.RunningScripts"
|
||||
|
@ -44,7 +45,10 @@ Window {
|
|||
onScriptCountChanged: updateRunningScripts();
|
||||
}
|
||||
|
||||
Component.onCompleted: updateRunningScripts()
|
||||
Component.onCompleted: {
|
||||
isHMD = HMD.active;
|
||||
updateRunningScripts();
|
||||
}
|
||||
|
||||
function setDefaultFocus() {
|
||||
// Work around FocusScope of scrollable window.
|
||||
|
@ -109,7 +113,9 @@ Window {
|
|||
}
|
||||
}
|
||||
|
||||
HifiControls.VerticalSpacer {}
|
||||
HifiControls.VerticalSpacer {
|
||||
height: hifi.dimensions.controlInterlineHeight + 2 // Add space for border
|
||||
}
|
||||
|
||||
HifiControls.Table {
|
||||
tableModel: runningScriptsModel
|
||||
|
@ -120,7 +126,7 @@ Window {
|
|||
}
|
||||
|
||||
HifiControls.VerticalSpacer {
|
||||
height: hifi.dimensions.controlInterlineHeight + 2 // Table view draws a little taller than it's height.
|
||||
height: hifi.dimensions.controlInterlineHeight + 2 // Add space for border
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,16 +181,19 @@ Window {
|
|||
|
||||
HifiControls.TextField {
|
||||
id: filterEdit
|
||||
isSearchField: true
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
focus: true
|
||||
colorScheme: hifi.colorSchemes.dark
|
||||
placeholderText: "filter"
|
||||
placeholderText: "Filter"
|
||||
onTextChanged: scriptsModel.filterRegExp = new RegExp("^.*" + text + ".*$", "i")
|
||||
Component.onCompleted: scriptsModel.filterRegExp = new RegExp("^.*$", "i")
|
||||
}
|
||||
|
||||
HifiControls.VerticalSpacer {}
|
||||
HifiControls.VerticalSpacer {
|
||||
height: hifi.dimensions.controlInterlineHeight + 2 // Add space for border
|
||||
}
|
||||
|
||||
HifiControls.Tree {
|
||||
id: treeView
|
||||
|
@ -195,7 +204,9 @@ Window {
|
|||
anchors.right: parent.right
|
||||
}
|
||||
|
||||
HifiControls.VerticalSpacer {}
|
||||
HifiControls.VerticalSpacer {
|
||||
height: hifi.dimensions.controlInterlineHeight + 2 // Add space for border
|
||||
}
|
||||
|
||||
HifiControls.TextField {
|
||||
id: selectedScript
|
||||
|
@ -236,7 +247,25 @@ Window {
|
|||
}
|
||||
}
|
||||
|
||||
HifiControls.VerticalSpacer { }
|
||||
HifiControls.VerticalSpacer {
|
||||
height: hifi.dimensions.controlInterlineHeight - (!isHMD ? 3 : 0)
|
||||
}
|
||||
|
||||
HifiControls.TextAction {
|
||||
id: directoryButton
|
||||
icon: hifi.glyphs.script
|
||||
iconSize: 24
|
||||
text: "Reveal Scripts Folder"
|
||||
onClicked: fileDialogHelper.openDirectory(scripts.defaultScriptsPath)
|
||||
colorScheme: hifi.colorSchemes.dark
|
||||
anchors.left: parent.left
|
||||
visible: !isHMD
|
||||
}
|
||||
|
||||
HifiControls.VerticalSpacer {
|
||||
height: hifi.dimensions.controlInterlineHeight - 3
|
||||
visible: !isHMD
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,8 +131,8 @@ Item {
|
|||
readonly property bool largeScreen: Screen.width >= 1920 && Screen.height >= 1080
|
||||
readonly property real borderRadius: largeScreen ? 7.5 : 5.0
|
||||
readonly property real borderWidth: largeScreen ? 2 : 1
|
||||
readonly property vector2d contentMargin: Qt.vector2d(12, 24)
|
||||
readonly property vector2d contentSpacing: Qt.vector2d(8, 12)
|
||||
readonly property vector2d contentMargin: Qt.vector2d(21, 21)
|
||||
readonly property vector2d contentSpacing: Qt.vector2d(11, 14)
|
||||
readonly property real labelPadding: 40
|
||||
readonly property real textPadding: 8
|
||||
readonly property real sliderHandleSize: 18
|
||||
|
@ -143,8 +143,8 @@ Item {
|
|||
readonly property real tableHeaderHeight: 40
|
||||
readonly property vector2d modalDialogMargin: Qt.vector2d(50, 30)
|
||||
readonly property real modalDialogTitleHeight: 40
|
||||
readonly property real controlLineHeight: 29 // Height of spinbox control on 1920 x 1080 monitor
|
||||
readonly property real controlInterlineHeight: 22 // 75% of controlLineHeight
|
||||
readonly property real controlLineHeight: 28 // Height of spinbox control on 1920 x 1080 monitor
|
||||
readonly property real controlInterlineHeight: 21 // 75% of controlLineHeight
|
||||
readonly property vector2d menuPadding: Qt.vector2d(14, 12)
|
||||
}
|
||||
|
||||
|
@ -156,6 +156,7 @@ Item {
|
|||
readonly property real inputLabel: dimensions.largeScreen ? 14 : 10
|
||||
readonly property real textFieldInput: dimensions.largeScreen ? 15 : 12
|
||||
readonly property real textFieldInputLabel: dimensions.largeScreen ? 13 : 9
|
||||
readonly property real textFieldSearchIcon: dimensions.largeScreen ? 30 : 24
|
||||
readonly property real tableText: dimensions.largeScreen ? 15 : 12
|
||||
readonly property real buttonLabel: dimensions.largeScreen ? 13 : 9
|
||||
readonly property real iconButton: dimensions.largeScreen ? 13 : 9
|
||||
|
|
|
@ -31,7 +31,7 @@ Fadable {
|
|||
// decorations can extend outside it.
|
||||
implicitHeight: content ? content.height : 0
|
||||
implicitWidth: content ? content.width : 0
|
||||
x: -1; y: -1
|
||||
x: desktop.invalid_position; y: desktop.invalid_position;
|
||||
enabled: visible
|
||||
|
||||
signal windowDestroyed();
|
||||
|
@ -215,7 +215,7 @@ Fadable {
|
|||
bottom: parent.bottom
|
||||
}
|
||||
width: parent.contentWidth
|
||||
height: footer.height + 2 * hifi.dimensions.contentSpacing.y
|
||||
height: footer.height + 2 * hifi.dimensions.contentSpacing.y + 3
|
||||
color: hifi.colors.baseGray
|
||||
visible: footer.height > 0
|
||||
|
||||
|
@ -252,6 +252,7 @@ Fadable {
|
|||
window.parentChanged.connect(raise);
|
||||
raise();
|
||||
setDefaultFocus();
|
||||
centerOrReposition();
|
||||
}
|
||||
Component.onDestruction: {
|
||||
window.parentChanged.disconnect(raise); // Prevent warning on shutdown
|
||||
|
@ -267,6 +268,18 @@ Fadable {
|
|||
raise();
|
||||
}
|
||||
enabled = visible
|
||||
|
||||
if (visible && parent) {
|
||||
centerOrReposition();
|
||||
}
|
||||
}
|
||||
|
||||
function centerOrReposition() {
|
||||
if (x == desktop.invalid_position && y == desktop.invalid_position) {
|
||||
desktop.centerOnVisible(window);
|
||||
} else {
|
||||
desktop.repositionOnVisible(window);
|
||||
}
|
||||
}
|
||||
|
||||
function raise() {
|
||||
|
|
|
@ -19,7 +19,7 @@ Fadable {
|
|||
// decorations can extend outside it.
|
||||
implicitHeight: content ? content.height : 0
|
||||
implicitWidth: content ? content.width : 0
|
||||
x: -1; y: -1
|
||||
x: desktop.invalid_position; y: desktop.invalid_position;
|
||||
enabled: visible
|
||||
|
||||
signal windowDestroyed();
|
||||
|
@ -117,12 +117,21 @@ Fadable {
|
|||
Component.onCompleted: {
|
||||
window.parentChanged.connect(raise);
|
||||
raise();
|
||||
centerOrReposition();
|
||||
}
|
||||
Component.onDestruction: {
|
||||
window.parentChanged.disconnect(raise); // Prevent warning on shutdown
|
||||
windowDestroyed();
|
||||
}
|
||||
|
||||
function centerOrReposition() {
|
||||
if (x == desktop.invalid_position && y == desktop.invalid_position) {
|
||||
desktop.centerOnVisible(window);
|
||||
} else {
|
||||
desktop.repositionOnVisible(window);
|
||||
}
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (!visible && destroyOnInvisible) {
|
||||
destroy();
|
||||
|
@ -132,6 +141,10 @@ Fadable {
|
|||
raise();
|
||||
}
|
||||
enabled = visible
|
||||
|
||||
if (visible && parent) {
|
||||
centerOrReposition();
|
||||
}
|
||||
}
|
||||
|
||||
function raise() {
|
||||
|
|
|
@ -131,6 +131,7 @@
|
|||
#include "scripting/WebWindowClass.h"
|
||||
#include "scripting/WindowScriptingInterface.h"
|
||||
#include "scripting/ControllerScriptingInterface.h"
|
||||
#include "scripting/RatesScriptingInterface.h"
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||
#include "SpeechRecognizer.h"
|
||||
#endif
|
||||
|
@ -1384,6 +1385,7 @@ void Application::initializeUi() {
|
|||
rootContext->setContextProperty("Preferences", DependencyManager::get<Preferences>().data());
|
||||
rootContext->setContextProperty("AddressManager", DependencyManager::get<AddressManager>().data());
|
||||
rootContext->setContextProperty("FrameTimings", &_frameTimingsScriptingInterface);
|
||||
rootContext->setContextProperty("Rates", new RatesScriptingInterface(this));
|
||||
|
||||
rootContext->setContextProperty("TREE_SCALE", TREE_SCALE);
|
||||
rootContext->setContextProperty("Quat", new Quat());
|
||||
|
@ -3102,10 +3104,8 @@ void Application::updateMyAvatarLookAtPosition() {
|
|||
} else {
|
||||
// I am not looking at anyone else, so just look forward
|
||||
if (isHMD) {
|
||||
glm::mat4 headPose = myAvatar->getHMDSensorMatrix();
|
||||
glm::quat headRotation = glm::quat_cast(headPose);
|
||||
lookAtSpot = myAvatar->getPosition() +
|
||||
myAvatar->getOrientation() * (headRotation * glm::vec3(0.0f, 0.0f, -TREE_SCALE));
|
||||
glm::mat4 worldHMDMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix();
|
||||
lookAtSpot = transformPoint(worldHMDMat, glm::vec3(0.0f, 0.0f, -TREE_SCALE));
|
||||
} else {
|
||||
lookAtSpot = myAvatar->getHead()->getEyePosition() +
|
||||
(myAvatar->getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, -TREE_SCALE));
|
||||
|
@ -4315,6 +4315,7 @@ void Application::nodeKilled(SharedNodePointer node) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Application::trackIncomingOctreePacket(ReceivedMessage& message, SharedNodePointer sendingNode, bool wasStatsPacket) {
|
||||
// Attempt to identify the sender from its address.
|
||||
if (sendingNode) {
|
||||
|
@ -4439,6 +4440,8 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
|
|||
// AvatarManager has some custom types
|
||||
AvatarManager::registerMetaTypes(scriptEngine);
|
||||
|
||||
scriptEngine->registerGlobalObject("Rates", new RatesScriptingInterface(this));
|
||||
|
||||
// hook our avatar and avatar hash map object into this script engine
|
||||
scriptEngine->registerGlobalObject("MyAvatar", getMyAvatar());
|
||||
qScriptRegisterMetaType(scriptEngine, audioListenModeToScriptValue, audioListenModeFromScriptValue);
|
||||
|
|
|
@ -360,6 +360,41 @@ Menu::Menu() {
|
|||
resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionThird, 0, false));
|
||||
resolutionGroup->addAction(addCheckableActionToQMenuAndActionHash(resolutionMenu, MenuOption::RenderResolutionQuarter, 0, false));
|
||||
|
||||
//const QString = "Automatic Texture Memory";
|
||||
//const QString = "64 MB";
|
||||
//const QString = "256 MB";
|
||||
//const QString = "512 MB";
|
||||
//const QString = "1024 MB";
|
||||
//const QString = "2048 MB";
|
||||
|
||||
// Developer > Render > Resolution
|
||||
MenuWrapper* textureMenu = renderOptionsMenu->addMenu(MenuOption::RenderMaxTextureMemory);
|
||||
QActionGroup* textureGroup = new QActionGroup(textureMenu);
|
||||
textureGroup->setExclusive(true);
|
||||
textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTextureAutomatic, 0, true));
|
||||
textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture64MB, 0, false));
|
||||
textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture256MB, 0, false));
|
||||
textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture512MB, 0, false));
|
||||
textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture1024MB, 0, false));
|
||||
textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture2048MB, 0, false));
|
||||
connect(textureGroup, &QActionGroup::triggered, [textureGroup] {
|
||||
auto checked = textureGroup->checkedAction();
|
||||
auto text = checked->text();
|
||||
gpu::Context::Size newMaxTextureMemory { 0 };
|
||||
if (MenuOption::RenderMaxTexture64MB == text) {
|
||||
newMaxTextureMemory = MB_TO_BYTES(64);
|
||||
} else if (MenuOption::RenderMaxTexture256MB == text) {
|
||||
newMaxTextureMemory = MB_TO_BYTES(256);
|
||||
} else if (MenuOption::RenderMaxTexture512MB == text) {
|
||||
newMaxTextureMemory = MB_TO_BYTES(512);
|
||||
} else if (MenuOption::RenderMaxTexture1024MB == text) {
|
||||
newMaxTextureMemory = MB_TO_BYTES(1024);
|
||||
} else if (MenuOption::RenderMaxTexture2048MB == text) {
|
||||
newMaxTextureMemory = MB_TO_BYTES(2048);
|
||||
}
|
||||
gpu::Texture::setAllowedGPUMemoryUsage(newMaxTextureMemory);
|
||||
});
|
||||
|
||||
// Developer > Render > LOD Tools
|
||||
addActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::LodTools, 0, dialogsManager.data(), SLOT(lodTools()));
|
||||
|
||||
|
|
|
@ -150,6 +150,13 @@ namespace MenuOption {
|
|||
const QString RenderFocusIndicator = "Show Eye Focus";
|
||||
const QString RenderLookAtTargets = "Show Look-at Targets";
|
||||
const QString RenderLookAtVectors = "Show Look-at Vectors";
|
||||
const QString RenderMaxTextureMemory = "Maximum Texture Memory";
|
||||
const QString RenderMaxTextureAutomatic = "Automatic Texture Memory";
|
||||
const QString RenderMaxTexture64MB = "64 MB";
|
||||
const QString RenderMaxTexture256MB = "256 MB";
|
||||
const QString RenderMaxTexture512MB = "512 MB";
|
||||
const QString RenderMaxTexture1024MB = "1024 MB";
|
||||
const QString RenderMaxTexture2048MB = "2048 MB";
|
||||
const QString RenderResolution = "Scale Resolution";
|
||||
const QString RenderResolutionOne = "1";
|
||||
const QString RenderResolutionTwoThird = "2/3";
|
||||
|
|
|
@ -254,10 +254,7 @@ void AvatarManager::clearAllAvatars() {
|
|||
|
||||
QWriteLocker locker(&_hashLock);
|
||||
|
||||
_myAvatar->die();
|
||||
_myAvatar.reset();
|
||||
|
||||
_avatarHash.clear();
|
||||
handleRemovedAvatar(_myAvatar);
|
||||
}
|
||||
|
||||
void AvatarManager::setLocalLights(const QVector<AvatarManager::LocalLight>& localLights) {
|
||||
|
|
|
@ -230,7 +230,7 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) {
|
|||
}
|
||||
|
||||
_leftEyePosition = _rightEyePosition = getPosition();
|
||||
_eyePosition = calculateAverageEyePosition();
|
||||
_eyePosition = getPosition();
|
||||
|
||||
if (!billboard && _owningAvatar) {
|
||||
auto skeletonModel = static_cast<Avatar*>(_owningAvatar)->getSkeletonModel();
|
||||
|
@ -238,6 +238,8 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) {
|
|||
skeletonModel->getEyePositions(_leftEyePosition, _rightEyePosition);
|
||||
}
|
||||
}
|
||||
|
||||
_eyePosition = calculateAverageEyePosition();
|
||||
}
|
||||
|
||||
void Head::calculateMouthShapes() {
|
||||
|
|
|
@ -235,7 +235,12 @@ QByteArray MyAvatar::toByteArray(bool cullSmallChanges, bool sendAll) {
|
|||
return AvatarData::toByteArray(cullSmallChanges, sendAll);
|
||||
}
|
||||
|
||||
void MyAvatar::reset(bool andReload) {
|
||||
void MyAvatar::reset(bool andRecenter) {
|
||||
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "reset", Q_ARG(bool, andRecenter));
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset dynamic state.
|
||||
_wasPushing = _isPushing = _isBraking = false;
|
||||
|
@ -245,7 +250,7 @@ void MyAvatar::reset(bool andReload) {
|
|||
_targetVelocity = glm::vec3(0.0f);
|
||||
setThrust(glm::vec3(0.0f));
|
||||
|
||||
if (andReload) {
|
||||
if (andRecenter) {
|
||||
// derive the desired body orientation from the *old* hmd orientation, before the sensor reset.
|
||||
auto newBodySensorMatrix = deriveBodyFromHMDSensor(); // Based on current cached HMD position/rotation..
|
||||
|
||||
|
@ -317,6 +322,37 @@ void MyAvatar::update(float deltaTime) {
|
|||
}
|
||||
currentEnergy = max(0.0f, min(currentEnergy,1.0f));
|
||||
emit energyChanged(currentEnergy);
|
||||
|
||||
updateEyeContactTarget(deltaTime);
|
||||
}
|
||||
|
||||
void MyAvatar::updateEyeContactTarget(float deltaTime) {
|
||||
|
||||
_eyeContactTargetTimer -= deltaTime;
|
||||
if (_eyeContactTargetTimer < 0.0f) {
|
||||
|
||||
const float CHANCE_OF_CHANGING_TARGET = 0.01f;
|
||||
if (randFloat() < CHANCE_OF_CHANGING_TARGET) {
|
||||
|
||||
float const FIFTY_FIFTY_CHANCE = 0.5f;
|
||||
float const EYE_TO_MOUTH_CHANCE = 0.25f;
|
||||
switch (_eyeContactTarget) {
|
||||
case LEFT_EYE:
|
||||
_eyeContactTarget = (randFloat() < EYE_TO_MOUTH_CHANCE) ? MOUTH : RIGHT_EYE;
|
||||
break;
|
||||
case RIGHT_EYE:
|
||||
_eyeContactTarget = (randFloat() < EYE_TO_MOUTH_CHANCE) ? MOUTH : LEFT_EYE;
|
||||
break;
|
||||
case MOUTH:
|
||||
default:
|
||||
_eyeContactTarget = (randFloat() < FIFTY_FIFTY_CHANCE) ? RIGHT_EYE : LEFT_EYE;
|
||||
break;
|
||||
}
|
||||
|
||||
const float EYE_TARGET_DELAY_TIME = 0.33f;
|
||||
_eyeContactTargetTimer = EYE_TARGET_DELAY_TIME;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern QByteArray avatarStateToFrame(const AvatarData* _avatar);
|
||||
|
@ -936,22 +972,6 @@ void MyAvatar::clearLookAtTargetAvatar() {
|
|||
}
|
||||
|
||||
eyeContactTarget MyAvatar::getEyeContactTarget() {
|
||||
float const CHANCE_OF_CHANGING_TARGET = 0.01f;
|
||||
if (randFloat() < CHANCE_OF_CHANGING_TARGET) {
|
||||
float const FIFTY_FIFTY_CHANCE = 0.5f;
|
||||
switch (_eyeContactTarget) {
|
||||
case LEFT_EYE:
|
||||
_eyeContactTarget = (randFloat() < FIFTY_FIFTY_CHANCE) ? MOUTH : RIGHT_EYE;
|
||||
break;
|
||||
case RIGHT_EYE:
|
||||
_eyeContactTarget = (randFloat() < FIFTY_FIFTY_CHANCE) ? LEFT_EYE : MOUTH;
|
||||
break;
|
||||
case MOUTH:
|
||||
_eyeContactTarget = (randFloat() < FIFTY_FIFTY_CHANCE) ? RIGHT_EYE : LEFT_EYE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return _eyeContactTarget;
|
||||
}
|
||||
|
||||
|
@ -1315,23 +1335,8 @@ void MyAvatar::setAnimGraphUrl(const QUrl& url) {
|
|||
}
|
||||
|
||||
void MyAvatar::initAnimGraph() {
|
||||
// avatar.json
|
||||
// https://gist.github.com/hyperlogic/7d6a0892a7319c69e2b9
|
||||
//
|
||||
// ik-avatar.json
|
||||
// https://gist.github.com/hyperlogic/e58e0a24cc341ad5d060
|
||||
//
|
||||
// ik-avatar-hands.json
|
||||
// https://gist.githubusercontent.com/hyperlogic/04a02c47eb56d8bfaebb
|
||||
//
|
||||
// ik-avatar-hands-idle.json
|
||||
// https://gist.githubusercontent.com/hyperlogic/d951c78532e7a20557ad
|
||||
//
|
||||
// or run a local web-server
|
||||
// python -m SimpleHTTPServer&
|
||||
//auto graphUrl = QUrl("http://localhost:8000/avatar.json");
|
||||
auto graphUrl =_animGraphUrl.isEmpty() ?
|
||||
QUrl::fromLocalFile(PathUtils::resourcesPath() + "meshes/defaultAvatar_full/avatar-animation.json") :
|
||||
QUrl::fromLocalFile(PathUtils::resourcesPath() + "avatar/avatar-animation.json") :
|
||||
QUrl(_animGraphUrl);
|
||||
_rig->initAnimGraph(graphUrl);
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ public:
|
|||
AudioListenerMode getAudioListenerModeCamera() const { return FROM_CAMERA; }
|
||||
AudioListenerMode getAudioListenerModeCustom() const { return CUSTOM; }
|
||||
|
||||
void reset(bool andReload = false);
|
||||
Q_INVOKABLE void reset(bool andRecenter = false);
|
||||
void update(float deltaTime);
|
||||
void preRender(RenderArgs* renderArgs);
|
||||
|
||||
|
@ -328,6 +328,8 @@ private:
|
|||
|
||||
bool cameraInsideHead() const;
|
||||
|
||||
void updateEyeContactTarget(float deltaTime);
|
||||
|
||||
// These are made private for MyAvatar so that you will use the "use" methods instead
|
||||
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override;
|
||||
|
||||
|
@ -368,6 +370,7 @@ private:
|
|||
float _oculusYawOffset;
|
||||
|
||||
eyeContactTarget _eyeContactTarget;
|
||||
float _eyeContactTargetTimer { 0.0f };
|
||||
|
||||
glm::vec3 _trackedHeadPosition;
|
||||
|
||||
|
|
|
@ -127,9 +127,9 @@ int main(int argc, const char* argv[]) {
|
|||
const char* CLOCK_SKEW = "--clockSkew";
|
||||
const char* clockSkewOption = getCmdOption(argc, argv, CLOCK_SKEW);
|
||||
if (clockSkewOption) {
|
||||
int clockSkew = atoi(clockSkewOption);
|
||||
qint64 clockSkew = atoll(clockSkewOption);
|
||||
usecTimestampNowForceClockSkew(clockSkew);
|
||||
qCDebug(interfaceapp, "clockSkewOption=%s clockSkew=%d", clockSkewOption, clockSkew);
|
||||
qCDebug(interfaceapp) << "clockSkewOption=" << clockSkewOption << "clockSkew=" << clockSkew;
|
||||
}
|
||||
|
||||
// Oculus initialization MUST PRECEDE OpenGL context creation.
|
||||
|
|
|
@ -292,6 +292,8 @@ void AssetMappingModel::refresh() {
|
|||
} else {
|
||||
emit errorGettingMappings(request->getErrorString());
|
||||
}
|
||||
|
||||
request->deleteLater();
|
||||
});
|
||||
|
||||
request->start();
|
||||
|
|
37
interface/src/scripting/RatesScriptingInterface.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
//
|
||||
// RatesScriptingInterface.h
|
||||
// interface/src/scripting
|
||||
//
|
||||
// Created by Zach Pomerantz on 4/20/16.
|
||||
// Copyright 2016 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_RATES_SCRIPTING_INTERFACE_H
|
||||
#define HIFI_RATES_SCRIPTING_INTERFACE_H
|
||||
|
||||
#include <display-plugins/DisplayPlugin.h>
|
||||
|
||||
class RatesScriptingInterface : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(float render READ getRenderRate)
|
||||
Q_PROPERTY(float present READ getPresentRate)
|
||||
Q_PROPERTY(float newFrame READ getNewFrameRate)
|
||||
Q_PROPERTY(float dropped READ getDropRate)
|
||||
Q_PROPERTY(float simulation READ getSimulationRate)
|
||||
Q_PROPERTY(float avatar READ getAvatarRate)
|
||||
|
||||
public:
|
||||
RatesScriptingInterface(QObject* parent) : QObject(parent) {}
|
||||
float getRenderRate() { return qApp->getFps(); }
|
||||
float getPresentRate() { return qApp->getActiveDisplayPlugin()->presentRate(); }
|
||||
float getNewFrameRate() { return qApp->getActiveDisplayPlugin()->newFramePresentRate(); }
|
||||
float getDropRate() { return qApp->getActiveDisplayPlugin()->droppedFrameRate(); }
|
||||
float getSimulationRate() { return qApp->getAverageSimsPerSecond(); }
|
||||
float getAvatarRate() { return qApp->getAvatarSimrate(); }
|
||||
};
|
||||
|
||||
#endif // HIFI_INTERFACE_RATES_SCRIPTING_INTERFACE_H
|
|
@ -281,7 +281,7 @@ void ApplicationOverlay::buildFramebufferObject() {
|
|||
_overlayFramebuffer->setRenderBuffer(0, newColorAttachment);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If the overlay framebuffer still has no color attachment, no textures were available for rendering, so build a new one
|
||||
if (!_overlayFramebuffer->getRenderBuffer(0)) {
|
||||
const gpu::Sampler OVERLAY_SAMPLER(gpu::Sampler::FILTER_MIN_MAG_LINEAR, gpu::Sampler::WRAP_CLAMP);
|
||||
|
|
|
@ -515,7 +515,9 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser
|
|||
QString incomingLikelyLostString = locale.toString((uint)seqStats.getLost());
|
||||
QString incomingRecovered = locale.toString((uint)seqStats.getRecovered());
|
||||
|
||||
int clockSkewInMS = node->getClockSkewUsec() / (int)USECS_PER_MSEC;
|
||||
qint64 clockSkewInUsecs = node->getClockSkewUsec();
|
||||
QString formattedClockSkewString = formatUsecTime(clockSkewInUsecs);
|
||||
qint64 clockSkewInMS = clockSkewInUsecs / (qint64)USECS_PER_MSEC;
|
||||
QString incomingFlightTimeString = locale.toString((int)stats.getIncomingFlightTimeAverage());
|
||||
QString incomingPingTimeString = locale.toString(node->getPingMs());
|
||||
QString incomingClockSkewString = locale.toString(clockSkewInMS);
|
||||
|
@ -536,7 +538,9 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser
|
|||
" Average Ping Time: " << qPrintable(incomingPingTimeString) << " msecs";
|
||||
|
||||
serverDetails << "<br/>" <<
|
||||
" Average Clock Skew: " << qPrintable(incomingClockSkewString) << " msecs";
|
||||
" Average Clock Skew: " << qPrintable(incomingClockSkewString) << " msecs" <<
|
||||
" [" << qPrintable(formattedClockSkewString) << "]";
|
||||
|
||||
|
||||
serverDetails << "<br/>" << "Incoming" <<
|
||||
" Bytes: " << qPrintable(incomingBytesString) <<
|
||||
|
|
|
@ -110,7 +110,14 @@ void Text3DOverlay::render(RenderArgs* args) {
|
|||
|
||||
glm::vec4 textColor = { _color.red / MAX_COLOR, _color.green / MAX_COLOR,
|
||||
_color.blue / MAX_COLOR, getTextAlpha() };
|
||||
|
||||
// FIXME: Factor out textRenderer so that Text3DOverlay overlay parts can be grouped by pipeline
|
||||
// for a gpu performance increase. Currently,
|
||||
// Text renderer sets its own pipeline,
|
||||
_textRenderer->draw(batch, 0, 0, _text, textColor, glm::vec2(-1.0f), getDrawInFront());
|
||||
// so before we continue, we must reset the pipeline
|
||||
batch.setPipeline(args->_pipeline->pipeline);
|
||||
args->_pipeline->prepare(batch);
|
||||
}
|
||||
|
||||
const render::ShapeKey Text3DOverlay::getShapeKey() {
|
||||
|
|
|
@ -248,7 +248,11 @@ static AnimNode::Pointer loadClipNode(const QJsonObject& jsonObj, const QString&
|
|||
READ_OPTIONAL_STRING(loopFlagVar, jsonObj);
|
||||
READ_OPTIONAL_STRING(mirrorFlagVar, jsonObj);
|
||||
|
||||
auto node = std::make_shared<AnimClip>(id, url, startFrame, endFrame, timeScale, loopFlag, mirrorFlag);
|
||||
// animation urls can be relative to the containing url document.
|
||||
auto tempUrl = QUrl(url);
|
||||
tempUrl = jsonUrl.resolved(tempUrl);
|
||||
|
||||
auto node = std::make_shared<AnimClip>(id, tempUrl.toString(), startFrame, endFrame, timeScale, loopFlag, mirrorFlag);
|
||||
|
||||
if (!startFrameVar.isEmpty()) {
|
||||
node->setStartFrameVar(startFrameVar);
|
||||
|
|
|
@ -820,16 +820,24 @@ void EntityTreeRenderer::playEntityCollisionSound(const QUuid& myNodeID, EntityT
|
|||
return;
|
||||
}
|
||||
|
||||
EntityItemPointer entity = entityTree->findEntityByEntityItemID(id);
|
||||
if (!entity) {
|
||||
QString collisionSoundURL;
|
||||
float mass = 1.0; // value doesn't get used, but set it so compiler is quiet
|
||||
AACube minAACube;
|
||||
bool success = false;
|
||||
_tree->withReadLock([&] {
|
||||
EntityItemPointer entity = entityTree->findEntityByEntityItemID(id);
|
||||
if (entity) {
|
||||
collisionSoundURL = entity->getCollisionSoundURL();
|
||||
mass = entity->computeMass();
|
||||
minAACube = entity->getMinimumAACube(success);
|
||||
}
|
||||
});
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QString& collisionSoundURL = entity->getCollisionSoundURL();
|
||||
if (collisionSoundURL.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
const float mass = entity->computeMass();
|
||||
const float COLLISION_PENETRATION_TO_VELOCITY = 50; // as a subsitute for RELATIVE entity->getVelocity()
|
||||
// The collision.penetration is a pretty good indicator of changed velocity AFTER the initial contact,
|
||||
// but that first contact depends on exactly where we hit in the physics step.
|
||||
|
@ -854,11 +862,6 @@ void EntityTreeRenderer::playEntityCollisionSound(const QUuid& myNodeID, EntityT
|
|||
|
||||
// Shift the pitch down by ln(1 + (size / COLLISION_SIZE_FOR_STANDARD_PITCH)) / ln(2)
|
||||
const float COLLISION_SIZE_FOR_STANDARD_PITCH = 0.2f;
|
||||
bool success;
|
||||
auto minAACube = entity->getMinimumAACube(success);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
const float stretchFactor = log(1.0f + (minAACube.getLargestDimension() / COLLISION_SIZE_FOR_STANDARD_PITCH)) / log(2);
|
||||
AudioInjector::playSound(collisionSoundURL, volume, stretchFactor, position);
|
||||
}
|
||||
|
|
|
@ -518,6 +518,7 @@ void RenderableModelEntityItem::update(const quint64& now) {
|
|||
if (!_dimensionsInitialized && _model && _model->isActive()) {
|
||||
if (_model->isLoaded()) {
|
||||
EntityItemProperties properties;
|
||||
properties.setLastEdited(usecTimestampNow()); // we must set the edit time since we're editing it
|
||||
auto extents = _model->getMeshExtents();
|
||||
properties.setDimensions(extents.maximum - extents.minimum);
|
||||
qCDebug(entitiesrenderer) << "Autoresizing:" << (!getName().isEmpty() ? getName() : getModelURL());
|
||||
|
|
|
@ -29,7 +29,7 @@ void EntityEditPacketSender::processEntityEditNackPacket(QSharedPointer<Received
|
|||
}
|
||||
}
|
||||
|
||||
void EntityEditPacketSender::adjustEditPacketForClockSkew(PacketType type, QByteArray& buffer, int clockSkew) {
|
||||
void EntityEditPacketSender::adjustEditPacketForClockSkew(PacketType type, QByteArray& buffer, qint64 clockSkew) {
|
||||
if (type == PacketType::EntityAdd || type == PacketType::EntityEdit) {
|
||||
EntityItem::adjustEditPacketForClockSkew(buffer, clockSkew);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ public:
|
|||
|
||||
// My server type is the model server
|
||||
virtual char getMyNodeType() const { return NodeType::EntityServer; }
|
||||
virtual void adjustEditPacketForClockSkew(PacketType type, QByteArray& buffer, int clockSkew);
|
||||
virtual void adjustEditPacketForClockSkew(PacketType type, QByteArray& buffer, qint64 clockSkew);
|
||||
|
||||
public slots:
|
||||
void processEntityEditNackPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
||||
|
|
|
@ -370,7 +370,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
return 0;
|
||||
}
|
||||
|
||||
int clockSkew = args.sourceNode ? args.sourceNode->getClockSkewUsec() : 0;
|
||||
qint64 clockSkew = args.sourceNode ? args.sourceNode->getClockSkewUsec() : 0;
|
||||
|
||||
BufferParser parser(data, bytesLeftToRead);
|
||||
|
||||
|
@ -485,7 +485,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
qCDebug(entities) << " now:" << now;
|
||||
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
||||
qCDebug(entities) << " lastEditedFromBuffer:" << debugTime(lastEditedFromBuffer, now);
|
||||
qCDebug(entities) << " clockSkew:" << debugTimeOnly(clockSkew);
|
||||
qCDebug(entities) << " clockSkew:" << clockSkew;
|
||||
qCDebug(entities) << " lastEditedFromBufferAdjusted:" << debugTime(lastEditedFromBufferAdjusted, now);
|
||||
qCDebug(entities) << " _lastEditedFromRemote:" << debugTime(_lastEditedFromRemote, now);
|
||||
qCDebug(entities) << " _lastEditedFromRemoteInRemoteTime:" << debugTime(_lastEditedFromRemoteInRemoteTime, now);
|
||||
|
@ -731,7 +731,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
|
||||
// we want to extrapolate the motion forward to compensate for packet travel time, but
|
||||
// we don't want the side effect of flag setting.
|
||||
simulateKinematicMotion(skipTimeForward, false);
|
||||
stepKinematicMotion(skipTimeForward);
|
||||
}
|
||||
|
||||
if (overwriteLocalData) {
|
||||
|
@ -760,7 +760,7 @@ void EntityItem::debugDump() const {
|
|||
}
|
||||
|
||||
// adjust any internal timestamps to fix clock skew for this server
|
||||
void EntityItem::adjustEditPacketForClockSkew(QByteArray& buffer, int clockSkew) {
|
||||
void EntityItem::adjustEditPacketForClockSkew(QByteArray& buffer, qint64 clockSkew) {
|
||||
unsigned char* dataAt = reinterpret_cast<unsigned char*>(buffer.data());
|
||||
int octets = numberOfThreeBitSectionsInCode(dataAt);
|
||||
int lengthOfOctcode = (int)bytesRequiredForCodeLength(octets);
|
||||
|
@ -872,130 +872,120 @@ void EntityItem::simulate(const quint64& now) {
|
|||
qCDebug(entities) << " ********** EntityItem::simulate() .... SETTING _lastSimulated=" << _lastSimulated;
|
||||
#endif
|
||||
|
||||
simulateKinematicMotion(timeElapsed);
|
||||
if (!hasActions()) {
|
||||
if (!stepKinematicMotion(timeElapsed)) {
|
||||
// this entity is no longer moving
|
||||
// flag it to transition from KINEMATIC to STATIC
|
||||
_dirtyFlags |= Simulation::DIRTY_MOTION_TYPE;
|
||||
setAcceleration(Vectors::ZERO);
|
||||
}
|
||||
}
|
||||
_lastSimulated = now;
|
||||
}
|
||||
|
||||
void EntityItem::simulateKinematicMotion(float timeElapsed, bool setFlags) {
|
||||
#ifdef WANT_DEBUG
|
||||
qCDebug(entities) << "EntityItem::simulateKinematicMotion timeElapsed" << timeElapsed;
|
||||
#endif
|
||||
bool EntityItem::stepKinematicMotion(float timeElapsed) {
|
||||
// get all the data
|
||||
Transform transform;
|
||||
glm::vec3 linearVelocity;
|
||||
glm::vec3 angularVelocity;
|
||||
getLocalTransformAndVelocities(transform, linearVelocity, angularVelocity);
|
||||
|
||||
const float MIN_TIME_SKIP = 0.0f;
|
||||
const float MAX_TIME_SKIP = 1.0f; // in seconds
|
||||
|
||||
timeElapsed = glm::clamp(timeElapsed, MIN_TIME_SKIP, MAX_TIME_SKIP);
|
||||
|
||||
if (hasActions()) {
|
||||
return;
|
||||
// find out if it is moving
|
||||
bool isSpinning = (glm::length2(angularVelocity) > 0.0f);
|
||||
float linearSpeedSquared = glm::length2(linearVelocity);
|
||||
bool isTranslating = linearSpeedSquared > 0.0f;
|
||||
bool moving = isTranslating || isSpinning;
|
||||
if (!moving) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hasLocalAngularVelocity()) {
|
||||
glm::vec3 localAngularVelocity = getLocalAngularVelocity();
|
||||
if (timeElapsed <= 0.0f) {
|
||||
// someone gave us a useless time value so bail early
|
||||
// but return 'true' because it is moving
|
||||
return true;
|
||||
}
|
||||
|
||||
const float MAX_TIME_ELAPSED = 1.0f; // seconds
|
||||
if (timeElapsed > MAX_TIME_ELAPSED) {
|
||||
qCWarning(entities) << "kinematic timestep = " << timeElapsed << " truncated to " << MAX_TIME_ELAPSED;
|
||||
}
|
||||
timeElapsed = glm::min(timeElapsed, MAX_TIME_ELAPSED);
|
||||
|
||||
if (isSpinning) {
|
||||
// angular damping
|
||||
if (_angularDamping > 0.0f) {
|
||||
localAngularVelocity *= powf(1.0f - _angularDamping, timeElapsed);
|
||||
#ifdef WANT_DEBUG
|
||||
qCDebug(entities) << " angularDamping :" << _angularDamping;
|
||||
qCDebug(entities) << " newAngularVelocity:" << localAngularVelocity;
|
||||
#endif
|
||||
angularVelocity *= powf(1.0f - _angularDamping, timeElapsed);
|
||||
}
|
||||
|
||||
float angularSpeed = glm::length(localAngularVelocity);
|
||||
|
||||
const float EPSILON_ANGULAR_VELOCITY_LENGTH = 0.0017453f; // 0.0017453 rad/sec = 0.1f degrees/sec
|
||||
if (angularSpeed < EPSILON_ANGULAR_VELOCITY_LENGTH) {
|
||||
if (setFlags && angularSpeed > 0.0f) {
|
||||
_dirtyFlags |= Simulation::DIRTY_MOTION_TYPE;
|
||||
}
|
||||
localAngularVelocity = ENTITY_ITEM_ZERO_VEC3;
|
||||
const float MIN_KINEMATIC_ANGULAR_SPEED_SQUARED =
|
||||
KINEMATIC_ANGULAR_SPEED_THRESHOLD * KINEMATIC_ANGULAR_SPEED_THRESHOLD;
|
||||
if (glm::length2(angularVelocity) < MIN_KINEMATIC_ANGULAR_SPEED_SQUARED) {
|
||||
angularVelocity = Vectors::ZERO;
|
||||
} else {
|
||||
// for improved agreement with the way Bullet integrates rotations we use an approximation
|
||||
// and break the integration into bullet-sized substeps
|
||||
glm::quat rotation = getRotation();
|
||||
glm::quat rotation = transform.getRotation();
|
||||
float dt = timeElapsed;
|
||||
while (dt > PHYSICS_ENGINE_FIXED_SUBSTEP) {
|
||||
glm::quat dQ = computeBulletRotationStep(localAngularVelocity, PHYSICS_ENGINE_FIXED_SUBSTEP);
|
||||
while (dt > 0.0f) {
|
||||
glm::quat dQ = computeBulletRotationStep(angularVelocity, glm::min(dt, PHYSICS_ENGINE_FIXED_SUBSTEP));
|
||||
rotation = glm::normalize(dQ * rotation);
|
||||
dt -= PHYSICS_ENGINE_FIXED_SUBSTEP;
|
||||
}
|
||||
// NOTE: this final partial substep can drift away from a real Bullet simulation however
|
||||
// it only becomes significant for rapidly rotating objects
|
||||
// (e.g. around PI/4 radians per substep, or 7.5 rotations/sec at 60 substeps/sec).
|
||||
glm::quat dQ = computeBulletRotationStep(localAngularVelocity, dt);
|
||||
rotation = glm::normalize(dQ * rotation);
|
||||
|
||||
bool success;
|
||||
setOrientation(rotation, success, false);
|
||||
transform.setRotation(rotation);
|
||||
}
|
||||
|
||||
setLocalAngularVelocity(localAngularVelocity);
|
||||
}
|
||||
|
||||
if (hasLocalVelocity()) {
|
||||
|
||||
// acceleration is in the global frame, so transform it into the local frame.
|
||||
// TODO: Move this into SpatiallyNestable.
|
||||
bool success;
|
||||
Transform transform = getParentTransform(success);
|
||||
glm::vec3 localAcceleration(glm::vec3::_null);
|
||||
if (success) {
|
||||
localAcceleration = glm::inverse(transform.getRotation()) * getAcceleration();
|
||||
} else {
|
||||
localAcceleration = getAcceleration();
|
||||
}
|
||||
glm::vec3 position = transform.getTranslation();
|
||||
const float MIN_KINEMATIC_LINEAR_SPEED_SQUARED =
|
||||
KINEMATIC_LINEAR_SPEED_THRESHOLD * KINEMATIC_LINEAR_SPEED_THRESHOLD;
|
||||
if (isTranslating) {
|
||||
glm::vec3 deltaVelocity = Vectors::ZERO;
|
||||
|
||||
// linear damping
|
||||
glm::vec3 localVelocity = getLocalVelocity();
|
||||
if (_damping > 0.0f) {
|
||||
localVelocity *= powf(1.0f - _damping, timeElapsed);
|
||||
#ifdef WANT_DEBUG
|
||||
qCDebug(entities) << " damping:" << _damping;
|
||||
qCDebug(entities) << " velocity AFTER dampingResistance:" << localVelocity;
|
||||
qCDebug(entities) << " glm::length(velocity):" << glm::length(localVelocity);
|
||||
#endif
|
||||
deltaVelocity = (powf(1.0f - _damping, timeElapsed) - 1.0f) * linearVelocity;
|
||||
}
|
||||
|
||||
// integrate position forward
|
||||
glm::vec3 localPosition = getLocalPosition();
|
||||
glm::vec3 newLocalPosition = localPosition + (localVelocity * timeElapsed) + 0.5f * localAcceleration * timeElapsed * timeElapsed;
|
||||
const float MIN_KINEMATIC_LINEAR_ACCELERATION_SQUARED = 1.0e-4f; // 0.01 m/sec^2
|
||||
if (glm::length2(_acceleration) > MIN_KINEMATIC_LINEAR_ACCELERATION_SQUARED) {
|
||||
// yes acceleration
|
||||
// acceleration is in world-frame but we need it in local-frame
|
||||
glm::vec3 linearAcceleration = _acceleration;
|
||||
bool success;
|
||||
Transform parentTransform = getParentTransform(success);
|
||||
if (success) {
|
||||
linearAcceleration = glm::inverse(parentTransform.getRotation()) * linearAcceleration;
|
||||
}
|
||||
deltaVelocity += linearAcceleration * timeElapsed;
|
||||
|
||||
#ifdef WANT_DEBUG
|
||||
qCDebug(entities) << " EntityItem::simulate()....";
|
||||
qCDebug(entities) << " timeElapsed:" << timeElapsed;
|
||||
qCDebug(entities) << " old AACube:" << getMaximumAACube();
|
||||
qCDebug(entities) << " old position:" << localPosition;
|
||||
qCDebug(entities) << " old velocity:" << localVelocity;
|
||||
qCDebug(entities) << " old getAABox:" << getAABox();
|
||||
qCDebug(entities) << " newPosition:" << newPosition;
|
||||
qCDebug(entities) << " glm::distance(newPosition, position):" << glm::distance(newLocalPosition, localPosition);
|
||||
#endif
|
||||
|
||||
localPosition = newLocalPosition;
|
||||
|
||||
// apply effective acceleration, which will be the same as gravity if the Entity isn't at rest.
|
||||
localVelocity += localAcceleration * timeElapsed;
|
||||
|
||||
float speed = glm::length(localVelocity);
|
||||
const float EPSILON_LINEAR_VELOCITY_LENGTH = 0.001f; // 1mm/sec
|
||||
if (speed < EPSILON_LINEAR_VELOCITY_LENGTH) {
|
||||
setVelocity(ENTITY_ITEM_ZERO_VEC3);
|
||||
if (setFlags && speed > 0.0f) {
|
||||
_dirtyFlags |= Simulation::DIRTY_MOTION_TYPE;
|
||||
if (linearSpeedSquared < MIN_KINEMATIC_LINEAR_SPEED_SQUARED
|
||||
&& glm::length2(deltaVelocity) < MIN_KINEMATIC_LINEAR_SPEED_SQUARED
|
||||
&& glm::length2(linearVelocity + deltaVelocity) < MIN_KINEMATIC_LINEAR_SPEED_SQUARED) {
|
||||
linearVelocity = Vectors::ZERO;
|
||||
} else {
|
||||
// NOTE: we do NOT include the second-order acceleration term (0.5 * a * dt^2)
|
||||
// when computing the displacement because Bullet also ignores that term. Yes,
|
||||
// this is an approximation and it works best when dt is small.
|
||||
position += timeElapsed * linearVelocity;
|
||||
linearVelocity += deltaVelocity;
|
||||
}
|
||||
} else {
|
||||
setLocalPosition(localPosition);
|
||||
setLocalVelocity(localVelocity);
|
||||
// no acceleration
|
||||
if (linearSpeedSquared < MIN_KINEMATIC_LINEAR_SPEED_SQUARED) {
|
||||
linearVelocity = Vectors::ZERO;
|
||||
} else {
|
||||
// NOTE: we don't use second-order acceleration term for linear displacement
|
||||
// because Bullet doesn't use it.
|
||||
position += timeElapsed * linearVelocity;
|
||||
linearVelocity += deltaVelocity;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WANT_DEBUG
|
||||
qCDebug(entities) << " new position:" << position;
|
||||
qCDebug(entities) << " new velocity:" << velocity;
|
||||
qCDebug(entities) << " new AACube:" << getMaximumAACube();
|
||||
qCDebug(entities) << " old getAABox:" << getAABox();
|
||||
#endif
|
||||
}
|
||||
|
||||
transform.setTranslation(position);
|
||||
setLocalTransformAndVelocities(transform, linearVelocity, angularVelocity);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EntityItem::isMoving() const {
|
||||
|
|
|
@ -144,7 +144,7 @@ public:
|
|||
|
||||
static int expectedBytes();
|
||||
|
||||
static void adjustEditPacketForClockSkew(QByteArray& buffer, int clockSkew);
|
||||
static void adjustEditPacketForClockSkew(QByteArray& buffer, qint64 clockSkew);
|
||||
|
||||
// perform update
|
||||
virtual void update(const quint64& now) { _lastUpdated = now; }
|
||||
|
@ -152,7 +152,7 @@ public:
|
|||
|
||||
// perform linear extrapolation for SimpleEntitySimulation
|
||||
void simulate(const quint64& now);
|
||||
void simulateKinematicMotion(float timeElapsed, bool setFlags=true);
|
||||
bool stepKinematicMotion(float timeElapsed); // return 'true' if moving
|
||||
|
||||
virtual bool needsToCallUpdate() const { return false; }
|
||||
|
||||
|
|
|
@ -74,13 +74,18 @@ void EntitySimulation::addEntityInternal(EntityItemPointer entity) {
|
|||
if (entity->isMovingRelativeToParent() && !entity->getPhysicsInfo()) {
|
||||
QMutexLocker lock(&_mutex);
|
||||
_simpleKinematicEntities.insert(entity);
|
||||
entity->setLastSimulated(usecTimestampNow());
|
||||
}
|
||||
}
|
||||
|
||||
void EntitySimulation::changeEntityInternal(EntityItemPointer entity) {
|
||||
QMutexLocker lock(&_mutex);
|
||||
if (entity->isMovingRelativeToParent() && !entity->getPhysicsInfo()) {
|
||||
int numKinematicEntities = _simpleKinematicEntities.size();
|
||||
_simpleKinematicEntities.insert(entity);
|
||||
if (numKinematicEntities != _simpleKinematicEntities.size()) {
|
||||
entity->setLastSimulated(usecTimestampNow());
|
||||
}
|
||||
} else {
|
||||
_simpleKinematicEntities.remove(entity);
|
||||
}
|
||||
|
|
|
@ -1459,10 +1459,12 @@ void EntityTree::trackIncomingEntityLastEdited(quint64 lastEditedTime, int bytes
|
|||
|
||||
void EntityTree::callLoader(EntityItemID entityID) {
|
||||
// this is used to bounce from the networking thread to the main thread
|
||||
EntityItemPointer entity = findEntityByEntityItemID(entityID);
|
||||
if (entity) {
|
||||
entity->loader();
|
||||
}
|
||||
this->withWriteLock([&] {
|
||||
EntityItemPointer entity = findEntityByEntityItemID(entityID);
|
||||
if (entity) {
|
||||
entity->loader();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
int EntityTree::getJointIndex(const QUuid& entityID, const QString& name) const {
|
||||
|
|
|
@ -33,6 +33,16 @@ QHash<QString, float> COMMENT_SCALE_HINTS = {{"This file uses centimeters as uni
|
|||
|
||||
const QString SMART_DEFAULT_MATERIAL_NAME = "High Fidelity smart default material name";
|
||||
|
||||
namespace {
|
||||
template<class T>
|
||||
T& checked_at(QVector<T>& vector, int i) {
|
||||
if (i < 0 || i >= vector.size()) {
|
||||
throw std::out_of_range("index " + std::to_string(i) + "is out of range");
|
||||
}
|
||||
return vector[i];
|
||||
}
|
||||
}
|
||||
|
||||
OBJTokenizer::OBJTokenizer(QIODevice* device) : _device(device), _pushedBackToken(-1) {
|
||||
}
|
||||
|
||||
|
@ -455,9 +465,9 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping,
|
|||
FaceGroup faceGroup = faceGroups[meshPartCount];
|
||||
bool specifiesUV = false;
|
||||
foreach(OBJFace face, faceGroup) {
|
||||
glm::vec3 v0 = vertices[face.vertexIndices[0]];
|
||||
glm::vec3 v1 = vertices[face.vertexIndices[1]];
|
||||
glm::vec3 v2 = vertices[face.vertexIndices[2]];
|
||||
glm::vec3 v0 = checked_at(vertices, face.vertexIndices[0]);
|
||||
glm::vec3 v1 = checked_at(vertices, face.vertexIndices[1]);
|
||||
glm::vec3 v2 = checked_at(vertices, face.vertexIndices[2]);
|
||||
meshPart.triangleIndices.append(mesh.vertices.count()); // not face.vertexIndices into vertices
|
||||
mesh.vertices << v0;
|
||||
meshPart.triangleIndices.append(mesh.vertices.count());
|
||||
|
@ -467,19 +477,19 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping,
|
|||
|
||||
glm::vec3 n0, n1, n2;
|
||||
if (face.normalIndices.count()) {
|
||||
n0 = normals[face.normalIndices[0]];
|
||||
n1 = normals[face.normalIndices[1]];
|
||||
n2 = normals[face.normalIndices[2]];
|
||||
n0 = checked_at(normals, face.normalIndices[0]);
|
||||
n1 = checked_at(normals, face.normalIndices[1]);
|
||||
n2 = checked_at(normals, face.normalIndices[2]);
|
||||
} else { // generate normals from triangle plane if not provided
|
||||
n0 = n1 = n2 = glm::cross(v1 - v0, v2 - v0);
|
||||
}
|
||||
mesh.normals << n0 << n1 << n2;
|
||||
if (face.textureUVIndices.count()) {
|
||||
specifiesUV = true;
|
||||
mesh.texCoords
|
||||
<< textureUVs[face.textureUVIndices[0]]
|
||||
<< textureUVs[face.textureUVIndices[1]]
|
||||
<< textureUVs[face.textureUVIndices[2]];
|
||||
mesh.texCoords <<
|
||||
checked_at(textureUVs, face.textureUVIndices[0]) <<
|
||||
checked_at(textureUVs, face.textureUVIndices[1]) <<
|
||||
checked_at(textureUVs, face.textureUVIndices[2]);
|
||||
} else {
|
||||
glm::vec2 corner(0.0f, 1.0f);
|
||||
mesh.texCoords << corner << corner << corner;
|
||||
|
|
|
@ -207,6 +207,7 @@ protected:
|
|||
static void incrementBufferGPUCount();
|
||||
static void decrementBufferGPUCount();
|
||||
static void updateBufferGPUMemoryUsage(Size prevObjectSize, Size newObjectSize);
|
||||
|
||||
static void incrementTextureGPUCount();
|
||||
static void decrementTextureGPUCount();
|
||||
static void updateTextureGPUMemoryUsage(Size prevObjectSize, Size newObjectSize);
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include <assert.h>
|
||||
#include <memory>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include "Forward.h"
|
||||
|
||||
namespace gpu {
|
||||
|
||||
|
@ -37,28 +37,6 @@ private:
|
|||
friend class Backend;
|
||||
};
|
||||
|
||||
typedef int Stamp;
|
||||
|
||||
typedef unsigned int uint32;
|
||||
typedef int int32;
|
||||
typedef unsigned short uint16;
|
||||
typedef short int16;
|
||||
typedef unsigned char uint8;
|
||||
typedef char int8;
|
||||
|
||||
typedef unsigned char Byte;
|
||||
|
||||
typedef size_t Offset;
|
||||
|
||||
typedef glm::mat4 Mat4;
|
||||
typedef glm::mat3 Mat3;
|
||||
typedef glm::vec4 Vec4;
|
||||
typedef glm::ivec4 Vec4i;
|
||||
typedef glm::vec3 Vec3;
|
||||
typedef glm::vec2 Vec2;
|
||||
typedef glm::ivec2 Vec2i;
|
||||
typedef glm::uvec2 Vec2u;
|
||||
|
||||
// Description of a scalar type
|
||||
enum Type {
|
||||
|
||||
|
|
|
@ -9,69 +9,77 @@
|
|||
#ifndef hifi_gpu_Forward_h
|
||||
#define hifi_gpu_Forward_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
namespace gpu {
|
||||
class Batch;
|
||||
class Backend;
|
||||
class Context;
|
||||
typedef std::shared_ptr<Context> ContextPointer;
|
||||
using ContextPointer = std::shared_ptr<Context>;
|
||||
class GPUObject;
|
||||
|
||||
typedef int Stamp;
|
||||
typedef uint32_t uint32;
|
||||
typedef int32_t int32;
|
||||
typedef uint16_t uint16;
|
||||
typedef int16_t int16;
|
||||
typedef uint8_t uint8;
|
||||
typedef int8_t int8;
|
||||
using Stamp = int;
|
||||
using uint32 = uint32_t;
|
||||
using int32 = int32_t;
|
||||
using uint16 = uint16_t;
|
||||
using int16 = int16_t;
|
||||
using uint8 = uint8_t;
|
||||
using int8 = int8_t;
|
||||
|
||||
typedef uint8 Byte;
|
||||
typedef uint32 Offset;
|
||||
typedef std::vector<Offset> Offsets;
|
||||
using Byte = uint8;
|
||||
using Offset = size_t;
|
||||
using Offsets = std::vector<Offset>;
|
||||
|
||||
typedef glm::mat4 Mat4;
|
||||
typedef glm::mat3 Mat3;
|
||||
typedef glm::vec4 Vec4;
|
||||
typedef glm::ivec4 Vec4i;
|
||||
typedef glm::vec3 Vec3;
|
||||
typedef glm::vec2 Vec2;
|
||||
typedef glm::ivec2 Vec2i;
|
||||
typedef glm::uvec2 Vec2u;
|
||||
using Mat4 = glm::mat4;
|
||||
using Mat3 = glm::mat3;
|
||||
using Vec4 = glm::vec4;
|
||||
using Vec4i = glm::ivec4;
|
||||
using Vec3 = glm::vec3;
|
||||
using Vec2 = glm::vec2;
|
||||
using Vec2i = glm::ivec2;
|
||||
using Vec2u = glm::uvec2;
|
||||
using Vec3u = glm::uvec3;
|
||||
using Vec3u = glm::uvec3;
|
||||
|
||||
class Element;
|
||||
typedef Element Format;
|
||||
using Format = Element;
|
||||
class Swapchain;
|
||||
typedef std::shared_ptr<Swapchain> SwapchainPointer;
|
||||
using SwapchainPointer = std::shared_ptr<Swapchain>;
|
||||
class Framebuffer;
|
||||
typedef std::shared_ptr<Framebuffer> FramebufferPointer;
|
||||
using FramebufferPointer = std::shared_ptr<Framebuffer>;
|
||||
class Pipeline;
|
||||
typedef std::shared_ptr<Pipeline> PipelinePointer;
|
||||
typedef std::vector<PipelinePointer> Pipelines;
|
||||
using PipelinePointer = std::shared_ptr<Pipeline>;
|
||||
using Pipelines = std::vector<PipelinePointer>;
|
||||
class Query;
|
||||
typedef std::shared_ptr<Query> QueryPointer;
|
||||
typedef std::vector<QueryPointer> Queries;
|
||||
using QueryPointer = std::shared_ptr<Query>;
|
||||
using Queries = std::vector<QueryPointer>;
|
||||
class Resource;
|
||||
class Buffer;
|
||||
typedef std::shared_ptr<Buffer> BufferPointer;
|
||||
typedef std::vector<BufferPointer> Buffers;
|
||||
using BufferPointer = std::shared_ptr<Buffer>;
|
||||
using Buffers = std::vector<BufferPointer>;
|
||||
class BufferView;
|
||||
class Shader;
|
||||
typedef Shader::Pointer ShaderPointer;
|
||||
typedef std::vector<ShaderPointer> Shaders;
|
||||
using ShaderPointer = std::shared_ptr<Shader>;
|
||||
using Shaders = std::vector<ShaderPointer>;
|
||||
class State;
|
||||
typedef std::shared_ptr<State> StatePointer;
|
||||
typedef std::vector<StatePointer> States;
|
||||
using StatePointer = std::shared_ptr<State>;
|
||||
using States = std::vector<StatePointer>;
|
||||
class Stream;
|
||||
class BufferStream;
|
||||
typedef std::shared_ptr<BufferStream> BufferStreamPointer;
|
||||
using BufferStreamPointer = std::shared_ptr<BufferStream>;
|
||||
class Texture;
|
||||
class SphericalHarmonics;
|
||||
typedef std::shared_ptr<SphericalHarmonics> SHPointer;
|
||||
using SHPointer = std::shared_ptr<SphericalHarmonics>;
|
||||
class Sampler;
|
||||
class Texture;
|
||||
typedef std::shared_ptr<Texture> TexturePointer;
|
||||
typedef std::vector<TexturePointer> Textures;
|
||||
using TexturePointer = std::shared_ptr<Texture>;
|
||||
using Textures = std::vector<TexturePointer>;
|
||||
class TextureView;
|
||||
typedef std::vector<TextureView> TextureViews;
|
||||
using TextureViews = std::vector<TextureView>;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -125,7 +125,7 @@ void Framebuffer::resize(uint16 width, uint16 height, uint16 numSamples) {
|
|||
if (_depthStencilBuffer) {
|
||||
_depthStencilBuffer._texture->resize2D(width, height, numSamples);
|
||||
_numSamples = _depthStencilBuffer._texture->getNumSamples();
|
||||
++_depthStamp;
|
||||
++_depthStamp;
|
||||
}
|
||||
|
||||
_width = width;
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include <queue>
|
||||
#include <list>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <GPUIdent.h>
|
||||
#include <NumericalConstants.h>
|
||||
|
||||
#if defined(NSIGHT_FOUND)
|
||||
#include "nvToolsExt.h"
|
||||
|
@ -86,10 +88,18 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
|||
void GLBackend::init() {
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [] {
|
||||
QString vendor{ (const char*)glGetString(GL_VENDOR) };
|
||||
QString renderer{ (const char*)glGetString(GL_RENDERER) };
|
||||
qCDebug(gpulogging) << "GL Version: " << QString((const char*) glGetString(GL_VERSION));
|
||||
qCDebug(gpulogging) << "GL Shader Language Version: " << QString((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
qCDebug(gpulogging) << "GL Vendor: " << QString((const char*) glGetString(GL_VENDOR));
|
||||
qCDebug(gpulogging) << "GL Renderer: " << QString((const char*) glGetString(GL_RENDERER));
|
||||
qCDebug(gpulogging) << "GL Vendor: " << vendor;
|
||||
qCDebug(gpulogging) << "GL Renderer: " << renderer;
|
||||
GPUIdent* gpu = GPUIdent::getInstance(vendor, renderer);
|
||||
// From here on, GPUIdent::getInstance()->getMumble() should efficiently give the same answers.
|
||||
qCDebug(gpulogging) << "GPU:";
|
||||
qCDebug(gpulogging) << "\tcard:" << gpu->getName();
|
||||
qCDebug(gpulogging) << "\tdriver:" << gpu->getDriver();
|
||||
qCDebug(gpulogging) << "\tdedicated memory:" << gpu->getMemory() << "MB";
|
||||
|
||||
glewExperimental = true;
|
||||
GLenum err = glewInit();
|
||||
|
@ -117,6 +127,50 @@ void GLBackend::init() {
|
|||
});
|
||||
}
|
||||
|
||||
Context::Size GLBackend::getDedicatedMemory() {
|
||||
static Context::Size dedicatedMemory { 0 };
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [&] {
|
||||
#ifdef Q_OS_WIN
|
||||
if (!dedicatedMemory && wglGetGPUIDsAMD && wglGetGPUInfoAMD) {
|
||||
UINT maxCount = wglGetGPUIDsAMD(0, 0);
|
||||
std::vector<UINT> ids;
|
||||
ids.resize(maxCount);
|
||||
wglGetGPUIDsAMD(maxCount, &ids[0]);
|
||||
GLuint memTotal;
|
||||
wglGetGPUInfoAMD(ids[0], WGL_GPU_RAM_AMD, GL_UNSIGNED_INT, sizeof(GLuint), &memTotal);
|
||||
dedicatedMemory = MB_TO_BYTES(memTotal);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!dedicatedMemory) {
|
||||
GLint atiGpuMemory[4];
|
||||
// not really total memory, but close enough if called early enough in the application lifecycle
|
||||
glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, atiGpuMemory);
|
||||
if (GL_NO_ERROR == glGetError()) {
|
||||
dedicatedMemory = KB_TO_BYTES(atiGpuMemory[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!dedicatedMemory) {
|
||||
GLint nvGpuMemory { 0 };
|
||||
glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &nvGpuMemory);
|
||||
if (GL_NO_ERROR == glGetError()) {
|
||||
dedicatedMemory = KB_TO_BYTES(nvGpuMemory);
|
||||
}
|
||||
}
|
||||
|
||||
if (!dedicatedMemory) {
|
||||
auto gpuIdent = GPUIdent::getInstance();
|
||||
if (gpuIdent && gpuIdent->isValid()) {
|
||||
dedicatedMemory = MB_TO_BYTES(gpuIdent->getMemory());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return dedicatedMemory;
|
||||
}
|
||||
|
||||
Backend* GLBackend::createBackend() {
|
||||
return new GLBackend();
|
||||
}
|
||||
|
@ -140,6 +194,7 @@ void GLBackend::renderPassTransfer(Batch& batch) {
|
|||
const Batch::Commands::value_type* command = batch.getCommands().data();
|
||||
const Batch::CommandOffsets::value_type* offset = batch.getCommandOffsets().data();
|
||||
|
||||
_inRenderTransferPass = true;
|
||||
{ // Sync all the buffers
|
||||
PROFILE_RANGE("syncGPUBuffer");
|
||||
|
||||
|
@ -187,7 +242,7 @@ void GLBackend::renderPassTransfer(Batch& batch) {
|
|||
_transform.transfer(batch);
|
||||
}
|
||||
|
||||
|
||||
_inRenderTransferPass = false;
|
||||
}
|
||||
|
||||
void GLBackend::renderPassDraw(Batch& batch) {
|
||||
|
@ -246,24 +301,17 @@ void GLBackend::render(Batch& batch) {
|
|||
if (!batch.isStereoEnabled()) {
|
||||
_stereo._enable = false;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
PROFILE_RANGE("Transfer");
|
||||
renderPassTransfer(batch);
|
||||
}
|
||||
|
||||
{
|
||||
PROFILE_RANGE(_stereo._enable ? "LeftRender" : "Render");
|
||||
PROFILE_RANGE(_stereo._enable ? "Render Stereo" : "Render");
|
||||
renderPassDraw(batch);
|
||||
}
|
||||
|
||||
if (_stereo._enable) {
|
||||
PROFILE_RANGE("RightRender");
|
||||
_stereo._pass = 1;
|
||||
renderPassDraw(batch);
|
||||
_stereo._pass = 0;
|
||||
}
|
||||
|
||||
// Restore the saved stereo state for the next batch
|
||||
_stereo._enable = savedStereo;
|
||||
}
|
||||
|
@ -319,17 +367,38 @@ void GLBackend::syncCache() {
|
|||
glEnable(GL_LINE_SMOOTH);
|
||||
}
|
||||
|
||||
void GLBackend::setupStereoSide(int side) {
|
||||
ivec4 vp = _transform._viewport;
|
||||
vp.z /= 2;
|
||||
glViewport(vp.x + side * vp.z, vp.y, vp.z, vp.w);
|
||||
|
||||
_transform.bindCurrentCamera(side);
|
||||
}
|
||||
|
||||
|
||||
void GLBackend::do_draw(Batch& batch, size_t paramOffset) {
|
||||
Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint;
|
||||
GLenum mode = _primitiveToGLmode[primitiveType];
|
||||
uint32 numVertices = batch._params[paramOffset + 1]._uint;
|
||||
uint32 startVertex = batch._params[paramOffset + 0]._uint;
|
||||
glDrawArrays(mode, startVertex, numVertices);
|
||||
_stats._DSNumTriangles += numVertices / 3;
|
||||
_stats._DSNumDrawcalls++;
|
||||
|
||||
if (isStereo()) {
|
||||
setupStereoSide(0);
|
||||
glDrawArrays(mode, startVertex, numVertices);
|
||||
setupStereoSide(1);
|
||||
glDrawArrays(mode, startVertex, numVertices);
|
||||
|
||||
_stats._DSNumTriangles += 2 * numVertices / 3;
|
||||
_stats._DSNumDrawcalls += 2;
|
||||
|
||||
} else {
|
||||
glDrawArrays(mode, startVertex, numVertices);
|
||||
_stats._DSNumTriangles += numVertices / 3;
|
||||
_stats._DSNumDrawcalls++;
|
||||
}
|
||||
_stats._DSNumAPIDrawcalls++;
|
||||
|
||||
(void)CHECK_GL_ERROR();
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void GLBackend::do_drawIndexed(Batch& batch, size_t paramOffset) {
|
||||
|
@ -343,9 +412,19 @@ void GLBackend::do_drawIndexed(Batch& batch, size_t paramOffset) {
|
|||
auto typeByteSize = TYPE_SIZE[_input._indexBufferType];
|
||||
GLvoid* indexBufferByteOffset = reinterpret_cast<GLvoid*>(startIndex * typeByteSize + _input._indexBufferOffset);
|
||||
|
||||
glDrawElements(mode, numIndices, glType, indexBufferByteOffset);
|
||||
_stats._DSNumTriangles += numIndices / 3;
|
||||
_stats._DSNumDrawcalls++;
|
||||
if (isStereo()) {
|
||||
setupStereoSide(0);
|
||||
glDrawElements(mode, numIndices, glType, indexBufferByteOffset);
|
||||
setupStereoSide(1);
|
||||
glDrawElements(mode, numIndices, glType, indexBufferByteOffset);
|
||||
|
||||
_stats._DSNumTriangles += 2 * numIndices / 3;
|
||||
_stats._DSNumDrawcalls += 2;
|
||||
} else {
|
||||
glDrawElements(mode, numIndices, glType, indexBufferByteOffset);
|
||||
_stats._DSNumTriangles += numIndices / 3;
|
||||
_stats._DSNumDrawcalls++;
|
||||
}
|
||||
_stats._DSNumAPIDrawcalls++;
|
||||
|
||||
(void) CHECK_GL_ERROR();
|
||||
|
@ -358,14 +437,35 @@ void GLBackend::do_drawInstanced(Batch& batch, size_t paramOffset) {
|
|||
uint32 numVertices = batch._params[paramOffset + 2]._uint;
|
||||
uint32 startVertex = batch._params[paramOffset + 1]._uint;
|
||||
|
||||
glDrawArraysInstancedARB(mode, startVertex, numVertices, numInstances);
|
||||
_stats._DSNumTriangles += (numInstances * numVertices) / 3;
|
||||
_stats._DSNumDrawcalls += numInstances;
|
||||
|
||||
if (isStereo()) {
|
||||
GLint trueNumInstances = 2 * numInstances;
|
||||
|
||||
setupStereoSide(0);
|
||||
glDrawArraysInstancedARB(mode, startVertex, numVertices, numInstances);
|
||||
setupStereoSide(1);
|
||||
glDrawArraysInstancedARB(mode, startVertex, numVertices, numInstances);
|
||||
|
||||
_stats._DSNumTriangles += (trueNumInstances * numVertices) / 3;
|
||||
_stats._DSNumDrawcalls += trueNumInstances;
|
||||
} else {
|
||||
glDrawArraysInstancedARB(mode, startVertex, numVertices, numInstances);
|
||||
_stats._DSNumTriangles += (numInstances * numVertices) / 3;
|
||||
_stats._DSNumDrawcalls += numInstances;
|
||||
}
|
||||
_stats._DSNumAPIDrawcalls++;
|
||||
|
||||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void glbackend_glDrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex, GLuint baseinstance) {
|
||||
#if (GPU_INPUT_PROFILE == GPU_CORE_43)
|
||||
glDrawElementsInstancedBaseVertexBaseInstance(mode, count, type, indices, primcount, basevertex, baseinstance);
|
||||
#else
|
||||
glDrawElementsInstanced(mode, count, type, indices, primcount);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GLBackend::do_drawIndexedInstanced(Batch& batch, size_t paramOffset) {
|
||||
GLint numInstances = batch._params[paramOffset + 4]._uint;
|
||||
GLenum mode = _primitiveToGLmode[(Primitive)batch._params[paramOffset + 3]._uint];
|
||||
|
@ -378,15 +478,23 @@ void GLBackend::do_drawIndexedInstanced(Batch& batch, size_t paramOffset) {
|
|||
|
||||
auto typeByteSize = TYPE_SIZE[_input._indexBufferType];
|
||||
GLvoid* indexBufferByteOffset = reinterpret_cast<GLvoid*>(startIndex * typeByteSize + _input._indexBufferOffset);
|
||||
|
||||
#if (GPU_INPUT_PROFILE == GPU_CORE_43)
|
||||
glDrawElementsInstancedBaseVertexBaseInstance(mode, numIndices, glType, indexBufferByteOffset, numInstances, 0, startInstance);
|
||||
#else
|
||||
glDrawElementsInstanced(mode, numIndices, glType, indexBufferByteOffset, numInstances);
|
||||
Q_UNUSED(startInstance);
|
||||
#endif
|
||||
_stats._DSNumTriangles += (numInstances * numIndices) / 3;
|
||||
_stats._DSNumDrawcalls += numInstances;
|
||||
|
||||
if (isStereo()) {
|
||||
GLint trueNumInstances = 2 * numInstances;
|
||||
|
||||
setupStereoSide(0);
|
||||
glbackend_glDrawElementsInstancedBaseVertexBaseInstance(mode, numIndices, glType, indexBufferByteOffset, numInstances, 0, startInstance);
|
||||
setupStereoSide(1);
|
||||
glbackend_glDrawElementsInstancedBaseVertexBaseInstance(mode, numIndices, glType, indexBufferByteOffset, numInstances, 0, startInstance);
|
||||
|
||||
_stats._DSNumTriangles += (trueNumInstances * numIndices) / 3;
|
||||
_stats._DSNumDrawcalls += trueNumInstances;
|
||||
} else {
|
||||
glbackend_glDrawElementsInstancedBaseVertexBaseInstance(mode, numIndices, glType, indexBufferByteOffset, numInstances, 0, startInstance);
|
||||
_stats._DSNumTriangles += (numInstances * numIndices) / 3;
|
||||
_stats._DSNumDrawcalls += numInstances;
|
||||
}
|
||||
|
||||
_stats._DSNumAPIDrawcalls++;
|
||||
|
||||
(void)CHECK_GL_ERROR();
|
||||
|
@ -461,10 +569,9 @@ void GLBackend::resetStages() {
|
|||
|
||||
#define ADD_COMMAND_GL(call) _commands.push_back(COMMAND_##call); _commandOffsets.push_back(_params.size());
|
||||
|
||||
// As long as we don;t use several versions of shaders we can avoid this more complex code path
|
||||
// #define GET_UNIFORM_LOCATION(shaderUniformLoc) _pipeline._programShader->getUniformLocation(shaderUniformLoc, isStereo());
|
||||
#define GET_UNIFORM_LOCATION(shaderUniformLoc) shaderUniformLoc
|
||||
// THis will be used in the next PR
|
||||
// #define GET_UNIFORM_LOCATION(shaderUniformLoc) _pipeline._programShader->getUniformLocation(shaderUniformLoc)
|
||||
|
||||
|
||||
void Batch::_glActiveBindTexture(GLenum unit, GLenum target, GLuint texture) {
|
||||
// clean the cache on the texture unit we are going to use so the next call to setResourceTexture() at the same slot works fine
|
||||
|
@ -492,6 +599,7 @@ void Batch::_glUniform1i(GLint location, GLint v0) {
|
|||
_params.push_back(v0);
|
||||
_params.push_back(location);
|
||||
}
|
||||
|
||||
void GLBackend::do_glUniform1i(Batch& batch, size_t paramOffset) {
|
||||
if (_pipeline._program == 0) {
|
||||
// We should call updatePipeline() to bind the program but we are not doing that
|
||||
|
@ -499,6 +607,7 @@ void GLBackend::do_glUniform1i(Batch& batch, size_t paramOffset) {
|
|||
return;
|
||||
}
|
||||
updatePipeline();
|
||||
|
||||
glUniform1f(
|
||||
GET_UNIFORM_LOCATION(batch._params[paramOffset + 1]._int),
|
||||
batch._params[paramOffset + 0]._int);
|
||||
|
@ -688,6 +797,7 @@ void GLBackend::do_glUniformMatrix4fv(Batch& batch, size_t paramOffset) {
|
|||
return;
|
||||
}
|
||||
updatePipeline();
|
||||
|
||||
glUniformMatrix4fv(
|
||||
GET_UNIFORM_LOCATION(batch._params[paramOffset + 3]._int),
|
||||
batch._params[paramOffset + 2]._uint,
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <queue>
|
||||
#include <utility>
|
||||
#include <list>
|
||||
#include <array>
|
||||
|
||||
#include <gl/Config.h>
|
||||
|
||||
|
@ -37,6 +38,8 @@ class GLBackend : public Backend {
|
|||
explicit GLBackend(bool syncCache);
|
||||
GLBackend();
|
||||
public:
|
||||
static Context::Size getDedicatedMemory();
|
||||
|
||||
virtual ~GLBackend();
|
||||
|
||||
virtual void render(Batch& batch);
|
||||
|
@ -82,11 +85,35 @@ public:
|
|||
const Stamp _storageStamp;
|
||||
Stamp _contentStamp { 0 };
|
||||
const GLenum _target;
|
||||
const uint16 _maxMip;
|
||||
const uint16 _minMip;
|
||||
const bool _transferrable;
|
||||
|
||||
GLTexture(const gpu::Texture& gpuTexture);
|
||||
struct DownsampleSource {
|
||||
using Pointer = std::shared_ptr<DownsampleSource>;
|
||||
DownsampleSource(GLTexture& oldTexture);
|
||||
~DownsampleSource();
|
||||
const GLuint _texture;
|
||||
const uint16 _minMip;
|
||||
const uint16 _maxMip;
|
||||
};
|
||||
|
||||
DownsampleSource::Pointer _downsampleSource;
|
||||
|
||||
GLTexture(bool transferrable, const gpu::Texture& gpuTexture);
|
||||
GLTexture(GLTexture& originalTexture, const gpu::Texture& gpuTexture);
|
||||
~GLTexture();
|
||||
|
||||
// Return a floating point value indicating how much of the allowed
|
||||
// texture memory we are currently consuming. A value of 0 indicates
|
||||
// no texture memory usage, while a value of 1 indicates all available / allowed memory
|
||||
// is consumed. A value above 1 indicates that there is a problem.
|
||||
static float getMemoryPressure();
|
||||
|
||||
void withPreservedTexture(std::function<void()> f);
|
||||
|
||||
void createTexture();
|
||||
void allocateStorage();
|
||||
|
||||
GLuint size() const { return _size; }
|
||||
GLuint virtualSize() const { return _virtualSize; }
|
||||
|
@ -118,26 +145,34 @@ public:
|
|||
// Is the texture in a state where it can be rendered with no work?
|
||||
bool isReady() const;
|
||||
|
||||
// Is this texture pushing us over the memory limit?
|
||||
bool isOverMaxMemory() const;
|
||||
|
||||
// Move the image bits from the CPU to the GPU
|
||||
void transfer() const;
|
||||
|
||||
// Execute any post-move operations that must occur only on the main thread
|
||||
void postTransfer();
|
||||
|
||||
uint16 usedMipLevels() const { return (_maxMip - _minMip) + 1; }
|
||||
|
||||
static const size_t CUBE_NUM_FACES = 6;
|
||||
static const GLenum CUBE_FACE_LAYOUT[6];
|
||||
|
||||
private:
|
||||
friend class GLTextureTransferHelper;
|
||||
|
||||
GLTexture(bool transferrable, const gpu::Texture& gpuTexture, bool init);
|
||||
// at creation the true texture is created in GL
|
||||
// it becomes public only when ready.
|
||||
GLuint _privateTexture{ 0 };
|
||||
|
||||
void setSize(GLuint size);
|
||||
void setVirtualSize(GLuint size);
|
||||
const std::vector<GLenum>& getFaceTargets() const;
|
||||
|
||||
GLuint _size; // true size as reported by the gl api
|
||||
GLuint _virtualSize; // theorical size as expected
|
||||
GLuint _numLevels{ 0 };
|
||||
void setSize(GLuint size);
|
||||
|
||||
const GLuint _virtualSize; // theorical size as expected
|
||||
GLuint _size { 0 }; // true size as reported by the gl api
|
||||
|
||||
void transferMip(uint16_t mipLevel, uint8_t face = 0) const;
|
||||
|
||||
|
@ -167,24 +202,24 @@ public:
|
|||
};
|
||||
|
||||
using ShaderObjects = std::array< ShaderObject, NumVersions >;
|
||||
|
||||
using UniformMapping = std::map<GLint, GLint>;
|
||||
using UniformMappingVersions = std::vector<UniformMapping>;
|
||||
|
||||
|
||||
|
||||
GLShader();
|
||||
~GLShader();
|
||||
|
||||
ShaderObjects _shaderObjects;
|
||||
UniformMappingVersions _uniformMappings;
|
||||
|
||||
GLuint getProgram() const {
|
||||
return _shaderObjects[Mono].glprogram;
|
||||
GLuint getProgram(Version version = Mono) const {
|
||||
return _shaderObjects[version].glprogram;
|
||||
}
|
||||
|
||||
GLint getUniformLocation(GLint srcLoc) {
|
||||
GLint getUniformLocation(GLint srcLoc, Version version = Mono) {
|
||||
// THIS will be used in the future PR as we grow the number of versions
|
||||
// return _uniformMappings[version][srcLoc];
|
||||
return srcLoc;
|
||||
// THIS will be used in the next PR
|
||||
// return _uniformMappings[Mono][srcLoc];
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -319,9 +354,15 @@ public:
|
|||
void do_setStateColorWriteMask(uint32 mask);
|
||||
|
||||
protected:
|
||||
static const size_t INVALID_OFFSET = (size_t)-1;
|
||||
|
||||
bool _inRenderTransferPass;
|
||||
|
||||
void renderPassTransfer(Batch& batch);
|
||||
void renderPassDraw(Batch& batch);
|
||||
|
||||
void setupStereoSide(int side);
|
||||
|
||||
void initTextureTransferHelper();
|
||||
static void transferGPUObject(const TexturePointer& texture);
|
||||
|
||||
|
@ -404,7 +445,8 @@ protected:
|
|||
void resetTransformStage();
|
||||
|
||||
struct TransformStageState {
|
||||
using TransformCameras = std::vector<TransformCamera>;
|
||||
using CameraBufferElement = TransformCamera;
|
||||
using TransformCameras = std::vector<CameraBufferElement>;
|
||||
|
||||
TransformCamera _camera;
|
||||
TransformCameras _cameras;
|
||||
|
@ -428,9 +470,11 @@ protected:
|
|||
using List = std::list<Pair>;
|
||||
List _cameraOffsets;
|
||||
mutable List::const_iterator _camerasItr;
|
||||
mutable size_t _currentCameraOffset{ INVALID_OFFSET };
|
||||
|
||||
void preUpdate(size_t commandIndex, const StereoState& stereo);
|
||||
void update(size_t commandIndex, const StereoState& stereo) const;
|
||||
void bindCurrentCamera(int stereoSide) const;
|
||||
void transfer(const Batch& batch) const;
|
||||
} _transform;
|
||||
|
||||
|
|
|
@ -84,7 +84,9 @@ void GLBackend::do_setPipeline(Batch& batch, size_t paramOffset) {
|
|||
}
|
||||
|
||||
// check the program cache
|
||||
// pick the program version
|
||||
GLuint glprogram = pipelineObject->_program->getProgram();
|
||||
|
||||
if (_pipeline._program != glprogram) {
|
||||
_pipeline._program = glprogram;
|
||||
_pipeline._programShader = pipelineObject->_program;
|
||||
|
|
|
@ -312,12 +312,10 @@ GLBackend::GLShader* compileBackendShader(const Shader& shader) {
|
|||
|
||||
// Domain specific defines
|
||||
const std::string domainDefines[NUM_SHADER_DOMAINS] = {
|
||||
"#define VERTEX_SHADER",
|
||||
"#define PIXEL_SHADER"
|
||||
"#define GPU_VERTEX_SHADER",
|
||||
"#define GPU_PIXEL_SHADER"
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Versions specific of the shader
|
||||
const std::string versionDefines[GLBackend::GLShader::NumVersions] = {
|
||||
""
|
||||
|
@ -375,7 +373,6 @@ GLBackend::GLShader* compileBackendProgram(const Shader& program) {
|
|||
makeProgramBindings(programObject);
|
||||
}
|
||||
|
||||
|
||||
// So far so good, the program versions have all been created successfully
|
||||
GLBackend::GLShader* object = new GLBackend::GLShader();
|
||||
object->_shaderObjects = programObjects;
|
||||
|
|