Merge branch 'master' of github.com:highfidelity/hifi into feat/resource-prefetch

This commit is contained in:
Zach Pomerantz 2016-04-27 11:55:24 -07:00
commit bc8a171fde
788 changed files with 8278 additions and 2489 deletions

View file

@ -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

View file

@ -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) { };

View file

@ -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

View file

@ -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)

View file

@ -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);

View file

@ -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();
}
}
});

View file

@ -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);

View file

@ -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");

View file

@ -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)
}

View file

@ -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();
});

View file

@ -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;
}

View file

@ -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}
)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View 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,

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 645 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 330 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

View file

@ -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

View file

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -22,4 +22,19 @@ Windows.Window {
url: infoView.url
}
}
Component.onCompleted: {
centerWindow(root);
}
onVisibleChanged: {
if (visible) {
centerWindow(root);
}
}
function centerWindow() {
desktop.centerOnVisible(root);
}
}

View file

@ -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 }

View file

@ -19,7 +19,7 @@ Original.Button {
property int colorScheme: hifi.colorSchemes.light
width: 120
height: 28
height: hifi.dimensions.controlLineHeight
style: ButtonStyle {

View file

@ -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 {

View file

@ -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

View file

@ -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
}

View 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()
}
}

View file

@ -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 != ""
}
}

View file

@ -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;

View file

@ -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

View file

@ -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
}
}
}
}

View file

@ -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

View file

@ -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() {

View file

@ -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() {

View file

@ -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);

View file

@ -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()));

View file

@ -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";

View file

@ -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) {

View file

@ -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() {

View file

@ -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);

View file

@ -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;

View file

@ -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.

View file

@ -292,6 +292,8 @@ void AssetMappingModel::refresh() {
} else {
emit errorGettingMappings(request->getErrorString());
}
request->deleteLater();
});
request->start();

View 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

View file

@ -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);

View file

@ -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) <<

View file

@ -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() {

View file

@ -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);

View file

@ -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);
}

View file

@ -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());

View file

@ -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);
}

View file

@ -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);

View file

@ -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 {

View file

@ -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; }

View file

@ -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);
}

View file

@ -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 {

View file

@ -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;

View file

@ -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);

View file

@ -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 {

View file

@ -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

View file

@ -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;

View file

@ -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,

View file

@ -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;

View file

@ -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;

View file

@ -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;

Some files were not shown because too many files have changed in this diff Show more