Merge branch 'master' of https://github.com/highfidelity/hifi into objReader-tweak

This commit is contained in:
Howard Stearns 2015-05-08 13:04:24 -07:00
commit ebea754997
31 changed files with 324 additions and 168 deletions

View file

@ -52,7 +52,7 @@ var button = Overlays.addOverlay('image', {
width: BUTTON_DIMENSIONS.width,
height: BUTTON_DIMENSIONS.height,
imageURL: HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/planky_button.svg',
alpha: 1
alpha: 0.8
});
@ -93,7 +93,7 @@ function resetBlocks() {
type: 'Model',
modelURL: HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/block.fbx',
shapeType: 'box',
name: 'JengaBlock' + ((layerIndex * BLOCKS_PER_LAYER) + blockIndex),
name: 'PlankyBlock' + ((layerIndex * BLOCKS_PER_LAYER) + blockIndex),
dimensions: BLOCK_SIZE,
position: {
x: basePosition.x + localTransform.x,
@ -133,7 +133,10 @@ function cleanup() {
}
function onUpdate() {
if (windowWidth != Window.innerWidth) {
windowWidth = Window.innerWidth;
Overlays.editOverlay(button, {x: getButtonPosX()});
}
}
Script.update.connect(onUpdate)

View file

@ -179,7 +179,7 @@ function update(deltaTime) {
if (distanceToTarget > CLOSE_ENOUGH) {
// compute current velocity in the direction we want to move
velocityTowardTarget = Vec3.dot(currentVelocity, Vec3.normalize(dPosition));
velocityTowardTarget = Vec3.multiply(dPosition, velocityTowardTarget);
velocityTowardTarget = Vec3.multiply(Vec3.normalize(dPosition), velocityTowardTarget);
// compute the speed we would like to be going toward the target position
desiredVelocity = Vec3.multiply(dPosition, (1.0 / deltaTime) * SPRING_RATE);

View file

@ -16,8 +16,7 @@
var ball, disc;
var time = 0.0;
var range = 1.0;
var speed = 0.5;
var omega = 2.0 * Math.PI / 32.0;
var basePosition = Vec3.sum(Camera.getPosition(), Quat.getFront(Camera.getOrientation()));
@ -25,35 +24,44 @@ ball = Entities.addEntity(
{ type: "Box",
position: basePosition,
dimensions: { x: 0.1, y: 0.1, z: 0.1 },
color: { red: 255, green: 0, blue: 255 }
color: { red: 255, green: 0, blue: 255 },
collisionsWillMove: false,
ignoreForCollisions: true
});
disc = Entities.addEntity(
{ type: "Sphere",
position: basePosition,
dimensions: { x: range, y: range / 20.0, z: range },
dimensions: { x: range * 0.8, y: range / 20.0, z: range * 0.8},
color: { red: 128, green: 128, blue: 128 }
});
function randomColor() {
return { red: Math.random() * 255, green: Math.random() * 255, blue: Math.random() * 255 };
}
function update(deltaTime) {
time += deltaTime * speed;
time += deltaTime;
if (!ball.isKnownID) {
ball = Entities.identifyEntity(ball);
}
rotation = Quat.angleAxis(time/Math.PI * 180.0, { x: 0, y: 1, z: 0 });
rotation = Quat.angleAxis(time * omega /Math.PI * 180.0, { x: 0, y: 1, z: 0 });
Entities.editEntity(ball,
{
color: { red: 255 * (Math.sin(time)/2.0 + 0.5),
green: 255 - 255 * (Math.sin(time)/2.0 + 0.5),
color: { red: 255 * (Math.sin(time * omega)/2.0 + 0.5),
green: 255 - 255 * (Math.sin(time * omega)/2.0 + 0.5),
blue: 0 },
position: { x: basePosition.x + Math.sin(time) / 2.0 * range,
position: { x: basePosition.x + Math.sin(time * omega) / 2.0 * range,
y: basePosition.y,
z: basePosition.z + Math.cos(time) / 2.0 * range },
velocity: { x: Math.cos(time)/2.0 * range,
z: basePosition.z + Math.cos(time * omega) / 2.0 * range },
velocity: { x: Math.cos(time * omega)/2.0 * range * omega,
y: 0.0,
z: -Math.sin(time)/2.0 * range },
z: -Math.sin(time * omega)/2.0 * range * omega},
rotation: rotation
});
if (Math.random() < 0.007) {
Entities.editEntity(disc, { color: randomColor() });
}
}
function scriptEnding() {

View file

@ -203,7 +203,7 @@ SelectionManager = (function() {
try {
listeners[i]();
} catch (e) {
print("got exception");
print("EntitySelectionTool got exception: " = JSON.stringify(e));
}
}
};

View file

@ -692,6 +692,9 @@ Application::~Application() {
nodeThread->quit();
nodeThread->wait();
Leapmotion::destroy();
RealSense::destroy();
qInstallMessageHandler(NULL); // NOTE: Do this as late as possible so we continue to get our log messages
}
@ -2644,7 +2647,10 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
if (rootCode) {
VoxelPositionSize rootDetails;
voxelDetailsForCode(rootCode, rootDetails);
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
AACube serverBounds(glm::vec3(rootDetails.x * TREE_SCALE,
rootDetails.y * TREE_SCALE,
rootDetails.z * TREE_SCALE),
rootDetails.s * TREE_SCALE);
ViewFrustum::location serverFrustumLocation = _viewFrustum.cubeInFrustum(serverBounds);
@ -2685,7 +2691,6 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
// only send to the NodeTypes that are serverType
if (node->getActiveSocket() && node->getType() == serverType) {
// get the server bounds for this server
QUuid nodeUUID = node->getUUID();
@ -2707,7 +2712,12 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
if (rootCode) {
VoxelPositionSize rootDetails;
voxelDetailsForCode(rootCode, rootDetails);
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
AACube serverBounds(glm::vec3(rootDetails.x * TREE_SCALE,
rootDetails.y * TREE_SCALE,
rootDetails.z * TREE_SCALE),
rootDetails.s * TREE_SCALE);
ViewFrustum::location serverFrustumLocation = _viewFrustum.cubeInFrustum(serverBounds);
if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
@ -2753,7 +2763,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
}
// set up the packet for sending...
unsigned char* endOfQueryPacket = queryPacket;
// insert packet type/version and node UUID
endOfQueryPacket += populatePacketHeader(reinterpret_cast<char*>(endOfQueryPacket), packetType);

View file

@ -396,7 +396,7 @@ Menu::Menu() {
#if defined(HAVE_FACESHIFT) || defined(HAVE_DDE)
faceTrackingMenu->addSeparator();
addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::MuteFaceTracking,
0, false,
Qt::CTRL | Qt::SHIFT | Qt::Key_F, false,
qApp, SLOT(toggleFaceTrackerMute()));
#endif

View file

@ -66,6 +66,14 @@ DeviceTracker::ID DeviceTracker::registerDevice(const Name& name, DeviceTracker*
return deviceID;
}
void DeviceTracker::destroyDevice(const Name& name) {
DeviceTracker::ID deviceID = getDeviceID(name);
if (deviceID != INVALID_DEVICE) {
delete Singleton::get()->_devicesVector[getDeviceID(name)];
Singleton::get()->_devicesVector[getDeviceID(name)] = nullptr;
}
}
void DeviceTracker::updateAll() {
//TODO C++11 for (auto deviceIt = Singleton::get()->_devicesVector.begin(); deviceIt != Singleton::get()->_devicesVector.end(); deviceIt++) {
for (Vector::iterator deviceIt = Singleton::get()->_devicesVector.begin(); deviceIt != Singleton::get()->_devicesVector.end(); deviceIt++) {

View file

@ -79,6 +79,8 @@ public:
/// INVALID_DEVICE_NAME if the name is already taken
static ID registerDevice(const Name& name, DeviceTracker* tracker);
static void destroyDevice(const Name& name);
// DeviceTracker interface
virtual void update();

View file

@ -50,6 +50,11 @@ void Leapmotion::init() {
}
}
// static
void Leapmotion::destroy() {
DeviceTracker::destroyDevice(NAME);
}
// static
Leapmotion* Leapmotion::getInstance() {
DeviceTracker* device = DeviceTracker::getDevice(NAME);

View file

@ -26,6 +26,7 @@ public:
static const Name NAME;
static void init();
static void destroy();
/// Leapmotion MotionTracker factory
static Leapmotion* getInstance();

View file

@ -54,6 +54,11 @@ void RealSense::init() {
}
}
// static
void RealSense::destroy() {
DeviceTracker::destroyDevice(NAME);
}
// static
RealSense* RealSense::getInstance() {
DeviceTracker* device = DeviceTracker::getDevice(NAME);

View file

@ -32,6 +32,7 @@ public:
static const Name NAME;
static void init();
static void destroy();
/// RealSense MotionTracker factory
static RealSense* getInstance();

View file

@ -25,6 +25,7 @@
#include <PerfStat.h>
#include <SceneScriptingInterface.h>
#include <ScriptEngine.h>
#include <TextureCache.h>
#include "EntityTreeRenderer.h"
@ -455,7 +456,9 @@ void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode,
if (_bestZone->getSkyboxProperties().getURL().isEmpty()) {
stage->getSkybox()->clearCubemap();
} else {
stage->getSkybox()->clearCubemap(); // NOTE: this should be changed to do something to set the cubemap
// Update the Texture of the Skybox with the one pointed by this zone
auto cubeMap = DependencyManager::get<TextureCache>()->getTexture(_bestZone->getSkyboxProperties().getURL(), CUBE_TEXTURE);
stage->getSkybox()->setCubemap(cubeMap->getGPUTexture());
}
stage->setBackgroundMode(model::SunSkyStage::SKY_BOX);
}

View file

@ -16,12 +16,19 @@
#include "EntityItemPropertiesMacros.h"
AtmospherePropertyGroup::AtmospherePropertyGroup() {
_center = glm::vec3(0.0f);
_innerRadius = 0.0f;
_outerRadius = 0.0f;
_mieScattering = 0.0f;
_rayleighScattering = 0.0f;
_scatteringWavelengths = glm::vec3(0.0f);
const glm::vec3 DEFAULT_CENTER = glm::vec3(0.0f, -1000.0f, 0.0f);
const float DEFAULT_INNER_RADIUS = 1000.0f;
const float DEFAULT_OUTER_RADIUS = 1025.0f;
const float DEFAULT_RAYLEIGH_SCATTERING = 0.0025f;
const float DEFAULT_MIE_SCATTERING = 0.0010f;
const glm::vec3 DEFAULT_SCATTERING_WAVELENGTHS = glm::vec3(0.650f, 0.570f, 0.475f);
_center = DEFAULT_CENTER;
_innerRadius = DEFAULT_INNER_RADIUS;
_outerRadius = DEFAULT_OUTER_RADIUS;
_mieScattering = DEFAULT_MIE_SCATTERING;
_rayleighScattering = DEFAULT_RAYLEIGH_SCATTERING;
_scatteringWavelengths = DEFAULT_SCATTERING_WAVELENGTHS;
_hasStars = true;
}

View file

@ -479,6 +479,7 @@ void GLBackend::getCurrentGLState(State::Data& state) {
void GLBackend::syncPipelineStateCache() {
State::Data state;
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
getCurrentGLState(state);
State::Signature signature = State::evalSignature(state);

View file

@ -373,7 +373,6 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) {
GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z };
if (needUpdate) {
if (texture.isStoredMipAvailable(0)) {
Texture::PixelsPointer mip = texture.accessStoredMip(0);

View file

@ -68,11 +68,11 @@ public:
uint8 _maxMip = MAX_MIP_LEVEL;
Desc() {}
Desc(const Filter filter) : _filter(filter) {}
Desc(const Filter filter, const WrapMode wrap = WRAP_REPEAT) : _filter(filter), _wrapModeU(wrap), _wrapModeV(wrap), _wrapModeW(wrap) {}
};
Sampler() {}
Sampler(const Filter filter) : _desc(filter) {}
Sampler(const Filter filter, const WrapMode wrap = WRAP_REPEAT) : _desc(filter, wrap) {}
Sampler(const Desc& desc) : _desc(desc) {}
~Sampler() {}

View file

@ -92,15 +92,3 @@ void Material::setTextureView(MapChannel channel, const gpu::TextureView& view)
_textureMap[channel] = view;
}
// TextureStorage
TextureStorage::TextureStorage(const QUrl& url) : gpu::Texture::Storage(), _url(url) {
init();
}
TextureStorage::~TextureStorage() {
}
void TextureStorage::init() {
_gpuTexture = TexturePointer(Texture::createFromStorage(this));
}

View file

@ -23,27 +23,6 @@
namespace model {
typedef glm::vec3 Color;
// TextureStorage is a specialized version of the gpu::Texture::Storage
// It adds the URL and the notion that it owns the gpu::Texture
class TextureStorage : public gpu::Texture::Storage {
public:
TextureStorage(const QUrl& url);
~TextureStorage();
const QUrl& getUrl() const { return _url; }
const gpu::TexturePointer& getGPUTexture() const { return _gpuTexture; }
protected:
gpu::TexturePointer _gpuTexture;
QUrl _url;
void init();
};
typedef std::shared_ptr< TextureStorage > TextureStoragePointer;
class Material {
public:
typedef gpu::BufferView UniformBufferView;
@ -62,6 +41,7 @@ public:
NUM_MAPS,
};
typedef std::map<MapChannel, TextureView> TextureMap;
typedef std::bitset<NUM_MAPS> MapFlags;
enum FlagBit {
DIFFUSE_BIT = 0,

View file

@ -21,6 +21,7 @@ using namespace model;
Skybox::Skybox() {
/* // PLease create a default engineer skybox
_cubemap.reset( gpu::Texture::createCube(gpu::Element::COLOR_RGBA_32, 1));
unsigned char texels[] = {
255, 0, 0, 255,
@ -30,7 +31,7 @@ Skybox::Skybox() {
0, 255, 0, 255,
255, 0, 255, 255,
};
_cubemap->assignStoredMip(0, gpu::Element::COLOR_RGBA_32, sizeof(texels), texels);
_cubemap->assignStoredMip(0, gpu::Element::COLOR_RGBA_32, sizeof(texels), texels);*/
}
void Skybox::setColor(const Color& color) {
@ -47,7 +48,7 @@ void Skybox::clearCubemap() {
void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) {
if (skybox.getCubemap()) {
if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) {
static gpu::PipelinePointer thePipeline;
static gpu::BufferPointer theBuffer;
static gpu::Stream::FormatPointer theFormat;

View file

@ -18,7 +18,8 @@ varying vec3 color;
void main(void) {
vec4 texel = textureCube(cubeMap, normalize(normal));
gl_FragData[0] = texel;
// gl_FragData[0] = vec4(normal, 1.0);
vec3 coord = normalize(normal);
vec4 texel = textureCube(cubeMap, coord);
// gl_FragData[0] = vec4(texel.xyz * color, texel.w);
gl_FragData[0] = vec4(texel.xyz, 1.0);
}

View file

@ -190,7 +190,8 @@ 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(new Light()),
_skybox(new Skybox())
{
_sunLight->setType(Light::SUN);
@ -290,6 +291,19 @@ void SunSkyStage::updateGraphicsObject() const {
_sunLight->setPosition(Vec3(0.0f, originAlt, 0.0f));
}
// Background
switch (getBackgroundMode()) {
case NO_BACKGROUND: {
break;
}
case SKY_DOME: {
break;
}
case SKY_BOX: {
break;
}
};
static int firstTime = 0;
if (firstTime == 0) {
firstTime++;

View file

@ -223,11 +223,11 @@ public:
const SkyboxPointer& getSkybox() const { valid(); return _skybox; }
protected:
BackgroundMode _backgroundMode = SKY_DOME;
BackgroundMode _backgroundMode = SKY_BOX;
LightPointer _sunLight;
AtmospherePointer _atmosphere;
SkyboxPointer _skybox;
mutable SkyboxPointer _skybox;
gpu::PipelinePointer _skyPipeline;

View file

@ -0,0 +1,28 @@
//
// TextureStorage.cpp
// libraries/model/src/model
//
// Created by Sam Gateau on 5/6/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 "TextureStorage.h"
using namespace model;
using namespace gpu;
// TextureStorage
TextureStorage::TextureStorage() : Texture::Storage(),
_gpuTexture(Texture::createFromStorage(this))
{}
TextureStorage::~TextureStorage() {
}
void TextureStorage::reset(const QUrl& url, const TextureUsage& usage) {
_url = url;
_usage = usage;
}

View file

@ -0,0 +1,56 @@
//
// TextureStorage.h
// libraries/model/src/model
//
// Created by Sam Gateau on 5/6/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_TextureStorage_h
#define hifi_model_TextureStorage_h
#include "gpu/Texture.h"
#include "Material.h"
#include <qurl.h>
namespace model {
typedef glm::vec3 Color;
class TextureUsage {
public:
gpu::Texture::Type _type{ gpu::Texture::TEX_2D };
Material::MapFlags _materialUsage{ Material::DIFFUSE_MAP };
int _environmentUsage = 0;
};
// TextureStorage is a specialized version of the gpu::Texture::Storage
// It provides the mechanism to create a texture from a Url and the intended usage
// that guides the internal format used
class TextureStorage : public gpu::Texture::Storage {
public:
TextureStorage();
~TextureStorage();
const QUrl& getUrl() const { return _url; }
const gpu::Texture::Type getType() const { return _usage._type; }
const gpu::TexturePointer& getGPUTexture() const { return _gpuTexture; }
void reset(const QUrl& url, const TextureUsage& usage);
protected:
gpu::TexturePointer _gpuTexture;
TextureUsage _usage;
QUrl _url;
};
typedef std::shared_ptr< TextureStorage > TextureStoragePointer;
};
#endif // hifi_model_TextureStorage_h

View file

@ -16,7 +16,7 @@
#include "OctreeConstants.h"
#include "OctreeQuery.h"
Setting::Handle<int> maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTREE_PPS);
Setting::Handle<int> maxOctreePacketsPerSecond("maxOctreePPSSpin", DEFAULT_MAX_OCTREE_PPS);
OctreeQuery::OctreeQuery() {
_maxOctreePPS = maxOctreePacketsPerSecond.get();

View file

@ -151,10 +151,10 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) {
_movingStepsWithoutSimulationOwner = 0;
}
int ownershipClaimDelay = 50; // TODO -- how to pick this? based on meters from our characterController?
uint32_t ownershipClaimDelay = 50; // TODO -- how to pick this? based on meters from our characterController?
if (_movingStepsWithoutSimulationOwner > ownershipClaimDelay) {
qDebug() << "Warning -- claiming something I saw moving." << getName();
//qDebug() << "Warning -- claiming something I saw moving." << getName();
setShouldClaimSimulationOwnership(true);
}
@ -178,7 +178,7 @@ void EntityMotionState::computeObjectShapeInfo(ShapeInfo& shapeInfo) {
const int MAX_NUM_NON_MOVING_UPDATES = 5;
bool EntityMotionState::doesNotNeedToSendUpdate() const {
return !_body->isActive() && _numNonMovingUpdates > MAX_NUM_NON_MOVING_UPDATES;
return !_body || (_body->isActive() && _numNonMovingUpdates > MAX_NUM_NON_MOVING_UPDATES);
}
bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
@ -232,6 +232,7 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
_serverPosition += dt * _serverVelocity;
}
// TODO: compensate for simulation offset here
btTransform worldTrans = _body->getWorldTransform();
glm::vec3 position = bulletToGLM(worldTrans.getOrigin());
@ -310,86 +311,60 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
return; // never update entities that are unknown
}
bool active = _body->isActive();
if (!active) {
if (_sentMoving) {
// make sure all derivatives are zero
glm::vec3 zero(0.0f);
_entity->setVelocity(zero);
_entity->setAngularVelocity(zero);
_entity->setAcceleration(zero);
}
} else {
float gravityLength = glm::length(_entity->getGravity());
float accVsGravity = glm::abs(glm::length(_measuredAcceleration) - gravityLength);
if (accVsGravity < ACCELERATION_EQUIVALENT_EPSILON_RATIO * gravityLength) {
// acceleration measured during the most recent simulation step was close to gravity.
if (getAccelerationNearlyGravityCount() < STEPS_TO_DECIDE_BALLISTIC) {
// only increment this if we haven't reached the threshold yet. this is to avoid
// overflowing the counter.
incrementAccelerationNearlyGravityCount();
}
} else {
// acceleration wasn't similar to this entities gravity, so reset the went-ballistic counter
resetAccelerationNearlyGravityCount();
}
// if this entity has been accelerated at close to gravity for a certain number of simulation-steps, let
// the entity server's estimates include gravity.
if (getAccelerationNearlyGravityCount() >= STEPS_TO_DECIDE_BALLISTIC) {
_entity->setAcceleration(_entity->getGravity());
} else {
_entity->setAcceleration(glm::vec3(0.0f));
}
}
// remember properties for local server prediction
_serverPosition = _entity->getPosition();
_serverRotation = _entity->getRotation();
_serverVelocity = _entity->getVelocity();
_serverAcceleration = _entity->getAcceleration();
_serverAngularVelocity = _entity->getAngularVelocity();
_sentMoving = _serverVelocity != glm::vec3(0.0f) || _serverAngularVelocity != glm::vec3(0.0f);
EntityItemProperties properties = _entity->getProperties();
float gravityLength = glm::length(_entity->getGravity());
float accVsGravity = glm::abs(glm::length(_measuredAcceleration) - gravityLength);
if (accVsGravity < ACCELERATION_EQUIVALENT_EPSILON_RATIO * gravityLength) {
// acceleration measured during the most recent simulation step was close to gravity.
if (getAccelerationNearlyGravityCount() < STEPS_TO_DECIDE_BALLISTIC) {
// only increment this if we haven't reached the threshold yet. this is to avoid
// overflowing the counter.
incrementAccelerationNearlyGravityCount();
}
} else {
// acceleration wasn't similar to this entities gravity, so reset the went-ballistic counter
resetAccelerationNearlyGravityCount();
}
// if this entity has been accelerated at close to gravity for a certain number of simulation-steps, let
// the entity server's estimates include gravity.
if (getAccelerationNearlyGravityCount() >= STEPS_TO_DECIDE_BALLISTIC) {
_entity->setAcceleration(_entity->getGravity());
} else {
_entity->setAcceleration(glm::vec3(0.0f));
}
btTransform worldTrans = _body->getWorldTransform();
_serverPosition = bulletToGLM(worldTrans.getOrigin());
properties.setPosition(_serverPosition + ObjectMotionState::getWorldOffset());
_serverRotation = bulletToGLM(worldTrans.getRotation());
// explicitly set the properties that changed
properties.setPosition(_serverPosition);
properties.setRotation(_serverRotation);
bool zeroSpeed = true;
bool zeroSpin = true;
if (_body->isActive()) {
_serverVelocity = bulletToGLM(_body->getLinearVelocity());
_serverAngularVelocity = bulletToGLM(_body->getAngularVelocity());
// if the speeds are very small we zero them out
const float MINIMUM_EXTRAPOLATION_SPEED_SQUARED = 1.0e-4f; // 1cm/sec
zeroSpeed = (glm::length2(_serverVelocity) < MINIMUM_EXTRAPOLATION_SPEED_SQUARED);
if (zeroSpeed) {
_serverVelocity = glm::vec3(0.0f);
}
const float MINIMUM_EXTRAPOLATION_SPIN_SQUARED = 0.004f; // ~0.01 rotation/sec
zeroSpin = glm::length2(_serverAngularVelocity) < MINIMUM_EXTRAPOLATION_SPIN_SQUARED;
if (zeroSpin) {
_serverAngularVelocity = glm::vec3(0.0f);
}
_sentMoving = ! (zeroSpeed && zeroSpin);
} else {
_serverVelocity = _serverAngularVelocity = glm::vec3(0.0f);
_sentMoving = false;
}
properties.setVelocity(_serverVelocity);
_serverGravity = _entity->getGravity();
properties.setGravity(_entity->getGravity());
_serverAcceleration = _entity->getAcceleration();
properties.setAcceleration(_serverAcceleration);
properties.setAngularVelocity(_serverAngularVelocity);
auto nodeList = DependencyManager::get<NodeList>();
QUuid myNodeID = nodeList->getSessionUUID();
QUuid simulatorID = _entity->getSimulatorID();
if (getShouldClaimSimulationOwnership()) {
properties.setSimulatorID(myNodeID);
setShouldClaimSimulationOwnership(false);
} else if (simulatorID == myNodeID && zeroSpeed && zeroSpin) {
// we are the simulator and the entity has stopped. give up "simulator" status
_entity->setSimulatorID(QUuid());
properties.setSimulatorID(QUuid());
} else if (simulatorID == myNodeID && !_body->isActive()) {
// it's not active. don't keep simulation ownership.
_entity->setSimulatorID(QUuid());
properties.setSimulatorID(QUuid());
}
// RELIABLE_SEND_HACK: count number of updates for entities at rest so we can stop sending them after some limit.
// RELIABLE_SEND_HACK: count number of updates for entities at rest
// so we can stop sending them after some limit.
if (_sentMoving) {
_numNonMovingUpdates = 0;
} else {
@ -397,8 +372,6 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
}
if (_numNonMovingUpdates <= 1) {
// we only update lastEdited when we're sending new physics data
// (i.e. NOT when we just simulate the positions forward, nor when we resend non-moving data)
// NOTE: Andrew & Brad to discuss. Let's make sure we're using lastEdited, lastSimulated, and lastUpdated correctly
quint64 lastSimulated = _entity->getLastSimulated();
_entity->setLastEdited(lastSimulated);
properties.setLastEdited(lastSimulated);
@ -415,6 +388,25 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
properties.setLastEdited(_entity->getLastEdited());
}
auto nodeList = DependencyManager::get<NodeList>();
QUuid myNodeID = nodeList->getSessionUUID();
QUuid simulatorID = _entity->getSimulatorID();
if (getShouldClaimSimulationOwnership()) {
// we think we should own it, so we tell the server that we do,
// but we don't remember that we own it...
// instead we expect the sever to tell us later whose ownership it has accepted
properties.setSimulatorID(myNodeID);
setShouldClaimSimulationOwnership(false);
} else if (simulatorID == myNodeID
&& !_sentMoving
&& _numNonMovingUpdates == MAX_NUM_NON_MOVING_UPDATES) {
// we own it, the entity has stopped, and we're sending the last non-moving update
// --> give up ownership
_entity->setSimulatorID(QUuid());
properties.setSimulatorID(QUuid());
}
if (EntityItem::getSendPhysicsUpdates()) {
EntityItemID id(_entity->getID());
EntityEditPacketSender* entityPacketSender = static_cast<EntityEditPacketSender*>(packetSender);

View file

@ -417,17 +417,23 @@ void ImageReader::run() {
return;
}
// enforce a fixed maximum area (1024 * 2048)
const int MAXIMUM_AREA_SIZE = 2097152;
int imageArea = image.width() * image.height();
if (imageArea > MAXIMUM_AREA_SIZE) {
float scaleRatio = sqrtf((float)MAXIMUM_AREA_SIZE) / sqrtf((float)imageArea);
int resizeWidth = static_cast<int>(std::floor(scaleRatio * static_cast<float>(image.width())));
int resizeHeight = static_cast<int>(std::floor(scaleRatio * static_cast<float>(image.height())));
qCDebug(renderutils) << "Image greater than maximum size:" << _url << image.width() << image.height() <<
" scaled to:" << resizeWidth << resizeHeight;
image = image.scaled(resizeWidth, resizeHeight, Qt::IgnoreAspectRatio);
imageArea = image.width() * image.height();
auto ntex = dynamic_cast<NetworkTexture*>(&*texture);
if (ntex && (ntex->getType() == CUBE_TEXTURE)) {
qCDebug(renderutils) << "Cube map size:" << _url << image.width() << image.height();
} else {
// enforce a fixed maximum area (1024 * 2048)
const int MAXIMUM_AREA_SIZE = 2097152;
if (imageArea > MAXIMUM_AREA_SIZE) {
float scaleRatio = sqrtf((float)MAXIMUM_AREA_SIZE) / sqrtf((float)imageArea);
int resizeWidth = static_cast<int>(std::floor(scaleRatio * static_cast<float>(image.width())));
int resizeHeight = static_cast<int>(std::floor(scaleRatio * static_cast<float>(image.height())));
qCDebug(renderutils) << "Image greater than maximum size:" << _url << image.width() << image.height() <<
" scaled to:" << resizeWidth << resizeHeight;
image = image.scaled(resizeWidth, resizeHeight, Qt::IgnoreAspectRatio);
imageArea = image.width() * image.height();
}
}
const int EIGHT_BIT_MAXIMUM = 255;
@ -507,6 +513,7 @@ void NetworkTexture::setImage(const QImage& image, bool translucent, const QColo
imageLoaded(image);
if ((_width > 0) && (_height > 0)) {
bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
@ -515,9 +522,18 @@ void NetworkTexture::setImage(const QImage& image, bool translucent, const QColo
formatGPU = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA));
formatMip = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA));
}
_gpuTexture = gpu::TexturePointer(gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
_gpuTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits());
_gpuTexture->autoGenerateMips(-1);
if (_type == CUBE_TEXTURE) {
if (_height >= (6 * _width)) {
_gpuTexture = gpu::TexturePointer(gpu::Texture::createCube(formatGPU, image.width(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR, gpu::Sampler::WRAP_CLAMP)));
_gpuTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits());
_gpuTexture->autoGenerateMips(-1);
}
} else {
_gpuTexture = gpu::TexturePointer(gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
_gpuTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits());
_gpuTexture->autoGenerateMips(-1);
}
}
}

View file

@ -27,7 +27,7 @@ class NetworkTexture;
typedef QSharedPointer<NetworkTexture> NetworkTexturePointer;
enum TextureType { DEFAULT_TEXTURE, NORMAL_TEXTURE, SPECULAR_TEXTURE, EMISSIVE_TEXTURE, SPLAT_TEXTURE };
enum TextureType { DEFAULT_TEXTURE, NORMAL_TEXTURE, SPECULAR_TEXTURE, EMISSIVE_TEXTURE, SPLAT_TEXTURE, CUBE_TEXTURE };
/// Stores cached textures, including render-to-texture targets.
class TextureCache : public ResourceCache, public Dependency {
@ -164,7 +164,7 @@ public:
int getOriginalHeight() const { return _originalHeight; }
int getWidth() const { return _width; }
int getHeight() const { return _height; }
TextureType getType() const { return _type; }
protected:
virtual void downloadFinished(QNetworkReply* reply);

View file

@ -13,6 +13,9 @@
#include "SceneScriptingInterface.h"
#include "SceneScriptingInterface.h"
void SceneScriptingInterface::setStageOrientation(const glm::quat& orientation) {
_skyStage->setOriginOrientation(orientation);
}
@ -86,6 +89,29 @@ bool SceneScriptingInterface::isStageSunModelEnabled() const {
return _skyStage->isSunModelEnabled();
}
void SceneScriptingInterface::setBackgroundMode(const QString& mode) {
if (mode == QString("inherit")) {
_skyStage->setBackgroundMode(model::SunSkyStage::NO_BACKGROUND);
} else if (mode == QString("atmosphere")) {
_skyStage->setBackgroundMode(model::SunSkyStage::SKY_DOME);
} else if (mode == QString("skybox")) {
_skyStage->setBackgroundMode(model::SunSkyStage::SKY_BOX);
}
}
QString SceneScriptingInterface::getBackgroundMode() const {
switch (_skyStage->getBackgroundMode()) {
case model::SunSkyStage::NO_BACKGROUND:
return QString("inherit");
case model::SunSkyStage::SKY_DOME:
return QString("atmosphere");
case model::SunSkyStage::SKY_BOX:
return QString("skybox");
default:
return QString("inherit");
};
}
model::SunSkyStagePointer SceneScriptingInterface::getSkyStage() const {
return _skyStage;
}

View file

@ -57,7 +57,8 @@ public:
Q_INVOKABLE glm::vec3 getKeyLightDirection() const;
Q_INVOKABLE void setBackgroundMode(const QString& mode);
Q_INVOKABLE QString getBackgroundMode() const;
model::SunSkyStagePointer getSkyStage() const;