mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 11:33:44 +02:00
merging
This commit is contained in:
commit
54c47fe3f9
32 changed files with 927 additions and 231 deletions
60
examples/example/entities/zoneSkyboxExample.js
Normal file
60
examples/example/entities/zoneSkyboxExample.js
Normal file
|
@ -0,0 +1,60 @@
|
|||
//
|
||||
// zoneSkyboxExample.js
|
||||
// examples
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 4/16/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// This is an example script that demonstrates creating a zone using the atmosphere features
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
||||
|
||||
var count = 0;
|
||||
var stopAfter = 600;
|
||||
|
||||
var zoneEntityA = Entities.addEntity({
|
||||
type: "Zone",
|
||||
position: { x: 1000, y: 1000, z: 1000},
|
||||
dimensions: { x: 2000, y: 2000, z: 2000 },
|
||||
keyLightColor: { red: 255, green: 0, blue: 0 },
|
||||
stageSunModelEnabled: false,
|
||||
shapeType: "sphere",
|
||||
backgroundMode: "skybox",
|
||||
atmosphere: {
|
||||
center: { x: 1000, y: 0, z: 1000},
|
||||
innerRadius: 1000.0,
|
||||
outerRadius: 1025.0,
|
||||
rayleighScattering: 0.0025,
|
||||
mieScattering: 0.0010,
|
||||
scatteringWavelengths: { x: 0.650, y: 0.570, z: 0.475 },
|
||||
hasStars: false
|
||||
},
|
||||
skybox: {
|
||||
color: { red: 255, green: 0, blue: 255 },
|
||||
url: ""
|
||||
},
|
||||
stageLatitude: 37.777,
|
||||
stageLongitude: 122.407,
|
||||
stageAltitude: 0.03,
|
||||
stageDay: 60,
|
||||
stageHour: 0,
|
||||
stageSunModelEnabled: true
|
||||
});
|
||||
|
||||
var props = Entities.getEntityProperties(zoneEntityA);
|
||||
print(JSON.stringify(props));
|
||||
|
||||
// register the call back so it fires before each data send
|
||||
Script.update.connect(function(deltaTime) {
|
||||
// stop it...
|
||||
if (count >= stopAfter) {
|
||||
print("calling Script.stop()");
|
||||
Script.stop();
|
||||
}
|
||||
count++;
|
||||
});
|
||||
|
140
examples/example/games/planky.js
Normal file
140
examples/example/games/planky.js
Normal file
|
@ -0,0 +1,140 @@
|
|||
//
|
||||
// planky.js
|
||||
// examples
|
||||
//
|
||||
// Created by Thijs Wenker on 5/2/14.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Pull blocks off the bottom and put them on the top using the grab.js script.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
||||
|
||||
const NUM_LAYERS = 16;
|
||||
const BASE_DIMENSION = { x: 7, y: 2, z: 7 };
|
||||
const BLOCKS_PER_LAYER = 3;
|
||||
const BLOCK_SIZE = {x: 0.2, y: 0.1, z: 0.8};
|
||||
const BLOCK_SPACING = BLOCK_SIZE.x / 3;
|
||||
const GRAVITY = {x: 0, y: -2.8, z: 0};
|
||||
const DENSITY = 2000;
|
||||
const DAMPING_FACTOR = 0.98;
|
||||
const ANGULAR_DAMPING_FACTOR = 0.8;
|
||||
const SPAWN_DISTANCE = 3;
|
||||
const BLOCK_YAW_OFFSET = 45;
|
||||
const BUTTON_DIMENSIONS = {width: 49, height: 49};
|
||||
|
||||
var windowWidth = Window.innerWidth;
|
||||
var size;
|
||||
var pieces = [];
|
||||
var ground = false;
|
||||
var layerRotated = false;
|
||||
|
||||
function grabLowestJointY() {
|
||||
var jointNames = MyAvatar.getJointNames();
|
||||
var floorY = MyAvatar.position.y;
|
||||
for (var jointName in jointNames) {
|
||||
if (MyAvatar.getJointPosition(jointNames[jointName]).y < floorY) {
|
||||
floorY = MyAvatar.getJointPosition(jointNames[jointName]).y;
|
||||
}
|
||||
}
|
||||
return floorY;
|
||||
}
|
||||
|
||||
function getButtonPosX() {
|
||||
return windowWidth - ((BUTTON_DIMENSIONS.width / 2) + BUTTON_DIMENSIONS.width);
|
||||
}
|
||||
|
||||
var button = Overlays.addOverlay('image', {
|
||||
x: getButtonPosX(),
|
||||
y: 10,
|
||||
width: BUTTON_DIMENSIONS.width,
|
||||
height: BUTTON_DIMENSIONS.height,
|
||||
imageURL: HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/planky_button.svg',
|
||||
alpha: 1
|
||||
});
|
||||
|
||||
|
||||
function resetBlocks() {
|
||||
pieces.forEach(function(piece) {
|
||||
Entities.deleteEntity(piece);
|
||||
});
|
||||
pieces = [];
|
||||
var avatarRot = Quat.fromPitchYawRollDegrees(0.0, MyAvatar.bodyYaw, 0.0);
|
||||
basePosition = Vec3.sum(MyAvatar.position, Vec3.multiply(SPAWN_DISTANCE, Quat.getFront(avatarRot)));
|
||||
basePosition.y = grabLowestJointY() - (BASE_DIMENSION.y / 2);
|
||||
if (!ground) {
|
||||
ground = Entities.addEntity({
|
||||
type: 'Model',
|
||||
modelURL: HIFI_PUBLIC_BUCKET + 'eric/models/woodFloor.fbx',
|
||||
dimensions: BASE_DIMENSION,
|
||||
position: basePosition,
|
||||
rotation: avatarRot,
|
||||
shapeType: 'box'
|
||||
});
|
||||
} else {
|
||||
Entities.editEntity(ground, {position: basePosition, rotation: avatarRot});
|
||||
}
|
||||
var offsetRot = Quat.multiply(avatarRot, Quat.fromPitchYawRollDegrees(0.0, BLOCK_YAW_OFFSET, 0.0));
|
||||
basePosition.y += (BASE_DIMENSION.y / 2);
|
||||
for (var layerIndex = 0; layerIndex < NUM_LAYERS; layerIndex++) {
|
||||
var layerRotated = layerIndex % 2 === 0;
|
||||
var offset = -(BLOCK_SPACING);
|
||||
var layerRotation = Quat.fromPitchYawRollDegrees(0, layerRotated ? 0 : 90, 0.0);
|
||||
for (var blockIndex = 0; blockIndex < BLOCKS_PER_LAYER; blockIndex++) {
|
||||
var blockPositionXZ = BLOCK_SIZE.x * blockIndex - (BLOCK_SIZE.x * 3 / 2 - BLOCK_SIZE.x / 2);
|
||||
var localTransform = Vec3.multiplyQbyV(offsetRot, {
|
||||
x: (layerRotated ? blockPositionXZ + offset: 0),
|
||||
y: (BLOCK_SIZE.y / 2) + (BLOCK_SIZE.y * layerIndex),
|
||||
z: (layerRotated ? 0 : blockPositionXZ + offset)
|
||||
});
|
||||
pieces.push(Entities.addEntity({
|
||||
type: 'Model',
|
||||
modelURL: HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/block.fbx',
|
||||
shapeType: 'box',
|
||||
name: 'JengaBlock' + ((layerIndex * BLOCKS_PER_LAYER) + blockIndex),
|
||||
dimensions: BLOCK_SIZE,
|
||||
position: {
|
||||
x: basePosition.x + localTransform.x,
|
||||
y: basePosition.y + localTransform.y,
|
||||
z: basePosition.z + localTransform.z
|
||||
},
|
||||
rotation: Quat.multiply(layerRotation, offsetRot),
|
||||
collisionsWillMove: true,
|
||||
damping: DAMPING_FACTOR,
|
||||
angularDamping: ANGULAR_DAMPING_FACTOR,
|
||||
gravity: GRAVITY,
|
||||
density: DENSITY
|
||||
}));
|
||||
offset += BLOCK_SPACING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function mousePressEvent(event) {
|
||||
var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y});
|
||||
if (clickedOverlay === button) {
|
||||
resetBlocks();
|
||||
}
|
||||
}
|
||||
|
||||
Controller.mousePressEvent.connect(mousePressEvent);
|
||||
|
||||
function cleanup() {
|
||||
Overlays.deleteOverlay(button);
|
||||
if (ground) {
|
||||
Entities.deleteEntity(ground);
|
||||
}
|
||||
pieces.forEach(function(piece) {
|
||||
Entities.deleteEntity(piece);
|
||||
});
|
||||
pieces = [];
|
||||
}
|
||||
|
||||
function onUpdate() {
|
||||
|
||||
}
|
||||
|
||||
Script.update.connect(onUpdate)
|
||||
Script.scriptEnding.connect(cleanup);
|
|
@ -35,6 +35,7 @@ ZoneOverlayManager = function(isEntityFunc, entityAddedFunc, entityRemovedFunc,
|
|||
this.setVisible = function(isVisible) {
|
||||
if (visible != isVisible) {
|
||||
visible = isVisible;
|
||||
Entities.setDrawZoneBoundaries(visible);
|
||||
for (var id in entityOverlays) {
|
||||
Overlays.editOverlay(entityOverlays[id].solid, { visible: visible });
|
||||
Overlays.editOverlay(entityOverlays[id].outline, { visible: visible });
|
||||
|
|
|
@ -3260,6 +3260,11 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
|||
renderMode = RenderArgs::MIRROR_RENDER_MODE;
|
||||
}
|
||||
_entities.render(renderMode, renderSide, renderDebugFlags);
|
||||
|
||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) {
|
||||
// Restaure polygon mode
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
}
|
||||
|
||||
// render JS/scriptable overlays
|
||||
|
|
|
@ -1173,8 +1173,10 @@ void MyAvatar::renderBody(ViewFrustum* renderFrustum, RenderArgs::RenderMode ren
|
|||
Camera *camera = Application::getInstance()->getCamera();
|
||||
const glm::vec3 cameraPos = camera->getPosition();
|
||||
|
||||
|
||||
// HACK: comment this block which possibly change the near and break the rendering 5/6/2015
|
||||
// Only tweak the frustum near far if it's not shadow
|
||||
if (renderMode != RenderArgs::SHADOW_RENDER_MODE) {
|
||||
/* if (renderMode != RenderArgs::SHADOW_RENDER_MODE) {
|
||||
// Set near clip distance according to skeleton model dimensions if first person and there is no separate head model.
|
||||
if (shouldRenderHead(cameraPos, renderMode) || !getHead()->getFaceModel().getURL().isEmpty()) {
|
||||
renderFrustum->setNearClip(DEFAULT_NEAR_CLIP);
|
||||
|
@ -1184,7 +1186,7 @@ void MyAvatar::renderBody(ViewFrustum* renderFrustum, RenderArgs::RenderMode ren
|
|||
+ camera->getOrientation() * glm::vec3(0.0f, 0.0f, -clipDistance) - cameraPos);
|
||||
renderFrustum->setNearClip(clipDistance);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// Render the body's voxels and head
|
||||
RenderArgs::RenderMode modelRenderMode = renderMode;
|
||||
|
|
|
@ -190,8 +190,8 @@ void ApplicationOverlay::renderOverlay() {
|
|||
Overlays& overlays = qApp->getOverlays();
|
||||
|
||||
_textureFov = glm::radians(_hmdUIAngularSize);
|
||||
auto deviceSize = Application::getInstance()->getDeviceSize();
|
||||
_textureAspectRatio = (float)deviceSize.width() / (float)deviceSize.height();
|
||||
glm::vec2 deviceSize = qApp->getCanvasSize();
|
||||
_textureAspectRatio = (float)deviceSize.x / (float)deviceSize.y;
|
||||
|
||||
//Handle fading and deactivation/activation of UI
|
||||
|
||||
|
@ -209,7 +209,7 @@ void ApplicationOverlay::renderOverlay() {
|
|||
const float NEAR_CLIP = -10000;
|
||||
const float FAR_CLIP = 10000;
|
||||
glLoadIdentity();
|
||||
glOrtho(0, deviceSize.width(), deviceSize.height(), 0, NEAR_CLIP, FAR_CLIP);
|
||||
glOrtho(0, deviceSize.x, deviceSize.y, 0, NEAR_CLIP, FAR_CLIP);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
|
@ -270,11 +270,11 @@ void ApplicationOverlay::displayOverlayTexture() {
|
|||
glEnable(GL_BLEND);
|
||||
}
|
||||
|
||||
static const glm::vec2 topLeft(-1, 1);
|
||||
static const glm::vec2 bottomRight(1, -1);
|
||||
static const glm::vec2 texCoordTopLeft(0.0f, 1.0f);
|
||||
static const glm::vec2 texCoordBottomRight(1.0f, 0.0f);
|
||||
with_each_texture(_overlays.getTexture(), _newUiTexture, [&] {
|
||||
static const glm::vec2 topLeft(-1, 1);
|
||||
static const glm::vec2 bottomRight(1, -1);
|
||||
static const glm::vec2 texCoordTopLeft(0.0f, 1.0f);
|
||||
static const glm::vec2 texCoordBottomRight(1.0f, 0.0f);
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
|
||||
glm::vec4(1.0f, 1.0f, 1.0f, _alpha));
|
||||
});
|
||||
|
@ -685,7 +685,7 @@ void ApplicationOverlay::renderControllerPointers() {
|
|||
}
|
||||
|
||||
//If the cursor is out of the screen then don't render it
|
||||
if (mouseX < 0 || mouseX >= canvasSize.x || mouseY < 0 || mouseY >= canvasSize.y) {
|
||||
if (mouseX < 0 || mouseX >= (int)canvasSize.x || mouseY < 0 || mouseY >= (int)canvasSize.y) {
|
||||
_reticleActive[index] = false;
|
||||
continue;
|
||||
}
|
||||
|
@ -998,7 +998,7 @@ void ApplicationOverlay::renderDomainConnectionStatusBorder() {
|
|||
if (nodeList && !nodeList->getDomainHandler().isConnected()) {
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
auto canvasSize = qApp->getCanvasSize();
|
||||
if (canvasSize.x != _previousBorderWidth || canvasSize.y != _previousBorderHeight) {
|
||||
if ((int)canvasSize.x != _previousBorderWidth || (int)canvasSize.y != _previousBorderHeight) {
|
||||
glm::vec4 color(CONNECTION_STATUS_BORDER_COLOR[0],
|
||||
CONNECTION_STATUS_BORDER_COLOR[1],
|
||||
CONNECTION_STATUS_BORDER_COLOR[2], 1.0f);
|
||||
|
|
|
@ -87,11 +87,10 @@ void Overlays::renderHUD() {
|
|||
QReadLocker lock(&_lock);
|
||||
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
RenderArgs args = { NULL, Application::getInstance()->getViewFrustum(),
|
||||
lodManager->getOctreeSizeScale(),
|
||||
lodManager->getBoundaryLevelAdjust(),
|
||||
RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
RenderArgs args(NULL, Application::getInstance()->getViewFrustum(),
|
||||
lodManager->getOctreeSizeScale(),
|
||||
lodManager->getBoundaryLevelAdjust(),
|
||||
RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE);
|
||||
|
||||
foreach(Overlay* thisOverlay, _overlaysHUD) {
|
||||
if (thisOverlay->is3D()) {
|
||||
|
@ -125,11 +124,10 @@ void Overlays::renderWorld(bool drawFront,
|
|||
float myAvatarScale = 1.0f;
|
||||
|
||||
auto lodManager = DependencyManager::get<LODManager>();
|
||||
RenderArgs args = { NULL, Application::getInstance()->getDisplayViewFrustum(),
|
||||
lodManager->getOctreeSizeScale(),
|
||||
lodManager->getBoundaryLevelAdjust(),
|
||||
renderMode, renderSide, renderDebugFlags,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
RenderArgs args(NULL, Application::getInstance()->getDisplayViewFrustum(),
|
||||
lodManager->getOctreeSizeScale(),
|
||||
lodManager->getBoundaryLevelAdjust(),
|
||||
renderMode, renderSide, renderDebugFlags);
|
||||
|
||||
|
||||
foreach(Overlay* thisOverlay, _overlaysWorld) {
|
||||
|
|
|
@ -392,8 +392,8 @@ void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode,
|
|||
ViewFrustum* frustum = (renderMode == RenderArgs::SHADOW_RENDER_MODE) ?
|
||||
_viewState->getShadowViewFrustum() : _viewState->getCurrentViewFrustum();
|
||||
|
||||
RenderArgs args = { this, frustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode, renderSide,
|
||||
renderDebugFlags, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
RenderArgs args(this, frustum, getSizeScale(), getBoundaryLevelAdjust(),
|
||||
renderMode, renderSide, renderDebugFlags);
|
||||
|
||||
_tree->lockForRead();
|
||||
|
||||
|
@ -445,7 +445,22 @@ void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode,
|
|||
data.setSunBrightness(sunBrightness);
|
||||
|
||||
_viewState->overrideEnvironmentData(data);
|
||||
scene->getSkyStage()->setBackgroundMode(model::SunSkyStage::SKY_DOME);
|
||||
|
||||
} else {
|
||||
_viewState->endOverrideEnvironmentData();
|
||||
if (_bestZone->getBackgroundMode() == BACKGROUND_MODE_SKYBOX) {
|
||||
auto stage = scene->getSkyStage();
|
||||
stage->getSkybox()->setColor(_bestZone->getSkyboxProperties().getColorVec3());
|
||||
if (_bestZone->getSkyboxProperties().getURL().isEmpty()) {
|
||||
stage->getSkybox()->clearCubemap();
|
||||
} else {
|
||||
stage->getSkybox()->clearCubemap(); // NOTE: this should be changed to do something to set the cubemap
|
||||
}
|
||||
stage->setBackgroundMode(model::SunSkyStage::SKY_BOX);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (_hasPreviousZone) {
|
||||
scene->setKeyLightColor(_previousKeyLightColor);
|
||||
|
@ -460,6 +475,7 @@ void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode,
|
|||
_hasPreviousZone = false;
|
||||
}
|
||||
_viewState->endOverrideEnvironmentData();
|
||||
scene->getSkyStage()->setBackgroundMode(model::SunSkyStage::SKY_DOME);
|
||||
}
|
||||
|
||||
// we must call endScene while we still have the tree locked so that no one deletes a model
|
||||
|
@ -661,8 +677,7 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
|
|||
|
||||
if (entityItem->isVisible()) {
|
||||
|
||||
// NOTE: Zone Entities are a special case we handle here... Zones don't render
|
||||
// like other entity types. So we will skip the normal rendering tests
|
||||
// NOTE: Zone Entities are a special case we handle here...
|
||||
if (entityItem->getType() == EntityTypes::Zone) {
|
||||
if (entityItem->contains(_viewState->getAvatarPosition())) {
|
||||
float entityVolumeEstimate = entityItem->getVolumeEstimate();
|
||||
|
@ -683,42 +698,42 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// render entityItem
|
||||
AABox entityBox = entityItem->getAABox();
|
||||
|
||||
// TODO: some entity types (like lights) might want to be rendered even
|
||||
// when they are outside of the view frustum...
|
||||
float distance = args->_viewFrustum->distanceToCamera(entityBox.calcCenter());
|
||||
}
|
||||
|
||||
bool outOfView = args->_viewFrustum->boxInFrustum(entityBox) == ViewFrustum::OUTSIDE;
|
||||
if (!outOfView) {
|
||||
bool bigEnoughToRender = _viewState->shouldRenderMesh(entityBox.getLargestDimension(), distance);
|
||||
// render entityItem
|
||||
AABox entityBox = entityItem->getAABox();
|
||||
|
||||
// TODO: some entity types (like lights) might want to be rendered even
|
||||
// when they are outside of the view frustum...
|
||||
float distance = args->_viewFrustum->distanceToCamera(entityBox.calcCenter());
|
||||
|
||||
bool outOfView = args->_viewFrustum->boxInFrustum(entityBox) == ViewFrustum::OUTSIDE;
|
||||
if (!outOfView) {
|
||||
bool bigEnoughToRender = _viewState->shouldRenderMesh(entityBox.getLargestDimension(), distance);
|
||||
|
||||
if (bigEnoughToRender) {
|
||||
renderProxies(entityItem, args);
|
||||
|
||||
Glower* glower = NULL;
|
||||
if (entityItem->getGlowLevel() > 0.0f) {
|
||||
glower = new Glower(entityItem->getGlowLevel());
|
||||
}
|
||||
entityItem->render(args);
|
||||
args->_itemsRendered++;
|
||||
if (glower) {
|
||||
delete glower;
|
||||
}
|
||||
} else {
|
||||
args->_itemsTooSmall++;
|
||||
if (bigEnoughToRender) {
|
||||
renderProxies(entityItem, args);
|
||||
|
||||
Glower* glower = NULL;
|
||||
if (entityItem->getGlowLevel() > 0.0f) {
|
||||
glower = new Glower(entityItem->getGlowLevel());
|
||||
}
|
||||
entityItem->render(args);
|
||||
args->_itemsRendered++;
|
||||
if (glower) {
|
||||
delete glower;
|
||||
}
|
||||
} else {
|
||||
args->_itemsOutOfView++;
|
||||
args->_itemsTooSmall++;
|
||||
}
|
||||
} else {
|
||||
args->_itemsOutOfView++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float EntityTreeRenderer::getSizeScale() const {
|
||||
float EntityTreeRenderer::getSizeScale() const {
|
||||
return _viewState->getSizeScale();
|
||||
}
|
||||
|
||||
|
|
|
@ -11,8 +11,10 @@
|
|||
|
||||
#include "RenderableZoneEntityItem.h"
|
||||
|
||||
#include <DeferredLightingEffect.h>
|
||||
#include <DependencyManager.h>
|
||||
#include <GeometryCache.h>
|
||||
#include <PerfStat.h>
|
||||
|
||||
EntityItem* RenderableZoneEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return new RenderableZoneEntityItem(entityID, properties);
|
||||
|
@ -27,10 +29,12 @@ void RenderableZoneEntityItem::changeProperties(Lambda setNewProperties) {
|
|||
setNewProperties();
|
||||
|
||||
if (oldShapeURL != getCompoundShapeURL()) {
|
||||
if (!_model) {
|
||||
_model = getModel();
|
||||
_needsInitialSimulation = true;
|
||||
if (_model) {
|
||||
delete _model;
|
||||
}
|
||||
|
||||
_model = getModel();
|
||||
_needsInitialSimulation = true;
|
||||
_model->setURL(getCompoundShapeURL(), QUrl(), true, true);
|
||||
}
|
||||
if (oldPosition != getPosition() ||
|
||||
|
@ -61,6 +65,7 @@ int RenderableZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch
|
|||
|
||||
Model* RenderableZoneEntityItem::getModel() {
|
||||
Model* model = new Model();
|
||||
model->setIsWireframe(true);
|
||||
model->init();
|
||||
return model;
|
||||
}
|
||||
|
@ -74,9 +79,66 @@ void RenderableZoneEntityItem::initialSimulation() {
|
|||
_needsInitialSimulation = false;
|
||||
}
|
||||
|
||||
void RenderableZoneEntityItem::updateGeometry() {
|
||||
if (_model && !_model->isActive() && hasCompoundShapeURL()) {
|
||||
// Since we have a delayload, we need to update the geometry if it has been downloaded
|
||||
_model->setURL(getCompoundShapeURL(), QUrl(), true);
|
||||
}
|
||||
if (_model && _model->isActive() && _needsInitialSimulation) {
|
||||
initialSimulation();
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableZoneEntityItem::render(RenderArgs* args) {
|
||||
if (_drawZoneBoundaries) {
|
||||
// TODO: Draw the zone boundaries...
|
||||
switch (getShapeType()) {
|
||||
case SHAPE_TYPE_COMPOUND: {
|
||||
updateGeometry();
|
||||
|
||||
if (_model && _model->isActive()) {
|
||||
PerformanceTimer perfTimer("zone->renderCompound");
|
||||
glPushMatrix();
|
||||
_model->renderInScene(getLocalRenderAlpha(), args);
|
||||
glPopMatrix();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SHAPE_TYPE_BOX:
|
||||
case SHAPE_TYPE_SPHERE: {
|
||||
PerformanceTimer perfTimer("zone->renderPrimitive");
|
||||
glm::vec3 position = getPosition();
|
||||
glm::vec3 center = getCenter();
|
||||
glm::vec3 dimensions = getDimensions();
|
||||
glm::quat rotation = getRotation();
|
||||
|
||||
glm::vec4 DEFAULT_COLOR(1.0f, 1.0f, 1.0f, getLocalRenderAlpha());
|
||||
|
||||
glPushMatrix(); {
|
||||
glTranslatef(position.x, position.y, position.z);
|
||||
glm::vec3 axis = glm::axis(rotation);
|
||||
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||
glPushMatrix(); {
|
||||
glm::vec3 positionToCenter = center - position;
|
||||
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
|
||||
glScalef(dimensions.x, dimensions.y, dimensions.z);
|
||||
|
||||
auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>();
|
||||
|
||||
if (getShapeType() == SHAPE_TYPE_SPHERE) {
|
||||
const int SLICES = 15;
|
||||
const int STACKS = 15;
|
||||
deferredLightingEffect->renderWireSphere(0.5f, SLICES, STACKS, DEFAULT_COLOR);
|
||||
} else {
|
||||
deferredLightingEffect->renderWireCube(1.0f, DEFAULT_COLOR);
|
||||
}
|
||||
} glPopMatrix();
|
||||
} glPopMatrix();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// Not handled
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,16 +146,9 @@ bool RenderableZoneEntityItem::contains(const glm::vec3& point) const {
|
|||
if (getShapeType() != SHAPE_TYPE_COMPOUND) {
|
||||
return EntityItem::contains(point);
|
||||
}
|
||||
|
||||
if (_model && !_model->isActive() && hasCompoundShapeURL()) {
|
||||
// Since we have a delayload, we need to update the geometry if it has been downloaded
|
||||
_model->setURL(getCompoundShapeURL(), QUrl(), true);
|
||||
}
|
||||
const_cast<RenderableZoneEntityItem*>(this)->updateGeometry();
|
||||
|
||||
if (_model && _model->isActive() && EntityItem::contains(point)) {
|
||||
if (_needsInitialSimulation) {
|
||||
const_cast<RenderableZoneEntityItem*>(this)->initialSimulation();
|
||||
}
|
||||
return _model->convexHullContains(point);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ public:
|
|||
private:
|
||||
Model* getModel();
|
||||
void initialSimulation();
|
||||
void updateGeometry();
|
||||
|
||||
template<typename Lambda>
|
||||
void changeProperties(Lambda functor);
|
||||
|
|
|
@ -26,13 +26,13 @@ AtmospherePropertyGroup::AtmospherePropertyGroup() {
|
|||
}
|
||||
|
||||
void AtmospherePropertyGroup::copyToScriptValue(QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const {
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_VEC3(Atmosphere, Center, center);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, InnerRadius, innerRadius);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, OuterRadius, outerRadius);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, MieScattering, mieScattering);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, RayleighScattering, rayleighScattering);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_VEC3(Atmosphere, ScatteringWavelengths, scatteringWavelengths);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, HasStars, hasStars);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_VEC3(Atmosphere, atmosphere, Center, center);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, atmosphere, InnerRadius, innerRadius);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, atmosphere, OuterRadius, outerRadius);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, atmosphere, MieScattering, mieScattering);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, atmosphere, RayleighScattering, rayleighScattering);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_VEC3(Atmosphere, atmosphere, ScatteringWavelengths, scatteringWavelengths);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Atmosphere, atmosphere, HasStars, hasStars);
|
||||
}
|
||||
|
||||
void AtmospherePropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) {
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "ZoneEntityItem.h"
|
||||
|
||||
AtmospherePropertyGroup EntityItemProperties::_staticAtmosphere;
|
||||
SkyboxPropertyGroup EntityItemProperties::_staticSkybox;
|
||||
|
||||
EntityPropertyList PROP_LAST_ITEM = (EntityPropertyList)(PROP_AFTER_LAST_ITEM - 1);
|
||||
|
||||
|
@ -237,7 +238,7 @@ void EntityItemProperties::setShapeTypeFromString(const QString& shapeName) {
|
|||
}
|
||||
}
|
||||
|
||||
const char* backgroundModeNames[] = {"inherit", "atmosphere", "texture" };
|
||||
const char* backgroundModeNames[] = {"inherit", "atmosphere", "skybox" };
|
||||
|
||||
QHash<QString, BackgroundMode> stringToBackgroundModeLookup;
|
||||
|
||||
|
@ -248,7 +249,7 @@ void addBackgroundMode(BackgroundMode type) {
|
|||
void buildStringToBackgroundModeLookup() {
|
||||
addBackgroundMode(BACKGROUND_MODE_INHERIT);
|
||||
addBackgroundMode(BACKGROUND_MODE_ATMOSPHERE);
|
||||
addBackgroundMode(BACKGROUND_MODE_TEXTURE);
|
||||
addBackgroundMode(BACKGROUND_MODE_SKYBOX);
|
||||
}
|
||||
|
||||
QString EntityItemProperties::getBackgroundModeAsString() const {
|
||||
|
@ -337,6 +338,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
CHECK_PROPERTY_CHANGE(PROP_BACKGROUND_MODE, backgroundMode);
|
||||
|
||||
changedProperties += _atmosphere.getChangedProperties();
|
||||
changedProperties += _skybox.getChangedProperties();
|
||||
|
||||
return changedProperties;
|
||||
}
|
||||
|
@ -455,6 +457,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
|||
}
|
||||
|
||||
_atmosphere.copyToScriptValue(properties, engine, skipDefaults, defaultEntityProperties);
|
||||
_skybox.copyToScriptValue(properties, engine, skipDefaults, defaultEntityProperties);
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
@ -526,6 +529,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object) {
|
|||
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(stageHour, setStageHour);
|
||||
COPY_PROPERTY_FROM_QSCRITPTVALUE_ENUM(backgroundMode, BackgroundMode);
|
||||
_atmosphere.copyFromScriptValue(object, _defaultSettings);
|
||||
_skybox.copyFromScriptValue(object, _defaultSettings);
|
||||
_lastEdited = usecTimestampNow();
|
||||
}
|
||||
|
||||
|
@ -735,6 +739,9 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
|
|||
|
||||
_staticAtmosphere.setProperties(properties);
|
||||
_staticAtmosphere.appentToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState );
|
||||
|
||||
_staticSkybox.setProperties(properties);
|
||||
_staticSkybox.appentToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState );
|
||||
}
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, appendValue, properties.getMarketplaceID());
|
||||
|
@ -986,6 +993,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
|||
READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_COMPOUND_SHAPE_URL, setCompoundShapeURL);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_BACKGROUND_MODE, BackgroundMode, setBackgroundMode);
|
||||
properties.getAtmosphere().decodeFromEditPacket(propertyFlags, dataAt , processedBytes);
|
||||
properties.getSkybox().decodeFromEditPacket(propertyFlags, dataAt , processedBytes);
|
||||
}
|
||||
|
||||
READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_MARKETPLACE_ID, setMarketplaceID);
|
||||
|
@ -1090,6 +1098,7 @@ void EntityItemProperties::markAllChanged() {
|
|||
|
||||
_backgroundModeChanged = true;
|
||||
_atmosphere.markAllChanged();
|
||||
_skybox.markAllChanged();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <ShapeInfo.h>
|
||||
|
||||
#include "AtmospherePropertyGroup.h"
|
||||
#include "SkyboxPropertyGroup.h"
|
||||
#include "EntityItemID.h"
|
||||
#include "EntityItemPropertiesMacros.h"
|
||||
#include "EntityTypes.h"
|
||||
|
@ -138,8 +139,9 @@ public:
|
|||
DEFINE_PROPERTY(PROP_STAGE_DAY, StageDay, stageDay, quint16);
|
||||
DEFINE_PROPERTY(PROP_STAGE_HOUR, StageHour, stageHour, float);
|
||||
DEFINE_PROPERTY_REF(PROP_NAME, Name, name, QString);
|
||||
DEFINE_PROPERTY_GROUP(Atmosphere, atmosphere, AtmospherePropertyGroup);
|
||||
DEFINE_PROPERTY_REF_ENUM(PROP_BACKGROUND_MODE, BackgroundMode, backgroundMode, BackgroundMode);
|
||||
DEFINE_PROPERTY_GROUP(Atmosphere, atmosphere, AtmospherePropertyGroup);
|
||||
DEFINE_PROPERTY_GROUP(Skybox, skybox, SkyboxPropertyGroup);
|
||||
|
||||
static QString getBackgroundModeString(BackgroundMode mode);
|
||||
|
||||
|
|
|
@ -116,6 +116,17 @@
|
|||
bytesRead += sizeof(rgbColor); \
|
||||
}
|
||||
|
||||
#define READ_ENTITY_PROPERTY_XCOLOR(P,M) \
|
||||
if (propertyFlags.getHasProperty(P)) { \
|
||||
if (overwriteLocalData) { \
|
||||
M.red = dataAt[RED_INDEX]; \
|
||||
M.green = dataAt[GREEN_INDEX]; \
|
||||
M.blue = dataAt[BLUE_INDEX]; \
|
||||
} \
|
||||
dataAt += sizeof(rgbColor); \
|
||||
bytesRead += sizeof(rgbColor); \
|
||||
}
|
||||
|
||||
#define READ_ENTITY_PROPERTY_TO_PROPERTIES(P,T,O) \
|
||||
if (propertyFlags.getHasProperty(P)) { \
|
||||
T fromBuffer; \
|
||||
|
@ -206,27 +217,40 @@
|
|||
}
|
||||
|
||||
|
||||
#define COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_VEC3(G,P,p) \
|
||||
#define COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_VEC3(G,g,P,p) \
|
||||
if (!skipDefaults || defaultEntityProperties.get##G().get##P() != _##p) { \
|
||||
QScriptValue groupProperties = properties.property(#G); \
|
||||
QScriptValue groupProperties = properties.property(#g); \
|
||||
if (!groupProperties.isValid()) { \
|
||||
groupProperties = engine->newObject(); \
|
||||
} \
|
||||
QScriptValue V = vec3toScriptValue(engine, _##p); \
|
||||
groupProperties.setProperty(#p, V); \
|
||||
properties.setProperty(#G, groupProperties); \
|
||||
properties.setProperty(#g, groupProperties); \
|
||||
}
|
||||
|
||||
#define COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(G,P,p) \
|
||||
#define COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(G,g,P,p) \
|
||||
if (!skipDefaults || defaultEntityProperties.get##G().get##P() != _##p) { \
|
||||
QScriptValue groupProperties = properties.property(#G); \
|
||||
QScriptValue groupProperties = properties.property(#g); \
|
||||
if (!groupProperties.isValid()) { \
|
||||
groupProperties = engine->newObject(); \
|
||||
} \
|
||||
groupProperties.setProperty(#p, _##p); \
|
||||
properties.setProperty(#G, groupProperties); \
|
||||
properties.setProperty(#g, groupProperties); \
|
||||
}
|
||||
|
||||
|
||||
#define COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_COLOR(G,g,P,p) \
|
||||
if (!skipDefaults || defaultEntityProperties.get##G().get##P() != _##p) { \
|
||||
QScriptValue groupProperties = properties.property(#g); \
|
||||
if (!groupProperties.isValid()) { \
|
||||
groupProperties = engine->newObject(); \
|
||||
} \
|
||||
QScriptValue colorValue = xColorToScriptValue(engine, _##p); \
|
||||
groupProperties.setProperty(#p, colorValue); \
|
||||
properties.setProperty(#g, groupProperties); \
|
||||
}
|
||||
|
||||
|
||||
#define COPY_PROPERTY_TO_QSCRIPTVALUE_VEC3(P) \
|
||||
if (!skipDefaults || defaultEntityProperties._##P != _##P) { \
|
||||
QScriptValue P = vec3toScriptValue(engine, _##P); \
|
||||
|
@ -328,6 +352,20 @@
|
|||
} \
|
||||
}
|
||||
|
||||
#define COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_STRING(G, P, S)\
|
||||
{ \
|
||||
QScriptValue G = object.property(#G); \
|
||||
if (G.isValid()) { \
|
||||
QScriptValue P = G.property(#P); \
|
||||
if (P.isValid()) { \
|
||||
QString newValue = P.toVariant().toString().trimmed();\
|
||||
if (_defaultSettings || newValue != _##P) { \
|
||||
S(newValue); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define COPY_PROPERTY_FROM_QSCRIPTVALUE_UUID(P, S) \
|
||||
QScriptValue P = object.property(#P); \
|
||||
if (P.isValid()) { \
|
||||
|
@ -428,6 +466,31 @@
|
|||
} \
|
||||
}
|
||||
|
||||
#define COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_COLOR(G, P, S) \
|
||||
{ \
|
||||
QScriptValue G = object.property(#G); \
|
||||
if (G.isValid()) { \
|
||||
QScriptValue P = G.property(#P); \
|
||||
if (P.isValid()) { \
|
||||
QScriptValue r = P.property("red"); \
|
||||
QScriptValue g = P.property("green"); \
|
||||
QScriptValue b = P.property("blue"); \
|
||||
if (r.isValid() && g.isValid() && b.isValid()) {\
|
||||
xColor newColor; \
|
||||
newColor.red = r.toVariant().toInt(); \
|
||||
newColor.green = g.toVariant().toInt(); \
|
||||
newColor.blue = b.toVariant().toInt(); \
|
||||
if (_defaultSettings || \
|
||||
(newColor.red != _color.red || \
|
||||
newColor.green != _color.green || \
|
||||
newColor.blue != _color.blue)) { \
|
||||
S(newColor); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define COPY_PROPERTY_FROM_QSCRITPTVALUE_ENUM(P, S) \
|
||||
QScriptValue P = object.property(#P); \
|
||||
if (P.isValid()) { \
|
||||
|
|
|
@ -144,6 +144,8 @@ enum EntityPropertyList {
|
|||
PROP_ATMOSPHERE_SCATTERING_WAVELENGTHS = PROP_LOCAL_GRAVITY,
|
||||
PROP_ATMOSPHERE_HAS_STARS = PROP_PARTICLE_RADIUS,
|
||||
PROP_BACKGROUND_MODE = PROP_MODEL_URL,
|
||||
PROP_SKYBOX_COLOR = PROP_ANIMATION_URL,
|
||||
PROP_SKYBOX_URL = PROP_ANIMATION_FPS,
|
||||
|
||||
// WARNING!!! DO NOT ADD PROPS_xxx here unless you really really meant to.... Add them UP above
|
||||
};
|
||||
|
@ -158,7 +160,7 @@ extern EntityPropertyList PROP_LAST_ITEM;
|
|||
enum BackgroundMode {
|
||||
BACKGROUND_MODE_INHERIT,
|
||||
BACKGROUND_MODE_ATMOSPHERE,
|
||||
BACKGROUND_MODE_TEXTURE,
|
||||
BACKGROUND_MODE_SKYBOX,
|
||||
};
|
||||
|
||||
|
||||
|
|
130
libraries/entities/src/SkyboxPropertyGroup.cpp
Normal file
130
libraries/entities/src/SkyboxPropertyGroup.cpp
Normal file
|
@ -0,0 +1,130 @@
|
|||
//
|
||||
// SkyboxPropertyGroup.cpp
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 12/4/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 <OctreePacketData.h>
|
||||
|
||||
#include "SkyboxPropertyGroup.h"
|
||||
#include "EntityItemProperties.h"
|
||||
#include "EntityItemPropertiesMacros.h"
|
||||
|
||||
SkyboxPropertyGroup::SkyboxPropertyGroup() {
|
||||
_color.red = _color.green = _color.blue = 0;
|
||||
_url = QString();
|
||||
}
|
||||
|
||||
void SkyboxPropertyGroup::copyToScriptValue(QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const {
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE_COLOR(Skybox, skybox, Color, color);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(Skybox, skybox, URL, url);
|
||||
}
|
||||
|
||||
void SkyboxPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) {
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_COLOR(skybox, color, setColor);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE_STRING(skybox, url, setURL);
|
||||
}
|
||||
|
||||
void SkyboxPropertyGroup::debugDump() const {
|
||||
qDebug() << " SkyboxPropertyGroup: ---------------------------------------------";
|
||||
qDebug() << " Color:" << getColor() << " has changed:" << colorChanged();
|
||||
qDebug() << " URL:" << getURL() << " has changed:" << urlChanged();
|
||||
}
|
||||
|
||||
bool SkyboxPropertyGroup::appentToEditPacket(OctreePacketData* packetData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const {
|
||||
|
||||
bool successPropertyFits = true;
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_SKYBOX_COLOR, appendColor, getColor());
|
||||
APPEND_ENTITY_PROPERTY(PROP_SKYBOX_URL, appendValue, getURL());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool SkyboxPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes) {
|
||||
|
||||
int bytesRead = 0;
|
||||
bool overwriteLocalData = true;
|
||||
|
||||
READ_ENTITY_PROPERTY_XCOLOR(PROP_SKYBOX_COLOR, _color);
|
||||
READ_ENTITY_PROPERTY_STRING(PROP_SKYBOX_URL, setURL);
|
||||
|
||||
processedBytes += bytesRead;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkyboxPropertyGroup::markAllChanged() {
|
||||
_colorChanged = true;
|
||||
_urlChanged = true;
|
||||
}
|
||||
|
||||
EntityPropertyFlags SkyboxPropertyGroup::getChangedProperties() const {
|
||||
EntityPropertyFlags changedProperties;
|
||||
|
||||
CHECK_PROPERTY_CHANGE(PROP_SKYBOX_COLOR, color);
|
||||
CHECK_PROPERTY_CHANGE(PROP_SKYBOX_URL, url);
|
||||
|
||||
return changedProperties;
|
||||
}
|
||||
|
||||
void SkyboxPropertyGroup::getProperties(EntityItemProperties& properties) const {
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Skybox, Color, getColor);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Skybox, URL, getURL);
|
||||
}
|
||||
|
||||
bool SkyboxPropertyGroup::setProperties(const EntityItemProperties& properties) {
|
||||
bool somethingChanged = false;
|
||||
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Skybox, Color, color, setColor);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Skybox, URL, url, setURL);
|
||||
|
||||
return somethingChanged;
|
||||
}
|
||||
|
||||
EntityPropertyFlags SkyboxPropertyGroup::getEntityProperties(EncodeBitstreamParams& params) const {
|
||||
EntityPropertyFlags requestedProperties;
|
||||
|
||||
requestedProperties += PROP_SKYBOX_COLOR;
|
||||
requestedProperties += PROP_SKYBOX_URL;
|
||||
|
||||
return requestedProperties;
|
||||
}
|
||||
|
||||
void SkyboxPropertyGroup::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
||||
EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const {
|
||||
|
||||
bool successPropertyFits = true;
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_SKYBOX_COLOR, appendColor, getColor());
|
||||
APPEND_ENTITY_PROPERTY(PROP_SKYBOX_URL, appendValue, getURL());
|
||||
}
|
||||
|
||||
int SkyboxPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
ReadBitstreamToTreeParams& args,
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData) {
|
||||
|
||||
int bytesRead = 0;
|
||||
const unsigned char* dataAt = data;
|
||||
|
||||
READ_ENTITY_PROPERTY_XCOLOR(PROP_SKYBOX_COLOR, _color);
|
||||
READ_ENTITY_PROPERTY_STRING(PROP_SKYBOX_URL, setURL);
|
||||
|
||||
return bytesRead;
|
||||
}
|
85
libraries/entities/src/SkyboxPropertyGroup.h
Normal file
85
libraries/entities/src/SkyboxPropertyGroup.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
//
|
||||
// SkyboxPropertyGroup.h
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 12/4/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
|
||||
//
|
||||
|
||||
#ifndef hifi_SkyboxPropertyGroup_h
|
||||
#define hifi_SkyboxPropertyGroup_h
|
||||
|
||||
#include <QtScript/QScriptEngine>
|
||||
|
||||
#include "PropertyGroup.h"
|
||||
#include "EntityItemPropertiesMacros.h"
|
||||
|
||||
class EntityItemProperties;
|
||||
class EncodeBitstreamParams;
|
||||
class OctreePacketData;
|
||||
class EntityTreeElementExtraEncodeData;
|
||||
class ReadBitstreamToTreeParams;
|
||||
|
||||
#include <stdint.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
|
||||
class SkyboxPropertyGroup : public PropertyGroup {
|
||||
public:
|
||||
SkyboxPropertyGroup();
|
||||
virtual ~SkyboxPropertyGroup() {}
|
||||
|
||||
// EntityItemProperty related helpers
|
||||
virtual void copyToScriptValue(QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const;
|
||||
virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings);
|
||||
virtual void debugDump() const;
|
||||
|
||||
virtual bool appentToEditPacket(OctreePacketData* packetData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const;
|
||||
|
||||
virtual bool decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes);
|
||||
virtual void markAllChanged();
|
||||
virtual EntityPropertyFlags getChangedProperties() const;
|
||||
|
||||
// EntityItem related helpers
|
||||
// methods for getting/setting all properties of an entity
|
||||
virtual void getProperties(EntityItemProperties& propertiesOut) const;
|
||||
|
||||
/// returns true if something changed
|
||||
virtual bool setProperties(const EntityItemProperties& properties);
|
||||
|
||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;
|
||||
|
||||
virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
||||
EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const;
|
||||
|
||||
virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
ReadBitstreamToTreeParams& args,
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData);
|
||||
|
||||
glm::vec3 getColorVec3() const {
|
||||
const quint8 MAX_COLOR = 255;
|
||||
glm::vec3 color = { (float)_color.red / (float)MAX_COLOR,
|
||||
(float)_color.green / (float)MAX_COLOR,
|
||||
(float)_color.blue / (float)MAX_COLOR };
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
DEFINE_PROPERTY_REF(PROP_SKYBOX_COLOR, Color, color, xColor);
|
||||
DEFINE_PROPERTY_REF(PROP_SKYBOX_URL, URL, url, QString);
|
||||
};
|
||||
|
||||
#endif // hifi_SkyboxPropertyGroup_h
|
|
@ -71,13 +71,13 @@ ZoneEntityItem::ZoneEntityItem(const EntityItemID& entityItemID, const EntityIte
|
|||
EnvironmentData ZoneEntityItem::getEnvironmentData() const {
|
||||
EnvironmentData result;
|
||||
|
||||
result.setAtmosphereCenter(_atmospherePropeties.getCenter());
|
||||
result.setAtmosphereInnerRadius(_atmospherePropeties.getInnerRadius());
|
||||
result.setAtmosphereOuterRadius(_atmospherePropeties.getOuterRadius());
|
||||
result.setRayleighScattering(_atmospherePropeties.getRayleighScattering());
|
||||
result.setMieScattering(_atmospherePropeties.getMieScattering());
|
||||
result.setScatteringWavelengths(_atmospherePropeties.getScatteringWavelengths());
|
||||
result.setHasStars(_atmospherePropeties.getHasStars());
|
||||
result.setAtmosphereCenter(_atmosphereProperties.getCenter());
|
||||
result.setAtmosphereInnerRadius(_atmosphereProperties.getInnerRadius());
|
||||
result.setAtmosphereOuterRadius(_atmosphereProperties.getOuterRadius());
|
||||
result.setRayleighScattering(_atmosphereProperties.getRayleighScattering());
|
||||
result.setMieScattering(_atmosphereProperties.getMieScattering());
|
||||
result.setScatteringWavelengths(_atmosphereProperties.getScatteringWavelengths());
|
||||
result.setHasStars(_atmosphereProperties.getHasStars());
|
||||
|
||||
// NOTE: The sunLocation and SunBrightness will be overwritten in the EntityTreeRenderer to use the
|
||||
// keyLight details from the scene interface
|
||||
|
@ -105,7 +105,8 @@ EntityItemProperties ZoneEntityItem::getProperties() const {
|
|||
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(backgroundMode, getBackgroundMode);
|
||||
|
||||
_atmospherePropeties.getProperties(properties);
|
||||
_atmosphereProperties.getProperties(properties);
|
||||
_skyboxProperties.getProperties(properties);
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
@ -128,9 +129,10 @@ bool ZoneEntityItem::setProperties(const EntityItemProperties& properties) {
|
|||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(compoundShapeURL, setCompoundShapeURL);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(backgroundMode, setBackgroundMode);
|
||||
|
||||
bool somethingChangedInAtmosphere = _atmospherePropeties.setProperties(properties);
|
||||
bool somethingChangedInAtmosphere = _atmosphereProperties.setProperties(properties);
|
||||
bool somethingChangedInSkybox = _skyboxProperties.setProperties(properties);
|
||||
|
||||
somethingChanged = somethingChanged || somethingChangedInAtmosphere;
|
||||
somethingChanged = somethingChanged || somethingChangedInAtmosphere || somethingChangedInSkybox;
|
||||
|
||||
if (somethingChanged) {
|
||||
bool wantDebug = false;
|
||||
|
@ -165,8 +167,17 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
|
|||
READ_ENTITY_PROPERTY_SETTER(PROP_SHAPE_TYPE, ShapeType, updateShapeType);
|
||||
READ_ENTITY_PROPERTY_STRING(PROP_COMPOUND_SHAPE_URL, setCompoundShapeURL);
|
||||
READ_ENTITY_PROPERTY_SETTER(PROP_BACKGROUND_MODE, BackgroundMode, setBackgroundMode);
|
||||
bytesRead += _atmospherePropeties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
|
||||
|
||||
int bytesFromAtmosphere = _atmosphereProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
|
||||
propertyFlags, overwriteLocalData);
|
||||
|
||||
bytesRead += bytesFromAtmosphere;
|
||||
dataAt += bytesFromAtmosphere;
|
||||
|
||||
int bytesFromSkybox = _skyboxProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
|
||||
propertyFlags, overwriteLocalData);
|
||||
bytesRead += bytesFromSkybox;
|
||||
dataAt += bytesFromSkybox;
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
|
@ -189,7 +200,8 @@ EntityPropertyFlags ZoneEntityItem::getEntityProperties(EncodeBitstreamParams& p
|
|||
requestedProperties += PROP_SHAPE_TYPE;
|
||||
requestedProperties += PROP_COMPOUND_SHAPE_URL;
|
||||
requestedProperties += PROP_BACKGROUND_MODE;
|
||||
requestedProperties += _atmospherePropeties.getEntityProperties(params);
|
||||
requestedProperties += _atmosphereProperties.getEntityProperties(params);
|
||||
requestedProperties += _skyboxProperties.getEntityProperties(params);
|
||||
|
||||
return requestedProperties;
|
||||
}
|
||||
|
@ -218,7 +230,10 @@ void ZoneEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits
|
|||
APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, appendValue, getCompoundShapeURL());
|
||||
APPEND_ENTITY_PROPERTY(PROP_BACKGROUND_MODE, appendValue, (uint32_t)getBackgroundMode()); // could this be a uint16??
|
||||
|
||||
_atmospherePropeties.appendSubclassData(packetData, params, modelTreeElementExtraEncodeData, requestedProperties,
|
||||
_atmosphereProperties.appendSubclassData(packetData, params, modelTreeElementExtraEncodeData, requestedProperties,
|
||||
propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||
|
||||
_skyboxProperties.appendSubclassData(packetData, params, modelTreeElementExtraEncodeData, requestedProperties,
|
||||
propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||
|
||||
}
|
||||
|
@ -241,23 +256,22 @@ void ZoneEntityItem::debugDump() const {
|
|||
qCDebug(entities) << " _stageHour:" << _stageHour;
|
||||
qCDebug(entities) << " _backgroundMode:" << EntityItemProperties::getBackgroundModeString(_backgroundMode);
|
||||
|
||||
_atmospherePropeties.debugDump();
|
||||
_atmosphereProperties.debugDump();
|
||||
_skyboxProperties.debugDump();
|
||||
}
|
||||
|
||||
ShapeType ZoneEntityItem::getShapeType() const {
|
||||
// Zones are not allowed to have a SHAPE_TYPE_NONE... they are always at least a SHAPE_TYPE_BOX
|
||||
if (_shapeType == SHAPE_TYPE_COMPOUND) {
|
||||
return hasCompoundShapeURL() ? SHAPE_TYPE_COMPOUND : SHAPE_TYPE_BOX;
|
||||
return hasCompoundShapeURL() ? SHAPE_TYPE_COMPOUND : DEFAULT_SHAPE_TYPE;
|
||||
} else {
|
||||
return _shapeType == SHAPE_TYPE_NONE ? SHAPE_TYPE_BOX : _shapeType;
|
||||
return _shapeType == SHAPE_TYPE_NONE ? DEFAULT_SHAPE_TYPE : _shapeType;
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setCompoundShapeURL(const QString& url) {
|
||||
_compoundShapeURL = url;
|
||||
if (!_compoundShapeURL.isEmpty()) {
|
||||
updateShapeType(SHAPE_TYPE_COMPOUND);
|
||||
} else if (_shapeType == SHAPE_TYPE_COMPOUND) {
|
||||
if (_compoundShapeURL.isEmpty() && _shapeType == SHAPE_TYPE_COMPOUND) {
|
||||
_shapeType = DEFAULT_SHAPE_TYPE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,11 +44,6 @@ public:
|
|||
ReadBitstreamToTreeParams& args,
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData);
|
||||
|
||||
// NOTE: Apparently if you begin to return a shape type, then the physics system will prevent an avatar
|
||||
// from penetrating the walls of the entity. This fact will likely be important to Clement as he works
|
||||
// on better defining the shape/volume of a zone.
|
||||
//virtual ShapeType getShapeType() const { return SHAPE_TYPE_BOX; }
|
||||
|
||||
xColor getKeyLightColor() const { xColor color = { _keyLightColor[RED_INDEX], _keyLightColor[GREEN_INDEX], _keyLightColor[BLUE_INDEX] }; return color; }
|
||||
void setKeyLightColor(const xColor& value) {
|
||||
_keyLightColor[RED_INDEX] = value.red;
|
||||
|
@ -110,6 +105,8 @@ public:
|
|||
BackgroundMode getBackgroundMode() const { return _backgroundMode; }
|
||||
|
||||
EnvironmentData getEnvironmentData() const;
|
||||
const AtmospherePropertyGroup& getAtmosphereProperties() const { return _atmosphereProperties; }
|
||||
const SkyboxPropertyGroup& getSkyboxProperties() const { return _skyboxProperties; }
|
||||
|
||||
virtual bool supportsDetailedRayIntersection() const { return true; }
|
||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
|
@ -144,11 +141,12 @@ protected:
|
|||
uint16_t _stageDay;
|
||||
float _stageHour;
|
||||
|
||||
ShapeType _shapeType = SHAPE_TYPE_NONE;
|
||||
ShapeType _shapeType = DEFAULT_SHAPE_TYPE;
|
||||
QString _compoundShapeURL;
|
||||
|
||||
BackgroundMode _backgroundMode = BACKGROUND_MODE_INHERIT;
|
||||
AtmospherePropertyGroup _atmospherePropeties;
|
||||
AtmospherePropertyGroup _atmosphereProperties;
|
||||
SkyboxPropertyGroup _skyboxProperties;
|
||||
|
||||
static bool _drawZoneBoundaries;
|
||||
static bool _zonesArePickable;
|
||||
|
|
|
@ -31,36 +31,51 @@ typedef GLBackend::GLState::Command1<State::DepthTest> CommandDepthTest;
|
|||
typedef GLBackend::GLState::Command3<State::StencilActivation, State::StencilTest, State::StencilTest> CommandStencil;
|
||||
typedef GLBackend::GLState::Command1<State::BlendFunction> CommandBlend;
|
||||
|
||||
// The state commands to reset to default,
|
||||
// WARNING depending on the order of the State::Field enum
|
||||
const GLBackend::GLState::Commands GLBackend::GLState::_resetStateCommands = {
|
||||
CommandPointer(new Command1I(&GLBackend::do_setStateFillMode, State::DEFAULT.fillMode)),
|
||||
CommandPointer(new Command1I(&GLBackend::do_setStateCullMode, State::DEFAULT.cullMode)),
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateFrontFaceClockwise, State::DEFAULT.frontFaceClockwise)),
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateDepthClipEnable, State::DEFAULT.depthClipEnable)),
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateScissorEnable, State::DEFAULT.scissorEnable)),
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateMultisampleEnable, State::DEFAULT.multisampleEnable)),
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateAntialiasedLineEnable, State::DEFAULT.antialisedLineEnable)),
|
||||
const GLBackend::GLState::Commands makeResetStateCommands();
|
||||
const GLBackend::GLState::Commands GLBackend::GLState::_resetStateCommands = makeResetStateCommands();
|
||||
|
||||
// Depth bias has 2 fields in State but really one call in GLBackend
|
||||
CommandPointer(new CommandDepthBias(&GLBackend::do_setStateDepthBias, Vec2(State::DEFAULT.depthBias, State::DEFAULT.depthBiasSlopeScale))),
|
||||
CommandPointer(new CommandDepthBias(&GLBackend::do_setStateDepthBias, Vec2(State::DEFAULT.depthBias, State::DEFAULT.depthBiasSlopeScale))),
|
||||
|
||||
CommandPointer(new CommandDepthTest(&GLBackend::do_setStateDepthTest, State::DEFAULT.depthTest)),
|
||||
|
||||
// Depth bias has 3 fields in State but really one call in GLBackend
|
||||
CommandPointer(new CommandStencil(&GLBackend::do_setStateStencil, State::DEFAULT.stencilActivation, State::DEFAULT.stencilTestFront, State::DEFAULT.stencilTestBack)),
|
||||
CommandPointer(new CommandStencil(&GLBackend::do_setStateStencil, State::DEFAULT.stencilActivation, State::DEFAULT.stencilTestFront, State::DEFAULT.stencilTestBack)),
|
||||
CommandPointer(new CommandStencil(&GLBackend::do_setStateStencil, State::DEFAULT.stencilActivation, State::DEFAULT.stencilTestFront, State::DEFAULT.stencilTestBack)),
|
||||
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateAlphaToCoverageEnable, State::DEFAULT.alphaToCoverageEnable)),
|
||||
|
||||
CommandPointer(new Command1U(&GLBackend::do_setStateSampleMask, State::DEFAULT.sampleMask)),
|
||||
|
||||
CommandPointer(new CommandBlend(&GLBackend::do_setStateBlend, State::DEFAULT.blendFunction)),
|
||||
|
||||
CommandPointer(new Command1U(&GLBackend::do_setStateColorWriteMask, State::DEFAULT.colorWriteMask))
|
||||
};
|
||||
const GLBackend::GLState::Commands makeResetStateCommands() {
|
||||
// Since State::DEFAULT is a static defined in another .cpp the initialisation order is random
|
||||
// and we have a 50/50 chance that State::DEFAULT is not yet initialized.
|
||||
// Since State::DEFAULT = State::Data() it is much easier to not use the actual State::DEFAULT
|
||||
// but another State::Data object with a default initialization.
|
||||
State::Data DEFAULT = State::Data();
|
||||
|
||||
CommandPointer depthBiasCommand = CommandPointer(new CommandDepthBias(&GLBackend::do_setStateDepthBias, Vec2(DEFAULT.depthBias, DEFAULT.depthBiasSlopeScale)));
|
||||
CommandPointer stencilCommand = CommandPointer(new CommandStencil(&GLBackend::do_setStateStencil, DEFAULT.stencilActivation, DEFAULT.stencilTestFront, DEFAULT.stencilTestBack));
|
||||
|
||||
// The state commands to reset to default,
|
||||
// WARNING depending on the order of the State::Field enum
|
||||
return {
|
||||
CommandPointer(new Command1I(&GLBackend::do_setStateFillMode, DEFAULT.fillMode)),
|
||||
CommandPointer(new Command1I(&GLBackend::do_setStateCullMode, DEFAULT.cullMode)),
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateFrontFaceClockwise, DEFAULT.frontFaceClockwise)),
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateDepthClipEnable, DEFAULT.depthClipEnable)),
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateScissorEnable, DEFAULT.scissorEnable)),
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateMultisampleEnable, DEFAULT.multisampleEnable)),
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateAntialiasedLineEnable, DEFAULT.antialisedLineEnable)),
|
||||
|
||||
// Depth bias has 2 fields in State but really one call in GLBackend
|
||||
CommandPointer(depthBiasCommand),
|
||||
CommandPointer(depthBiasCommand),
|
||||
|
||||
CommandPointer(new CommandDepthTest(&GLBackend::do_setStateDepthTest, DEFAULT.depthTest)),
|
||||
|
||||
// Depth bias has 3 fields in State but really one call in GLBackend
|
||||
CommandPointer(stencilCommand),
|
||||
CommandPointer(stencilCommand),
|
||||
CommandPointer(stencilCommand),
|
||||
|
||||
CommandPointer(new Command1B(&GLBackend::do_setStateAlphaToCoverageEnable, DEFAULT.alphaToCoverageEnable)),
|
||||
|
||||
CommandPointer(new Command1U(&GLBackend::do_setStateSampleMask, DEFAULT.sampleMask)),
|
||||
|
||||
CommandPointer(new CommandBlend(&GLBackend::do_setStateBlend, DEFAULT.blendFunction)),
|
||||
|
||||
CommandPointer(new Command1U(&GLBackend::do_setStateColorWriteMask, DEFAULT.colorWriteMask))
|
||||
};
|
||||
}
|
||||
|
||||
void generateFillMode(GLBackend::GLState::Commands& commands, State::FillMode fillMode) {
|
||||
commands.push_back(CommandPointer(new Command1I(&GLBackend::do_setStateFillMode, int32(fillMode))));
|
||||
|
|
|
@ -20,6 +20,8 @@ State::State() {
|
|||
State::~State() {
|
||||
}
|
||||
|
||||
// WARNING: GLBackend::GLState::_resetStateCommands heavily relies on the fact that State::DEFAULT = State::Data()
|
||||
// Please make sure to go check makeResetStateCommands() before modifying this value
|
||||
const State::Data State::DEFAULT = State::Data();
|
||||
|
||||
State::Signature State::evalSignature(const Data& state) {
|
||||
|
|
|
@ -41,10 +41,13 @@ void Skybox::setCubemap(const gpu::TexturePointer& cubemap) {
|
|||
_cubemap = cubemap;
|
||||
}
|
||||
|
||||
void Skybox::clearCubemap() {
|
||||
_cubemap.reset();
|
||||
}
|
||||
|
||||
void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) {
|
||||
|
||||
if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) {
|
||||
|
||||
static gpu::PipelinePointer thePipeline;
|
||||
static gpu::BufferPointer theBuffer;
|
||||
static gpu::Stream::FormatPointer theFormat;
|
||||
|
|
|
@ -32,6 +32,7 @@ public:
|
|||
|
||||
void setCubemap(const gpu::TexturePointer& cubemap);
|
||||
const gpu::TexturePointer& getCubemap() const { return _cubemap; }
|
||||
void clearCubemap();
|
||||
|
||||
static void render(gpu::Batch& batch, const ViewFrustum& frustum, const Skybox& skybox);
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ PacketVersion versionForPacketType(PacketType type) {
|
|||
return 1;
|
||||
case PacketTypeEntityAddOrEdit:
|
||||
case PacketTypeEntityData:
|
||||
return VERSION_ENTITIES_ZONE_ENTITIES_HAVE_ATMOSPHERE;
|
||||
return VERSION_ENTITIES_ZONE_ENTITIES_HAVE_SKYBOX;
|
||||
case PacketTypeEntityErase:
|
||||
return 2;
|
||||
case PacketTypeAudioStreamStats:
|
||||
|
|
|
@ -141,5 +141,6 @@ const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_EXIST = 17;
|
|||
const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_HAVE_DYNAMIC_SHAPE = 18;
|
||||
const PacketVersion VERSION_ENTITIES_HAVE_NAMES = 19;
|
||||
const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_HAVE_ATMOSPHERE = 20;
|
||||
const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_HAVE_SKYBOX = 21;
|
||||
|
||||
#endif // hifi_PacketHeaders_h
|
||||
|
|
|
@ -167,8 +167,8 @@ bool OctreeRenderer::renderOperation(OctreeElement* element, void* extraData) {
|
|||
void OctreeRenderer::render(RenderArgs::RenderMode renderMode,
|
||||
RenderArgs::RenderSide renderSide,
|
||||
RenderArgs::DebugFlags renderDebugFlags) {
|
||||
RenderArgs args = { this, _viewFrustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode, renderSide,
|
||||
renderDebugFlags, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
RenderArgs args(this, _viewFrustum, getSizeScale(), getBoundaryLevelAdjust(),
|
||||
renderMode, renderSide, renderDebugFlags);
|
||||
if (_tree) {
|
||||
_tree->lockForRead();
|
||||
_tree->recurseTreeWithOperation(renderOperation, &args);
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
const float DEFAULT_KEYHOLE_RADIUS = 3.0f;
|
||||
const float DEFAULT_FIELD_OF_VIEW_DEGREES = 45.0f;
|
||||
const float DEFAULT_ASPECT_RATIO = 16.0f/9.0f;
|
||||
const float DEFAULT_NEAR_CLIP = 0.08f;
|
||||
//const float DEFAULT_NEAR_CLIP = 0.08f;
|
||||
const float DEFAULT_NEAR_CLIP = 0.25f;
|
||||
const float DEFAULT_FAR_CLIP = (float)TREE_SCALE;
|
||||
|
||||
class ViewFrustum {
|
||||
|
|
|
@ -84,6 +84,7 @@ Model::Model(QObject* parent) :
|
|||
_calculatedMeshBoxesValid(false),
|
||||
_calculatedMeshTrianglesValid(false),
|
||||
_meshGroupsKnown(false),
|
||||
_isWireframe(false),
|
||||
_renderCollisionHull(false) {
|
||||
|
||||
// we may have been created in the network thread, but we live in the main thread
|
||||
|
@ -100,8 +101,8 @@ Model::RenderPipelineLib Model::_renderPipelineLib;
|
|||
const GLint MATERIAL_GPU_SLOT = 3;
|
||||
|
||||
void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey key,
|
||||
gpu::ShaderPointer& vertexShader,
|
||||
gpu::ShaderPointer& pixelShader ) {
|
||||
gpu::ShaderPointer& vertexShader,
|
||||
gpu::ShaderPointer& pixelShader ) {
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), MATERIAL_GPU_SLOT));
|
||||
|
@ -119,7 +120,7 @@ void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey key,
|
|||
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
|
||||
// Backface on shadow
|
||||
if (key.isShadow()) {
|
||||
state->setCullMode(gpu::State::CULL_FRONT);
|
||||
|
@ -140,7 +141,20 @@ void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey key,
|
|||
// Good to go add the brand new pipeline
|
||||
auto pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state));
|
||||
insert(value_type(key.getRaw(), RenderPipeline(pipeline, locations)));
|
||||
|
||||
|
||||
|
||||
if (!key.isWireFrame()) {
|
||||
|
||||
RenderKey wireframeKey(key.getRaw() | RenderKey::IS_WIREFRAME);
|
||||
gpu::StatePointer wireframeState = gpu::StatePointer(new gpu::State(state->getValues()));
|
||||
|
||||
wireframeState->setFillMode(gpu::State::FILL_LINE);
|
||||
|
||||
// create a new RenderPipeline with the same shader side and the mirrorState
|
||||
auto wireframePipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, wireframeState));
|
||||
insert(value_type(wireframeKey.getRaw(), RenderPipeline(wireframePipeline, locations)));
|
||||
}
|
||||
|
||||
// If not a shadow pass, create the mirror version from the same state, just change the FrontFace
|
||||
if (!key.isShadow()) {
|
||||
|
||||
|
@ -152,6 +166,17 @@ void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey key,
|
|||
// create a new RenderPipeline with the same shader side and the mirrorState
|
||||
auto mirrorPipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, mirrorState));
|
||||
insert(value_type(mirrorKey.getRaw(), RenderPipeline(mirrorPipeline, locations)));
|
||||
|
||||
if (!key.isWireFrame()) {
|
||||
RenderKey wireframeKey(key.getRaw() | RenderKey::IS_MIRROR | RenderKey::IS_WIREFRAME);
|
||||
gpu::StatePointer wireframeState = gpu::StatePointer(new gpu::State(state->getValues()));;
|
||||
|
||||
wireframeState->setFillMode(gpu::State::FILL_LINE);
|
||||
|
||||
// create a new RenderPipeline with the same shader side and the mirrorState
|
||||
auto wireframePipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, wireframeState));
|
||||
insert(value_type(wireframeKey.getRaw(), RenderPipeline(wireframePipeline, locations)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -808,19 +833,19 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
|||
|
||||
//renderMeshes(batch, mode, translucent, alphaThreshold, hasTangents, hasSpecular, isSkinned, args, forceRenderMeshes);
|
||||
int opaqueMeshPartsRendered = 0;
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, true, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, true, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, true, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, true, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, true, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, true, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, true, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, true, false, args, true);
|
||||
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, false, false, args, true);
|
||||
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, false, false, args, true);
|
||||
|
||||
// render translucent meshes afterwards
|
||||
//DependencyManager::get<TextureCache>()->setPrimaryDrawBuffers(false, true, true);
|
||||
|
@ -834,14 +859,14 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
|||
|
||||
int translucentMeshPartsRendered = 0;
|
||||
const float MOSTLY_OPAQUE_THRESHOLD = 0.75f;
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, true, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, true, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, true, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, true, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, true, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, true, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, true, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, true, false, args, true);
|
||||
|
||||
{
|
||||
GLenum buffers[1];
|
||||
|
@ -855,14 +880,14 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
|||
// batch.setFramebuffer(DependencyManager::get<TextureCache>()->getPrimaryTransparentFramebuffer());
|
||||
|
||||
const float MOSTLY_TRANSPARENT_THRESHOLD = 0.0f;
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, true, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, true, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, true, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, true, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, true, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, true, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, true, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, false, false, args, true);
|
||||
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, true, false, args, true);
|
||||
|
||||
// batch.setFramebuffer(DependencyManager::get<TextureCache>()->getPrimaryOpaqueFramebuffer());
|
||||
}
|
||||
|
@ -1110,7 +1135,7 @@ void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bo
|
|||
// if so instructed, keep the current geometry until the new one is loaded
|
||||
_nextBaseGeometry = _nextGeometry = DependencyManager::get<GeometryCache>()->getGeometry(url, fallback, delayLoad);
|
||||
_nextLODHysteresis = NetworkGeometry::NO_HYSTERESIS;
|
||||
if (!retainCurrent || !isActive() || _nextGeometry->isLoaded()) {
|
||||
if (!retainCurrent || !isActive() || (_nextGeometry && _nextGeometry->isLoaded())) {
|
||||
applyNextGeometry();
|
||||
}
|
||||
}
|
||||
|
@ -1873,19 +1898,21 @@ void Model::endScene(RenderMode mode, RenderArgs* args) {
|
|||
int opaqueMeshPartsRendered = 0;
|
||||
|
||||
// now, for each model in the scene, render the mesh portions
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, true, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, true, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, true, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, true, args);
|
||||
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, true, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, true, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, true, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, true, false, args);
|
||||
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, false, false, args);
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, false, false, args);
|
||||
|
||||
opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, false, true, args);
|
||||
|
||||
// render translucent meshes afterwards
|
||||
{
|
||||
|
@ -1898,14 +1925,14 @@ void Model::endScene(RenderMode mode, RenderArgs* args) {
|
|||
|
||||
int translucentParts = 0;
|
||||
const float MOSTLY_OPAQUE_THRESHOLD = 0.75f;
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, true, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, true, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, true, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, true, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, true, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, true, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, true, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, true, false, args);
|
||||
|
||||
|
||||
{
|
||||
|
@ -1921,14 +1948,14 @@ void Model::endScene(RenderMode mode, RenderArgs* args) {
|
|||
// batch.setFramebuffer(DependencyManager::get<TextureCache>()->getPrimaryTransparentFramebuffer());
|
||||
|
||||
const float MOSTLY_TRANSPARENT_THRESHOLD = 0.0f;
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, true, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, true, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, true, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, true, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, true, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, true, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, true, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, false, false, args);
|
||||
translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, true, false, args);
|
||||
|
||||
// batch.setFramebuffer(DependencyManager::get<TextureCache>()->getPrimaryOpaqueFramebuffer());
|
||||
}
|
||||
|
@ -2017,7 +2044,7 @@ bool Model::renderInScene(float alpha, RenderArgs* args) {
|
|||
updateGeometry();
|
||||
simulate(0.0, true);
|
||||
}
|
||||
|
||||
|
||||
renderSetup(args);
|
||||
_modelsInScene.push_back(this);
|
||||
return true;
|
||||
|
@ -2057,8 +2084,8 @@ void Model::segregateMeshGroups() {
|
|||
if (wantDebug) {
|
||||
qCDebug(renderutils) << "materialID:" << materialID << "parts:" << mesh.parts.size();
|
||||
}
|
||||
|
||||
RenderKey key(translucentMesh, hasLightmap, hasTangents, hasSpecular, isSkinned);
|
||||
|
||||
RenderKey key(translucentMesh, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe());
|
||||
|
||||
// reuse or create the bucket corresponding to that key and insert the mesh as unsorted
|
||||
_renderBuckets[key.getRaw()]._unsortedMeshes.insertMulti(materialID, i);
|
||||
|
@ -2067,20 +2094,20 @@ void Model::segregateMeshGroups() {
|
|||
for(auto& b : _renderBuckets) {
|
||||
foreach(auto i, b.second._unsortedMeshes) {
|
||||
b.second._meshes.append(i);
|
||||
b.second._unsortedMeshes.clear();
|
||||
}
|
||||
b.second._unsortedMeshes.clear();
|
||||
}
|
||||
|
||||
_meshGroupsKnown = true;
|
||||
}
|
||||
}
|
||||
|
||||
QVector<int>* Model::pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned) {
|
||||
QVector<int>* Model::pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe) {
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
|
||||
// depending on which parameters we were called with, pick the correct mesh group to render
|
||||
QVector<int>* whichList = NULL;
|
||||
|
||||
RenderKey key(translucent, hasLightmap, hasTangents, hasSpecular, isSkinned);
|
||||
RenderKey key(translucent, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe);
|
||||
|
||||
auto bucket = _renderBuckets.find(key.getRaw());
|
||||
if (bucket != _renderBuckets.end()) {
|
||||
|
@ -2091,10 +2118,10 @@ QVector<int>* Model::pickMeshList(bool translucent, float alphaThreshold, bool h
|
|||
}
|
||||
|
||||
void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args,
|
||||
Locations*& locations) {
|
||||
|
||||
RenderKey key(mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned);
|
||||
RenderKey key(mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe);
|
||||
auto pipeline = _renderPipelineLib.find(key.getRaw());
|
||||
if (pipeline == _renderPipelineLib.end()) {
|
||||
qDebug() << "No good, couldn't find a pipeline from the key ?" << key.getRaw();
|
||||
|
@ -2119,7 +2146,7 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f
|
|||
}
|
||||
|
||||
int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args) {
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args) {
|
||||
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
int meshPartsRendered = 0;
|
||||
|
@ -2128,12 +2155,12 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool
|
|||
Locations* locations = nullptr;
|
||||
|
||||
foreach(Model* model, _modelsInScene) {
|
||||
QVector<int>* whichList = model->pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned);
|
||||
QVector<int>* whichList = model->pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe);
|
||||
if (whichList) {
|
||||
QVector<int>& list = *whichList;
|
||||
if (list.size() > 0) {
|
||||
if (pickProgramsNeeded) {
|
||||
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, args, locations);
|
||||
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe, args, locations);
|
||||
pickProgramsNeeded = false;
|
||||
}
|
||||
|
||||
|
@ -2147,14 +2174,14 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool
|
|||
}
|
||||
|
||||
int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args,
|
||||
bool forceRenderSomeMeshes) {
|
||||
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
int meshPartsRendered = 0;
|
||||
|
||||
//Pick the mesh list with the requested render flags
|
||||
QVector<int>* whichList = pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned);
|
||||
QVector<int>* whichList = pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe);
|
||||
if (!whichList) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -2166,9 +2193,9 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl
|
|||
}
|
||||
|
||||
Locations* locations = nullptr;
|
||||
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned,
|
||||
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe,
|
||||
args, locations);
|
||||
meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold,
|
||||
meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold,
|
||||
args, locations, forceRenderSomeMeshes);
|
||||
|
||||
return meshPartsRendered;
|
||||
|
|
|
@ -116,6 +116,9 @@ public:
|
|||
Q_INVOKABLE void setCollisionModelURL(const QUrl& url);
|
||||
const QUrl& getCollisionURL() const { return _collisionUrl; }
|
||||
|
||||
void setIsWireframe(bool isWireframe) { _isWireframe = isWireframe; }
|
||||
bool isWireframe() const { return _isWireframe; }
|
||||
|
||||
/// Sets the distance parameter used for LOD computations.
|
||||
void setLODDistance(float distance) { _lodDistance = distance; }
|
||||
|
||||
|
@ -350,6 +353,7 @@ private:
|
|||
void segregateMeshGroups(); // used to calculate our list of translucent vs opaque meshes
|
||||
|
||||
bool _meshGroupsKnown;
|
||||
bool _isWireframe;
|
||||
|
||||
|
||||
// debug rendering support
|
||||
|
@ -366,23 +370,23 @@ private:
|
|||
// helper functions used by render() or renderInScene()
|
||||
void renderSetup(RenderArgs* args);
|
||||
bool renderCore(float alpha, RenderArgs::RenderMode mode, RenderArgs* args);
|
||||
int renderMeshes(gpu::Batch& batch, RenderArgs::RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args = NULL,
|
||||
int renderMeshes(gpu::Batch& batch, RenderArgs::RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args = NULL,
|
||||
bool forceRenderMeshes = false);
|
||||
|
||||
void setupBatchTransform(gpu::Batch& batch, RenderArgs* args);
|
||||
QVector<int>* pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned);
|
||||
QVector<int>* pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe);
|
||||
|
||||
int renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderArgs::RenderMode mode, bool translucent, float alphaThreshold,
|
||||
RenderArgs* args, Locations* locations,
|
||||
bool forceRenderSomeMeshes = false);
|
||||
|
||||
static void pickPrograms(gpu::Batch& batch, RenderArgs::RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args,
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args,
|
||||
Locations*& locations);
|
||||
|
||||
static int renderMeshesForModelsInScene(gpu::Batch& batch, RenderArgs::RenderMode mode, bool translucent, float alphaThreshold,
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args);
|
||||
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args);
|
||||
|
||||
|
||||
static AbstractViewStateInterface* _viewState;
|
||||
|
@ -400,7 +404,8 @@ private:
|
|||
IS_DEPTH_ONLY_FLAG,
|
||||
IS_SHADOW_FLAG,
|
||||
IS_MIRROR_FLAG, //THis means that the mesh is rendered mirrored, not the same as "Rear view mirror"
|
||||
|
||||
IS_WIREFRAME_FLAG,
|
||||
|
||||
NUM_FLAGS,
|
||||
};
|
||||
|
||||
|
@ -415,7 +420,7 @@ private:
|
|||
IS_DEPTH_ONLY = (1 << IS_DEPTH_ONLY_FLAG),
|
||||
IS_SHADOW = (1 << IS_SHADOW_FLAG),
|
||||
IS_MIRROR = (1 << IS_MIRROR_FLAG),
|
||||
|
||||
IS_WIREFRAME = (1 << IS_WIREFRAME_FLAG),
|
||||
};
|
||||
typedef unsigned short Flags;
|
||||
|
||||
|
@ -433,6 +438,7 @@ private:
|
|||
bool isDepthOnly() const { return isFlag(IS_DEPTH_ONLY); }
|
||||
bool isShadow() const { return isFlag(IS_SHADOW); } // = depth only but with back facing
|
||||
bool isMirror() const { return isFlag(IS_MIRROR); }
|
||||
bool isWireFrame() const { return isFlag(IS_WIREFRAME); }
|
||||
|
||||
Flags _flags = 0;
|
||||
short _spare = 0;
|
||||
|
@ -442,22 +448,24 @@ private:
|
|||
|
||||
RenderKey(
|
||||
bool translucent, bool hasLightmap,
|
||||
bool hasTangents, bool hasSpecular, bool isSkinned) :
|
||||
bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe) :
|
||||
RenderKey( (translucent ? IS_TRANSLUCENT : 0)
|
||||
| (hasLightmap ? HAS_LIGHTMAP : 0)
|
||||
| (hasTangents ? HAS_TANGENTS : 0)
|
||||
| (hasSpecular ? HAS_SPECULAR : 0)
|
||||
| (isSkinned ? IS_SKINNED : 0)
|
||||
| (isWireframe ? IS_WIREFRAME : 0)
|
||||
) {}
|
||||
|
||||
RenderKey(RenderArgs::RenderMode mode,
|
||||
bool translucent, float alphaThreshold, bool hasLightmap,
|
||||
bool hasTangents, bool hasSpecular, bool isSkinned) :
|
||||
bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe) :
|
||||
RenderKey( ((translucent && (alphaThreshold == 0.0f) && (mode != RenderArgs::SHADOW_RENDER_MODE)) ? IS_TRANSLUCENT : 0)
|
||||
| (hasLightmap && (mode != RenderArgs::SHADOW_RENDER_MODE) ? HAS_LIGHTMAP : 0) // Lightmap, tangents and specular don't matter for depthOnly
|
||||
| (hasTangents && (mode != RenderArgs::SHADOW_RENDER_MODE) ? HAS_TANGENTS : 0)
|
||||
| (hasSpecular && (mode != RenderArgs::SHADOW_RENDER_MODE) ? HAS_SPECULAR : 0)
|
||||
| (isSkinned ? IS_SKINNED : 0)
|
||||
| (isWireframe ? IS_WIREFRAME : 0)
|
||||
| ((mode == RenderArgs::SHADOW_RENDER_MODE) ? IS_DEPTH_ONLY : 0)
|
||||
| ((mode == RenderArgs::SHADOW_RENDER_MODE) ? IS_SHADOW : 0)
|
||||
| ((mode == RenderArgs::MIRROR_RENDER_MODE) ? IS_MIRROR :0)
|
||||
|
|
|
@ -294,7 +294,7 @@ GLuint TextureCache::getShadowDepthTextureID() {
|
|||
|
||||
/// Returns a texture version of an image file
|
||||
gpu::TexturePointer TextureCache::getImageTexture(const QString & path) {
|
||||
QImage image(path);
|
||||
QImage image = QImage(path).mirrored(false, true);
|
||||
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, gpu::RGB);
|
||||
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::UINT8, gpu::RGB);
|
||||
if (image.hasAlphaChannel()) {
|
||||
|
|
|
@ -22,10 +22,60 @@ public:
|
|||
enum RenderSide { MONO, STEREO_LEFT, STEREO_RIGHT };
|
||||
|
||||
enum DebugFlags {
|
||||
RENDER_DEBUG_NONE=0,
|
||||
RENDER_DEBUG_HULLS=1,
|
||||
RENDER_DEBUG_SIMULATION_OWNERSHIP=2
|
||||
RENDER_DEBUG_NONE = 0,
|
||||
RENDER_DEBUG_HULLS = 1,
|
||||
RENDER_DEBUG_SIMULATION_OWNERSHIP = 2,
|
||||
};
|
||||
|
||||
RenderArgs(OctreeRenderer* renderer = nullptr,
|
||||
ViewFrustum* viewFrustum = nullptr,
|
||||
float sizeScale = 1.0f,
|
||||
int boundaryLevelAdjust = 0,
|
||||
RenderMode renderMode = DEFAULT_RENDER_MODE,
|
||||
RenderSide renderSide = MONO,
|
||||
DebugFlags debugFlags = RENDER_DEBUG_NONE,
|
||||
|
||||
int elementsTouched = 0,
|
||||
int itemsRendered = 0,
|
||||
int itemsOutOfView = 0,
|
||||
int itemsTooSmall = 0,
|
||||
|
||||
int meshesConsidered = 0,
|
||||
int meshesRendered = 0,
|
||||
int meshesOutOfView = 0,
|
||||
int meshesTooSmall = 0,
|
||||
|
||||
int materialSwitches = 0,
|
||||
int trianglesRendered = 0,
|
||||
int quadsRendered = 0,
|
||||
|
||||
int translucentMeshPartsRendered = 0,
|
||||
int opaqueMeshPartsRendered = 0) :
|
||||
_renderer(renderer),
|
||||
_viewFrustum(viewFrustum),
|
||||
_sizeScale(sizeScale),
|
||||
_boundaryLevelAdjust(boundaryLevelAdjust),
|
||||
_renderMode(renderMode),
|
||||
_renderSide(renderSide),
|
||||
_debugFlags(debugFlags),
|
||||
|
||||
_elementsTouched(elementsTouched),
|
||||
_itemsRendered(itemsRendered),
|
||||
_itemsOutOfView(itemsOutOfView),
|
||||
_itemsTooSmall(itemsTooSmall),
|
||||
|
||||
_meshesConsidered(meshesConsidered),
|
||||
_meshesRendered(meshesRendered),
|
||||
_meshesOutOfView(meshesOutOfView),
|
||||
_meshesTooSmall(meshesTooSmall),
|
||||
|
||||
_materialSwitches(materialSwitches),
|
||||
_trianglesRendered(trianglesRendered),
|
||||
_quadsRendered(quadsRendered),
|
||||
|
||||
_translucentMeshPartsRendered(translucentMeshPartsRendered),
|
||||
_opaqueMeshPartsRendered(opaqueMeshPartsRendered) {
|
||||
}
|
||||
|
||||
OctreeRenderer* _renderer;
|
||||
ViewFrustum* _viewFrustum;
|
||||
|
|
|
@ -23,11 +23,19 @@
|
|||
|
||||
const int BYTES_PER_COLOR = 3;
|
||||
const int BYTES_PER_FLAGS = 1;
|
||||
typedef unsigned char rgbColor[BYTES_PER_COLOR];
|
||||
typedef unsigned char colorPart;
|
||||
typedef unsigned char nodeColor[BYTES_PER_COLOR + BYTES_PER_FLAGS];
|
||||
typedef unsigned char rgbColor[BYTES_PER_COLOR];
|
||||
|
||||
inline QDebug& operator<<(QDebug& dbg, const rgbColor& c) {
|
||||
dbg.nospace() << "{type='rgbColor'"
|
||||
", red=" << c[0] <<
|
||||
", green=" << c[1] <<
|
||||
", blue=" << c[2] <<
|
||||
"}";
|
||||
return dbg;
|
||||
}
|
||||
|
||||
struct xColor {
|
||||
unsigned char red;
|
||||
unsigned char green;
|
||||
|
|
Loading…
Reference in a new issue