From 6b29e314c20b672cf83a870724f966d2ad250357 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 25 Feb 2015 19:05:27 -0800 Subject: [PATCH 01/28] Adding the Stage of the Scene and exposing control of the sun light from javascript --- interface/src/Application.cpp | 15 +- libraries/gpu/src/gpu/Context.h | 2 +- libraries/gpu/src/gpu/GLBackend.h | 4 +- libraries/model/src/model/Stage.cpp | 442 ++++++++++++++++++ libraries/model/src/model/Stage.h | 200 ++++++++ .../src/SceneScriptingInterface.cpp | 36 ++ .../src/SceneScriptingInterface.h | 43 ++ libraries/script-engine/src/ScriptEngine.cpp | 5 + 8 files changed, 741 insertions(+), 6 deletions(-) create mode 100644 libraries/model/src/model/Stage.cpp create mode 100644 libraries/model/src/model/Stage.h create mode 100644 libraries/script-engine/src/SceneScriptingInterface.cpp create mode 100644 libraries/script-engine/src/SceneScriptingInterface.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a7e73da1bd..9b27c6c570 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -82,6 +82,8 @@ #include #include +#include + #include "Application.h" #include "AudioClient.h" #include "InterfaceVersion.h" @@ -2495,7 +2497,10 @@ void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) { glm::vec3 Application::getSunDirection() { // Sun direction is in fact just the location of the sun relative to the origin - return glm::normalize(_environment.getClosestData(_myCamera.getPosition()).getSunLocation(_myCamera.getPosition())); + // return glm::normalize(_environment.getClosestData(_myCamera.getPosition()).getSunLocation(_myCamera.getPosition())); + + auto skyStage = DependencyManager::get()->getSkyStage(); + return skyStage->getSunLight()->getDirection(); } void Application::updateShadowMap() { @@ -2505,7 +2510,7 @@ void Application::updateShadowMap() { glEnable(GL_DEPTH_TEST); glClear(GL_DEPTH_BUFFER_BIT); - glm::vec3 lightDirection = -getSunDirection(); + glm::vec3 lightDirection = getSunDirection(); glm::quat rotation = rotationBetween(IDENTITY_FRONT, lightDirection); glm::quat inverseRotation = glm::inverse(rotation); @@ -2875,7 +2880,11 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs { DependencyManager::get()->setAmbientLightMode(getRenderAmbientLight()); - DependencyManager::get()->setGlobalLight(-getSunDirection(), GLOBAL_LIGHT_COLOR, GLOBAL_LIGHT_INTENSITY); + // DependencyManager::get()->setGlobalLight(-getSunDirection(), GLOBAL_LIGHT_COLOR, GLOBAL_LIGHT_INTENSITY); + auto skyStage = DependencyManager::get()->getSkyStage(); +// DependencyManager::get()->setGlobalLight(-getSunDirection(), GLOBAL_LIGHT_COLOR, skyStage->_light->getIntensity()); + DependencyManager::get()->setGlobalLight(skyStage->getSunLight()->getDirection(), skyStage->getSunLight()->getColor(), skyStage->getSunLight()->getIntensity()); + PROFILE_RANGE("DeferredLighting"); PerformanceTimer perfTimer("lighting"); DependencyManager::get()->render(); diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h index b8cba3ded1..8140c91bf6 100644 --- a/libraries/gpu/src/gpu/Context.h +++ b/libraries/gpu/src/gpu/Context.h @@ -21,7 +21,7 @@ namespace gpu { class GPUObject { public: GPUObject() {} - ~GPUObject() {} + virtual ~GPUObject() {} }; class Batch; diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index e3450ae71a..806ba0b1eb 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -32,7 +32,7 @@ public: static void checkGLError(); - class GLBuffer { + class GLBuffer : public GPUObject { public: Stamp _stamp; GLuint _buffer; @@ -44,7 +44,7 @@ public: static void syncGPUObject(const Buffer& buffer); static GLuint getBufferID(const Buffer& buffer); - class GLTexture { + class GLTexture : public GPUObject { public: Stamp _storageStamp; Stamp _contentStamp; diff --git a/libraries/model/src/model/Stage.cpp b/libraries/model/src/model/Stage.cpp new file mode 100644 index 0000000000..64aa504965 --- /dev/null +++ b/libraries/model/src/model/Stage.cpp @@ -0,0 +1,442 @@ +// +// Stage.cpp +// libraries/model/src/model +// +// Created by Sam Gateau on 2/24/2015. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#include "Stage.h" + +#include +using namespace model; + + +void EarthSunModel::updateAll() const { + updateWorldToSurface(); + updateSurfaceToEye(); + updateSun(); +} + +Mat4d EarthSunModel::evalWorldToGeoLocationMat(double longitude, double latitude, double absAltitude, double scale) { + + + // Longitude is along Z axis but - from east to west + Mat4d rotLon = glm::rotate(glm::radians(longitude), Vec3d(0.0, 0.0, 1.0)); + + // latitude is along X axis + from south to north + Mat4d rotLat = glm::rotate(-glm::radians(latitude), Vec3d(1.0, 0.0, 0.0)); + + // translation is movin to the earth surface + altiture at the radius along Y axis + Mat4d surfaceT = glm::translate(Vec3d(0.0, -absAltitude, 0.0)); + + // Mat4d worldScale = glm::scale(Vec3d(scale)); + + Mat4d worldToGeoLocMat = surfaceT * rotLat * rotLon; + + return worldToGeoLocMat; +} + +void EarthSunModel::updateWorldToSurface() const { + // Check if the final position is too close to the earth center ? + double absAltitude = _earthRadius + _altitude; + if ( absAltitude < 0.01) { + absAltitude = 0.01; + } + + // Final world to local Frame + _worldToSurfaceMat = evalWorldToGeoLocationMat(_longitude, _latitude, absAltitude, _scale); + // and the inverse + _surfaceToWorldMat = glm::inverse(_worldToSurfaceMat); + + _surfacePos = Vec3d(_surfaceToWorldMat * Vec4d(0.0, 0.0, 0.0, 1.0)); +} + +void EarthSunModel::updateSurfaceToEye() const +{ + + _surfaceToEyeMat = glm::inverse(_eyeToSurfaceMat); + _worldToEyeMat = _surfaceToEyeMat * _worldToSurfaceMat; + _eyeToWorldMat = _surfaceToWorldMat * _eyeToSurfaceMat; + _eyePos = Vec3d(_eyeToWorldMat * Vec4d(0.0, 0.0, 0.0, 1.0) ); + _eyeDir = Vec3d(_eyeToWorldMat * Vec4d(0.0, 0.0, -1.0, 0.0) ); +} + +void EarthSunModel::updateSun() const { + // Longitude is along Y axis but - from east to west + Mat4d rotSunLon; + + Mat4d rotSun = evalWorldToGeoLocationMat(_sunLongitude, _sunLatitude, _earthRadius, _scale); + rotSun = glm::inverse(rotSun); + + _sunDir = Vec3d(rotSun * Vec4d(0.0, 1.0, 0.0, 0.0)); + + // sun direction is looking up toward Y axis at the specified sun lat, long + Vec3d lssd = Vec3d(_worldToSurfaceMat * Vec4d(_sunDir.x, _sunDir.y, _sunDir.z, 0.0)); + _surfaceSunDir = glm::normalize(Vec3(lssd.x, lssd.y, lssd.z)); +} + + +float moduloRange(float val, float minVal, float maxVal) { + float range = maxVal - minVal; + float rval = (val - minVal) / range; + float intval; + return modf(rval, &intval) * range + minVal; +} + +void EarthSunModel::setLatitude(float lat) { + _latitude = moduloRange(lat, -90.0f, 90.0f); + invalidate(); +} +void EarthSunModel::setLongitude(float lon) { + _longitude = moduloRange(lon, -180.0f, 180.0f); + invalidate(); +} +void EarthSunModel::setAltitude(float altitude) { + _altitude = moduloRange(altitude, -1000.f, 100000.f); + invalidate(); +} + +void EarthSunModel::setSunLatitude(float lat) { + _sunLatitude = moduloRange(lat, -90.0f, 90.0f); + invalidate(); +} +void EarthSunModel::setSunLongitude(float lon) { + _sunLongitude = moduloRange(lon, -180.0f, 180.0f); + invalidate(); +} + +const int NUM_DAYS_PER_YEAR = 365; +const float NUM_HOURS_PER_DAY = 24.0f; + +SunSkyStage::SunSkyStage() : + _sunLight(new Light()) +{ + _sunLight->setType(Light::SUN); + + setSunIntensity(1.0f); + setSunColor(Vec3(1.0f, 1.0f, 1.0f)); + + // setOriginLocation(45.0f, 20.0f, 1.0f); + setDayTime(18.0f); + setYearTime(60.0f); +} + +SunSkyStage::~SunSkyStage() { +} + +void SunSkyStage::setDayTime(float hour) { + _dayTime = moduloRange(hour, 0.f, NUM_HOURS_PER_DAY); + invalidate(); +} + +void SunSkyStage::setYearTime(unsigned int day) { + _yearTime = day % NUM_DAYS_PER_YEAR; + invalidate(); +} + +void SunSkyStage::setOriginLocation(float longitude, float latitude, float altitude) { + _earthSunModel.setLongitude(longitude); + _earthSunModel.setLatitude(latitude); + _earthSunModel.setAltitude(altitude); + invalidate(); +} + +void SunSkyStage::setSunColor(const Vec3& color) { + _sunLight->setColor(color); +} +void SunSkyStage::setSunIntensity(float intensity) { + _sunLight->setIntensity(intensity); +} + +void SunSkyStage::updateGraphicsObject() const { + // Always update the sunLongitude based on the current dayTIme and the current origin + _earthSunModel.setSunLongitude(_earthSunModel.getLongitude() + (-180.0 + 360.0 * _dayTime / NUM_HOURS_PER_DAY)); + + // And update the sunLAtitude as the declinaison depending of the time of the year + _earthSunModel.setSunLatitude(-(23.0 + 44.0/60.0)*cos(glm::radians((360.0/365.0)*(_yearTime + 10)))); + + Vec3d sunLightDir = -_earthSunModel.getSurfaceSunDir(); + + _sunLight->setDirection(Vec3(sunLightDir.x, sunLightDir.y, sunLightDir.z)); +} + + + + + + +// +// Environment.cpp +// interface/src +// +// Created by Andrzej Kapolka on 5/6/13. +// Copyright 2013 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "InterfaceConfig.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "Application.h" +#include "Camera.h" +#include "world.h" + +#include "Environment.h" + +uint qHash(const HifiSockAddr& sockAddr) { + if (sockAddr.getAddress().isNull()) { + return 0; // shouldn't happen, but if it does, zero is a perfectly valid hash + } + quint32 address = sockAddr.getAddress().toIPv4Address(); + return sockAddr.getPort() + qHash(QByteArray::fromRawData((char*) &address, + sizeof(address))); +} + +Environment::Environment() + : _initialized(false) { +} + +Environment::~Environment() { + if (_initialized) { + delete _skyFromAtmosphereProgram; + delete _skyFromSpaceProgram; + } +} + +void Environment::init() { + if (_initialized) { + qDebug("[ERROR] Environment is already initialized."); + return; + } + + _skyFromAtmosphereProgram = createSkyProgram("Atmosphere", _skyFromAtmosphereUniformLocations); + _skyFromSpaceProgram = createSkyProgram("Space", _skyFromSpaceUniformLocations); + + // start off with a default-constructed environment data + _data[HifiSockAddr()][0]; + + _initialized = true; +} + +void Environment::resetToDefault() { + _data.clear(); + _data[HifiSockAddr()][0]; +} + +void Environment::renderAtmospheres(Camera& camera) { + // get the lock for the duration of the call + QMutexLocker locker(&_mutex); + + foreach (const ServerData& serverData, _data) { + // TODO: do something about EnvironmentData + foreach (const EnvironmentData& environmentData, serverData) { + renderAtmosphere(camera, environmentData); + } + } +} + +glm::vec3 Environment::getGravity (const glm::vec3& position) { + // + // 'Default' gravity pulls you downward in Y when you are near the X/Z plane + const glm::vec3 DEFAULT_GRAVITY(0.0f, -1.0f, 0.0f); + glm::vec3 gravity(DEFAULT_GRAVITY); + float DEFAULT_SURFACE_RADIUS = 30.0f; + float gravityStrength; + + // Weaken gravity with height + if (position.y > 0.0f) { + gravityStrength = 1.0f / powf((DEFAULT_SURFACE_RADIUS + position.y) / DEFAULT_SURFACE_RADIUS, 2.0f); + gravity *= gravityStrength; + } + + // get the lock for the duration of the call + QMutexLocker locker(&_mutex); + + foreach (const ServerData& serverData, _data) { + foreach (const EnvironmentData& environmentData, serverData) { + glm::vec3 vector = environmentData.getAtmosphereCenter(position) - position; + float surfaceRadius = environmentData.getAtmosphereInnerRadius(); + if (glm::length(vector) <= surfaceRadius) { + // At or inside a planet, gravity is as set for the planet + gravity += glm::normalize(vector) * environmentData.getGravity(); + } else { + // Outside a planet, the gravity falls off with distance + gravityStrength = 1.0f / powf(glm::length(vector) / surfaceRadius, 2.0f); + gravity += glm::normalize(vector) * environmentData.getGravity() * gravityStrength; + } + } + } + + return gravity; +} + +const EnvironmentData Environment::getClosestData(const glm::vec3& position) { + // get the lock for the duration of the call + QMutexLocker locker(&_mutex); + + EnvironmentData closest; + float closestDistance = FLT_MAX; + foreach (const ServerData& serverData, _data) { + foreach (const EnvironmentData& environmentData, serverData) { + float distance = glm::distance(position, environmentData.getAtmosphereCenter(position)) - + environmentData.getAtmosphereOuterRadius(); + if (distance < closestDistance) { + closest = environmentData; + closestDistance = distance; + } + } + } + return closest; +} + +bool Environment::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, + float radius, glm::vec3& penetration) { + // collide with the "floor" + bool found = findCapsulePlanePenetration(start, end, radius, glm::vec4(0.0f, 1.0f, 0.0f, 0.0f), penetration); + + glm::vec3 middle = (start + end) * 0.5f; + + // get the lock for the duration of the call + QMutexLocker locker(&_mutex); + + foreach (const ServerData& serverData, _data) { + foreach (const EnvironmentData& environmentData, serverData) { + if (environmentData.getGravity() == 0.0f) { + continue; // don't bother colliding with gravity-less environments + } + glm::vec3 environmentPenetration; + if (findCapsuleSpherePenetration(start, end, radius, environmentData.getAtmosphereCenter(middle), + environmentData.getAtmosphereInnerRadius(), environmentPenetration)) { + penetration = addPenetrations(penetration, environmentPenetration); + found = true; + } + } + } + return found; +} + +int Environment::parseData(const HifiSockAddr& senderAddress, const QByteArray& packet) { + // push past the packet header + int bytesRead = numBytesForPacketHeader(packet); + + // push past flags, sequence, timestamp + bytesRead += sizeof(OCTREE_PACKET_FLAGS); + bytesRead += sizeof(OCTREE_PACKET_SEQUENCE); + bytesRead += sizeof(OCTREE_PACKET_SENT_TIME); + + // get the lock for the duration of the call + QMutexLocker locker(&_mutex); + + EnvironmentData newData; + while (bytesRead < packet.size()) { + int dataLength = newData.parseData(reinterpret_cast(packet.data()) + bytesRead, + packet.size() - bytesRead); + + // update the mapping by address/ID + _data[senderAddress][newData.getID()] = newData; + + bytesRead += dataLength; + } + + // remove the default mapping, if any + _data.remove(HifiSockAddr()); + + return bytesRead; +} + +ProgramObject* Environment::createSkyProgram(const char* from, int* locations) { + ProgramObject* program = new ProgramObject(); + QByteArray prefix = QString(PathUtils::resourcesPath() + "/shaders/SkyFrom" + from).toUtf8(); + program->addShaderFromSourceFile(QGLShader::Vertex, prefix + ".vert"); + program->addShaderFromSourceFile(QGLShader::Fragment, prefix + ".frag"); + program->link(); + + locations[CAMERA_POS_LOCATION] = program->uniformLocation("v3CameraPos"); + locations[LIGHT_POS_LOCATION] = program->uniformLocation("v3LightPos"); + locations[INV_WAVELENGTH_LOCATION] = program->uniformLocation("v3InvWavelength"); + locations[CAMERA_HEIGHT2_LOCATION] = program->uniformLocation("fCameraHeight2"); + locations[OUTER_RADIUS_LOCATION] = program->uniformLocation("fOuterRadius"); + locations[OUTER_RADIUS2_LOCATION] = program->uniformLocation("fOuterRadius2"); + locations[INNER_RADIUS_LOCATION] = program->uniformLocation("fInnerRadius"); + locations[KR_ESUN_LOCATION] = program->uniformLocation("fKrESun"); + locations[KM_ESUN_LOCATION] = program->uniformLocation("fKmESun"); + locations[KR_4PI_LOCATION] = program->uniformLocation("fKr4PI"); + locations[KM_4PI_LOCATION] = program->uniformLocation("fKm4PI"); + locations[SCALE_LOCATION] = program->uniformLocation("fScale"); + locations[SCALE_DEPTH_LOCATION] = program->uniformLocation("fScaleDepth"); + locations[SCALE_OVER_SCALE_DEPTH_LOCATION] = program->uniformLocation("fScaleOverScaleDepth"); + locations[G_LOCATION] = program->uniformLocation("g"); + locations[G2_LOCATION] = program->uniformLocation("g2"); + + return program; +} + +void Environment::renderAtmosphere(Camera& camera, const EnvironmentData& data) { + glm::vec3 center = data.getAtmosphereCenter(camera.getPosition()); + + glPushMatrix(); + glTranslatef(center.x, center.y, center.z); + + glm::vec3 relativeCameraPos = camera.getPosition() - center; + float height = glm::length(relativeCameraPos); + + // use the appropriate shader depending on whether we're inside or outside + ProgramObject* program; + int* locations; + if (height < data.getAtmosphereOuterRadius()) { + program = _skyFromAtmosphereProgram; + locations = _skyFromAtmosphereUniformLocations; + + } else { + program = _skyFromSpaceProgram; + locations = _skyFromSpaceUniformLocations; + } + + // the constants here are from Sean O'Neil's GPU Gems entry + // (http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html), GameEngine.cpp + program->bind(); + program->setUniform(locations[CAMERA_POS_LOCATION], relativeCameraPos); + glm::vec3 lightDirection = glm::normalize(data.getSunLocation()); + program->setUniform(locations[LIGHT_POS_LOCATION], lightDirection); + program->setUniformValue(locations[INV_WAVELENGTH_LOCATION], + 1 / powf(data.getScatteringWavelengths().r, 4.0f), + 1 / powf(data.getScatteringWavelengths().g, 4.0f), + 1 / powf(data.getScatteringWavelengths().b, 4.0f)); + program->setUniformValue(locations[CAMERA_HEIGHT2_LOCATION], height * height); + program->setUniformValue(locations[OUTER_RADIUS_LOCATION], data.getAtmosphereOuterRadius()); + program->setUniformValue(locations[OUTER_RADIUS2_LOCATION], data.getAtmosphereOuterRadius() * data.getAtmosphereOuterRadius()); + program->setUniformValue(locations[INNER_RADIUS_LOCATION], data.getAtmosphereInnerRadius()); + program->setUniformValue(locations[KR_ESUN_LOCATION], data.getRayleighScattering() * data.getSunBrightness()); + program->setUniformValue(locations[KM_ESUN_LOCATION], data.getMieScattering() * data.getSunBrightness()); + program->setUniformValue(locations[KR_4PI_LOCATION], data.getRayleighScattering() * 4.0f * PI); + program->setUniformValue(locations[KM_4PI_LOCATION], data.getMieScattering() * 4.0f * PI); + program->setUniformValue(locations[SCALE_LOCATION], 1.0f / (data.getAtmosphereOuterRadius() - data.getAtmosphereInnerRadius())); + program->setUniformValue(locations[SCALE_DEPTH_LOCATION], 0.25f); + program->setUniformValue(locations[SCALE_OVER_SCALE_DEPTH_LOCATION], + (1.0f / (data.getAtmosphereOuterRadius() - data.getAtmosphereInnerRadius())) / 0.25f); + program->setUniformValue(locations[G_LOCATION], -0.990f); + program->setUniformValue(locations[G2_LOCATION], -0.990f * -0.990f); + + glDepthMask(GL_FALSE); + glDisable(GL_DEPTH_TEST); + DependencyManager::get()->renderSphere(1.0f, 100, 50, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); //Draw a unit sphere + glDepthMask(GL_TRUE); + + program->release(); + + glPopMatrix(); +} diff --git a/libraries/model/src/model/Stage.h b/libraries/model/src/model/Stage.h new file mode 100644 index 0000000000..9b2922e163 --- /dev/null +++ b/libraries/model/src/model/Stage.h @@ -0,0 +1,200 @@ +// +// Stage.h +// libraries/model/src/model +// +// Created by Sam Gateau on 2/24/2015. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#ifndef hifi_model_Stage_h +#define hifi_model_Stage_h + +#include "Light.h" + +namespace model { + +typedef glm::dvec3 Vec3d; +typedef glm::dvec4 Vec4d; +typedef glm::dmat4 Mat4d; +typedef glm::mat4 Mat4; + +class EarthSunModel { +public: + enum Preset + { + Toulouse = 0, + SanFrancisco, + Sydney, + Num_Presets, + }; + static const std::string PresetNames[Num_Presets]; + //void assignPreset( Preset p); + //Preset preset() const { return mPreset; } + + void setScale(float scale); + float getScale() const { return _scale; } + + void setLatitude(float lat); + float getLatitude() const { return _latitude; } + void setLongitude(float lon); + float getLongitude() const { return _longitude; } + void setAltitude(float altitude); + float getAltitude() const { return _altitude; } + + const Vec3d& getSurfacePos() const { valid(); return _surfacePos; } + + const Mat4d& getSurfaceToWorldMat() const { valid(); return _surfaceToWorldMat; } + const Mat4d& getWoldToSurfaceMat() const { valid(); return _worldToSurfaceMat; } + + const Mat4d& getEyeToSurfaceMat() const { valid(); return _eyeToSurfaceMat; } + const Mat4d& getSurfaceToEyeMat() const { valid(); return _surfaceToEyeMat; } + + const Mat4d& getEyeToWorldMat() const { valid(); return _eyeToWorldMat; } + const Mat4d& getWorldToEyeMat() const { valid(); return _worldToEyeMat; } + + + //or set the surfaceToEye mat directly + void setEyeToSurfaceMat( const Mat4d& e2s); + + const Vec3d& getEyePos() const { valid(); return _eyePos; } + const Vec3d& getEyeDir() const { valid(); return _eyeDir; } + + void setSunLongitude(float lon); + float getSunLongitude() const { return _sunLongitude; } + + void setSunLatitude(float lat); + float getSunLatitude() const { return _sunLatitude; } + + const Vec3d& getWorldSunDir() const { valid(); return _sunDir; } + const Vec3d& getSurfaceSunDir() const { valid(); return _surfaceSunDir; } + + + EarthSunModel() { valid(); } + +protected: + double _scale = 1000.0; //Km + double _earthRadius = 6360.0; + + double _longitude = 0.0; + double _latitude = 0.0; + double _altitude = 0.01; + mutable Vec3d _surfacePos; + mutable Mat4d _worldToSurfaceMat; + mutable Mat4d _surfaceToWorldMat; + void updateWorldToSurface() const; + + mutable Mat4d _surfaceToEyeMat; + mutable Mat4d _eyeToSurfaceMat; + mutable Vec3d _eyeDir; + mutable Vec3d _eyePos; + void updateSurfaceToEye() const; + + mutable Mat4d _worldToEyeMat; + mutable Mat4d _eyeToWorldMat; + + double _sunLongitude = 0.0; + double _sunLatitude = 0.0; + mutable Vec3d _sunDir; + mutable Vec3d _surfaceSunDir; + void updateSun() const; + + mutable bool _invalid = true; + void invalidate() const { _invalid = true; } + void valid() const { if (_invalid) { updateAll(); _invalid = false; } } + void updateAll() const; + + static Mat4d evalWorldToGeoLocationMat(double longitude, double latitude, double altitude, double scale); +}; + +namespace gpu { + class Batch; +}; + +class ProgramObject; + +class Skybox { +public: + void recordBatch(gpu::Batch& batch, const Transform& viewTransform, const Mat4& projection); + + Skybox(); + ~Skybox(); +protected: + ProgramObject* createSkyProgram(const char* from, int* locations); + ProgramObject* _skyFromAtmosphereProgram; + ProgramObject* _skyFromSpaceProgram; + enum { + CAMERA_POS_LOCATION, + LIGHT_POS_LOCATION, + INV_WAVELENGTH_LOCATION, + CAMERA_HEIGHT2_LOCATION, + OUTER_RADIUS_LOCATION, + OUTER_RADIUS2_LOCATION, + INNER_RADIUS_LOCATION, + KR_ESUN_LOCATION, + KM_ESUN_LOCATION, + KR_4PI_LOCATION, + KM_4PI_LOCATION, + SCALE_LOCATION, + SCALE_DEPTH_LOCATION, + SCALE_OVER_SCALE_DEPTH_LOCATION, + G_LOCATION, + G2_LOCATION, + LOCATION_COUNT + }; + + int _skyFromAtmosphereUniformLocations[LOCATION_COUNT]; + int _skyFromSpaceUniformLocations[LOCATION_COUNT]; +}; + +// Sun sky stage generates the rendering primitives to display a scene realistically +// at the specified location and time around earth +class SunSkyStage { +public: + + SunSkyStage(); + ~SunSkyStage(); + + // time of the day (local to the position) expressed in decimal hour in the range [0.0, 24.0] + void setDayTime(float hour); + float getDayTime() const { return _dayTime; } + + // time of the year expressed in day in the range [0, 365] + void setYearTime(unsigned int day); + unsigned int getYearTime() const { return _yearTime; } + + // Location used to define the sun & sky is a longitude and latitude [rad] and a earth surface altitude [km] + void setOriginLocation(float longitude, float latitude, float surfaceAltitude); + float getOriginLatitude() const { return _earthSunModel.getLatitude(); } + float getOriginLongitude() const { return _earthSunModel.getLongitude(); } + float getOriginSurfaceAltitude() const { return _earthSunModel.getAltitude(); } + + // Sun properties + void setSunColor(const Vec3& color); + const Vec3& getSunColor() const { return getSunLight()->getColor(); } + void setSunIntensity(float intensity); + float getSunIntensity() const { return getSunLight()->getIntensity(); } + + LightPointer getSunLight() const { valid(); return _sunLight; } + +protected: + LightPointer _sunLight; + + // default day is 1st of january at noun + float _dayTime = 12.0f; + int _yearTime = 0; + + mutable EarthSunModel _earthSunModel; + + mutable bool _invalid = true; + void invalidate() const { _invalid = true; } + void valid() const { if (_invalid) { updateGraphicsObject(); _invalid = false; } } + void updateGraphicsObject() const; +}; + +typedef QSharedPointer< SunSkyStage > SunSkyStagePointer; + +}; + +#endif diff --git a/libraries/script-engine/src/SceneScriptingInterface.cpp b/libraries/script-engine/src/SceneScriptingInterface.cpp new file mode 100644 index 0000000000..ff255a3e5e --- /dev/null +++ b/libraries/script-engine/src/SceneScriptingInterface.cpp @@ -0,0 +1,36 @@ +// +// SceneScriptingInterface.cpp +// interface/src/scripting +// +// Created by Sam Gateau on 2/24/15. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include + +#include "SceneScriptingInterface.h" + + Q_INVOKABLE void setOriginGeoLocation(float longitude, float latitude, float altitude); +void SceneScriptingInterface::setOriginLocation(float longitude, float latitude, float altitude) { + _skyStage->setOriginLocation(longitude, latitude, altitude); +} +void SceneScriptingInterface::setSunColor(const glm::vec3& color) { + _skyStage->setSunColor(color); +} +void SceneScriptingInterface::setSunIntensity(float intensity) { + _skyStage->setSunIntensity(intensity); +} + +void SceneScriptingInterface::setDayTime(float hour) { + _skyStage->setDayTime(hour); +} +void SceneScriptingInterface::setYearTime(int day) { + _skyStage->setYearTime(day); +} + +model::SunSkyStagePointer SceneScriptingInterface::getSkyStage() const { + return _skyStage; +} \ No newline at end of file diff --git a/libraries/script-engine/src/SceneScriptingInterface.h b/libraries/script-engine/src/SceneScriptingInterface.h new file mode 100644 index 0000000000..3fc909f9a0 --- /dev/null +++ b/libraries/script-engine/src/SceneScriptingInterface.h @@ -0,0 +1,43 @@ +// +// SceneScriptingInterface.h +// interface/src/scripting +// +// Created by Sam Gateau on 2/24/15. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_SceneScriptingInterface_h +#define hifi_SceneScriptingInterface_h + +#include + +#include + +#include "model/Stage.h" + +class SceneScriptingInterface : public QObject, public Dependency { + Q_OBJECT + SINGLETON_DEPENDENCY + +public: + Q_INVOKABLE void setOriginLocation(float longitude, float latitude, float altitude); + + Q_INVOKABLE void setSunColor(const glm::vec3& color); + Q_INVOKABLE void setSunIntensity(float intensity); + + Q_INVOKABLE void setDayTime(float hour); + Q_INVOKABLE void setYearTime(int day); + + model::SunSkyStagePointer getSkyStage() const; + +protected: + SceneScriptingInterface() {}; + ~SceneScriptingInterface() {}; + + model::SunSkyStagePointer _skyStage = model::SunSkyStagePointer(new model::SunSkyStage()); +}; + +#endif // hifi_SceneScriptingInterface_h diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 0956374238..aed5d91410 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -39,6 +39,8 @@ #include "TypedArrays.h" #include "XMLHttpRequestClass.h" +#include "SceneScriptingInterface.h" + #include "MIDIEvent.h" EntityScriptingInterface ScriptEngine::_entityScriptingInterface; @@ -208,6 +210,8 @@ void ScriptEngine::init() { _isInitialized = true; + auto sceneScriptingInterface = DependencyManager::set(); + _entityScriptingInterface.init(); // register various meta-types @@ -251,6 +255,7 @@ void ScriptEngine::init() { registerGlobalObject("Vec3", &_vec3Library); registerGlobalObject("Uuid", &_uuidLibrary); registerGlobalObject("AnimationCache", DependencyManager::get().data()); + registerGlobalObject("Scene", DependencyManager::get().data()); // constants globalObject().setProperty("TREE_SCALE", newVariant(QVariant(TREE_SCALE))); From b4cb5ca9d1e455ec7425a950259bdbc7bb65c9f7 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 25 Feb 2015 19:09:18 -0800 Subject: [PATCH 02/28] add an example script to control the sun light --- examples/example/misc/sunLightExample.js | 32 ++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 examples/example/misc/sunLightExample.js diff --git a/examples/example/misc/sunLightExample.js b/examples/example/misc/sunLightExample.js new file mode 100644 index 0000000000..0bc3b0dfea --- /dev/null +++ b/examples/example/misc/sunLightExample.js @@ -0,0 +1,32 @@ +// +// SunLightExample.js +// examples +// Sam Gateau +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var intensity = 1.0; +var day = 0.0; +var hour = 12.0; +var longitude = 0.0; +var latitude = -45.0; + +Scene.setDayTime(hour); +Scene.setOriginLocation(longitude, latitude, 0.0); + +function ticktack() { + hour += 0.1; + //Scene.setSunIntensity(Math.cos(time)); + if (hour > 24.0) { + hour = 0.0; + day++; + Scene.setYearTime(day); + } + Scene.setDayTime(hour); + +} + +Script.setInterval(ticktack, 41); From 4959e2924e0bd00ab17ed7812763c35cfae5300b Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 25 Feb 2015 19:17:38 -0800 Subject: [PATCH 03/28] add an example script to control the sun light --- libraries/model/src/model/Stage.cpp | 277 ---------------------------- 1 file changed, 277 deletions(-) diff --git a/libraries/model/src/model/Stage.cpp b/libraries/model/src/model/Stage.cpp index 64aa504965..dcd633f35c 100644 --- a/libraries/model/src/model/Stage.cpp +++ b/libraries/model/src/model/Stage.cpp @@ -163,280 +163,3 @@ void SunSkyStage::updateGraphicsObject() const { _sunLight->setDirection(Vec3(sunLightDir.x, sunLightDir.y, sunLightDir.z)); } - - - - - -// -// Environment.cpp -// interface/src -// -// Created by Andrzej Kapolka on 5/6/13. -// Copyright 2013 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "InterfaceConfig.h" - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "Application.h" -#include "Camera.h" -#include "world.h" - -#include "Environment.h" - -uint qHash(const HifiSockAddr& sockAddr) { - if (sockAddr.getAddress().isNull()) { - return 0; // shouldn't happen, but if it does, zero is a perfectly valid hash - } - quint32 address = sockAddr.getAddress().toIPv4Address(); - return sockAddr.getPort() + qHash(QByteArray::fromRawData((char*) &address, - sizeof(address))); -} - -Environment::Environment() - : _initialized(false) { -} - -Environment::~Environment() { - if (_initialized) { - delete _skyFromAtmosphereProgram; - delete _skyFromSpaceProgram; - } -} - -void Environment::init() { - if (_initialized) { - qDebug("[ERROR] Environment is already initialized."); - return; - } - - _skyFromAtmosphereProgram = createSkyProgram("Atmosphere", _skyFromAtmosphereUniformLocations); - _skyFromSpaceProgram = createSkyProgram("Space", _skyFromSpaceUniformLocations); - - // start off with a default-constructed environment data - _data[HifiSockAddr()][0]; - - _initialized = true; -} - -void Environment::resetToDefault() { - _data.clear(); - _data[HifiSockAddr()][0]; -} - -void Environment::renderAtmospheres(Camera& camera) { - // get the lock for the duration of the call - QMutexLocker locker(&_mutex); - - foreach (const ServerData& serverData, _data) { - // TODO: do something about EnvironmentData - foreach (const EnvironmentData& environmentData, serverData) { - renderAtmosphere(camera, environmentData); - } - } -} - -glm::vec3 Environment::getGravity (const glm::vec3& position) { - // - // 'Default' gravity pulls you downward in Y when you are near the X/Z plane - const glm::vec3 DEFAULT_GRAVITY(0.0f, -1.0f, 0.0f); - glm::vec3 gravity(DEFAULT_GRAVITY); - float DEFAULT_SURFACE_RADIUS = 30.0f; - float gravityStrength; - - // Weaken gravity with height - if (position.y > 0.0f) { - gravityStrength = 1.0f / powf((DEFAULT_SURFACE_RADIUS + position.y) / DEFAULT_SURFACE_RADIUS, 2.0f); - gravity *= gravityStrength; - } - - // get the lock for the duration of the call - QMutexLocker locker(&_mutex); - - foreach (const ServerData& serverData, _data) { - foreach (const EnvironmentData& environmentData, serverData) { - glm::vec3 vector = environmentData.getAtmosphereCenter(position) - position; - float surfaceRadius = environmentData.getAtmosphereInnerRadius(); - if (glm::length(vector) <= surfaceRadius) { - // At or inside a planet, gravity is as set for the planet - gravity += glm::normalize(vector) * environmentData.getGravity(); - } else { - // Outside a planet, the gravity falls off with distance - gravityStrength = 1.0f / powf(glm::length(vector) / surfaceRadius, 2.0f); - gravity += glm::normalize(vector) * environmentData.getGravity() * gravityStrength; - } - } - } - - return gravity; -} - -const EnvironmentData Environment::getClosestData(const glm::vec3& position) { - // get the lock for the duration of the call - QMutexLocker locker(&_mutex); - - EnvironmentData closest; - float closestDistance = FLT_MAX; - foreach (const ServerData& serverData, _data) { - foreach (const EnvironmentData& environmentData, serverData) { - float distance = glm::distance(position, environmentData.getAtmosphereCenter(position)) - - environmentData.getAtmosphereOuterRadius(); - if (distance < closestDistance) { - closest = environmentData; - closestDistance = distance; - } - } - } - return closest; -} - -bool Environment::findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, - float radius, glm::vec3& penetration) { - // collide with the "floor" - bool found = findCapsulePlanePenetration(start, end, radius, glm::vec4(0.0f, 1.0f, 0.0f, 0.0f), penetration); - - glm::vec3 middle = (start + end) * 0.5f; - - // get the lock for the duration of the call - QMutexLocker locker(&_mutex); - - foreach (const ServerData& serverData, _data) { - foreach (const EnvironmentData& environmentData, serverData) { - if (environmentData.getGravity() == 0.0f) { - continue; // don't bother colliding with gravity-less environments - } - glm::vec3 environmentPenetration; - if (findCapsuleSpherePenetration(start, end, radius, environmentData.getAtmosphereCenter(middle), - environmentData.getAtmosphereInnerRadius(), environmentPenetration)) { - penetration = addPenetrations(penetration, environmentPenetration); - found = true; - } - } - } - return found; -} - -int Environment::parseData(const HifiSockAddr& senderAddress, const QByteArray& packet) { - // push past the packet header - int bytesRead = numBytesForPacketHeader(packet); - - // push past flags, sequence, timestamp - bytesRead += sizeof(OCTREE_PACKET_FLAGS); - bytesRead += sizeof(OCTREE_PACKET_SEQUENCE); - bytesRead += sizeof(OCTREE_PACKET_SENT_TIME); - - // get the lock for the duration of the call - QMutexLocker locker(&_mutex); - - EnvironmentData newData; - while (bytesRead < packet.size()) { - int dataLength = newData.parseData(reinterpret_cast(packet.data()) + bytesRead, - packet.size() - bytesRead); - - // update the mapping by address/ID - _data[senderAddress][newData.getID()] = newData; - - bytesRead += dataLength; - } - - // remove the default mapping, if any - _data.remove(HifiSockAddr()); - - return bytesRead; -} - -ProgramObject* Environment::createSkyProgram(const char* from, int* locations) { - ProgramObject* program = new ProgramObject(); - QByteArray prefix = QString(PathUtils::resourcesPath() + "/shaders/SkyFrom" + from).toUtf8(); - program->addShaderFromSourceFile(QGLShader::Vertex, prefix + ".vert"); - program->addShaderFromSourceFile(QGLShader::Fragment, prefix + ".frag"); - program->link(); - - locations[CAMERA_POS_LOCATION] = program->uniformLocation("v3CameraPos"); - locations[LIGHT_POS_LOCATION] = program->uniformLocation("v3LightPos"); - locations[INV_WAVELENGTH_LOCATION] = program->uniformLocation("v3InvWavelength"); - locations[CAMERA_HEIGHT2_LOCATION] = program->uniformLocation("fCameraHeight2"); - locations[OUTER_RADIUS_LOCATION] = program->uniformLocation("fOuterRadius"); - locations[OUTER_RADIUS2_LOCATION] = program->uniformLocation("fOuterRadius2"); - locations[INNER_RADIUS_LOCATION] = program->uniformLocation("fInnerRadius"); - locations[KR_ESUN_LOCATION] = program->uniformLocation("fKrESun"); - locations[KM_ESUN_LOCATION] = program->uniformLocation("fKmESun"); - locations[KR_4PI_LOCATION] = program->uniformLocation("fKr4PI"); - locations[KM_4PI_LOCATION] = program->uniformLocation("fKm4PI"); - locations[SCALE_LOCATION] = program->uniformLocation("fScale"); - locations[SCALE_DEPTH_LOCATION] = program->uniformLocation("fScaleDepth"); - locations[SCALE_OVER_SCALE_DEPTH_LOCATION] = program->uniformLocation("fScaleOverScaleDepth"); - locations[G_LOCATION] = program->uniformLocation("g"); - locations[G2_LOCATION] = program->uniformLocation("g2"); - - return program; -} - -void Environment::renderAtmosphere(Camera& camera, const EnvironmentData& data) { - glm::vec3 center = data.getAtmosphereCenter(camera.getPosition()); - - glPushMatrix(); - glTranslatef(center.x, center.y, center.z); - - glm::vec3 relativeCameraPos = camera.getPosition() - center; - float height = glm::length(relativeCameraPos); - - // use the appropriate shader depending on whether we're inside or outside - ProgramObject* program; - int* locations; - if (height < data.getAtmosphereOuterRadius()) { - program = _skyFromAtmosphereProgram; - locations = _skyFromAtmosphereUniformLocations; - - } else { - program = _skyFromSpaceProgram; - locations = _skyFromSpaceUniformLocations; - } - - // the constants here are from Sean O'Neil's GPU Gems entry - // (http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html), GameEngine.cpp - program->bind(); - program->setUniform(locations[CAMERA_POS_LOCATION], relativeCameraPos); - glm::vec3 lightDirection = glm::normalize(data.getSunLocation()); - program->setUniform(locations[LIGHT_POS_LOCATION], lightDirection); - program->setUniformValue(locations[INV_WAVELENGTH_LOCATION], - 1 / powf(data.getScatteringWavelengths().r, 4.0f), - 1 / powf(data.getScatteringWavelengths().g, 4.0f), - 1 / powf(data.getScatteringWavelengths().b, 4.0f)); - program->setUniformValue(locations[CAMERA_HEIGHT2_LOCATION], height * height); - program->setUniformValue(locations[OUTER_RADIUS_LOCATION], data.getAtmosphereOuterRadius()); - program->setUniformValue(locations[OUTER_RADIUS2_LOCATION], data.getAtmosphereOuterRadius() * data.getAtmosphereOuterRadius()); - program->setUniformValue(locations[INNER_RADIUS_LOCATION], data.getAtmosphereInnerRadius()); - program->setUniformValue(locations[KR_ESUN_LOCATION], data.getRayleighScattering() * data.getSunBrightness()); - program->setUniformValue(locations[KM_ESUN_LOCATION], data.getMieScattering() * data.getSunBrightness()); - program->setUniformValue(locations[KR_4PI_LOCATION], data.getRayleighScattering() * 4.0f * PI); - program->setUniformValue(locations[KM_4PI_LOCATION], data.getMieScattering() * 4.0f * PI); - program->setUniformValue(locations[SCALE_LOCATION], 1.0f / (data.getAtmosphereOuterRadius() - data.getAtmosphereInnerRadius())); - program->setUniformValue(locations[SCALE_DEPTH_LOCATION], 0.25f); - program->setUniformValue(locations[SCALE_OVER_SCALE_DEPTH_LOCATION], - (1.0f / (data.getAtmosphereOuterRadius() - data.getAtmosphereInnerRadius())) / 0.25f); - program->setUniformValue(locations[G_LOCATION], -0.990f); - program->setUniformValue(locations[G2_LOCATION], -0.990f * -0.990f); - - glDepthMask(GL_FALSE); - glDisable(GL_DEPTH_TEST); - DependencyManager::get()->renderSphere(1.0f, 100, 50, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); //Draw a unit sphere - glDepthMask(GL_TRUE); - - program->release(); - - glPopMatrix(); -} From 8eb4abc49cb8c23c344be69a2e50e813b6b32bf2 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 26 Feb 2015 19:14:09 +0100 Subject: [PATCH 04/28] Rework FaceTracker --- interface/src/devices/FaceTracker.cpp | 5 ++--- interface/src/devices/FaceTracker.h | 24 +++++++++++++++++------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/interface/src/devices/FaceTracker.cpp b/interface/src/devices/FaceTracker.cpp index 52fe04de77..8d61789715 100644 --- a/interface/src/devices/FaceTracker.cpp +++ b/interface/src/devices/FaceTracker.cpp @@ -11,7 +11,6 @@ #include "FaceTracker.h" -FaceTracker::FaceTracker() : - _estimatedEyePitch(0.0f), - _estimatedEyeYaw(0.0f) { +inline float FaceTracker::getBlendshapeCoefficient(int index) const { + return isValidBlendshapeIndex(index) ? _blendshapeCoefficients[index] : 0.0f; } diff --git a/interface/src/devices/FaceTracker.h b/interface/src/devices/FaceTracker.h index 7c367b7899..07c479e3e3 100644 --- a/interface/src/devices/FaceTracker.h +++ b/interface/src/devices/FaceTracker.h @@ -18,13 +18,17 @@ #include #include -/// Base class for face trackers (Faceshift, Visage). +/// Base class for face trackers (Faceshift, Visage, DDE). class FaceTracker : public QObject { Q_OBJECT public: - FaceTracker(); - virtual ~FaceTracker() {} + virtual bool isActive() const { return false; } + virtual bool isTracking() const { return false; } + + virtual void init() {} + virtual void update(float deltaTime) {} + virtual void reset() {} const glm::vec3& getHeadTranslation() const { return _headTranslation; } const glm::quat& getHeadRotation() const { return _headRotation; } @@ -32,15 +36,21 @@ public: float getEstimatedEyePitch() const { return _estimatedEyePitch; } float getEstimatedEyeYaw() const { return _estimatedEyeYaw; } + int getNumBlendshapes() const { return _blendshapeCoefficients.size(); } + bool isValidBlendshapeIndex(int index) const { return index >= 0 && index < getNumBlendshapes(); } const QVector& getBlendshapeCoefficients() const { return _blendshapeCoefficients; } + float getBlendshapeCoefficient(int index) const; protected: - glm::vec3 _headTranslation; - glm::quat _headRotation; - float _estimatedEyePitch; - float _estimatedEyeYaw; + + glm::vec3 _headTranslation = glm::vec3(0.0f); + glm::quat _headRotation = glm::quat(); + float _estimatedEyePitch = 0.0f; + float _estimatedEyeYaw = 0.0f; QVector _blendshapeCoefficients; + + float _fadeCoefficient = 0.0f; }; #endif // hifi_FaceTracker_h From b6968a6b1538875504b4f90b6d71038b13b75850 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 26 Feb 2015 19:15:49 +0100 Subject: [PATCH 05/28] Update Facetrackers --- interface/src/devices/DdeFaceTracker.cpp | 18 +---- interface/src/devices/DdeFaceTracker.h | 10 ++- interface/src/devices/Faceshift.cpp | 73 ++++++------------- interface/src/devices/Faceshift.h | 89 ++++++++++++------------ interface/src/devices/Visage.cpp | 3 +- interface/src/devices/Visage.h | 10 +-- 6 files changed, 77 insertions(+), 126 deletions(-) diff --git a/interface/src/devices/DdeFaceTracker.cpp b/interface/src/devices/DdeFaceTracker.cpp index 87a180bd1e..ed0e4057ef 100644 --- a/interface/src/devices/DdeFaceTracker.cpp +++ b/interface/src/devices/DdeFaceTracker.cpp @@ -50,6 +50,8 @@ DdeFaceTracker::DdeFaceTracker() : } DdeFaceTracker::DdeFaceTracker(const QHostAddress& host, quint16 port) : + _host(host), + _port(port), _lastReceiveTimestamp(0), _reset(false), _leftBlinkIndex(0), // see http://support.faceshift.com/support/articles/35129-export-of-blendshapes @@ -63,9 +65,7 @@ DdeFaceTracker::DdeFaceTracker(const QHostAddress& host, quint16 port) : _browUpRightIndex(18), _mouthSmileLeftIndex(28), _mouthSmileRightIndex(29), - _jawOpenIndex(21), - _host(host), - _port(port) + _jawOpenIndex(21) { _blendshapeCoefficients.resize(NUM_EXPRESSION); @@ -80,18 +80,6 @@ DdeFaceTracker::~DdeFaceTracker() { } } -void DdeFaceTracker::init() { - -} - -void DdeFaceTracker::reset() { - _reset = true; -} - -void DdeFaceTracker::update() { - -} - void DdeFaceTracker::setEnabled(bool enabled) { // isOpen() does not work as one might expect on QUdpSocket; don't test isOpen() before closing socket. _udpSocket.close(); diff --git a/interface/src/devices/DdeFaceTracker.h b/interface/src/devices/DdeFaceTracker.h index bd5d066732..88528370a2 100644 --- a/interface/src/devices/DdeFaceTracker.h +++ b/interface/src/devices/DdeFaceTracker.h @@ -23,12 +23,10 @@ class DdeFaceTracker : public FaceTracker, public Dependency { SINGLETON_DEPENDENCY public: - //initialization - void init(); - void reset(); - void update(); - - bool isActive() const; + virtual void reset() { _reset = true; } + + virtual bool isActive() const; + virtual bool isTracking() const { return isActive(); } float getLeftBlink() const { return getBlendshapeCoefficient(_leftBlinkIndex); } float getRightBlink() const { return getBlendshapeCoefficient(_rightBlinkIndex); } diff --git a/interface/src/devices/Faceshift.cpp b/interface/src/devices/Faceshift.cpp index 2f541c1c4e..87ee0ef31c 100644 --- a/interface/src/devices/Faceshift.cpp +++ b/interface/src/devices/Faceshift.cpp @@ -25,37 +25,11 @@ using namespace fs; using namespace std; +const QString DEFAULT_FACESHIFT_HOSTNAME = "localhost"; const quint16 FACESHIFT_PORT = 33433; -float STARTING_FACESHIFT_FRAME_TIME = 0.033f; +const float DEFAULT_FACESHIFT_EYE_DEFLECTION = 0.25f; Faceshift::Faceshift() : - _tcpEnabled(true), - _tcpRetryCount(0), - _lastTrackingStateReceived(0), - _averageFrameTime(STARTING_FACESHIFT_FRAME_TIME), - _headAngularVelocity(0), - _headLinearVelocity(0), - _lastHeadTranslation(0), - _filteredHeadTranslation(0), - _eyeGazeLeftPitch(0.0f), - _eyeGazeLeftYaw(0.0f), - _eyeGazeRightPitch(0.0f), - _eyeGazeRightYaw(0.0f), - _leftBlinkIndex(0), // see http://support.faceshift.com/support/articles/35129-export-of-blendshapes - _rightBlinkIndex(1), - _leftEyeOpenIndex(8), - _rightEyeOpenIndex(9), - _browDownLeftIndex(14), - _browDownRightIndex(15), - _browUpCenterIndex(16), - _browUpLeftIndex(17), - _browUpRightIndex(18), - _mouthSmileLeftIndex(28), - _mouthSmileRightIndex(29), - _jawOpenIndex(21), - _longTermAverageEyePitch(0.0f), - _longTermAverageEyeYaw(0.0f), - _longTermAverageInitialized(false), _eyeDeflection("faceshiftEyeDeflection", DEFAULT_FACESHIFT_EYE_DEFLECTION), _hostname("faceshiftHostname", DEFAULT_FACESHIFT_HOSTNAME) { @@ -71,31 +45,15 @@ Faceshift::Faceshift() : #endif } +#ifdef HAVE_FACESHIFT void Faceshift::init() { -#ifdef HAVE_FACESHIFT setTCPEnabled(Menu::getInstance()->isOptionChecked(MenuOption::Faceshift)); -#endif } -bool Faceshift::isConnectedOrConnecting() const { - return _tcpSocket.state() == QAbstractSocket::ConnectedState || - (_tcpRetryCount == 0 && _tcpSocket.state() != QAbstractSocket::UnconnectedState); -} - -bool Faceshift::isActive() const { -#ifdef HAVE_FACESHIFT - const quint64 ACTIVE_TIMEOUT_USECS = 1000000; - return (usecTimestampNow() - _lastTrackingStateReceived) < ACTIVE_TIMEOUT_USECS; -#else - return false; -#endif -} - -void Faceshift::update() { +void Faceshift::update(float deltaTime) { if (!isActive()) { return; } - PerformanceTimer perfTimer("faceshift"); // get the euler angles relative to the window glm::vec3 eulers = glm::degrees(safeEulerAngles(_headRotation * glm::quat(glm::radians(glm::vec3( (_eyeGazeLeftPitch + _eyeGazeRightPitch) / 2.0f, (_eyeGazeLeftYaw + _eyeGazeRightYaw) / 2.0f, 0.0f))))); @@ -116,14 +74,28 @@ void Faceshift::update() { } void Faceshift::reset() { -#ifdef HAVE_FACESHIFT if (_tcpSocket.state() == QAbstractSocket::ConnectedState) { string message; fsBinaryStream::encode_message(message, fsMsgCalibrateNeutral()); send(message); } _longTermAverageInitialized = false; +} + +bool Faceshift::isActive() const { + const quint64 ACTIVE_TIMEOUT_USECS = 1000000; + return (usecTimestampNow() - _lastTrackingStateReceived) < ACTIVE_TIMEOUT_USECS; +} + +bool Faceshift::isTracking() const { + return isActive() && _tracking; +} #endif + + +bool Faceshift::isConnectedOrConnecting() const { + return _tcpSocket.state() == QAbstractSocket::ConnectedState || + (_tcpRetryCount == 0 && _tcpSocket.state() != QAbstractSocket::UnconnectedState); } void Faceshift::updateFakeCoefficients(float leftBlink, float rightBlink, float browUp, @@ -148,12 +120,13 @@ void Faceshift::updateFakeCoefficients(float leftBlink, float rightBlink, float } void Faceshift::setTCPEnabled(bool enabled) { +#ifdef HAVE_FACESHIFT if ((_tcpEnabled = enabled)) { connectSocket(); - } else { _tcpSocket.disconnectFromHost(); } +#endif } void Faceshift::connectSocket() { @@ -202,10 +175,6 @@ void Faceshift::readFromSocket() { receive(_tcpSocket.readAll()); } -float Faceshift::getBlendshapeCoefficient(int index) const { - return (index >= 0 && index < (int)_blendshapeCoefficients.size()) ? _blendshapeCoefficients[index] : 0.0f; -} - void Faceshift::send(const std::string& message) { _tcpSocket.write(message.data(), message.size()); } diff --git a/interface/src/devices/Faceshift.h b/interface/src/devices/Faceshift.h index 0cef3d3e13..f224448b8e 100644 --- a/interface/src/devices/Faceshift.h +++ b/interface/src/devices/Faceshift.h @@ -24,8 +24,7 @@ #include "FaceTracker.h" -const float DEFAULT_FACESHIFT_EYE_DEFLECTION = 0.25f; -const QString DEFAULT_FACESHIFT_HOSTNAME = "localhost"; +const float STARTING_FACESHIFT_FRAME_TIME = 0.033f; /// Handles interaction with the Faceshift software, which provides head position/orientation and facial features. class Faceshift : public FaceTracker, public Dependency { @@ -33,11 +32,17 @@ class Faceshift : public FaceTracker, public Dependency { SINGLETON_DEPENDENCY public: - void init(); +#ifdef HAVE_FACESHIFT + // If we don't have faceshift, use the base class' methods + virtual void init(); + virtual void update(float deltaTime); + virtual void reset(); - bool isConnectedOrConnecting() const; + virtual bool isActive() const; + virtual bool isTracking() const; +#endif - bool isActive() const; + bool isConnectedOrConnecting() const; const glm::vec3& getHeadAngularVelocity() const { return _headAngularVelocity; } @@ -68,9 +73,6 @@ public: QString getHostname() { return _hostname.get(); } void setHostname(const QString& hostname); - - void update(); - void reset(); void updateFakeCoefficients(float leftBlink, float rightBlink, @@ -82,15 +84,12 @@ public: QVector& coefficients) const; signals: - void connectionStateChanged(); public slots: - void setTCPEnabled(bool enabled); private slots: - void connectSocket(); void noteConnected(); void noteError(QAbstractSocket::SocketError error); @@ -101,8 +100,6 @@ private: Faceshift(); virtual ~Faceshift() {} - float getBlendshapeCoefficient(int index) const; - void send(const std::string& message); void receive(const QByteArray& buffer); @@ -113,48 +110,48 @@ private: fs::fsBinaryStream _stream; #endif - bool _tcpEnabled; - int _tcpRetryCount; - bool _tracking; - quint64 _lastTrackingStateReceived; - float _averageFrameTime; + bool _tcpEnabled = true; + int _tcpRetryCount = 0; + bool _tracking = false; + quint64 _lastTrackingStateReceived = 0; + float _averageFrameTime = STARTING_FACESHIFT_FRAME_TIME; - glm::vec3 _headAngularVelocity; - glm::vec3 _headLinearVelocity; - glm::vec3 _lastHeadTranslation; - glm::vec3 _filteredHeadTranslation; + glm::vec3 _headAngularVelocity = glm::vec3(0.0f); + glm::vec3 _headLinearVelocity = glm::vec3(0.0f); + glm::vec3 _lastHeadTranslation = glm::vec3(0.0f); + glm::vec3 _filteredHeadTranslation = glm::vec3(0.0f); // degrees - float _eyeGazeLeftPitch; - float _eyeGazeLeftYaw; - float _eyeGazeRightPitch; - float _eyeGazeRightYaw; - - int _leftBlinkIndex; - int _rightBlinkIndex; - int _leftEyeOpenIndex; - int _rightEyeOpenIndex; - - // Brows - int _browDownLeftIndex; - int _browDownRightIndex; - int _browUpCenterIndex; - int _browUpLeftIndex; - int _browUpRightIndex; - - int _mouthSmileLeftIndex; - int _mouthSmileRightIndex; - - int _jawOpenIndex; + float _eyeGazeLeftPitch = 0.0f; + float _eyeGazeLeftYaw = 0.0f; + float _eyeGazeRightPitch = 0.0f; + float _eyeGazeRightYaw = 0.0f; // degrees - float _longTermAverageEyePitch; - float _longTermAverageEyeYaw; - bool _longTermAverageInitialized; + float _longTermAverageEyePitch = 0.0f; + float _longTermAverageEyeYaw = 0.0f; + bool _longTermAverageInitialized = false; Setting::Handle _eyeDeflection; Setting::Handle _hostname; + // see http://support.faceshift.com/support/articles/35129-export-of-blendshapes + int _leftBlinkIndex = 0; + int _rightBlinkIndex = 1; + int _leftEyeOpenIndex = 8; + int _rightEyeOpenIndex = 9; + + // Brows + int _browDownLeftIndex = 14; + int _browDownRightIndex = 15; + int _browUpCenterIndex = 16; + int _browUpLeftIndex = 17; + int _browUpRightIndex = 18; + + int _mouthSmileLeftIndex = 28; + int _mouthSmileRightIndex = 29; + + int _jawOpenIndex = 21; }; #endif // hifi_Faceshift_h diff --git a/interface/src/devices/Visage.cpp b/interface/src/devices/Visage.cpp index 39bda83e61..45c19a6ab3 100644 --- a/interface/src/devices/Visage.cpp +++ b/interface/src/devices/Visage.cpp @@ -126,13 +126,12 @@ void Visage::init() { updateEnabled(); } -void Visage::update() { +void Visage::update(float deltaTime) { #ifdef HAVE_VISAGE _active = (_tracker->getTrackingData(_data) == TRACK_STAT_OK); if (!_active) { return; } - PerformanceTimer perfTimer("visage"); _headRotation = glm::quat(glm::vec3(-_data->faceRotation[0], -_data->faceRotation[1], _data->faceRotation[2])); _headTranslation = (glm::vec3(_data->faceTranslation[0], _data->faceTranslation[1], _data->faceTranslation[2]) - _headOrigin) * TRANSLATION_SCALE; diff --git a/interface/src/devices/Visage.h b/interface/src/devices/Visage.h index 690a9f3066..cd2ec3ecad 100644 --- a/interface/src/devices/Visage.h +++ b/interface/src/devices/Visage.h @@ -31,12 +31,12 @@ class Visage : public FaceTracker, public Dependency { SINGLETON_DEPENDENCY public: - void init(); + virtual void init(); + virtual void update(float deltaTime); + virtual void reset(); - bool isActive() const { return _active; } - - void update(); - void reset(); + virtual bool isActive() const { return _active; } + virtual bool isTracking() const { return isActive(); } public slots: From f560f97c6b5c1ed0b3381a8be5439843caaeec51 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 26 Feb 2015 19:18:05 +0100 Subject: [PATCH 06/28] Only update active FaceTracker --- interface/src/Application.cpp | 36 ++++------------------------------- interface/src/Application.h | 3 --- 2 files changed, 4 insertions(+), 35 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0bdd8f8f53..e1b4aa40ea 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1859,35 +1859,6 @@ void Application::updateMouseRay() { } } -void Application::updateFaceshift() { - bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); - PerformanceWarning warn(showWarnings, "Application::updateFaceshift()"); - auto faceshift = DependencyManager::get(); - // Update faceshift - faceshift->update(); - - // Copy angular velocity if measured by faceshift, to the head - if (faceshift->isActive()) { - _myAvatar->getHead()->setAngularVelocity(faceshift->getHeadAngularVelocity()); - } -} - -void Application::updateVisage() { - bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); - PerformanceWarning warn(showWarnings, "Application::updateVisage()"); - - // Update Visage - DependencyManager::get()->update(); -} - -void Application::updateDDE() { - bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); - PerformanceWarning warn(showWarnings, "Application::updateDDE()"); - - // Update Cara - DependencyManager::get()->update(); -} - void Application::updateMyAvatarLookAtPosition() { PerformanceTimer perfTimer("lookAt"); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); @@ -2067,12 +2038,13 @@ void Application::update(float deltaTime) { { PerformanceTimer perfTimer("devices"); DeviceTracker::updateAll(); - updateFaceshift(); - updateVisage(); + FaceTracker* tracker = getActiveFaceTracker(); + if (tracker) { + tracker->update(deltaTime); + } SixenseManager::getInstance().update(deltaTime); JoystickScriptingInterface::getInstance().update(); _prioVR.update(deltaTime); - } // Dispatch input events diff --git a/interface/src/Application.h b/interface/src/Application.h index 9cd19c8259..4a8e712d30 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -421,9 +421,6 @@ private: // Various helper functions called during update() void updateLOD(); void updateMouseRay(); - void updateFaceshift(); - void updateVisage(); - void updateDDE(); void updateMyAvatarLookAtPosition(); void updateThreads(float deltaTime); void updateMetavoxels(float deltaTime); From 682b3f5e61c109a659e8f2ea11a2926b92dc6049 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 26 Feb 2015 19:18:52 +0100 Subject: [PATCH 07/28] Remove unused angular velocity --- interface/src/avatar/Head.cpp | 1 - interface/src/avatar/Head.h | 4 ---- 2 files changed, 5 deletions(-) diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 52f1b3ee86..a6458c7a22 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -42,7 +42,6 @@ Head::Head(Avatar* owningAvatar) : _mouth2(0.0f), _mouth3(0.0f), _mouth4(0.0f), - _angularVelocity(0,0,0), _renderLookatVectors(false), _saccade(0.0f, 0.0f, 0.0f), _saccadeTarget(0.0f, 0.0f, 0.0f), diff --git a/interface/src/avatar/Head.h b/interface/src/avatar/Head.h index 89eea35903..6c53c2d7aa 100644 --- a/interface/src/avatar/Head.h +++ b/interface/src/avatar/Head.h @@ -55,9 +55,6 @@ public: /// \return orientationBody * orientationBasePitch glm::quat getCameraOrientation () const; - - const glm::vec3& getAngularVelocity() const { return _angularVelocity; } - void setAngularVelocity(glm::vec3 angularVelocity) { _angularVelocity = angularVelocity; } void setCorrectedLookAtPosition(glm::vec3 correctedLookAtPosition); glm::vec3 getCorrectedLookAtPosition(); @@ -130,7 +127,6 @@ private: float _mouth2; float _mouth3; float _mouth4; - glm::vec3 _angularVelocity; bool _renderLookatVectors; glm::vec3 _saccade; glm::vec3 _saccadeTarget; From e37ef226fc6b04378d2d8ce48960dc49d5cd4312 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 26 Feb 2015 19:21:14 +0100 Subject: [PATCH 08/28] Simplify lookForward compute --- interface/src/avatar/MyAvatar.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index ba628ea0d4..9cdd38dbc8 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -892,13 +892,7 @@ void MyAvatar::updateLookAtTargetAvatar() { _lookAtTargetAvatar.clear(); _targetAvatarPosition = glm::vec3(0.0f); - glm::quat faceRotation = Application::getInstance()->getViewFrustum()->getOrientation(); - FaceTracker* tracker = Application::getInstance()->getActiveFaceTracker(); - if (tracker) { - // If faceshift or other face tracker in use, add on the actual angle of the head - faceRotation *= tracker->getHeadRotation(); - } - glm::vec3 lookForward = faceRotation * IDENTITY_FRONT; + glm::vec3 lookForward = getHead()->getFinalOrientationInWorldFrame() * IDENTITY_FRONT; glm::vec3 cameraPosition = Application::getInstance()->getCamera()->getPosition(); float smallestAngleTo = glm::radians(Application::getInstance()->getCamera()->getFieldOfView()) / 2.0f; From fcb293d0b2155d4334610dc6448a2073356bbca7 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 26 Feb 2015 10:45:00 -0800 Subject: [PATCH 09/28] CLean up before pr --- examples/example/misc/sunLightExample.js | 1 - interface/src/Application.cpp | 4 -- libraries/model/src/model/Stage.cpp | 56 +++++++++++++++++------- libraries/model/src/model/Stage.h | 55 +---------------------- 4 files changed, 42 insertions(+), 74 deletions(-) diff --git a/examples/example/misc/sunLightExample.js b/examples/example/misc/sunLightExample.js index 0bc3b0dfea..7f38211052 100644 --- a/examples/example/misc/sunLightExample.js +++ b/examples/example/misc/sunLightExample.js @@ -26,7 +26,6 @@ function ticktack() { Scene.setYearTime(day); } Scene.setDayTime(hour); - } Script.setInterval(ticktack, 41); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 298814f484..46fec006ca 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2493,8 +2493,6 @@ void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) { glm::vec3 Application::getSunDirection() { // Sun direction is in fact just the location of the sun relative to the origin - // return glm::normalize(_environment.getClosestData(_myCamera.getPosition()).getSunLocation(_myCamera.getPosition())); - auto skyStage = DependencyManager::get()->getSkyStage(); return skyStage->getSunLight()->getDirection(); } @@ -2875,9 +2873,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs { DependencyManager::get()->setAmbientLightMode(getRenderAmbientLight()); - // DependencyManager::get()->setGlobalLight(-getSunDirection(), GLOBAL_LIGHT_COLOR, GLOBAL_LIGHT_INTENSITY); auto skyStage = DependencyManager::get()->getSkyStage(); -// DependencyManager::get()->setGlobalLight(-getSunDirection(), GLOBAL_LIGHT_COLOR, skyStage->_light->getIntensity()); DependencyManager::get()->setGlobalLight(skyStage->getSunLight()->getDirection(), skyStage->getSunLight()->getColor(), skyStage->getSunLight()->getIntensity()); PROFILE_RANGE("DeferredLighting"); diff --git a/libraries/model/src/model/Stage.cpp b/libraries/model/src/model/Stage.cpp index dcd633f35c..12ed186cf6 100644 --- a/libraries/model/src/model/Stage.cpp +++ b/libraries/model/src/model/Stage.cpp @@ -21,8 +21,6 @@ void EarthSunModel::updateAll() const { } Mat4d EarthSunModel::evalWorldToGeoLocationMat(double longitude, double latitude, double absAltitude, double scale) { - - // Longitude is along Z axis but - from east to west Mat4d rotLon = glm::rotate(glm::radians(longitude), Vec3d(0.0, 0.0, 1.0)); @@ -54,9 +52,7 @@ void EarthSunModel::updateWorldToSurface() const { _surfacePos = Vec3d(_surfaceToWorldMat * Vec4d(0.0, 0.0, 0.0, 1.0)); } -void EarthSunModel::updateSurfaceToEye() const -{ - +void EarthSunModel::updateSurfaceToEye() const { _surfaceToEyeMat = glm::inverse(_eyeToSurfaceMat); _worldToEyeMat = _surfaceToEyeMat * _worldToSurfaceMat; _eyeToWorldMat = _surfaceToWorldMat * _eyeToSurfaceMat; @@ -76,8 +72,7 @@ void EarthSunModel::updateSun() const { // sun direction is looking up toward Y axis at the specified sun lat, long Vec3d lssd = Vec3d(_worldToSurfaceMat * Vec4d(_sunDir.x, _sunDir.y, _sunDir.z, 0.0)); _surfaceSunDir = glm::normalize(Vec3(lssd.x, lssd.y, lssd.z)); -} - +} float moduloRange(float val, float minVal, float maxVal) { float range = maxVal - minVal; @@ -86,30 +81,48 @@ float moduloRange(float val, float minVal, float maxVal) { return modf(rval, &intval) * range + minVal; } +const float MAX_LONGITUDE = 180.0f; +const float MAX_LATITUDE = 90.0f; + +float validateLongitude(float lon) { + return moduloRange(lon, -MAX_LONGITUDE, MAX_LONGITUDE); +} + +float validateLatitude(float lat) { + return moduloRange(lat, -MAX_LATITUDE, MAX_LATITUDE); +} + +float validateAltitude(float altitude) { + const float MIN_ALTITUDE = -1000.0f; + const float MAX_ALTITUDE = 100000.0f; + return std::min(std::max(altitude, MIN_ALTITUDE), MAX_ALTITUDE); +} + void EarthSunModel::setLatitude(float lat) { - _latitude = moduloRange(lat, -90.0f, 90.0f); + _latitude = validateLatitude(lat); invalidate(); } void EarthSunModel::setLongitude(float lon) { - _longitude = moduloRange(lon, -180.0f, 180.0f); + _longitude = validateLongitude(lon); invalidate(); } void EarthSunModel::setAltitude(float altitude) { - _altitude = moduloRange(altitude, -1000.f, 100000.f); + _altitude = validateAltitude(altitude); invalidate(); } void EarthSunModel::setSunLatitude(float lat) { - _sunLatitude = moduloRange(lat, -90.0f, 90.0f); + _sunLatitude = validateLatitude(lat); invalidate(); } void EarthSunModel::setSunLongitude(float lon) { - _sunLongitude = moduloRange(lon, -180.0f, 180.0f); + _sunLongitude = validateLongitude(lon); invalidate(); } const int NUM_DAYS_PER_YEAR = 365; const float NUM_HOURS_PER_DAY = 24.0f; +const float NUM_HOURS_PER_HALF_DAY = NUM_HOURS_PER_DAY * 0.5f; SunSkyStage::SunSkyStage() : _sunLight(new Light()) @@ -119,8 +132,11 @@ SunSkyStage::SunSkyStage() : setSunIntensity(1.0f); setSunColor(Vec3(1.0f, 1.0f, 1.0f)); - // setOriginLocation(45.0f, 20.0f, 1.0f); + // Default origin location is a special place in the world... + setOriginLocation(122.407f, 37.777f, 0.03f); + // 6pm setDayTime(18.0f); + // Begining of march setYearTime(60.0f); } @@ -151,12 +167,20 @@ void SunSkyStage::setSunIntensity(float intensity) { _sunLight->setIntensity(intensity); } +// THe sun declinaison calculus is taken from https://en.wikipedia.org/wiki/Position_of_the_Sun +double evalSunDeclinaison(double dayNumber) { + return -(23.0 + 44.0/60.0)*cos(glm::radians((360.0/365.0)*(dayNumber + 10.0))); +} + void SunSkyStage::updateGraphicsObject() const { - // Always update the sunLongitude based on the current dayTIme and the current origin - _earthSunModel.setSunLongitude(_earthSunModel.getLongitude() + (-180.0 + 360.0 * _dayTime / NUM_HOURS_PER_DAY)); + // Always update the sunLongitude based on the current dayTime and the current origin + // The day time is supposed to be local at the origin + double signedNormalizedDayTime = (_dayTime - NUM_HOURS_PER_HALF_DAY) / NUM_HOURS_PER_HALF_DAY; + double sunLongitude = _earthSunModel.getLongitude() + (MAX_LONGITUDE * signedNormalizedDayTime); + _earthSunModel.setSunLongitude(sunLongitude); // And update the sunLAtitude as the declinaison depending of the time of the year - _earthSunModel.setSunLatitude(-(23.0 + 44.0/60.0)*cos(glm::radians((360.0/365.0)*(_yearTime + 10)))); + _earthSunModel.setSunLatitude(evalSunDeclinaison(_yearTime)); Vec3d sunLightDir = -_earthSunModel.getSurfaceSunDir(); diff --git a/libraries/model/src/model/Stage.h b/libraries/model/src/model/Stage.h index 9b2922e163..f99d2c1648 100644 --- a/libraries/model/src/model/Stage.h +++ b/libraries/model/src/model/Stage.h @@ -22,16 +22,6 @@ typedef glm::mat4 Mat4; class EarthSunModel { public: - enum Preset - { - Toulouse = 0, - SanFrancisco, - Sydney, - Num_Presets, - }; - static const std::string PresetNames[Num_Presets]; - //void assignPreset( Preset p); - //Preset preset() const { return mPreset; } void setScale(float scale); float getScale() const { return _scale; } @@ -108,46 +98,6 @@ protected: static Mat4d evalWorldToGeoLocationMat(double longitude, double latitude, double altitude, double scale); }; -namespace gpu { - class Batch; -}; - -class ProgramObject; - -class Skybox { -public: - void recordBatch(gpu::Batch& batch, const Transform& viewTransform, const Mat4& projection); - - Skybox(); - ~Skybox(); -protected: - ProgramObject* createSkyProgram(const char* from, int* locations); - ProgramObject* _skyFromAtmosphereProgram; - ProgramObject* _skyFromSpaceProgram; - enum { - CAMERA_POS_LOCATION, - LIGHT_POS_LOCATION, - INV_WAVELENGTH_LOCATION, - CAMERA_HEIGHT2_LOCATION, - OUTER_RADIUS_LOCATION, - OUTER_RADIUS2_LOCATION, - INNER_RADIUS_LOCATION, - KR_ESUN_LOCATION, - KM_ESUN_LOCATION, - KR_4PI_LOCATION, - KM_4PI_LOCATION, - SCALE_LOCATION, - SCALE_DEPTH_LOCATION, - SCALE_OVER_SCALE_DEPTH_LOCATION, - G_LOCATION, - G2_LOCATION, - LOCATION_COUNT - }; - - int _skyFromAtmosphereUniformLocations[LOCATION_COUNT]; - int _skyFromSpaceUniformLocations[LOCATION_COUNT]; -}; - // Sun sky stage generates the rendering primitives to display a scene realistically // at the specified location and time around earth class SunSkyStage { @@ -181,9 +131,8 @@ public: protected: LightPointer _sunLight; - // default day is 1st of january at noun - float _dayTime = 12.0f; - int _yearTime = 0; + float _dayTime; + int _yearTime; mutable EarthSunModel _earthSunModel; From c3a72574391f35d4c0a6dabfa89fb24117b18b14 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 26 Feb 2015 11:03:06 -0800 Subject: [PATCH 10/28] Remove unused light properties from entity properties window --- examples/html/entityProperties.html | 70 ++--------------------------- 1 file changed, 4 insertions(+), 66 deletions(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index ad2b359e79..38a2ca5ea8 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -132,17 +132,7 @@ var elLightDiffuseGreen = document.getElementById("property-light-diffuse-green"); var elLightDiffuseBlue = document.getElementById("property-light-diffuse-blue"); - var elLightAmbientRed = document.getElementById("property-light-ambient-red"); - var elLightAmbientGreen = document.getElementById("property-light-ambient-green"); - var elLightAmbientBlue = document.getElementById("property-light-ambient-blue"); - - var elLightSpecularRed = document.getElementById("property-light-specular-red"); - var elLightSpecularGreen = document.getElementById("property-light-specular-green"); - var elLightSpecularBlue = document.getElementById("property-light-specular-blue"); - var elLightConstantAttenuation = document.getElementById("property-light-constant-attenuation"); - var elLightLinearAttenuation = document.getElementById("property-light-linear-attenuation"); - var elLightQuadraticAttenuation = document.getElementById("property-light-quadratic-attenuation"); var elLightExponent = document.getElementById("property-light-exponent"); var elLightCutoff = document.getElementById("property-light-cutoff"); @@ -294,17 +284,7 @@ elLightDiffuseGreen.value = properties.diffuseColor.green; elLightDiffuseBlue.value = properties.diffuseColor.blue; - elLightAmbientRed.value = properties.ambientColor.red; - elLightAmbientGreen.value = properties.ambientColor.green; - elLightAmbientBlue.value = properties.ambientColor.blue; - - elLightSpecularRed.value = properties.specularColor.red; - elLightSpecularGreen.value = properties.specularColor.green; - elLightSpecularBlue.value = properties.specularColor.blue; - elLightConstantAttenuation.value = properties.constantAttenuation; - elLightLinearAttenuation.value = properties.linearAttenuation; - elLightQuadraticAttenuation.value = properties.quadraticAttenuation; elLightExponent.value = properties.exponent; elLightCutoff.value = properties.cutoff; } @@ -381,21 +361,7 @@ elLightDiffuseGreen.addEventListener('change', lightDiffuseChangeFunction); elLightDiffuseBlue.addEventListener('change', lightDiffuseChangeFunction); - var lightAmbientChangeFunction = createEmitColorPropertyUpdateFunction( - 'ambientColor', elLightAmbientRed, elLightAmbientGreen, elLightAmbientBlue); - elLightAmbientRed.addEventListener('change', lightAmbientChangeFunction); - elLightAmbientGreen.addEventListener('change', lightAmbientChangeFunction); - elLightAmbientBlue.addEventListener('change', lightAmbientChangeFunction); - - var lightSpecularChangeFunction = createEmitColorPropertyUpdateFunction( - 'specularColor', elLightSpecularRed, elLightSpecularGreen, elLightSpecularBlue); - elLightSpecularRed.addEventListener('change', lightSpecularChangeFunction); - elLightSpecularGreen.addEventListener('change', lightSpecularChangeFunction); - elLightSpecularBlue.addEventListener('change', lightSpecularChangeFunction); - elLightConstantAttenuation.addEventListener('change', createEmitNumberPropertyUpdateFunction('constantAttenuation')); - elLightLinearAttenuation.addEventListener('change', createEmitNumberPropertyUpdateFunction('linearAttenuation')); - elLightQuadraticAttenuation.addEventListener('change', createEmitNumberPropertyUpdateFunction('quadraticAttenuation')); elLightExponent.addEventListener('change', createEmitNumberPropertyUpdateFunction('exponent')); elLightCutoff.addEventListener('change', createEmitNumberPropertyUpdateFunction('cutoff')); @@ -715,7 +681,7 @@
-
Diffuse
+
Color
R
G
@@ -723,47 +689,19 @@
-
Ambient
-
-
R
-
G
-
B
-
-
-
-
Specular
-
-
R
-
G
-
B
-
-
-
-
Constant Attenuation
+
Intensity
-
Linear Attenuation
-
- -
-
-
-
Quadratic Attenuation
-
- -
-
-
-
Exponent
+
Spot Light Exponent
-
Cutoff (degrees)
+
Spot Light Cutoff (degrees)
From e42b708b562d1fc9e7a916c110d7a5c726945305 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 26 Feb 2015 11:03:47 -0800 Subject: [PATCH 11/28] Update deferredLightingEffect::add*Light methods --- interface/src/avatar/Avatar.cpp | 3 +-- .../src/RenderableLightEntityItem.cpp | 7 +++---- .../src/DeferredLightingEffect.cpp | 21 ++++++++++--------- .../render-utils/src/DeferredLightingEffect.h | 11 ++++------ 4 files changed, 19 insertions(+), 23 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 6dc3d4b339..467f63ccef 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -380,8 +380,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool foreach (const AvatarManager::LocalLight& light, DependencyManager::get()->getLocalLights()) { glm::vec3 direction = orientation * light.direction; DependencyManager::get()->addSpotLight(position - direction * distance, - distance * 2.0f, glm::vec3(), light.color, light.color, 1.0f, 0.5f, 0.0f, direction, - LIGHT_EXPONENT, LIGHT_CUTOFF); + distance * 2.0f, light.color, 0.5f, orientation, LIGHT_EXPONENT, LIGHT_CUTOFF); } } diff --git a/libraries/entities-renderer/src/RenderableLightEntityItem.cpp b/libraries/entities-renderer/src/RenderableLightEntityItem.cpp index 1e0a9b6fc7..978ca11d9d 100644 --- a/libraries/entities-renderer/src/RenderableLightEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableLightEntityItem.cpp @@ -48,7 +48,7 @@ void RenderableLightEntityItem::render(RenderArgs* args) { glm::vec3 diffuse = glm::vec3(diffuseR, diffuseG, diffuseB); glm::vec3 specular = glm::vec3(specularR, specularG, specularB); glm::vec3 direction = IDENTITY_FRONT * rotation; - float constantAttenuation = getConstantAttenuation(); + float intensity = getConstantAttenuation(); float linearAttenuation = getLinearAttenuation(); float quadraticAttenuation = getQuadraticAttenuation(); float exponent = getExponent(); @@ -56,11 +56,10 @@ void RenderableLightEntityItem::render(RenderArgs* args) { if (_isSpotlight) { DependencyManager::get()->addSpotLight(position, largestDiameter / 2.0f, - ambient, diffuse, specular, constantAttenuation, linearAttenuation, quadraticAttenuation, - direction, exponent, cutoff); + diffuse, intensity, rotation, exponent, cutoff); } else { DependencyManager::get()->addPointLight(position, largestDiameter / 2.0f, - ambient, diffuse, specular, constantAttenuation, linearAttenuation, quadraticAttenuation); + diffuse, intensity); } #ifdef WANT_DEBUG diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 1f5d0ce4c3..5e203b041d 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -126,15 +126,16 @@ void DeferredLightingEffect::renderSolidCone(float base, float height, int slice releaseSimpleProgram(); } -void DeferredLightingEffect::addPointLight(const glm::vec3& position, float radius, const glm::vec3& ambient, - const glm::vec3& diffuse, const glm::vec3& specular, float constantAttenuation, - float linearAttenuation, float quadraticAttenuation) { - addSpotLight(position, radius, ambient, diffuse, specular, constantAttenuation, linearAttenuation, quadraticAttenuation); +void DeferredLightingEffect::addPointLight(const glm::vec3& position, float radius, const glm::vec3& color, + float intensity) { + addSpotLight(position, radius, color, intensity); } -void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radius, const glm::vec3& ambient, - const glm::vec3& diffuse, const glm::vec3& specular, float constantAttenuation, float linearAttenuation, - float quadraticAttenuation, const glm::vec3& direction, float exponent, float cutoff) { +// Remove: ambient, specular, *Attenuation, direction +// Add: intensity, radius +// Rename: diffuseColor -> color +void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radius, const glm::vec3& color, + float intensity, const glm::quat& orientation, float exponent, float cutoff) { int lightID = _pointLights.size() + _spotLights.size() + _globalLights.size(); if (lightID >= _allocatedLights.size()) { @@ -144,8 +145,8 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu lp->setPosition(position); lp->setMaximumRadius(radius); - lp->setColor(diffuse); - lp->setIntensity(1.0f); + lp->setColor(color); + lp->setIntensity(intensity); //lp->setShowContour(quadraticAttenuation); if (exponent == 0.0f && cutoff == PI) { @@ -153,7 +154,7 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu _pointLights.push_back(lightID); } else { - lp->setDirection(direction); + lp->setOrientation(orientation); lp->setSpotAngle(cutoff); lp->setSpotExponent(exponent); lp->setType(model::Light::SPOT); diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index eeb92f19c7..c375f3eb52 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -57,15 +57,12 @@ public: void renderSolidCone(float base, float height, int slices, int stacks); /// Adds a point light to render for the current frame. - void addPointLight(const glm::vec3& position, float radius, const glm::vec3& ambient = glm::vec3(0.0f, 0.0f, 0.0f), - const glm::vec3& diffuse = glm::vec3(1.0f, 1.0f, 1.0f), const glm::vec3& specular = glm::vec3(1.0f, 1.0f, 1.0f), - float constantAttenuation = 1.0f, float linearAttenuation = 0.0f, float quadraticAttenuation = 0.0f); + void addPointLight(const glm::vec3& position, float radius, const glm::vec3& color = glm::vec3(0.0f, 0.0f, 0.0f), + float intensity = 0.5f); /// Adds a spot light to render for the current frame. - void addSpotLight(const glm::vec3& position, float radius, const glm::vec3& ambient = glm::vec3(0.0f, 0.0f, 0.0f), - const glm::vec3& diffuse = glm::vec3(1.0f, 1.0f, 1.0f), const glm::vec3& specular = glm::vec3(1.0f, 1.0f, 1.0f), - float constantAttenuation = 1.0f, float linearAttenuation = 0.0f, float quadraticAttenuation = 0.0f, - const glm::vec3& direction = glm::vec3(0.0f, 0.0f, -1.0f), float exponent = 0.0f, float cutoff = PI); + void addSpotLight(const glm::vec3& position, float radius, const glm::vec3& color = glm::vec3(1.0f, 1.0f, 1.0f), + float intensity = 0.5f, const glm::quat& orientation = glm::quat(), float exponent = 0.0f, float cutoff = PI); /// Adds an object to render after performing the deferred lighting for the current frame (e.g., a translucent object). void addPostLightingRenderable(PostLightingRenderable* renderable) { _postLightingRenderables.append(renderable); } From fdf9fdd8778d38263c4c3c17d1228ddeb9e32e9c Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 26 Feb 2015 20:05:47 +0100 Subject: [PATCH 12/28] Relax head/lean when not tracking --- interface/src/avatar/MyAvatar.cpp | 9 +------- interface/src/devices/FaceTracker.cpp | 30 +++++++++++++++++++++++++++ interface/src/devices/FaceTracker.h | 12 +++++------ interface/src/devices/Faceshift.cpp | 2 ++ interface/src/devices/Visage.cpp | 12 +++++------ interface/src/devices/Visage.h | 6 +++--- 6 files changed, 48 insertions(+), 23 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 9cdd38dbc8..8c4ea73775 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1158,15 +1158,8 @@ void MyAvatar::updateOrientation(float deltaTime) { pitch *= DEGREES_PER_RADIAN; roll *= DEGREES_PER_RADIAN; - // Record the angular velocity - Head* head = getHead(); - if (deltaTime > 0.0f) { - glm::vec3 angularVelocity(pitch - head->getBasePitch(), yaw - head->getBaseYaw(), roll - head->getBaseRoll()); - angularVelocity *= 1.0f / deltaTime; - head->setAngularVelocity(angularVelocity); - } - //Invert yaw and roll when in mirror mode + Head* head = getHead(); if (Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_MIRROR) { head->setBaseYaw(-yaw); head->setBasePitch(pitch); diff --git a/interface/src/devices/FaceTracker.cpp b/interface/src/devices/FaceTracker.cpp index 8d61789715..e570e39345 100644 --- a/interface/src/devices/FaceTracker.cpp +++ b/interface/src/devices/FaceTracker.cpp @@ -14,3 +14,33 @@ inline float FaceTracker::getBlendshapeCoefficient(int index) const { return isValidBlendshapeIndex(index) ? _blendshapeCoefficients[index] : 0.0f; } + +float FaceTracker::getFadeCoefficient() const { + // TODO: apply exponential relaxation + return _relaxationStatus; +} + +const glm::vec3 FaceTracker::getHeadTranslation() const { + return glm::mix(glm::vec3(0.0f), _headTranslation, getFadeCoefficient()); +} + +const glm::quat FaceTracker::getHeadRotation() const { + return glm::mix(glm::quat(), _headRotation, getFadeCoefficient()); +} + +void FaceTracker::update(float deltaTime) { + static const float RELAXATION_TIME = 0.4; // sec + + if (isTracking()) { + if (_relaxationStatus == 1.0f) { + return; + } + _relaxationStatus += deltaTime / RELAXATION_TIME; + } else { + if (_relaxationStatus == 0.0f) { + return; + } + _relaxationStatus -= deltaTime / RELAXATION_TIME; + } + _relaxationStatus = glm::clamp(_relaxationStatus, 0.0f, 1.0f); +} \ No newline at end of file diff --git a/interface/src/devices/FaceTracker.h b/interface/src/devices/FaceTracker.h index 07c479e3e3..89ba1f22f6 100644 --- a/interface/src/devices/FaceTracker.h +++ b/interface/src/devices/FaceTracker.h @@ -27,11 +27,13 @@ public: virtual bool isTracking() const { return false; } virtual void init() {} - virtual void update(float deltaTime) {} + virtual void update(float deltaTime); virtual void reset() {} - const glm::vec3& getHeadTranslation() const { return _headTranslation; } - const glm::quat& getHeadRotation() const { return _headRotation; } + float getFadeCoefficient() const; + + const glm::vec3 getHeadTranslation() const; + const glm::quat getHeadRotation() const; float getEstimatedEyePitch() const { return _estimatedEyePitch; } float getEstimatedEyeYaw() const { return _estimatedEyeYaw; } @@ -42,15 +44,13 @@ public: float getBlendshapeCoefficient(int index) const; protected: - - glm::vec3 _headTranslation = glm::vec3(0.0f); glm::quat _headRotation = glm::quat(); float _estimatedEyePitch = 0.0f; float _estimatedEyeYaw = 0.0f; QVector _blendshapeCoefficients; - float _fadeCoefficient = 0.0f; + float _relaxationStatus = 0.0f; // Between 0.0f and 1.0f }; #endif // hifi_FaceTracker_h diff --git a/interface/src/devices/Faceshift.cpp b/interface/src/devices/Faceshift.cpp index 87ee0ef31c..a2bb4e74a9 100644 --- a/interface/src/devices/Faceshift.cpp +++ b/interface/src/devices/Faceshift.cpp @@ -54,6 +54,8 @@ void Faceshift::update(float deltaTime) { if (!isActive()) { return; } + FaceTracker::update(deltaTime); + // get the euler angles relative to the window glm::vec3 eulers = glm::degrees(safeEulerAngles(_headRotation * glm::quat(glm::radians(glm::vec3( (_eyeGazeLeftPitch + _eyeGazeRightPitch) / 2.0f, (_eyeGazeLeftYaw + _eyeGazeRightYaw) / 2.0f, 0.0f))))); diff --git a/interface/src/devices/Visage.cpp b/interface/src/devices/Visage.cpp index 45c19a6ab3..010b872bc6 100644 --- a/interface/src/devices/Visage.cpp +++ b/interface/src/devices/Visage.cpp @@ -41,7 +41,6 @@ const glm::vec3 DEFAULT_HEAD_ORIGIN(0.0f, 0.0f, 0.7f); Visage::Visage() : _enabled(false), - _active(false), _headOrigin(DEFAULT_HEAD_ORIGIN) { #ifdef HAVE_VISAGE @@ -119,19 +118,20 @@ static const QMultiHash >& getActionUnitNameMap() } #endif -const float TRANSLATION_SCALE = 20.0f; +#ifdef HAVE_VISAGE +const float TRANSLATION_SCALE = 20.0f; void Visage::init() { connect(DependencyManager::get().data(), SIGNAL(connectionStateChanged()), SLOT(updateEnabled())); updateEnabled(); } void Visage::update(float deltaTime) { -#ifdef HAVE_VISAGE - _active = (_tracker->getTrackingData(_data) == TRACK_STAT_OK); - if (!_active) { + if (!isActive()) { return; } + FaceTracker::update(deltaTime); + _headRotation = glm::quat(glm::vec3(-_data->faceRotation[0], -_data->faceRotation[1], _data->faceRotation[2])); _headTranslation = (glm::vec3(_data->faceTranslation[0], _data->faceTranslation[1], _data->faceTranslation[2]) - _headOrigin) * TRANSLATION_SCALE; @@ -163,12 +163,12 @@ void Visage::update(float deltaTime) { } _blendshapeCoefficients[leftEyeBlinkIndex] = 1.0f - _data->eyeClosure[1]; _blendshapeCoefficients[rightEyeBlinkIndex] = 1.0f - _data->eyeClosure[0]; -#endif } void Visage::reset() { _headOrigin += _headTranslation / TRANSLATION_SCALE; } +#endif void Visage::updateEnabled() { setEnabled(Menu::getInstance()->isOptionChecked(MenuOption::Visage) && diff --git a/interface/src/devices/Visage.h b/interface/src/devices/Visage.h index cd2ec3ecad..3ff1ea8c27 100644 --- a/interface/src/devices/Visage.h +++ b/interface/src/devices/Visage.h @@ -31,15 +31,16 @@ class Visage : public FaceTracker, public Dependency { SINGLETON_DEPENDENCY public: +#ifdef HAVE_VISAGE virtual void init(); virtual void update(float deltaTime); virtual void reset(); - virtual bool isActive() const { return _active; } + virtual bool isActive() const { return _tracker->getTrackingData(_data) == TRACK_STAT_OK; } virtual bool isTracking() const { return isActive(); } +#endif public slots: - void updateEnabled(); private: @@ -55,7 +56,6 @@ private: void setEnabled(bool enabled); bool _enabled; - bool _active; glm::vec3 _headOrigin; }; From b04dbf7a34b85ee5c013e12aedd0f66f1f14dbee Mon Sep 17 00:00:00 2001 From: dev Date: Thu, 26 Feb 2015 11:27:40 -0800 Subject: [PATCH 13/28] fixing compilation issue on macos --- libraries/model/src/model/Stage.cpp | 264 ++++++++++++++-------------- 1 file changed, 133 insertions(+), 131 deletions(-) diff --git a/libraries/model/src/model/Stage.cpp b/libraries/model/src/model/Stage.cpp index 12ed186cf6..dd5a44a0cb 100644 --- a/libraries/model/src/model/Stage.cpp +++ b/libraries/model/src/model/Stage.cpp @@ -1,19 +1,21 @@ -// -// Stage.cpp -// libraries/model/src/model -// -// Created by Sam Gateau on 2/24/2015. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// -#include "Stage.h" - -#include -using namespace model; - - +// +// Stage.cpp +// libraries/model/src/model +// +// Created by Sam Gateau on 2/24/2015. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#include "Stage.h" + +#include +#include + +using namespace model; + + void EarthSunModel::updateAll() const { updateWorldToSurface(); updateSurfaceToEye(); @@ -72,118 +74,118 @@ void EarthSunModel::updateSun() const { // sun direction is looking up toward Y axis at the specified sun lat, long Vec3d lssd = Vec3d(_worldToSurfaceMat * Vec4d(_sunDir.x, _sunDir.y, _sunDir.z, 0.0)); _surfaceSunDir = glm::normalize(Vec3(lssd.x, lssd.y, lssd.z)); -} - -float moduloRange(float val, float minVal, float maxVal) { - float range = maxVal - minVal; - float rval = (val - minVal) / range; - float intval; - return modf(rval, &intval) * range + minVal; -} - -const float MAX_LONGITUDE = 180.0f; -const float MAX_LATITUDE = 90.0f; - -float validateLongitude(float lon) { - return moduloRange(lon, -MAX_LONGITUDE, MAX_LONGITUDE); -} - -float validateLatitude(float lat) { - return moduloRange(lat, -MAX_LATITUDE, MAX_LATITUDE); -} - -float validateAltitude(float altitude) { - const float MIN_ALTITUDE = -1000.0f; - const float MAX_ALTITUDE = 100000.0f; - return std::min(std::max(altitude, MIN_ALTITUDE), MAX_ALTITUDE); -} - -void EarthSunModel::setLatitude(float lat) { - _latitude = validateLatitude(lat); - invalidate(); -} -void EarthSunModel::setLongitude(float lon) { - _longitude = validateLongitude(lon); - invalidate(); -} -void EarthSunModel::setAltitude(float altitude) { - _altitude = validateAltitude(altitude); - invalidate(); -} - -void EarthSunModel::setSunLatitude(float lat) { - _sunLatitude = validateLatitude(lat); - invalidate(); -} -void EarthSunModel::setSunLongitude(float lon) { - _sunLongitude = validateLongitude(lon); - invalidate(); -} - -const int NUM_DAYS_PER_YEAR = 365; -const float NUM_HOURS_PER_DAY = 24.0f; -const float NUM_HOURS_PER_HALF_DAY = NUM_HOURS_PER_DAY * 0.5f; - -SunSkyStage::SunSkyStage() : - _sunLight(new Light()) -{ - _sunLight->setType(Light::SUN); - - setSunIntensity(1.0f); - setSunColor(Vec3(1.0f, 1.0f, 1.0f)); - - // Default origin location is a special place in the world... - setOriginLocation(122.407f, 37.777f, 0.03f); - // 6pm - setDayTime(18.0f); - // Begining of march - setYearTime(60.0f); -} - -SunSkyStage::~SunSkyStage() { -} - -void SunSkyStage::setDayTime(float hour) { - _dayTime = moduloRange(hour, 0.f, NUM_HOURS_PER_DAY); - invalidate(); -} - -void SunSkyStage::setYearTime(unsigned int day) { - _yearTime = day % NUM_DAYS_PER_YEAR; - invalidate(); -} - -void SunSkyStage::setOriginLocation(float longitude, float latitude, float altitude) { - _earthSunModel.setLongitude(longitude); - _earthSunModel.setLatitude(latitude); - _earthSunModel.setAltitude(altitude); - invalidate(); -} - -void SunSkyStage::setSunColor(const Vec3& color) { - _sunLight->setColor(color); -} -void SunSkyStage::setSunIntensity(float intensity) { - _sunLight->setIntensity(intensity); -} - -// THe sun declinaison calculus is taken from https://en.wikipedia.org/wiki/Position_of_the_Sun -double evalSunDeclinaison(double dayNumber) { - return -(23.0 + 44.0/60.0)*cos(glm::radians((360.0/365.0)*(dayNumber + 10.0))); -} - -void SunSkyStage::updateGraphicsObject() const { - // Always update the sunLongitude based on the current dayTime and the current origin - // The day time is supposed to be local at the origin - double signedNormalizedDayTime = (_dayTime - NUM_HOURS_PER_HALF_DAY) / NUM_HOURS_PER_HALF_DAY; - double sunLongitude = _earthSunModel.getLongitude() + (MAX_LONGITUDE * signedNormalizedDayTime); - _earthSunModel.setSunLongitude(sunLongitude); - - // And update the sunLAtitude as the declinaison depending of the time of the year - _earthSunModel.setSunLatitude(evalSunDeclinaison(_yearTime)); - - Vec3d sunLightDir = -_earthSunModel.getSurfaceSunDir(); - - _sunLight->setDirection(Vec3(sunLightDir.x, sunLightDir.y, sunLightDir.z)); -} - +} + +double moduloRange(double val, double minVal, double maxVal) { + double range = maxVal - minVal; + double rval = (val - minVal) / range; + double intval; + return modf(rval, &intval) * range + minVal; +} + +const float MAX_LONGITUDE = 180.0f; +const float MAX_LATITUDE = 90.0f; + +float validateLongitude(float lon) { + return moduloRange(lon, -MAX_LONGITUDE, MAX_LONGITUDE); +} + +float validateLatitude(float lat) { + return moduloRange(lat, -MAX_LATITUDE, MAX_LATITUDE); +} + +float validateAltitude(float altitude) { + const float MIN_ALTITUDE = -1000.0f; + const float MAX_ALTITUDE = 100000.0f; + return std::min(std::max(altitude, MIN_ALTITUDE), MAX_ALTITUDE); +} + +void EarthSunModel::setLatitude(float lat) { + _latitude = validateLatitude(lat); + invalidate(); +} +void EarthSunModel::setLongitude(float lon) { + _longitude = validateLongitude(lon); + invalidate(); +} +void EarthSunModel::setAltitude(float altitude) { + _altitude = validateAltitude(altitude); + invalidate(); +} + +void EarthSunModel::setSunLatitude(float lat) { + _sunLatitude = validateLatitude(lat); + invalidate(); +} +void EarthSunModel::setSunLongitude(float lon) { + _sunLongitude = validateLongitude(lon); + invalidate(); +} + +const int NUM_DAYS_PER_YEAR = 365; +const float NUM_HOURS_PER_DAY = 24.0f; +const float NUM_HOURS_PER_HALF_DAY = NUM_HOURS_PER_DAY * 0.5f; + +SunSkyStage::SunSkyStage() : + _sunLight(new Light()) +{ + _sunLight->setType(Light::SUN); + + setSunIntensity(1.0f); + setSunColor(Vec3(1.0f, 1.0f, 1.0f)); + + // Default origin location is a special place in the world... + setOriginLocation(122.407f, 37.777f, 0.03f); + // 6pm + setDayTime(18.0f); + // Begining of march + setYearTime(60.0f); +} + +SunSkyStage::~SunSkyStage() { +} + +void SunSkyStage::setDayTime(float hour) { + _dayTime = moduloRange(hour, 0.f, NUM_HOURS_PER_DAY); + invalidate(); +} + +void SunSkyStage::setYearTime(unsigned int day) { + _yearTime = day % NUM_DAYS_PER_YEAR; + invalidate(); +} + +void SunSkyStage::setOriginLocation(float longitude, float latitude, float altitude) { + _earthSunModel.setLongitude(longitude); + _earthSunModel.setLatitude(latitude); + _earthSunModel.setAltitude(altitude); + invalidate(); +} + +void SunSkyStage::setSunColor(const Vec3& color) { + _sunLight->setColor(color); +} +void SunSkyStage::setSunIntensity(float intensity) { + _sunLight->setIntensity(intensity); +} + +// THe sun declinaison calculus is taken from https://en.wikipedia.org/wiki/Position_of_the_Sun +double evalSunDeclinaison(double dayNumber) { + return -(23.0 + 44.0/60.0)*cos(glm::radians((360.0/365.0)*(dayNumber + 10.0))); +} + +void SunSkyStage::updateGraphicsObject() const { + // Always update the sunLongitude based on the current dayTime and the current origin + // The day time is supposed to be local at the origin + double signedNormalizedDayTime = (_dayTime - NUM_HOURS_PER_HALF_DAY) / NUM_HOURS_PER_HALF_DAY; + double sunLongitude = _earthSunModel.getLongitude() + (MAX_LONGITUDE * signedNormalizedDayTime); + _earthSunModel.setSunLongitude(sunLongitude); + + // And update the sunLAtitude as the declinaison depending of the time of the year + _earthSunModel.setSunLatitude(evalSunDeclinaison(_yearTime)); + + Vec3d sunLightDir = -_earthSunModel.getSurfaceSunDir(); + + _sunLight->setDirection(Vec3(sunLightDir.x, sunLightDir.y, sunLightDir.z)); +} + From bc8d688cdea8dab4871523a66c6a123198b6ecc2 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 26 Feb 2015 12:04:33 -0800 Subject: [PATCH 14/28] fixing tab maybe --- examples/example/misc/sunLightExample.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/example/misc/sunLightExample.js b/examples/example/misc/sunLightExample.js index 7f38211052..bc00a39246 100644 --- a/examples/example/misc/sunLightExample.js +++ b/examples/example/misc/sunLightExample.js @@ -11,21 +11,21 @@ var intensity = 1.0; var day = 0.0; var hour = 12.0; -var longitude = 0.0; -var latitude = -45.0; +var longitude = -115.0; +var latitude = -31.0; Scene.setDayTime(hour); -Scene.setOriginLocation(longitude, latitude, 0.0); +//Scene.setOriginLocation(longitude, latitude, 0.0); function ticktack() { hour += 0.1; - //Scene.setSunIntensity(Math.cos(time)); - if (hour > 24.0) { - hour = 0.0; - day++; - Scene.setYearTime(day); - } - Scene.setDayTime(hour); + //Scene.setSunIntensity(Math.cos(time)); + if (hour > 24.0) { + hour = 0.0; + day++; + Scene.setYearTime(day); + } + Scene.setDayTime(hour); } Script.setInterval(ticktack, 41); From 96d5a2ab4221e214d364e4437374a5059454209f Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 26 Feb 2015 12:10:08 -0800 Subject: [PATCH 15/28] fixing tab maybe --- examples/example/misc/sunLightExample.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/example/misc/sunLightExample.js b/examples/example/misc/sunLightExample.js index bc00a39246..47fbb9761e 100644 --- a/examples/example/misc/sunLightExample.js +++ b/examples/example/misc/sunLightExample.js @@ -18,7 +18,7 @@ Scene.setDayTime(hour); //Scene.setOriginLocation(longitude, latitude, 0.0); function ticktack() { - hour += 0.1; + hour += 0.1; //Scene.setSunIntensity(Math.cos(time)); if (hour > 24.0) { hour = 0.0; From 3c5f11e6ed0268115275e8dd297562a102484af2 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 26 Feb 2015 14:23:11 -0800 Subject: [PATCH 16/28] Add initial support for multi-selection in properties window --- examples/editEntities.js | 31 +++++++++++++++++-------- examples/html/entityProperties.html | 35 ++++++++++++++++++++++++----- 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/examples/editEntities.js b/examples/editEntities.js index 9b13b167e7..ef6472e4b8 100644 --- a/examples/editEntities.js +++ b/examples/editEntities.js @@ -934,24 +934,37 @@ PropertiesTool = function(opts) { data = { type: 'update', }; - if (selectionManager.hasSelection()) { - data.id = selectionManager.selections[0].id; - data.properties = Entities.getEntityProperties(selectionManager.selections[0]); - data.properties.rotation = Quat.safeEulerAngles(data.properties.rotation); + var selections = []; + for (var i = 0; i < selectionManager.selections.length; i++) { + var entity = {}; + entity.id = selectionManager.selections[i].id; + entity.properties = Entities.getEntityProperties(selectionManager.selections[i]); + entity.properties.rotation = Quat.safeEulerAngles(entity.properties.rotation); + selections.push(entity); } + data.selections = selections; webView.eventBridge.emitScriptEvent(JSON.stringify(data)); }); webView.eventBridge.webEventReceived.connect(function(data) { - print(data); data = JSON.parse(data); if (data.type == "update") { selectionManager.saveProperties(); - if (data.properties.rotation !== undefined) { - var rotation = data.properties.rotation; - data.properties.rotation = Quat.fromPitchYawRollDegrees(rotation.x, rotation.y, rotation.z); + if (selectionManager.selections.length > 1) { + properties = { + locked: data.properties.locked, + visible: data.properties.visible, + }; + for (var i = 0; i < selectionManager.selections.length; i++) { + Entities.editEntity(selectionManager.selections[i], properties); + } + } else { + if (data.properties.rotation !== undefined) { + var rotation = data.properties.rotation; + data.properties.rotation = Quat.fromPitchYawRollDegrees(rotation.x, rotation.y, rotation.z); + } + Entities.editEntity(selectionManager.selections[0], data.properties); } - Entities.editEntity(selectionManager.selections[0], data.properties); pushCommandForSelections(); selectionManager._update(); } else if (data.type == "action") { diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index ad2b359e79..f264b569d6 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -171,12 +171,37 @@ EventBridge.scriptEventReceived.connect(function(data) { data = JSON.parse(data); if (data.type == "update") { - if (data.properties === undefined) { - disableChildren(document.getElementById("properties"), 'input'); - } else { - var properties = data.properties; + if (data.selections.length == 0) { + elType.innerHTML = "No Selection"; + elID.innerHTML = ""; + disableChildren(document.getElementById("properties-list"), 'input'); + } else if (data.selections.length > 1) { + var selections = data.selections; - elID.innerHTML = data.id; + var ids = []; + var types = {}; + + for (var i = 0; i < selections.length; i++) { + ids.push(selections[i].id); + var type = selections[i].properties.type; + if (types[type] === undefined) { + types[type] = 0; + } + types[type]++; + } + elID.innerHTML = ids.join("
"); + + var typeStrs = []; + for (type in types) { + typeStrs.push(type + " (" + types[type] + ")"); + } + elType.innerHTML = typeStrs.join(", "); + + disableChildren(document.getElementById("properties-list"), 'input'); + } else { + var properties = data.selections[0].properties; + + elID.innerHTML = properties.id; elType.innerHTML = properties.type; From ecc003c5e1885f45f0a7f261d0cb7eeff9fd5384 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 26 Feb 2015 14:23:25 -0800 Subject: [PATCH 17/28] Adjust colors for disabled input elements --- examples/html/style.css | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/examples/html/style.css b/examples/html/style.css index 7177b8c8ba..0aedc43480 100644 --- a/examples/html/style.css +++ b/examples/html/style.css @@ -189,6 +189,11 @@ input, textarea { font-size: 7.5pt; } +input:disabled, textarea:disabled { + background-color: rgb(102, 102, 102); + color: rgb(160, 160, 160); +} + #properties-list input[type=button] { cursor: pointer; background-color: rgb(51, 102, 102); @@ -199,6 +204,11 @@ input, textarea { color: rgb(204, 204, 204); } +#properties-list input[type=button]:disabled { + background-color: rgb(41, 82, 82); + color: rgb(160, 160, 160); +} + #properties-list .property { padding: 6pt 6pt; border-top: 0.75pt solid rgb(63, 63, 63); From 74bc48ce55049cd0fb4e409d2a3461b4430380e4 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 26 Feb 2015 14:34:32 -0800 Subject: [PATCH 18/28] Add message to edit entities list for when no entities are nearby --- examples/html/entityList.html | 20 +++++++++++++++----- examples/html/style.css | 8 ++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/examples/html/entityList.html b/examples/html/entityList.html index bbfa4d81b8..bcc1c117ea 100644 --- a/examples/html/entityList.html +++ b/examples/html/entityList.html @@ -20,6 +20,7 @@ elRefresh = document.getElementById("refresh"); elDelete = document.getElementById("delete"); elTeleport = document.getElementById("teleport"); + elNoEntitiesMessage = document.getElementById("no-entities"); document.getElementById("entity-type").onclick = function() { setSortColumn('type'); @@ -155,11 +156,18 @@ } } else if (data.type == "update") { var newEntities = data.entities; - for (var i = 0; i < newEntities.length; i++) { - var id = newEntities[i].id; - addEntity(id, newEntities[i].type, newEntities[i].url); + if (newEntities.length == 0) { + elEntityTable.style.display = "none"; + elNoEntitiesMessage.style.display = "block"; + } else { + elEntityTable.style.display = "table"; + elNoEntitiesMessage.style.display = "none"; + for (var i = 0; i < newEntities.length; i++) { + var id = newEntities[i].id; + addEntity(id, newEntities[i].type, newEntities[i].url); + } + updateSelectedEntities(data.selectedIDs); } - updateSelectedEntities(data.selectedIDs); } }); setTimeout(refreshEntities, 1000); @@ -194,6 +202,8 @@
- +
+ No entities found within 50 meter radius. Try moving to a different location and refreshing. +
diff --git a/examples/html/style.css b/examples/html/style.css index 7177b8c8ba..5d60835e47 100644 --- a/examples/html/style.css +++ b/examples/html/style.css @@ -257,3 +257,11 @@ td { vertical-align: top; } + +#no-entities { + display: none; + font-size: 120%; + padding: 10pt; + font-weight: bold; + font-style: italic; +} From dc2b670fa8e6358a3f60d15ec6133abb67b5a9e2 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 26 Feb 2015 14:46:05 -0800 Subject: [PATCH 19/28] Remove extraneous comments --- libraries/render-utils/src/DeferredLightingEffect.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 5e203b041d..c8ad3711d3 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -131,9 +131,6 @@ void DeferredLightingEffect::addPointLight(const glm::vec3& position, float radi addSpotLight(position, radius, color, intensity); } -// Remove: ambient, specular, *Attenuation, direction -// Add: intensity, radius -// Rename: diffuseColor -> color void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radius, const glm::vec3& color, float intensity, const glm::quat& orientation, float exponent, float cutoff) { From d60618a582801b9d9e0e4e4b5c1e07080e58a1b6 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 26 Feb 2015 14:58:04 -0800 Subject: [PATCH 20/28] Remove unused variables from RenderableLightEntityItem::render --- .../src/RenderableLightEntityItem.cpp | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableLightEntityItem.cpp b/libraries/entities-renderer/src/RenderableLightEntityItem.cpp index 978ca11d9d..7f630f1c8c 100644 --- a/libraries/entities-renderer/src/RenderableLightEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableLightEntityItem.cpp @@ -36,30 +36,18 @@ void RenderableLightEntityItem::render(RenderArgs* args) { float diffuseG = getDiffuseColor()[GREEN_INDEX] / MAX_COLOR; float diffuseB = getDiffuseColor()[BLUE_INDEX] / MAX_COLOR; - float ambientR = getAmbientColor()[RED_INDEX] / MAX_COLOR; - float ambientG = getAmbientColor()[GREEN_INDEX] / MAX_COLOR; - float ambientB = getAmbientColor()[BLUE_INDEX] / MAX_COLOR; + glm::vec3 color = glm::vec3(diffuseR, diffuseG, diffuseB); - float specularR = getSpecularColor()[RED_INDEX] / MAX_COLOR; - float specularG = getSpecularColor()[GREEN_INDEX] / MAX_COLOR; - float specularB = getSpecularColor()[BLUE_INDEX] / MAX_COLOR; - - glm::vec3 ambient = glm::vec3(ambientR, ambientG, ambientB); - glm::vec3 diffuse = glm::vec3(diffuseR, diffuseG, diffuseB); - glm::vec3 specular = glm::vec3(specularR, specularG, specularB); - glm::vec3 direction = IDENTITY_FRONT * rotation; float intensity = getConstantAttenuation(); - float linearAttenuation = getLinearAttenuation(); - float quadraticAttenuation = getQuadraticAttenuation(); float exponent = getExponent(); float cutoff = glm::radians(getCutoff()); if (_isSpotlight) { - DependencyManager::get()->addSpotLight(position, largestDiameter / 2.0f, - diffuse, intensity, rotation, exponent, cutoff); + DependencyManager::get()->addSpotLight(position, largestDiameter / 2.0f, + color, intensity, rotation, exponent, cutoff); } else { - DependencyManager::get()->addPointLight(position, largestDiameter / 2.0f, - diffuse, intensity); + DependencyManager::get()->addPointLight(position, largestDiameter / 2.0f, + color, intensity); } #ifdef WANT_DEBUG From e3b3c8e1ef8f23324f188efd7f01ad5f9e3b34f5 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 26 Feb 2015 16:09:21 -0800 Subject: [PATCH 21/28] Setting the defalt at a better time of the day --- libraries/model/src/model/Stage.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libraries/model/src/model/Stage.cpp b/libraries/model/src/model/Stage.cpp index dd5a44a0cb..8befec2ed3 100644 --- a/libraries/model/src/model/Stage.cpp +++ b/libraries/model/src/model/Stage.cpp @@ -136,8 +136,8 @@ SunSkyStage::SunSkyStage() : // Default origin location is a special place in the world... setOriginLocation(122.407f, 37.777f, 0.03f); - // 6pm - setDayTime(18.0f); + // Noun + setDayTime(12.0f); // Begining of march setYearTime(60.0f); } @@ -185,7 +185,10 @@ void SunSkyStage::updateGraphicsObject() const { _earthSunModel.setSunLatitude(evalSunDeclinaison(_yearTime)); Vec3d sunLightDir = -_earthSunModel.getSurfaceSunDir(); - _sunLight->setDirection(Vec3(sunLightDir.x, sunLightDir.y, sunLightDir.z)); + + double originAlt = _earthSunModel.getAltitude(); + _sunLight->setPosition(Vec3(0.0f, originAlt, 0.0f)); + } From f6a9bd187090049e807c8ff51e32d3d5647ea276 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 26 Feb 2015 17:26:41 -0800 Subject: [PATCH 22/28] REfining the naming and introducing an orientation offset --- examples/example/misc/sunLightExample.js | 10 ++++++---- libraries/model/src/model/Stage.cpp | 15 ++++++++++++++ libraries/model/src/model/Stage.h | 12 +++++++++++ .../src/SceneScriptingInterface.cpp | 20 +++++++++++-------- .../src/SceneScriptingInterface.h | 8 ++++---- 5 files changed, 49 insertions(+), 16 deletions(-) diff --git a/examples/example/misc/sunLightExample.js b/examples/example/misc/sunLightExample.js index 47fbb9761e..9c58d0bac3 100644 --- a/examples/example/misc/sunLightExample.js +++ b/examples/example/misc/sunLightExample.js @@ -13,9 +13,11 @@ var day = 0.0; var hour = 12.0; var longitude = -115.0; var latitude = -31.0; +var stageOrientation = Quat.fromPitchYawRollDegrees(0.0, 180.0, 0.0); -Scene.setDayTime(hour); -//Scene.setOriginLocation(longitude, latitude, 0.0); +Scene.setStageDayTime(hour); +Scene.setStageOrientation(stageOrientation); +Scene.setStageLocation(longitude, latitude, 0.0); function ticktack() { hour += 0.1; @@ -23,9 +25,9 @@ function ticktack() { if (hour > 24.0) { hour = 0.0; day++; - Scene.setYearTime(day); + Scene.setStageYearTime(day); } - Scene.setDayTime(hour); + Scene.setStageDayTime(hour); } Script.setInterval(ticktack, 41); diff --git a/libraries/model/src/model/Stage.cpp b/libraries/model/src/model/Stage.cpp index 8befec2ed3..d867056e8a 100644 --- a/libraries/model/src/model/Stage.cpp +++ b/libraries/model/src/model/Stage.cpp @@ -73,9 +73,19 @@ void EarthSunModel::updateSun() const { // sun direction is looking up toward Y axis at the specified sun lat, long Vec3d lssd = Vec3d(_worldToSurfaceMat * Vec4d(_sunDir.x, _sunDir.y, _sunDir.z, 0.0)); + + // apply surface rotation offset + glm::dquat dSurfOrient(_surfaceOrientation); + lssd = glm::rotate(dSurfOrient, lssd); + _surfaceSunDir = glm::normalize(Vec3(lssd.x, lssd.y, lssd.z)); } +void EarthSunModel::setSurfaceOrientation(const Quat& orientation) { + _surfaceOrientation = orientation; + invalidate(); +} + double moduloRange(double val, double minVal, double maxVal) { double range = maxVal - minVal; double rval = (val - minVal) / range; @@ -155,6 +165,11 @@ void SunSkyStage::setYearTime(unsigned int day) { invalidate(); } +void SunSkyStage::setOriginOrientation(const Quat& orientation) { + _earthSunModel.setSurfaceOrientation(orientation); + invalidate(); +} + void SunSkyStage::setOriginLocation(float longitude, float latitude, float altitude) { _earthSunModel.setLongitude(longitude); _earthSunModel.setLatitude(latitude); diff --git a/libraries/model/src/model/Stage.h b/libraries/model/src/model/Stage.h index f99d2c1648..762e2d9717 100644 --- a/libraries/model/src/model/Stage.h +++ b/libraries/model/src/model/Stage.h @@ -33,6 +33,10 @@ public: void setAltitude(float altitude); float getAltitude() const { return _altitude; } + + void setSurfaceOrientation(const Quat& orientation); + const Quat& getSurfaceOrientation() const { valid(); return _surfaceOrientation; } + const Vec3d& getSurfacePos() const { valid(); return _surfacePos; } const Mat4d& getSurfaceToWorldMat() const { valid(); return _surfaceToWorldMat; } @@ -67,6 +71,8 @@ protected: double _scale = 1000.0; //Km double _earthRadius = 6360.0; + Quat _surfaceOrientation; + double _longitude = 0.0; double _latitude = 0.0; double _altitude = 0.01; @@ -114,6 +120,12 @@ public: void setYearTime(unsigned int day); unsigned int getYearTime() const { return _yearTime; } + // Origin orientation used to modify the cardinal axis alignement used. + // THe default is north along +Z axis and west along +X axis. this orientation gets added + // to the transform stack producing the sun light direction. + void setOriginOrientation(const Quat& orientation); + const Quat& getOriginOrientation() const { return _earthSunModel.getSurfaceOrientation(); } + // Location used to define the sun & sky is a longitude and latitude [rad] and a earth surface altitude [km] void setOriginLocation(float longitude, float latitude, float surfaceAltitude); float getOriginLatitude() const { return _earthSunModel.getLatitude(); } diff --git a/libraries/script-engine/src/SceneScriptingInterface.cpp b/libraries/script-engine/src/SceneScriptingInterface.cpp index ff255a3e5e..9cac521225 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.cpp +++ b/libraries/script-engine/src/SceneScriptingInterface.cpp @@ -13,10 +13,20 @@ #include "SceneScriptingInterface.h" - Q_INVOKABLE void setOriginGeoLocation(float longitude, float latitude, float altitude); -void SceneScriptingInterface::setOriginLocation(float longitude, float latitude, float altitude) { +void SceneScriptingInterface::setStageOrientation(const glm::quat& orientation) { + _skyStage->setOriginOrientation(orientation); +} +void SceneScriptingInterface::setStageLocation(float longitude, float latitude, float altitude) { _skyStage->setOriginLocation(longitude, latitude, altitude); } + +void SceneScriptingInterface::setStageDayTime(float hour) { + _skyStage->setDayTime(hour); +} +void SceneScriptingInterface::setStageYearTime(int day) { + _skyStage->setYearTime(day); +} + void SceneScriptingInterface::setSunColor(const glm::vec3& color) { _skyStage->setSunColor(color); } @@ -24,12 +34,6 @@ void SceneScriptingInterface::setSunIntensity(float intensity) { _skyStage->setSunIntensity(intensity); } -void SceneScriptingInterface::setDayTime(float hour) { - _skyStage->setDayTime(hour); -} -void SceneScriptingInterface::setYearTime(int day) { - _skyStage->setYearTime(day); -} model::SunSkyStagePointer SceneScriptingInterface::getSkyStage() const { return _skyStage; diff --git a/libraries/script-engine/src/SceneScriptingInterface.h b/libraries/script-engine/src/SceneScriptingInterface.h index 3fc909f9a0..8ae9424c95 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.h +++ b/libraries/script-engine/src/SceneScriptingInterface.h @@ -23,14 +23,14 @@ class SceneScriptingInterface : public QObject, public Dependency { SINGLETON_DEPENDENCY public: - Q_INVOKABLE void setOriginLocation(float longitude, float latitude, float altitude); + Q_INVOKABLE void setStageOrientation(const glm::quat& orientation); + Q_INVOKABLE void setStageLocation(float longitude, float latitude, float altitude); + Q_INVOKABLE void setStageDayTime(float hour); + Q_INVOKABLE void setStageYearTime(int day); Q_INVOKABLE void setSunColor(const glm::vec3& color); Q_INVOKABLE void setSunIntensity(float intensity); - Q_INVOKABLE void setDayTime(float hour); - Q_INVOKABLE void setYearTime(int day); - model::SunSkyStagePointer getSkyStage() const; protected: From 74f0d98fd6ff65ae26dfda6374edc03c2a1d5ec9 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 26 Feb 2015 17:44:04 -0800 Subject: [PATCH 23/28] REfining the naming and introducing an orientation offset --- examples/example/misc/sunLightExample.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/example/misc/sunLightExample.js b/examples/example/misc/sunLightExample.js index 9c58d0bac3..93fc06d088 100644 --- a/examples/example/misc/sunLightExample.js +++ b/examples/example/misc/sunLightExample.js @@ -11,8 +11,8 @@ var intensity = 1.0; var day = 0.0; var hour = 12.0; -var longitude = -115.0; -var latitude = -31.0; +var longitude = 115.0; +var latitude = 31.0; var stageOrientation = Quat.fromPitchYawRollDegrees(0.0, 180.0, 0.0); Scene.setStageDayTime(hour); From c7eeebe52cc4b030a6bd6f3436497b4ee8047426 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 26 Feb 2015 18:07:43 -0800 Subject: [PATCH 24/28] and fixing a bug with shadowing of lightmapped surface --- examples/example/misc/sunLightExample.js | 3 ++- libraries/render-utils/src/DeferredGlobalLight.slh | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/example/misc/sunLightExample.js b/examples/example/misc/sunLightExample.js index 93fc06d088..42837c6836 100644 --- a/examples/example/misc/sunLightExample.js +++ b/examples/example/misc/sunLightExample.js @@ -18,7 +18,7 @@ var stageOrientation = Quat.fromPitchYawRollDegrees(0.0, 180.0, 0.0); Scene.setStageDayTime(hour); Scene.setStageOrientation(stageOrientation); Scene.setStageLocation(longitude, latitude, 0.0); - +/* function ticktack() { hour += 0.1; //Scene.setSunIntensity(Math.cos(time)); @@ -31,3 +31,4 @@ function ticktack() { } Script.setInterval(ticktack, 41); +*/ \ No newline at end of file diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index 6868b96c24..0fe2d18e74 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -95,7 +95,8 @@ vec3 evalAmbienSphereGlobalColor(float shadowAttenuation, vec3 position, vec3 no vec3 evalLightmappedColor(float shadowAttenuation, vec3 normal, vec3 diffuse, vec3 lightmap) { Light light = getLight(); - float diffuseDot = dot(normal, getLightDirection(light)); + vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0)); + float diffuseDot = dot(fragNormal, -getLightDirection(light)); // need to catch normals perpendicular to the projection plane hence the magic number for the threshold // it should be just 0, but we have innacurracy so we need to overshoot From 9849efe0130082673622349ffc45559e68beafb4 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 27 Feb 2015 15:33:24 +0100 Subject: [PATCH 25/28] Exponential relaxation --- interface/src/devices/FaceTracker.cpp | 13 +++++++------ interface/src/devices/FaceTracker.h | 1 + 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/interface/src/devices/FaceTracker.cpp b/interface/src/devices/FaceTracker.cpp index e570e39345..f1ab35859b 100644 --- a/interface/src/devices/FaceTracker.cpp +++ b/interface/src/devices/FaceTracker.cpp @@ -16,8 +16,7 @@ inline float FaceTracker::getBlendshapeCoefficient(int index) const { } float FaceTracker::getFadeCoefficient() const { - // TODO: apply exponential relaxation - return _relaxationStatus; + return _fadeCoefficient; } const glm::vec3 FaceTracker::getHeadTranslation() const { @@ -29,18 +28,20 @@ const glm::quat FaceTracker::getHeadRotation() const { } void FaceTracker::update(float deltaTime) { - static const float RELAXATION_TIME = 0.4; // sec + static const float RELAXATION_TIME = 1.0f; // sec + static const float LAMBDA = 1.5; if (isTracking()) { if (_relaxationStatus == 1.0f) { return; } - _relaxationStatus += deltaTime / RELAXATION_TIME; + _relaxationStatus = glm::clamp(_relaxationStatus + deltaTime / RELAXATION_TIME, 0.0f, 1.0f); + _fadeCoefficient = std::exp(-LAMBDA * _relaxationStatus); } else { if (_relaxationStatus == 0.0f) { return; } - _relaxationStatus -= deltaTime / RELAXATION_TIME; + _relaxationStatus = glm::clamp(_relaxationStatus - deltaTime / RELAXATION_TIME, 0.0f, 1.0f); + _fadeCoefficient = 1.0f - std::exp(-LAMBDA * (1.0f - _relaxationStatus)); } - _relaxationStatus = glm::clamp(_relaxationStatus, 0.0f, 1.0f); } \ No newline at end of file diff --git a/interface/src/devices/FaceTracker.h b/interface/src/devices/FaceTracker.h index 89ba1f22f6..1ec0468dec 100644 --- a/interface/src/devices/FaceTracker.h +++ b/interface/src/devices/FaceTracker.h @@ -51,6 +51,7 @@ protected: QVector _blendshapeCoefficients; float _relaxationStatus = 0.0f; // Between 0.0f and 1.0f + float _fadeCoefficient = 0.0f; // Between 0.0f and 1.0f }; #endif // hifi_FaceTracker_h From 8615bb7cff3a39a37cd50301977e35c58b4bd6d0 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 27 Feb 2015 15:58:28 +0100 Subject: [PATCH 26/28] Make relaxation go to EPSILON within TIME --- interface/src/devices/FaceTracker.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/interface/src/devices/FaceTracker.cpp b/interface/src/devices/FaceTracker.cpp index f1ab35859b..d6ccc38a45 100644 --- a/interface/src/devices/FaceTracker.cpp +++ b/interface/src/devices/FaceTracker.cpp @@ -28,20 +28,25 @@ const glm::quat FaceTracker::getHeadRotation() const { } void FaceTracker::update(float deltaTime) { - static const float RELAXATION_TIME = 1.0f; // sec + // Based on exponential distributions: http://en.wikipedia.org/wiki/Exponential_distribution + static const float EPSILON = 0.02f; static const float LAMBDA = 1.5; + static const float INVERSE_AT_EPSILON = -std::log(EPSILON) / LAMBDA; // So that f(1) = EPSILON ~ 0 + static const float RELAXATION_TIME = 0.8f; // sec if (isTracking()) { if (_relaxationStatus == 1.0f) { + _fadeCoefficient = 1.0f; return; } _relaxationStatus = glm::clamp(_relaxationStatus + deltaTime / RELAXATION_TIME, 0.0f, 1.0f); - _fadeCoefficient = std::exp(-LAMBDA * _relaxationStatus); + _fadeCoefficient = 1.0f - std::exp(-LAMBDA * _relaxationStatus * INVERSE_AT_EPSILON); } else { if (_relaxationStatus == 0.0f) { + _fadeCoefficient = 0.0f; return; } _relaxationStatus = glm::clamp(_relaxationStatus - deltaTime / RELAXATION_TIME, 0.0f, 1.0f); - _fadeCoefficient = 1.0f - std::exp(-LAMBDA * (1.0f - _relaxationStatus)); + _fadeCoefficient = std::exp(-LAMBDA * (1.0f - _relaxationStatus) * INVERSE_AT_EPSILON); } } \ No newline at end of file From db90fcdb6220a7a377cd816d765631230dcbc0a5 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 27 Feb 2015 16:09:15 +0100 Subject: [PATCH 27/28] Simplify expression --- interface/src/devices/FaceTracker.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/interface/src/devices/FaceTracker.cpp b/interface/src/devices/FaceTracker.cpp index d6ccc38a45..d3e0600057 100644 --- a/interface/src/devices/FaceTracker.cpp +++ b/interface/src/devices/FaceTracker.cpp @@ -29,9 +29,8 @@ const glm::quat FaceTracker::getHeadRotation() const { void FaceTracker::update(float deltaTime) { // Based on exponential distributions: http://en.wikipedia.org/wiki/Exponential_distribution - static const float EPSILON = 0.02f; - static const float LAMBDA = 1.5; - static const float INVERSE_AT_EPSILON = -std::log(EPSILON) / LAMBDA; // So that f(1) = EPSILON ~ 0 + static const float EPSILON = 0.02f; // MUST BE < 1.0f + static const float INVERSE_AT_EPSILON = -std::log(EPSILON); // So that f(1.0f) = EPSILON ~ 0.0f static const float RELAXATION_TIME = 0.8f; // sec if (isTracking()) { @@ -40,13 +39,13 @@ void FaceTracker::update(float deltaTime) { return; } _relaxationStatus = glm::clamp(_relaxationStatus + deltaTime / RELAXATION_TIME, 0.0f, 1.0f); - _fadeCoefficient = 1.0f - std::exp(-LAMBDA * _relaxationStatus * INVERSE_AT_EPSILON); + _fadeCoefficient = 1.0f - std::exp(-_relaxationStatus * INVERSE_AT_EPSILON); } else { if (_relaxationStatus == 0.0f) { _fadeCoefficient = 0.0f; return; } _relaxationStatus = glm::clamp(_relaxationStatus - deltaTime / RELAXATION_TIME, 0.0f, 1.0f); - _fadeCoefficient = std::exp(-LAMBDA * (1.0f - _relaxationStatus) * INVERSE_AT_EPSILON); + _fadeCoefficient = std::exp(-(1.0f - _relaxationStatus) * INVERSE_AT_EPSILON); } } \ No newline at end of file From 01cac7445a2cee96522e1dd180adf508a35ed40c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 27 Feb 2015 10:58:04 -0800 Subject: [PATCH 28/28] add suppressions for log-spam caused by idle assignment-client --- domain-server/src/DomainServer.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 64e0d335b1..9aec456587 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include "DomainServerNodeData.h" @@ -943,8 +944,10 @@ void DomainServer::readAvailableDatagrams() { if (requestAssignment.getType() != Assignment::AgentType || noisyMessageTimer.elapsed() > NOISY_MESSAGE_INTERVAL_MSECS) { + static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex + ("Received a request for assignment type [^ ]+ from [^ ]+"); qDebug() << "Received a request for assignment type" << requestAssignment.getType() - << "from" << senderSockAddr; + << "from" << senderSockAddr; noisyMessageTimer.restart(); } @@ -974,6 +977,8 @@ void DomainServer::readAvailableDatagrams() { } else { if (requestAssignment.getType() != Assignment::AgentType || noisyMessageTimer.elapsed() > NOISY_MESSAGE_INTERVAL_MSECS) { + static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex + ("Unable to fulfill assignment request of type [^ ]+ from [^ ]+"); qDebug() << "Unable to fulfill assignment request of type" << requestAssignment.getType() << "from" << senderSockAddr; noisyMessageTimer.restart();