mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 15:13:30 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into metavoxels
This commit is contained in:
commit
5b4869f43d
23 changed files with 377 additions and 157 deletions
assignment-client/src
domain-server/src
examples
interface
resources/shaders
src
libraries
animation/src
entities/src
fbx/src
networking/src
|
@ -10,6 +10,7 @@
|
|||
//
|
||||
|
||||
#include <QtCore/QProcess>
|
||||
#include <QtCore/qsharedmemory.h>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
|
@ -38,7 +39,8 @@ int hifiSockAddrMeta = qRegisterMetaType<HifiSockAddr>("HifiSockAddr");
|
|||
AssignmentClient::AssignmentClient(int &argc, char **argv) :
|
||||
QCoreApplication(argc, argv),
|
||||
_shutdownEventListener(this),
|
||||
_assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME)
|
||||
_assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME),
|
||||
_localASPortSharedMem(NULL)
|
||||
{
|
||||
LogUtils::init();
|
||||
|
||||
|
@ -89,13 +91,7 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) :
|
|||
// create a NodeList as an unassigned client
|
||||
NodeList* nodeList = NodeList::createInstance(NodeType::Unassigned);
|
||||
|
||||
unsigned short assignmentServerPort = DEFAULT_DOMAIN_SERVER_PORT;
|
||||
|
||||
// check for an overriden assignment server port
|
||||
if (argumentVariantMap.contains(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION)) {
|
||||
assignmentServerPort =
|
||||
argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION).toString().toUInt();
|
||||
}
|
||||
quint16 assignmentServerPort = DEFAULT_DOMAIN_SERVER_PORT;
|
||||
|
||||
// check for an overriden assignment server hostname
|
||||
if (argumentVariantMap.contains(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION)) {
|
||||
|
@ -103,10 +99,16 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) :
|
|||
_assignmentServerHostname = argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION).toString();
|
||||
}
|
||||
|
||||
HifiSockAddr assignmentServerSocket(_assignmentServerHostname, assignmentServerPort, true);
|
||||
nodeList->setAssignmentServerSocket(assignmentServerSocket);
|
||||
// check for an overriden assignment server port
|
||||
if (argumentVariantMap.contains(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION)) {
|
||||
assignmentServerPort =
|
||||
argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION).toString().toUInt();
|
||||
}
|
||||
|
||||
_assignmentServerSocket = HifiSockAddr(_assignmentServerHostname, assignmentServerPort, true);
|
||||
nodeList->setAssignmentServerSocket(_assignmentServerSocket);
|
||||
|
||||
qDebug() << "Assignment server socket is" << assignmentServerSocket;
|
||||
qDebug() << "Assignment server socket is" << _assignmentServerSocket;
|
||||
|
||||
// call a timer function every ASSIGNMENT_REQUEST_INTERVAL_MSECS to ask for assignment, if required
|
||||
qDebug() << "Waiting for assignment -" << _requestAssignment;
|
||||
|
@ -129,7 +131,40 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) :
|
|||
|
||||
void AssignmentClient::sendAssignmentRequest() {
|
||||
if (!_currentAssignment) {
|
||||
NodeList::getInstance()->sendAssignment(_requestAssignment);
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
if (_assignmentServerHostname == "localhost") {
|
||||
// we want to check again for the local domain-server port in case the DS has restarted
|
||||
if (!_localASPortSharedMem) {
|
||||
_localASPortSharedMem = new QSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this);
|
||||
|
||||
if (!_localASPortSharedMem->attach(QSharedMemory::ReadOnly)) {
|
||||
qWarning() << "Could not attach to shared memory at key" << DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY
|
||||
<< "- will attempt to connect to domain-server on" << _assignmentServerSocket.getPort();
|
||||
}
|
||||
}
|
||||
|
||||
if (_localASPortSharedMem->isAttached()) {
|
||||
_localASPortSharedMem->lock();
|
||||
|
||||
quint16 localAssignmentServerPort;
|
||||
memcpy(&localAssignmentServerPort, _localASPortSharedMem->data(), sizeof(localAssignmentServerPort));
|
||||
|
||||
_localASPortSharedMem->unlock();
|
||||
|
||||
if (localAssignmentServerPort != _assignmentServerSocket.getPort()) {
|
||||
qDebug() << "Port for local assignment server read from shared memory is"
|
||||
<< localAssignmentServerPort;
|
||||
|
||||
_assignmentServerSocket.setPort(localAssignmentServerPort);
|
||||
nodeList->setAssignmentServerSocket(_assignmentServerSocket);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
nodeList->sendAssignment(_requestAssignment);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#include "ShutdownEventListener.h"
|
||||
#include "ThreadedAssignment.h"
|
||||
|
||||
class QSharedMemory;
|
||||
|
||||
class AssignmentClient : public QCoreApplication {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -34,6 +36,8 @@ private:
|
|||
static SharedAssignmentPointer _currentAssignment;
|
||||
ShutdownEventListener _shutdownEventListener;
|
||||
QString _assignmentServerHostname;
|
||||
HifiSockAddr _assignmentServerSocket;
|
||||
QSharedMemory* _localASPortSharedMem;
|
||||
};
|
||||
|
||||
#endif // hifi_AssignmentClient_h
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <QtCore/QJsonObject>
|
||||
#include <QtCore/QJsonArray>
|
||||
#include <QtCore/QProcess>
|
||||
#include <QtCore/qsharedmemory.h>
|
||||
#include <QtCore/QStandardPaths>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QUrlQuery>
|
||||
|
@ -228,6 +229,21 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) {
|
|||
|
||||
LimitedNodeList* nodeList = LimitedNodeList::createInstance(domainServerPort, domainServerDTLSPort);
|
||||
|
||||
// no matter the local port, save it to shared mem so that local assignment clients can ask what it is
|
||||
QSharedMemory* sharedPortMem = new QSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this);
|
||||
quint16 localPort = nodeList->getNodeSocket().localPort();
|
||||
|
||||
// attempt to create the shared memory segment
|
||||
if (sharedPortMem->create(sizeof(localPort)) || sharedPortMem->attach()) {
|
||||
sharedPortMem->lock();
|
||||
memcpy(sharedPortMem->data(), &localPort, sizeof(localPort));
|
||||
sharedPortMem->unlock();
|
||||
|
||||
qDebug() << "Wrote local listening port" << localPort << "to shared memory at key" << DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY;
|
||||
} else {
|
||||
qWarning() << "Failed to create and attach to shared memory to share local port with assignment-client children.";
|
||||
}
|
||||
|
||||
// set our LimitedNodeList UUID to match the UUID from our config
|
||||
// nodes will currently use this to add resources to data-web that relate to our domain
|
||||
const QString METAVERSE_DOMAIN_ID_KEY_PATH = "metaverse.id";
|
||||
|
|
37
examples/developerMenuItems.js
Normal file
37
examples/developerMenuItems.js
Normal file
|
@ -0,0 +1,37 @@
|
|||
//
|
||||
// developerMenuItems.js
|
||||
// examples
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 2/24/14
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Adds a bunch of developer and debugging menu items
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
|
||||
function setupMenus() {
|
||||
if (!Menu.menuExists("Developer")) {
|
||||
Menu.addMenu("Developer");
|
||||
}
|
||||
if (!Menu.menuExists("Developer > Entities")) {
|
||||
Menu.addMenu("Developer > Entities");
|
||||
Menu.addMenuItem({ menuName: "Developer > Entities", menuItemName: "Display Model Bounds", isCheckable: true, isChecked: false });
|
||||
Menu.addMenuItem({ menuName: "Developer > Entities", menuItemName: "Display Model Element Bounds", isCheckable: true, isChecked: false });
|
||||
Menu.addMenuItem({ menuName: "Developer > Entities", menuItemName: "Display Model Element Children", isCheckable: true, isChecked: false });
|
||||
Menu.addMenuItem({ menuName: "Developer > Entities", menuItemName: "Disable Light Entities", isCheckable: true, isChecked: false });
|
||||
Menu.addMenuItem({ menuName: "Developer > Entities", menuItemName: "Don't Attempt to Reduce Material Switches", isCheckable: true, isChecked: false });
|
||||
Menu.addMenuItem({ menuName: "Developer > Entities", menuItemName: "Don't Attempt Render Entities as Scene", isCheckable: true, isChecked: false });
|
||||
Menu.addMenu("Developer > Entities > Culling");
|
||||
Menu.addMenuItem({ menuName: "Developer > Entities > Culling", menuItemName: "Don't Cull Out Of View Mesh Parts", isCheckable: true, isChecked: false });
|
||||
Menu.addMenuItem({ menuName: "Developer > Entities > Culling", menuItemName: "Don't Cull Too Small Mesh Parts", isCheckable: true, isChecked: false });
|
||||
}
|
||||
}
|
||||
|
||||
function scriptEnding() {
|
||||
Menu.removeMenu("Developer > Entities");
|
||||
}
|
||||
setupMenus();
|
||||
Script.scriptEnding.connect(scriptEnding);
|
|
@ -19,6 +19,7 @@ var warpPosition = { x: 0, y: 0, z: 0 };
|
|||
|
||||
var hipsToEyes;
|
||||
var restoreCountdownTimer;
|
||||
var headTurningTimer = 0.0;
|
||||
|
||||
// Overlays to show target location
|
||||
|
||||
|
@ -168,6 +169,20 @@ function update(deltaTime) {
|
|||
restoreCountDownTimer = 0.0;
|
||||
}
|
||||
}
|
||||
var HEAD_TURN_TIME = 0.10;
|
||||
var HEAD_TURN_DEGREES = 4.0;
|
||||
var HEAD_TURN_START_ANGLE = 45.0;
|
||||
var currentYaw = MyAvatar.getHeadFinalYaw();
|
||||
if (Math.abs(currentYaw) > HEAD_TURN_START_ANGLE) {
|
||||
headTurningTimer += deltaTime;
|
||||
if (headTurningTimer > HEAD_TURN_TIME) {
|
||||
headTurningTimer = 0.0;
|
||||
MyAvatar.orientation = Quat.multiply(Quat.fromPitchYawRollDegrees(0, (currentYaw > 0) ? HEAD_TURN_DEGREES: -HEAD_TURN_DEGREES, 0),
|
||||
MyAvatar.orientation);
|
||||
}
|
||||
} else {
|
||||
headTurningTimer = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
Controller.keyPressEvent.connect(function(event) {
|
||||
|
|
|
@ -36,25 +36,36 @@ uniform vec2 depthTexCoordOffset;
|
|||
uniform vec2 depthTexCoordScale;
|
||||
|
||||
void main(void) {
|
||||
float depthVal = texture2D(depthMap, gl_TexCoord[0].st).r;
|
||||
vec4 normalVal = texture2D(normalMap, gl_TexCoord[0].st);
|
||||
vec4 diffuseVal = texture2D(diffuseMap, gl_TexCoord[0].st);
|
||||
vec4 specularVal = texture2D(specularMap, gl_TexCoord[0].st);
|
||||
|
||||
// compute the view space position using the depth
|
||||
float z = near / (texture2D(depthMap, gl_TexCoord[0].st).r * depthScale - 1.0);
|
||||
float z = near / (depthVal * depthScale - 1.0);
|
||||
vec4 position = vec4((depthTexCoordOffset + gl_TexCoord[0].st * depthTexCoordScale) * z, z, 0.0);
|
||||
|
||||
// get the normal from the map
|
||||
vec4 normal = texture2D(normalMap, gl_TexCoord[0].st);
|
||||
vec4 normalizedNormal = normalize(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0));
|
||||
|
||||
// compute the base color based on OpenGL lighting model
|
||||
float diffuse = dot(normalizedNormal, gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse);
|
||||
vec4 baseColor = texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightModelProduct.sceneColor +
|
||||
gl_FrontLightProduct[0].ambient + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
||||
|
||||
// compute the specular multiplier (sans exponent)
|
||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(position)),
|
||||
normalizedNormal));
|
||||
|
||||
// add specular contribution
|
||||
vec4 specularColor = texture2D(specularMap, gl_TexCoord[0].st);
|
||||
gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb, normal.a);
|
||||
vec4 normal = normalVal;
|
||||
if ((normalVal.a >= 0.45) && (normalVal.a <= 0.55)) {
|
||||
normal.a = 1.0;
|
||||
normalVal.a = 0.0;
|
||||
gl_FragColor = vec4(diffuseVal.rgb * specularVal.rgb, 1.0);
|
||||
} else {
|
||||
vec3 normalizedNormal = normalize(normal.xyz * 2.0 - vec3(1.0));
|
||||
|
||||
// compute the base color based on OpenGL lighting model
|
||||
float diffuse = dot(normalizedNormal, gl_LightSource[0].position.xyz);
|
||||
float facingLight = step(0.0, diffuse);
|
||||
vec3 baseColor = diffuseVal.rgb * (gl_FrontLightModelProduct.sceneColor.rgb +
|
||||
gl_FrontLightProduct[0].ambient.rgb + gl_FrontLightProduct[0].diffuse.rgb * (diffuse * facingLight));
|
||||
|
||||
// compute the specular multiplier (sans exponent)
|
||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position.xyz - normalize(position.xyz)),
|
||||
normalizedNormal));
|
||||
|
||||
// add specular contribution
|
||||
vec4 specularColor = specularVal;
|
||||
gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb, normal.a);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ void main(void) {
|
|||
// set the diffuse, normal, specular data
|
||||
vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st);
|
||||
vec4 emissive = texture2D(emissiveMap, interpolatedTexcoord1.st);
|
||||
gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb * (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb), mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold)));
|
||||
gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
|
||||
gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0);
|
||||
gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold)));
|
||||
gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 0.5);
|
||||
gl_FragData[2] = vec4((vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb), gl_FrontMaterial.shininess / 128.0);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// model_normal_map.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 10/14/13.
|
||||
// Created by Andrzej Kapolka on 10/29/13.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
|
|
|
@ -438,6 +438,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
|
||||
void Application::aboutToQuit() {
|
||||
_aboutToQuit = true;
|
||||
setFullscreen(false); // if you exit while in full screen, you'll get bad behavior when you restart.
|
||||
}
|
||||
|
||||
Application::~Application() {
|
||||
|
@ -650,20 +651,11 @@ void Application::paintGL() {
|
|||
}
|
||||
|
||||
} else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||
//Only behave like a true mirror when in the OR
|
||||
if (OculusManager::isConnected()) {
|
||||
_myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)));
|
||||
_myCamera.setPosition(_myAvatar->getHead()->getEyePosition() +
|
||||
glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) +
|
||||
(_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) *
|
||||
glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror);
|
||||
} else {
|
||||
_myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)));
|
||||
_myCamera.setPosition(_myAvatar->getHead()->getEyePosition() +
|
||||
glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) +
|
||||
(_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) *
|
||||
glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror);
|
||||
}
|
||||
_myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)));
|
||||
_myCamera.setPosition(_myAvatar->getDefaultEyePosition() +
|
||||
glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) +
|
||||
(_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) *
|
||||
glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror);
|
||||
}
|
||||
|
||||
// Update camera position
|
||||
|
|
|
@ -445,23 +445,7 @@ Menu::Menu() :
|
|||
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderBoundingCollisionShapes);
|
||||
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderLookAtVectors, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderFocusIndicator, 0, false);
|
||||
|
||||
QMenu* entitiesDebugMenu = developerMenu->addMenu("Entities");
|
||||
addCheckableActionToQMenuAndActionHash(entitiesDebugMenu, MenuOption::DisplayModelBounds, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(entitiesDebugMenu, MenuOption::DisplayModelElementProxy, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(entitiesDebugMenu, MenuOption::DisplayModelElementChildProxies, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(entitiesDebugMenu, MenuOption::DisableLightEntities, 0, false);
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(entitiesDebugMenu, MenuOption::DontReduceMaterialSwitches, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(entitiesDebugMenu, MenuOption::DontRenderEntitiesAsScene, 0, false);
|
||||
|
||||
QMenu* entityCullingMenu = entitiesDebugMenu->addMenu("Culling");
|
||||
addCheckableActionToQMenuAndActionHash(entityCullingMenu, MenuOption::DontCullOutOfViewMeshParts, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(entityCullingMenu, MenuOption::DontCullTooSmallMeshParts, 0, false);
|
||||
|
||||
|
||||
|
||||
|
||||
QMenu* voxelOptionsMenu = developerMenu->addMenu("Voxels");
|
||||
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures);
|
||||
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion);
|
||||
|
|
|
@ -367,6 +367,15 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
|
|||
const float TORSO_LENGTH = 0.5f;
|
||||
glm::vec3 relativePosition = estimatedPosition - glm::vec3(0.0f, -TORSO_LENGTH, 0.0f);
|
||||
const float MAX_LEAN = 45.0f;
|
||||
|
||||
// Invert left/right lean when in mirror mode
|
||||
// NOTE: this is kinda a hack, it's the same hack we use to make the head tilt. But it's not really a mirror
|
||||
// it just makes you feel like you're looking in a mirror because the body movements of the avatar appear to
|
||||
// match your body movements.
|
||||
if (OculusManager::isConnected() && Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_MIRROR) {
|
||||
relativePosition.x = -relativePosition.x;
|
||||
}
|
||||
|
||||
head->setLeanSideways(glm::clamp(glm::degrees(atanf(relativePosition.x * _leanScale / TORSO_LENGTH)),
|
||||
-MAX_LEAN, MAX_LEAN));
|
||||
head->setLeanForward(glm::clamp(glm::degrees(atanf(relativePosition.z * _leanScale / TORSO_LENGTH)),
|
||||
|
|
|
@ -477,7 +477,8 @@ void SixenseManager::emulateMouse(PalmData* palm, int index) {
|
|||
triggerButton = Qt::LeftButton;
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)
|
||||
|| Menu::getInstance()->isOptionChecked(MenuOption::EnableVRMode)) {
|
||||
pos = application->getApplicationOverlay().getPalmClickLocation(palm);
|
||||
} else {
|
||||
// Get directon relative to avatar orientation
|
||||
|
|
|
@ -138,11 +138,9 @@ void AnimationHandle::simulate(float deltaTime) {
|
|||
return;
|
||||
}
|
||||
|
||||
// TODO: When moving the loop/frame calculations to AnimationLoop class, we changed this behavior
|
||||
// see AnimationLoop class for more details. Do we need to support clamping the endFrameIndex to
|
||||
// the max number of frames in the geometry???
|
||||
//
|
||||
// float endFrameIndex = qMin(_lastFrame, animationGeometry.animationFrames.size() - (_loop ? 0.0f : 1.0f));
|
||||
if (_animationLoop.getMaxFrameIndexHint() != animationGeometry.animationFrames.size()) {
|
||||
_animationLoop.setMaxFrameIndexHint(animationGeometry.animationFrames.size());
|
||||
}
|
||||
|
||||
// blend between the closest two frames
|
||||
applyFrame(getFrameIndex());
|
||||
|
|
|
@ -829,10 +829,25 @@ void GeometryReader::run() {
|
|||
return;
|
||||
}
|
||||
try {
|
||||
QMetaObject::invokeMethod(geometry.data(), "setGeometry", Q_ARG(const FBXGeometry&,
|
||||
std::string urlname = _url.path().toLower().toStdString();
|
||||
FBXGeometry fbxgeo;
|
||||
if (_url.path().toLower().endsWith(".svo")) {
|
||||
fbxgeo = readSVO(_reply->readAll());
|
||||
} else {
|
||||
bool grabLightmaps = true;
|
||||
float lightmapLevel = 1.0f;
|
||||
// HACK: For monday 12/01/2014 we need to kill lighmaps loading in starchamber...
|
||||
if (_url.path().toLower().endsWith("loungev4_11-18.fbx")) {
|
||||
grabLightmaps = false;
|
||||
} else if (_url.path().toLower().endsWith("apt8_reboot.fbx")) {
|
||||
lightmapLevel = 4.0f;
|
||||
}
|
||||
fbxgeo = readFBX(_reply->readAll(), _mapping, grabLightmaps, lightmapLevel);
|
||||
}
|
||||
QMetaObject::invokeMethod(geometry.data(), "setGeometry", Q_ARG(const FBXGeometry&, fbxgeo));
|
||||
|
||||
|
||||
_url.path().toLower().endsWith(".svo") ? readSVO(_reply->readAll()) : readFBX(_reply->readAll(), _mapping)));
|
||||
// _url.path().toLower().endsWith(".svo") ? readSVO(_reply->readAll()) : readFBX(_reply->readAll(), _mapping)));
|
||||
|
||||
} catch (const QString& error) {
|
||||
qDebug() << "Error reading " << _url << ": " << error;
|
||||
|
|
|
@ -2347,8 +2347,12 @@ int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMod
|
|||
diffuseMap = (_dilatedTextures[i][j] =
|
||||
static_cast<DilatableNetworkTexture*>(diffuseMap)->getDilatedTexture(_pupilDilation)).data();
|
||||
}
|
||||
GLBATCH(glBindTexture)(GL_TEXTURE_2D, !diffuseMap ?
|
||||
Application::getInstance()->getTextureCache()->getWhiteTextureID() : diffuseMap->getID());
|
||||
static bool showDiffuse = true;
|
||||
if (showDiffuse && diffuseMap) {
|
||||
GLBATCH(glBindTexture)(GL_TEXTURE_2D, diffuseMap->getID());
|
||||
} else {
|
||||
GLBATCH(glBindTexture)(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getWhiteTextureID());
|
||||
}
|
||||
|
||||
if (locations->texcoordMatrices >= 0) {
|
||||
glm::mat4 texcoordTransform[2];
|
||||
|
@ -2377,22 +2381,27 @@ int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMod
|
|||
GLBATCH(glActiveTexture)(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
if (locations->emissiveTextureUnit >= 0) {
|
||||
assert(locations->emissiveParams >= 0); // we should have the emissiveParams defined in the shader
|
||||
GLBATCH(glUniform2f)(locations->emissiveParams, 0.1f, 4.0f);
|
||||
|
||||
GLBATCH(glActiveTexture)(GL_TEXTURE0 + locations->emissiveTextureUnit);
|
||||
Texture* emissiveMap = networkPart.emissiveTexture.data();
|
||||
GLBATCH(glBindTexture)(GL_TEXTURE_2D, !emissiveMap ?
|
||||
Application::getInstance()->getTextureCache()->getWhiteTextureID() : emissiveMap->getID());
|
||||
GLBATCH(glActiveTexture)(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
if (args) {
|
||||
args->_materialSwitches++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// HACK: For unkwon reason (yet!) this code that should be assigned only if the material changes need to be called for every
|
||||
// drawcall with an emissive, so let's do it for now.
|
||||
if (locations->emissiveTextureUnit >= 0) {
|
||||
// assert(locations->emissiveParams >= 0); // we should have the emissiveParams defined in the shader
|
||||
float emissiveOffset = part.emissiveParams.x;
|
||||
float emissiveScale = part.emissiveParams.y;
|
||||
GLBATCH(glUniform2f)(locations->emissiveParams, emissiveOffset, emissiveScale);
|
||||
|
||||
GLBATCH(glActiveTexture)(GL_TEXTURE0 + locations->emissiveTextureUnit);
|
||||
Texture* emissiveMap = networkPart.emissiveTexture.data();
|
||||
GLBATCH(glBindTexture)(GL_TEXTURE_2D, !emissiveMap ?
|
||||
Application::getInstance()->getTextureCache()->getWhiteTextureID() : emissiveMap->getID());
|
||||
GLBATCH(glActiveTexture)(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
lastMaterialID = part.materialID;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,27 +30,27 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) :
|
|||
QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint) ,
|
||||
_previousScreen(NULL),
|
||||
_hmdScreen(NULL),
|
||||
_previousDialogScreen(NULL)
|
||||
_hmdScreenNumber(-1),
|
||||
_switchModeButton(NULL),
|
||||
_debugDetails(NULL),
|
||||
_previousDialogScreen(NULL),
|
||||
_inHDMMode(false)
|
||||
{
|
||||
this->setWindowTitle("HMD Tools");
|
||||
|
||||
// Create layouter
|
||||
QFormLayout* form = new QFormLayout();
|
||||
const int WIDTH = 350;
|
||||
|
||||
// Add a button to enter
|
||||
QPushButton* enterModeButton = new QPushButton("Enter HMD Mode");
|
||||
form->addRow("", enterModeButton);
|
||||
connect(enterModeButton,SIGNAL(clicked(bool)),this,SLOT(enterModeClicked(bool)));
|
||||
|
||||
// Add a button to leave
|
||||
QPushButton* leaveModeButton = new QPushButton("Leave HMD Mode");
|
||||
form->addRow("", leaveModeButton);
|
||||
connect(leaveModeButton,SIGNAL(clicked(bool)),this,SLOT(leaveModeClicked(bool)));
|
||||
_switchModeButton = new QPushButton("Enter HMD Mode");
|
||||
_switchModeButton->setFixedWidth(WIDTH);
|
||||
form->addRow("", _switchModeButton);
|
||||
connect(_switchModeButton,SIGNAL(clicked(bool)),this,SLOT(switchModeClicked(bool)));
|
||||
|
||||
// Create a label with debug details...
|
||||
_debugDetails = new QLabel();
|
||||
_debugDetails->setText(getDebugDetails());
|
||||
const int WIDTH = 350;
|
||||
const int HEIGHT = 100;
|
||||
_debugDetails->setFixedSize(WIDTH, HEIGHT);
|
||||
form->addRow("", _debugDetails);
|
||||
|
@ -65,14 +65,21 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) :
|
|||
QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle();
|
||||
connect(mainWindow, &QWindow::screenChanged, this, &HMDToolsDialog::applicationWindowScreenChanged);
|
||||
|
||||
// watch for our dialog window moving screens. If it does we want to enforce our rules about what screens we're
|
||||
// allowed on
|
||||
// watch for our dialog window moving screens. If it does we want to enforce our rules about
|
||||
// what screens we're allowed on
|
||||
QWindow* dialogWindow = windowHandle();
|
||||
connect(dialogWindow, &QWindow::screenChanged, this, &HMDToolsDialog::dialogWindowScreenChanged);
|
||||
connect(dialogWindow, &QWindow::xChanged, this, &HMDToolsDialog::dialogWindowGeometryChanged);
|
||||
connect(dialogWindow, &QWindow::yChanged, this, &HMDToolsDialog::dialogWindowGeometryChanged);
|
||||
connect(dialogWindow, &QWindow::widthChanged, this, &HMDToolsDialog::dialogWindowGeometryChanged);
|
||||
connect(dialogWindow, &QWindow::heightChanged, this, &HMDToolsDialog::dialogWindowGeometryChanged);
|
||||
|
||||
// when the application is about to quit, leave HDM mode
|
||||
connect(Application::getInstance(), SIGNAL(aboutToQuit()), this, SLOT(aboutToQuit()));
|
||||
|
||||
// keep track of changes to the number of screens
|
||||
connect(QApplication::desktop(), &QDesktopWidget::screenCountChanged, this, &HMDToolsDialog::screenCountChanged);
|
||||
|
||||
}
|
||||
|
||||
HMDToolsDialog::~HMDToolsDialog() {
|
||||
|
@ -96,11 +103,11 @@ void HMDToolsDialog::dialogWindowScreenChanged(QScreen* screen) {
|
|||
// if we have more than one screen, and a known hmdScreen then try to
|
||||
// keep our dialog off of the hmdScreen
|
||||
if (QApplication::desktop()->screenCount() > 1) {
|
||||
int hmdScreenNumber = OculusManager::getHMDScreen();
|
||||
|
||||
if (hmdScreenNumber >= 0) {
|
||||
QScreen* hmdScreen = QGuiApplication::screens()[hmdScreenNumber];
|
||||
|
||||
// we want to use a local variable here because we are not necesarily in HMD mode
|
||||
int hmdScreenNumber = OculusManager::getHMDScreen();
|
||||
if (_hmdScreenNumber >= 0) {
|
||||
QScreen* hmdScreen = QGuiApplication::screens()[hmdScreenNumber];
|
||||
if (screen == hmdScreen) {
|
||||
qDebug() << "HMD Tools: Whoa! What are you doing? You don't want to move me to the HMD Screen!";
|
||||
QWindow* dialogWindow = windowHandle();
|
||||
|
@ -154,42 +161,55 @@ QString HMDToolsDialog::getDebugDetails() const {
|
|||
results += "Application Primary Screen: " + QGuiApplication::primaryScreen()->name() + "\n";
|
||||
QScreen* mainWindowScreen = Application::getInstance()->getWindow()->windowHandle()->screen();
|
||||
results += "Application Main Window Screen: " + mainWindowScreen->name() + "\n";
|
||||
results += "Total Screens: " + QString::number(QApplication::desktop()->screenCount()) + "\n";
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
void HMDToolsDialog::enterModeClicked(bool checked) {
|
||||
_debugDetails->setText(getDebugDetails());
|
||||
void HMDToolsDialog::switchModeClicked(bool checked) {
|
||||
if (!_inHDMMode) {
|
||||
enterHDMMode();
|
||||
} else {
|
||||
leaveHDMMode();
|
||||
}
|
||||
}
|
||||
|
||||
int hmdScreen = OculusManager::getHMDScreen();
|
||||
qDebug() << "enterModeClicked().... hmdScreen:" << hmdScreen;
|
||||
void HMDToolsDialog::enterHDMMode() {
|
||||
if (!_inHDMMode) {
|
||||
_switchModeButton->setText("Leave HMD Mode");
|
||||
_debugDetails->setText(getDebugDetails());
|
||||
|
||||
_hmdScreenNumber = OculusManager::getHMDScreen();
|
||||
|
||||
if (hmdScreen >= 0) {
|
||||
QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle();
|
||||
_hmdScreen = QGuiApplication::screens()[hmdScreen];
|
||||
if (_hmdScreenNumber >= 0) {
|
||||
QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle();
|
||||
_hmdScreen = QGuiApplication::screens()[_hmdScreenNumber];
|
||||
|
||||
_previousRect = Application::getInstance()->getWindow()->rect();
|
||||
_previousRect = QRect(mainWindow->mapToGlobal(_previousRect.topLeft()),
|
||||
mainWindow->mapToGlobal(_previousRect.bottomRight()));
|
||||
_previousScreen = mainWindow->screen();
|
||||
QRect rect = QApplication::desktop()->screenGeometry(hmdScreen);
|
||||
mainWindow->setScreen(_hmdScreen);
|
||||
mainWindow->setGeometry(rect);
|
||||
_previousRect = Application::getInstance()->getWindow()->rect();
|
||||
_previousRect = QRect(mainWindow->mapToGlobal(_previousRect.topLeft()),
|
||||
mainWindow->mapToGlobal(_previousRect.bottomRight()));
|
||||
_previousScreen = mainWindow->screen();
|
||||
QRect rect = QApplication::desktop()->screenGeometry(_hmdScreenNumber);
|
||||
mainWindow->setScreen(_hmdScreen);
|
||||
mainWindow->setGeometry(rect);
|
||||
|
||||
_wasMoved = true;
|
||||
}
|
||||
_wasMoved = true;
|
||||
}
|
||||
|
||||
|
||||
// if we're on a single screen setup, then hide our tools window when entering HMD mode
|
||||
if (QApplication::desktop()->screenCount() == 1) {
|
||||
close();
|
||||
}
|
||||
// if we're on a single screen setup, then hide our tools window when entering HMD mode
|
||||
if (QApplication::desktop()->screenCount() == 1) {
|
||||
close();
|
||||
}
|
||||
|
||||
Application::getInstance()->setFullscreen(true);
|
||||
Application::getInstance()->setEnableVRMode(true);
|
||||
Application::getInstance()->setFullscreen(true);
|
||||
Application::getInstance()->setEnableVRMode(true);
|
||||
|
||||
const int SLIGHT_DELAY = 500;
|
||||
QTimer::singleShot(SLIGHT_DELAY, this, SLOT(activateWindowAfterEnterMode()));
|
||||
const int SLIGHT_DELAY = 500;
|
||||
QTimer::singleShot(SLIGHT_DELAY, this, SLOT(activateWindowAfterEnterMode()));
|
||||
|
||||
_inHDMMode = true;
|
||||
}
|
||||
}
|
||||
|
||||
void HMDToolsDialog::activateWindowAfterEnterMode() {
|
||||
|
@ -199,23 +219,26 @@ void HMDToolsDialog::activateWindowAfterEnterMode() {
|
|||
centerCursorOnWidget(Application::getInstance()->getWindow());
|
||||
}
|
||||
|
||||
void HMDToolsDialog::leaveHDMMode() {
|
||||
if (_inHDMMode) {
|
||||
_switchModeButton->setText("Enter HMD Mode");
|
||||
_debugDetails->setText(getDebugDetails());
|
||||
|
||||
void HMDToolsDialog::leaveModeClicked(bool checked) {
|
||||
_debugDetails->setText(getDebugDetails());
|
||||
Application::getInstance()->setFullscreen(false);
|
||||
Application::getInstance()->setEnableVRMode(false);
|
||||
Application::getInstance()->getWindow()->activateWindow();
|
||||
|
||||
Application::getInstance()->setFullscreen(false);
|
||||
Application::getInstance()->setEnableVRMode(false);
|
||||
Application::getInstance()->getWindow()->activateWindow();
|
||||
|
||||
if (_wasMoved) {
|
||||
QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle();
|
||||
mainWindow->setScreen(_previousScreen);
|
||||
mainWindow->setGeometry(_previousRect);
|
||||
if (_wasMoved) {
|
||||
QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle();
|
||||
mainWindow->setScreen(_previousScreen);
|
||||
mainWindow->setGeometry(_previousRect);
|
||||
|
||||
const int SLIGHT_DELAY = 1500;
|
||||
QTimer::singleShot(SLIGHT_DELAY, this, SLOT(moveWindowAfterLeaveMode()));
|
||||
const int SLIGHT_DELAY = 1500;
|
||||
QTimer::singleShot(SLIGHT_DELAY, this, SLOT(moveWindowAfterLeaveMode()));
|
||||
}
|
||||
_wasMoved = false;
|
||||
_inHDMMode = false;
|
||||
}
|
||||
_wasMoved = false;
|
||||
}
|
||||
|
||||
void HMDToolsDialog::moveWindowAfterLeaveMode() {
|
||||
|
@ -256,3 +279,31 @@ void HMDToolsDialog::hideEvent(QHideEvent* event) {
|
|||
}
|
||||
|
||||
|
||||
void HMDToolsDialog::aboutToQuit() {
|
||||
if (_inHDMMode) {
|
||||
leaveHDMMode();
|
||||
}
|
||||
}
|
||||
|
||||
void HMDToolsDialog::screenCountChanged(int newCount) {
|
||||
if (!OculusManager::isConnected()) {
|
||||
OculusManager::connect();
|
||||
}
|
||||
int hmdScreenNumber = OculusManager::getHMDScreen();
|
||||
|
||||
if (_inHDMMode && _hmdScreenNumber != hmdScreenNumber) {
|
||||
qDebug() << "HMD Display changed WHILE IN HMD MODE";
|
||||
leaveHDMMode();
|
||||
|
||||
// if there is a new best HDM screen then go back into HDM mode after done leaving
|
||||
if (hmdScreenNumber >= 0) {
|
||||
qDebug() << "Trying to go back into HDM Mode";
|
||||
const int SLIGHT_DELAY = 2000;
|
||||
QTimer::singleShot(SLIGHT_DELAY, this, SLOT(enterHDMMode()));
|
||||
}
|
||||
}
|
||||
_debugDetails->setText(getDebugDetails());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -28,14 +28,15 @@ signals:
|
|||
|
||||
public slots:
|
||||
void reject();
|
||||
void enterModeClicked(bool checked);
|
||||
void leaveModeClicked(bool checked);
|
||||
void switchModeClicked(bool checked);
|
||||
void activateWindowAfterEnterMode();
|
||||
void moveWindowAfterLeaveMode();
|
||||
void applicationWindowScreenChanged(QScreen* screen);
|
||||
void dialogWindowScreenChanged(QScreen* screen);
|
||||
void dialogWindowGeometryChanged(int arg);
|
||||
|
||||
void aboutToQuit();
|
||||
void screenCountChanged(int newCount);
|
||||
|
||||
protected:
|
||||
virtual void closeEvent(QCloseEvent*); // Emits a 'closed' signal when this dialog is closed.
|
||||
virtual void showEvent(QShowEvent* event);
|
||||
|
@ -43,15 +44,20 @@ protected:
|
|||
|
||||
private:
|
||||
void centerCursorOnWidget(QWidget* widget);
|
||||
void enterHDMMode();
|
||||
void leaveHDMMode();
|
||||
|
||||
bool _wasMoved;
|
||||
QRect _previousRect;
|
||||
QScreen* _previousScreen;
|
||||
QScreen* _hmdScreen;
|
||||
int _hmdScreenNumber;
|
||||
QPushButton* _switchModeButton;
|
||||
QLabel* _debugDetails;
|
||||
|
||||
QRect _previousDialogRect;
|
||||
QScreen* _previousDialogScreen;
|
||||
bool _inHDMMode;
|
||||
};
|
||||
|
||||
#endif // hifi_HMDToolsDialog_h
|
||||
|
|
|
@ -20,7 +20,8 @@ AnimationLoop::AnimationLoop() :
|
|||
_firstFrame(0.0f),
|
||||
_lastFrame(FLT_MAX),
|
||||
_running(false),
|
||||
_frameIndex(0.0f)
|
||||
_frameIndex(0.0f),
|
||||
_maxFrameIndexHint(FLT_MAX)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -55,7 +56,7 @@ void AnimationLoop::simulate(float deltaTime) {
|
|||
|
||||
// If we knew the number of frames from the animation, we'd consider using it here
|
||||
// animationGeometry.animationFrames.size()
|
||||
float maxFrame = _lastFrame;
|
||||
float maxFrame = _maxFrameIndexHint;
|
||||
float endFrameIndex = qMin(_lastFrame, maxFrame - (_loop ? 0.0f : 1.0f));
|
||||
float startFrameIndex = qMin(_firstFrame, endFrameIndex);
|
||||
if ((!_loop && (_frameIndex < startFrameIndex || _frameIndex > endFrameIndex)) || startFrameIndex == endFrameIndex) {
|
||||
|
|
|
@ -44,6 +44,9 @@ public:
|
|||
|
||||
void setFrameIndex(float frameIndex) { _frameIndex = glm::clamp(frameIndex, _firstFrame, _lastFrame); }
|
||||
float getFrameIndex() const { return _frameIndex; }
|
||||
|
||||
void setMaxFrameIndexHint(float value) { _maxFrameIndexHint = value; }
|
||||
float getMaxFrameIndexHint() const { return _maxFrameIndexHint; }
|
||||
|
||||
void start() { setRunning(true); }
|
||||
void stop() { setRunning(false); }
|
||||
|
@ -58,6 +61,7 @@ private:
|
|||
float _lastFrame;
|
||||
bool _running;
|
||||
float _frameIndex;
|
||||
float _maxFrameIndexHint;
|
||||
};
|
||||
|
||||
#endif // hifi_AnimationLoop_h
|
||||
|
|
|
@ -344,7 +344,9 @@ QVector<glm::quat> ModelEntityItem::getAnimationFrame() {
|
|||
Animation* myAnimation = getAnimation(_animationURL);
|
||||
QVector<FBXAnimationFrame> frames = myAnimation->getFrames();
|
||||
int frameCount = frames.size();
|
||||
|
||||
if (_animationLoop.getMaxFrameIndexHint() != frameCount) {
|
||||
_animationLoop.setMaxFrameIndexHint(frameCount);
|
||||
}
|
||||
if (frameCount > 0) {
|
||||
int animationFrameIndex = (int)(glm::floor(getAnimationFrameIndex())) % frameCount;
|
||||
if (animationFrameIndex < 0 || animationFrameIndex > frameCount) {
|
||||
|
|
|
@ -1194,7 +1194,7 @@ int matchTextureUVSetToAttributeChannel(const std::string& texUVSetName, const Q
|
|||
}
|
||||
}
|
||||
|
||||
FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) {
|
||||
FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping, bool loadLightmaps, float lightmapLevel) {
|
||||
QHash<QString, ExtractedMesh> meshes;
|
||||
QHash<QString, QString> modelIDsToNames;
|
||||
QHash<QString, int> meshIDsToMeshIndices;
|
||||
|
@ -1216,6 +1216,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
|||
QHash<QString, QString> bumpTextures;
|
||||
QHash<QString, QString> specularTextures;
|
||||
QHash<QString, QString> emissiveTextures;
|
||||
QHash<QString, QString> ambientTextures;
|
||||
QHash<QString, QString> localRotations;
|
||||
QHash<QString, QString> xComponents;
|
||||
QHash<QString, QString> yComponents;
|
||||
|
@ -1597,9 +1598,28 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
|||
} else if (property.properties.at(0) == "Opacity") {
|
||||
material.opacity = property.properties.at(index).value<double>();
|
||||
}
|
||||
#if defined(DEBUG_FBXREADER)
|
||||
else {
|
||||
const std::string propname = property.properties.at(0).toString().toStdString();
|
||||
if (propname == "EmissiveFactor") {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#if defined(DEBUG_FBXREADER)
|
||||
else {
|
||||
std::string propname = subobject.name.data();
|
||||
int unknown = 0;
|
||||
if ( (propname == "Version")
|
||||
||(propname == "ShadingModel")
|
||||
||(propname == "Multilayer")) {
|
||||
} else {
|
||||
unknown++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
material.id = getID(object.properties);
|
||||
materials.insert(material.id, material);
|
||||
|
@ -1684,10 +1704,13 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
|||
} else if (type.contains("shininess")) {
|
||||
counter++;
|
||||
|
||||
} else if (type.contains("emissive")) {
|
||||
} else if (loadLightmaps && type.contains("emissive")) {
|
||||
emissiveTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
|
||||
} else if (loadLightmaps && type.contains("ambient")) {
|
||||
ambientTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
|
||||
} else {
|
||||
std::string typenam = type.data();
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
@ -1930,19 +1953,21 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
|||
}
|
||||
|
||||
FBXTexture emissiveTexture;
|
||||
glm::vec2 emissiveParams(0.f, 1.f);
|
||||
emissiveParams.y = lightmapLevel;
|
||||
QString emissiveTextureID = emissiveTextures.value(childID);
|
||||
if (!emissiveTextureID.isNull()) {
|
||||
emissiveTexture = getTexture(emissiveTextureID, textureNames, textureFilenames, textureContent, textureParams);
|
||||
|
||||
// FBX files generated by 3DSMax have an intermediate texture parent, apparently
|
||||
foreach (const QString& childTextureID, childMap.values(diffuseTextureID)) {
|
||||
if (textureFilenames.contains(childTextureID)) {
|
||||
emissiveTexture = getTexture(emissiveTextureID, textureNames, textureFilenames, textureContent, textureParams);
|
||||
}
|
||||
QString ambientTextureID = ambientTextures.value(childID);
|
||||
if (!emissiveTextureID.isNull() || !ambientTextureID.isNull()) {
|
||||
|
||||
if (!emissiveTextureID.isNull()) {
|
||||
emissiveTexture = getTexture(emissiveTextureID, textureNames, textureFilenames, textureContent, textureParams);
|
||||
emissiveParams.y = 4.0f;
|
||||
} else if (!ambientTextureID.isNull()) {
|
||||
emissiveTexture = getTexture(ambientTextureID, textureNames, textureFilenames, textureContent, textureParams);
|
||||
}
|
||||
|
||||
emissiveTexture.texcoordSet = matchTextureUVSetToAttributeChannel(emissiveTexture.texcoordSetName, extracted.texcoordSetMap);
|
||||
|
||||
|
||||
detectDifferentUVs |= (emissiveTexture.texcoordSet != 0) || (!emissiveTexture.transform.isIdentity());
|
||||
}
|
||||
|
||||
|
@ -1970,6 +1995,8 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
|||
if (!emissiveTexture.filename.isNull()) {
|
||||
part.emissiveTexture = emissiveTexture;
|
||||
}
|
||||
part.emissiveParams = emissiveParams;
|
||||
|
||||
part.materialID = material.id;
|
||||
}
|
||||
}
|
||||
|
@ -2346,10 +2373,10 @@ QByteArray writeMapping(const QVariantHash& mapping) {
|
|||
return buffer.data();
|
||||
}
|
||||
|
||||
FBXGeometry readFBX(const QByteArray& model, const QVariantHash& mapping) {
|
||||
FBXGeometry readFBX(const QByteArray& model, const QVariantHash& mapping, bool loadLightmaps, float lightmapLevel) {
|
||||
QBuffer buffer(const_cast<QByteArray*>(&model));
|
||||
buffer.open(QIODevice::ReadOnly);
|
||||
return extractFBXGeometry(parseFBX(&buffer), mapping);
|
||||
return extractFBXGeometry(parseFBX(&buffer), mapping, loadLightmaps, lightmapLevel);
|
||||
}
|
||||
|
||||
bool addMeshVoxelsOperation(OctreeElement* element, void* extraData) {
|
||||
|
|
|
@ -119,6 +119,7 @@ public:
|
|||
glm::vec3 diffuseColor;
|
||||
glm::vec3 specularColor;
|
||||
glm::vec3 emissiveColor;
|
||||
glm::vec2 emissiveParams;
|
||||
float shininess;
|
||||
float opacity;
|
||||
|
||||
|
@ -252,7 +253,7 @@ QByteArray writeMapping(const QVariantHash& mapping);
|
|||
|
||||
/// Reads FBX geometry from the supplied model and mapping data.
|
||||
/// \exception QString if an error occurs in parsing
|
||||
FBXGeometry readFBX(const QByteArray& model, const QVariantHash& mapping);
|
||||
FBXGeometry readFBX(const QByteArray& model, const QVariantHash& mapping, bool loadLightmaps = true, float lightmapLevel = 1.0f);
|
||||
|
||||
/// Reads SVO geometry from the supplied model data.
|
||||
FBXGeometry readSVO(const QByteArray& model);
|
||||
|
|
|
@ -44,6 +44,8 @@ const char DEFAULT_ASSIGNMENT_SERVER_HOSTNAME[] = "localhost";
|
|||
const char STUN_SERVER_HOSTNAME[] = "stun.highfidelity.io";
|
||||
const unsigned short STUN_SERVER_PORT = 3478;
|
||||
|
||||
const QString DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY = "domain-server.local-port";
|
||||
|
||||
class HifiSockAddr;
|
||||
|
||||
typedef QSet<NodeType_t> NodeSet;
|
||||
|
|
Loading…
Reference in a new issue