Merge pull request #5551 from sethalves/quiet-compiler

Quiet compiler
This commit is contained in:
Andrew Meadows 2015-08-18 09:54:29 -07:00
commit 9ee49c3e1e
7 changed files with 513 additions and 515 deletions

View file

@ -154,9 +154,9 @@ public:
DEFINE_PROPERTY_REF(PROP_HREF, Href, href, QString); DEFINE_PROPERTY_REF(PROP_HREF, Href, href, QString);
DEFINE_PROPERTY_REF(PROP_DESCRIPTION, Description, description, QString); DEFINE_PROPERTY_REF(PROP_DESCRIPTION, Description, description, QString);
DEFINE_PROPERTY(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool); DEFINE_PROPERTY(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool);
DEFINE_PROPERTY_REF(PROP_ACTION_DATA, ActionData, actionData, QByteArray);
DEFINE_PROPERTY(PROP_NORMALS, Normals, normals, QVector<glm::vec3>); DEFINE_PROPERTY(PROP_NORMALS, Normals, normals, QVector<glm::vec3>);
DEFINE_PROPERTY(PROP_STROKE_WIDTHS, StrokeWidths, strokeWidths, QVector<float>); DEFINE_PROPERTY(PROP_STROKE_WIDTHS, StrokeWidths, strokeWidths, QVector<float>);
DEFINE_PROPERTY_REF(PROP_ACTION_DATA, ActionData, actionData, QByteArray);
DEFINE_PROPERTY_REF(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString); DEFINE_PROPERTY_REF(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString);
DEFINE_PROPERTY_REF(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString); DEFINE_PROPERTY_REF(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString);
DEFINE_PROPERTY_REF(PROP_Z_TEXTURE_URL, ZTextureURL, zTextureURL, QString); DEFINE_PROPERTY_REF(PROP_Z_TEXTURE_URL, ZTextureURL, zTextureURL, QString);

View file

@ -170,9 +170,10 @@ bool PolyLineEntityItem::setLinePoints(const QVector<glm::vec3>& points) {
for (int i = 0; i < points.size(); i++) { for (int i = 0; i < points.size(); i++) {
glm::vec3 point = points.at(i); glm::vec3 point = points.at(i);
glm::vec3 pos = getPosition();
glm::vec3 halfBox = getDimensions() * 0.5f; glm::vec3 halfBox = getDimensions() * 0.5f;
if ( (point.x < - halfBox.x || point.x > halfBox.x) || (point.y < -halfBox.y || point.y > halfBox.y) || (point.z < - halfBox.z || point.z > halfBox.z) ) { if ((point.x < - halfBox.x || point.x > halfBox.x) ||
(point.y < -halfBox.y || point.y > halfBox.y) ||
(point.z < - halfBox.z || point.z > halfBox.z)) {
qDebug() << "Point is outside entity's bounding box"; qDebug() << "Point is outside entity's bounding box";
return false; return false;
} }

View file

@ -1108,11 +1108,10 @@ ExtractedMesh extractMesh(const FBXNode& object, unsigned int& meshIndex) {
if (subdata.name == "Materials") { if (subdata.name == "Materials") {
materials = getIntVector(subdata); materials = getIntVector(subdata);
} else if (subdata.name == "MappingInformationType") { } else if (subdata.name == "MappingInformationType") {
if (subdata.properties.at(0) == "ByPolygon") { if (subdata.properties.at(0) == "ByPolygon")
isMaterialPerPolygon = true; isMaterialPerPolygon = true;
} else { } else {
isMaterialPerPolygon = false; isMaterialPerPolygon = false;
}
} }
} }
@ -1126,7 +1125,6 @@ ExtractedMesh extractMesh(const FBXNode& object, unsigned int& meshIndex) {
} }
} }
bool isMultiMaterial = false; bool isMultiMaterial = false;
if (isMaterialPerPolygon) { if (isMaterialPerPolygon) {
isMultiMaterial = true; isMultiMaterial = true;

View file

@ -1,408 +1,408 @@
// //
// State // State
// libraries/gpu/src/gpu // libraries/gpu/src/gpu
// //
// Created by Sam Gateau on 3/8/2015. // Created by Sam Gateau on 3/8/2015.
// Copyright 2014 High Fidelity, Inc. // Copyright 2014 High Fidelity, Inc.
// //
// Distributed under the Apache License, Version 2.0. // Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#ifndef hifi_gpu_State_h #ifndef hifi_gpu_State_h
#define hifi_gpu_State_h #define hifi_gpu_State_h
#include "Format.h" #include "Format.h"
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <unordered_map> #include <unordered_map>
#include <bitset> #include <bitset>
// Why a macro and not a fancy template you will ask me ? // Why a macro and not a fancy template you will ask me ?
// Because some of the fields are bool packed tightly in the State::Cache class // Because some of the fields are bool packed tightly in the State::Cache class
// and it s just not good anymore for template T& variable manipulation... // and it s just not good anymore for template T& variable manipulation...
#define SET_FIELD(field, defaultValue, value, dest) {\ #define SET_FIELD(field, defaultValue, value, dest) {\
dest = value;\ dest = value;\
if (value == defaultValue) {\ if (value == defaultValue) {\
_signature.reset(field);\ _signature.reset(field);\
} else {\ } else {\
_signature.set(field);\ _signature.set(field);\
}\ }\
_stamp++;\ _stamp++;\
}\ }\
namespace gpu { namespace gpu {
class GPUObject; class GPUObject;
class State { class State {
public: public:
State(); State();
virtual ~State(); virtual ~State();
Stamp getStamp() const { return _stamp; } Stamp getStamp() const { return _stamp; }
typedef ::gpu::ComparisonFunction ComparisonFunction; typedef ::gpu::ComparisonFunction ComparisonFunction;
enum FillMode { enum FillMode {
FILL_POINT = 0, FILL_POINT = 0,
FILL_LINE, FILL_LINE,
FILL_FACE, FILL_FACE,
NUM_FILL_MODES, NUM_FILL_MODES,
}; };
enum CullMode { enum CullMode {
CULL_NONE = 0, CULL_NONE = 0,
CULL_FRONT, CULL_FRONT,
CULL_BACK, CULL_BACK,
NUM_CULL_MODES, NUM_CULL_MODES,
}; };
enum StencilOp { enum StencilOp {
STENCIL_OP_KEEP = 0, STENCIL_OP_KEEP = 0,
STENCIL_OP_ZERO, STENCIL_OP_ZERO,
STENCIL_OP_REPLACE, STENCIL_OP_REPLACE,
STENCIL_OP_INCR_SAT, STENCIL_OP_INCR_SAT,
STENCIL_OP_DECR_SAT, STENCIL_OP_DECR_SAT,
STENCIL_OP_INVERT, STENCIL_OP_INVERT,
STENCIL_OP_INCR, STENCIL_OP_INCR,
STENCIL_OP_DECR, STENCIL_OP_DECR,
NUM_STENCIL_OPS, NUM_STENCIL_OPS,
}; };
enum BlendArg { enum BlendArg {
ZERO = 0, ZERO = 0,
ONE, ONE,
SRC_COLOR, SRC_COLOR,
INV_SRC_COLOR, INV_SRC_COLOR,
SRC_ALPHA, SRC_ALPHA,
INV_SRC_ALPHA, INV_SRC_ALPHA,
DEST_ALPHA, DEST_ALPHA,
INV_DEST_ALPHA, INV_DEST_ALPHA,
DEST_COLOR, DEST_COLOR,
INV_DEST_COLOR, INV_DEST_COLOR,
SRC_ALPHA_SAT, SRC_ALPHA_SAT,
FACTOR_COLOR, FACTOR_COLOR,
INV_FACTOR_COLOR, INV_FACTOR_COLOR,
FACTOR_ALPHA, FACTOR_ALPHA,
INV_FACTOR_ALPHA, INV_FACTOR_ALPHA,
NUM_BLEND_ARGS, NUM_BLEND_ARGS,
}; };
enum BlendOp { enum BlendOp {
BLEND_OP_ADD = 0, BLEND_OP_ADD = 0,
BLEND_OP_SUBTRACT, BLEND_OP_SUBTRACT,
BLEND_OP_REV_SUBTRACT, BLEND_OP_REV_SUBTRACT,
BLEND_OP_MIN, BLEND_OP_MIN,
BLEND_OP_MAX, BLEND_OP_MAX,
NUM_BLEND_OPS, NUM_BLEND_OPS,
}; };
enum ColorMask enum ColorMask
{ {
WRITE_NONE = 0, WRITE_NONE = 0,
WRITE_RED = 1, WRITE_RED = 1,
WRITE_GREEN = 2, WRITE_GREEN = 2,
WRITE_BLUE = 4, WRITE_BLUE = 4,
WRITE_ALPHA = 8, WRITE_ALPHA = 8,
WRITE_ALL = (WRITE_RED | WRITE_GREEN | WRITE_BLUE | WRITE_ALPHA ), WRITE_ALL = (WRITE_RED | WRITE_GREEN | WRITE_BLUE | WRITE_ALPHA ),
}; };
class DepthTest { class DepthTest {
uint8 _function = LESS; uint8 _function = LESS;
uint8 _writeMask = true; uint8 _writeMask = true;
uint8 _enabled = false; uint8 _enabled = false;
uint8 _spare = 0; uint8 _spare = 0;
public: public:
DepthTest(bool enabled = false, bool writeMask = true, ComparisonFunction func = LESS) : DepthTest(bool enabled = false, bool writeMask = true, ComparisonFunction func = LESS) :
_function(func), _writeMask(writeMask), _enabled(enabled) {} _function(func), _writeMask(writeMask), _enabled(enabled) {}
bool isEnabled() const { return _enabled; } bool isEnabled() const { return _enabled != 0; }
ComparisonFunction getFunction() const { return ComparisonFunction(_function); } ComparisonFunction getFunction() const { return ComparisonFunction(_function); }
bool getWriteMask() const { return _writeMask; } uint8 getWriteMask() const { return _writeMask; }
int32 getRaw() const { return *(reinterpret_cast<const int32*>(this)); } int32 getRaw() const { return *(reinterpret_cast<const int32*>(this)); }
DepthTest(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; } DepthTest(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; }
bool operator== (const DepthTest& right) const { return getRaw() == right.getRaw(); } bool operator== (const DepthTest& right) const { return getRaw() == right.getRaw(); }
bool operator!= (const DepthTest& right) const { return getRaw() != right.getRaw(); } bool operator!= (const DepthTest& right) const { return getRaw() != right.getRaw(); }
}; };
class StencilTest { class StencilTest {
static const int FUNC_MASK = 0x000f; static const int FUNC_MASK = 0x000f;
static const int FAIL_OP_MASK = 0x00f0; static const int FAIL_OP_MASK = 0x00f0;
static const int DEPTH_FAIL_OP_MASK = 0x0f00; static const int DEPTH_FAIL_OP_MASK = 0x0f00;
static const int PASS_OP_MASK = 0xf000; static const int PASS_OP_MASK = 0xf000;
static const int FAIL_OP_OFFSET = 4; static const int FAIL_OP_OFFSET = 4;
static const int DEPTH_FAIL_OP_OFFSET = 8; static const int DEPTH_FAIL_OP_OFFSET = 8;
static const int PASS_OP_OFFSET = 12; static const int PASS_OP_OFFSET = 12;
uint16 _functionAndOperations; uint16 _functionAndOperations;
uint8 _reference = 0; uint8 _reference = 0;
uint8 _readMask = 0xff; uint8 _readMask = 0xff;
public: public:
StencilTest(uint8 reference = 0, uint8 readMask =0xFF, ComparisonFunction func = ALWAYS, StencilOp failOp = STENCIL_OP_KEEP, StencilOp depthFailOp = STENCIL_OP_KEEP, StencilOp passOp = STENCIL_OP_KEEP) : StencilTest(uint8 reference = 0, uint8 readMask =0xFF, ComparisonFunction func = ALWAYS, StencilOp failOp = STENCIL_OP_KEEP, StencilOp depthFailOp = STENCIL_OP_KEEP, StencilOp passOp = STENCIL_OP_KEEP) :
_functionAndOperations(func | (failOp << FAIL_OP_OFFSET) | (depthFailOp << DEPTH_FAIL_OP_OFFSET) | (passOp << PASS_OP_OFFSET)), _functionAndOperations(func | (failOp << FAIL_OP_OFFSET) | (depthFailOp << DEPTH_FAIL_OP_OFFSET) | (passOp << PASS_OP_OFFSET)),
_reference(reference), _readMask(readMask) _reference(reference), _readMask(readMask)
{} {}
ComparisonFunction getFunction() const { return ComparisonFunction(_functionAndOperations & FUNC_MASK); } ComparisonFunction getFunction() const { return ComparisonFunction(_functionAndOperations & FUNC_MASK); }
StencilOp getFailOp() const { return StencilOp((_functionAndOperations & FAIL_OP_MASK) >> FAIL_OP_OFFSET); } StencilOp getFailOp() const { return StencilOp((_functionAndOperations & FAIL_OP_MASK) >> FAIL_OP_OFFSET); }
StencilOp getDepthFailOp() const { return StencilOp((_functionAndOperations & DEPTH_FAIL_OP_MASK) >> DEPTH_FAIL_OP_OFFSET); } StencilOp getDepthFailOp() const { return StencilOp((_functionAndOperations & DEPTH_FAIL_OP_MASK) >> DEPTH_FAIL_OP_OFFSET); }
StencilOp getPassOp() const { return StencilOp((_functionAndOperations & PASS_OP_MASK) >> PASS_OP_OFFSET); } StencilOp getPassOp() const { return StencilOp((_functionAndOperations & PASS_OP_MASK) >> PASS_OP_OFFSET); }
uint8 getReference() const { return _reference; } uint8 getReference() const { return _reference; }
uint8 getReadMask() const { return _readMask; } uint8 getReadMask() const { return _readMask; }
int32 getRaw() const { return *(reinterpret_cast<const int32*>(this)); } int32 getRaw() const { return *(reinterpret_cast<const int32*>(this)); }
StencilTest(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; } StencilTest(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; }
bool operator== (const StencilTest& right) const { return getRaw() == right.getRaw(); } bool operator== (const StencilTest& right) const { return getRaw() == right.getRaw(); }
bool operator!= (const StencilTest& right) const { return getRaw() != right.getRaw(); } bool operator!= (const StencilTest& right) const { return getRaw() != right.getRaw(); }
}; };
class StencilActivation { class StencilActivation {
uint8 _frontWriteMask = 0xFF; uint8 _frontWriteMask = 0xFF;
uint8 _backWriteMask = 0xFF; uint8 _backWriteMask = 0xFF;
uint16 _enabled = 0; uint16 _enabled = 0;
public: public:
StencilActivation(bool enabled, uint8 frontWriteMask = 0xFF, uint8 backWriteMask = 0xFF) : StencilActivation(bool enabled, uint8 frontWriteMask = 0xFF, uint8 backWriteMask = 0xFF) :
_frontWriteMask(frontWriteMask), _backWriteMask(backWriteMask), _enabled(enabled) {} _frontWriteMask(frontWriteMask), _backWriteMask(backWriteMask), _enabled(enabled) {}
bool isEnabled() const { return (_enabled != 0); } bool isEnabled() const { return (_enabled != 0); }
uint8 getWriteMaskFront() const { return _frontWriteMask; } uint8 getWriteMaskFront() const { return _frontWriteMask; }
uint8 getWriteMaskBack() const { return _backWriteMask; } uint8 getWriteMaskBack() const { return _backWriteMask; }
int32 getRaw() const { return *(reinterpret_cast<const int32*>(this)); } int32 getRaw() const { return *(reinterpret_cast<const int32*>(this)); }
StencilActivation(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; } StencilActivation(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; }
bool operator== (const StencilActivation& right) const { return getRaw() == right.getRaw(); } bool operator== (const StencilActivation& right) const { return getRaw() == right.getRaw(); }
bool operator!= (const StencilActivation& right) const { return getRaw() != right.getRaw(); } bool operator!= (const StencilActivation& right) const { return getRaw() != right.getRaw(); }
}; };
class BlendFunction { class BlendFunction {
static const int COLOR_MASK = 0x0f; static const int COLOR_MASK = 0x0f;
static const int ALPHA_MASK = 0xf0; static const int ALPHA_MASK = 0xf0;
static const int ALPHA_OFFSET = 4; static const int ALPHA_OFFSET = 4;
uint8 _enabled; uint8 _enabled;
uint8 _source; uint8 _source;
uint8 _destination; uint8 _destination;
uint8 _operation; uint8 _operation;
public: public:
BlendFunction(bool enabled, BlendFunction(bool enabled,
BlendArg sourceColor, BlendOp operationColor, BlendArg destinationColor, BlendArg sourceColor, BlendOp operationColor, BlendArg destinationColor,
BlendArg sourceAlpha, BlendOp operationAlpha, BlendArg destinationAlpha) : BlendArg sourceAlpha, BlendOp operationAlpha, BlendArg destinationAlpha) :
_enabled(enabled), _enabled(enabled),
_source(sourceColor | (sourceAlpha << ALPHA_OFFSET)), _source(sourceColor | (sourceAlpha << ALPHA_OFFSET)),
_destination(destinationColor | (destinationAlpha << ALPHA_OFFSET)), _destination(destinationColor | (destinationAlpha << ALPHA_OFFSET)),
_operation(operationColor | (operationAlpha << ALPHA_OFFSET)) {} _operation(operationColor | (operationAlpha << ALPHA_OFFSET)) {}
BlendFunction(bool enabled, BlendArg source = ONE, BlendOp operation = BLEND_OP_ADD, BlendArg destination = ZERO) : BlendFunction(bool enabled, BlendArg source = ONE, BlendOp operation = BLEND_OP_ADD, BlendArg destination = ZERO) :
_enabled(enabled), _enabled(enabled),
_source(source | (source << ALPHA_OFFSET)), _source(source | (source << ALPHA_OFFSET)),
_destination(destination | (destination << ALPHA_OFFSET)), _destination(destination | (destination << ALPHA_OFFSET)),
_operation(operation | (operation << ALPHA_OFFSET)) {} _operation(operation | (operation << ALPHA_OFFSET)) {}
bool isEnabled() const { return (_enabled != 0); } bool isEnabled() const { return (_enabled != 0); }
BlendArg getSourceColor() const { return BlendArg(_source & COLOR_MASK); } BlendArg getSourceColor() const { return BlendArg(_source & COLOR_MASK); }
BlendArg getDestinationColor() const { return BlendArg(_destination & COLOR_MASK); } BlendArg getDestinationColor() const { return BlendArg(_destination & COLOR_MASK); }
BlendOp getOperationColor() const { return BlendOp(_operation & COLOR_MASK); } BlendOp getOperationColor() const { return BlendOp(_operation & COLOR_MASK); }
BlendArg getSourceAlpha() const { return BlendArg((_source & ALPHA_MASK) >> ALPHA_OFFSET); } BlendArg getSourceAlpha() const { return BlendArg((_source & ALPHA_MASK) >> ALPHA_OFFSET); }
BlendArg getDestinationAlpha() const { return BlendArg((_destination & ALPHA_MASK) >> ALPHA_OFFSET); } BlendArg getDestinationAlpha() const { return BlendArg((_destination & ALPHA_MASK) >> ALPHA_OFFSET); }
BlendOp getOperationAlpha() const { return BlendOp((_operation & ALPHA_MASK) >> ALPHA_OFFSET); } BlendOp getOperationAlpha() const { return BlendOp((_operation & ALPHA_MASK) >> ALPHA_OFFSET); }
int32 getRaw() const { return *(reinterpret_cast<const int32*>(this)); } int32 getRaw() const { return *(reinterpret_cast<const int32*>(this)); }
BlendFunction(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; } BlendFunction(int32 raw) { *(reinterpret_cast<int32*>(this)) = raw; }
bool operator== (const BlendFunction& right) const { return getRaw() == right.getRaw(); } bool operator== (const BlendFunction& right) const { return getRaw() == right.getRaw(); }
bool operator!= (const BlendFunction& right) const { return getRaw() != right.getRaw(); } bool operator!= (const BlendFunction& right) const { return getRaw() != right.getRaw(); }
}; };
// The Data class is the full explicit description of the State class fields value. // The Data class is the full explicit description of the State class fields value.
// Useful for having one const static called Default for reference or for the gpu::Backend to keep track of the current value // Useful for having one const static called Default for reference or for the gpu::Backend to keep track of the current value
class Data { class Data {
public: public:
float depthBias = 0.0f; float depthBias = 0.0f;
float depthBiasSlopeScale = 0.0f; float depthBiasSlopeScale = 0.0f;
DepthTest depthTest = DepthTest(false, true, LESS); DepthTest depthTest = DepthTest(false, true, LESS);
StencilActivation stencilActivation = StencilActivation(false); StencilActivation stencilActivation = StencilActivation(false);
StencilTest stencilTestFront = StencilTest(0, 0xff, ALWAYS, STENCIL_OP_KEEP, STENCIL_OP_KEEP, STENCIL_OP_KEEP); StencilTest stencilTestFront = StencilTest(0, 0xff, ALWAYS, STENCIL_OP_KEEP, STENCIL_OP_KEEP, STENCIL_OP_KEEP);
StencilTest stencilTestBack = StencilTest(0, 0xff, ALWAYS, STENCIL_OP_KEEP, STENCIL_OP_KEEP, STENCIL_OP_KEEP); StencilTest stencilTestBack = StencilTest(0, 0xff, ALWAYS, STENCIL_OP_KEEP, STENCIL_OP_KEEP, STENCIL_OP_KEEP);
uint32 sampleMask = 0xFFFFFFFF; uint32 sampleMask = 0xFFFFFFFF;
BlendFunction blendFunction = BlendFunction(false); BlendFunction blendFunction = BlendFunction(false);
uint8 fillMode = FILL_FACE; uint8 fillMode = FILL_FACE;
uint8 cullMode = CULL_NONE; uint8 cullMode = CULL_NONE;
uint8 colorWriteMask = WRITE_ALL; uint8 colorWriteMask = WRITE_ALL;
bool frontFaceClockwise : 1; bool frontFaceClockwise : 1;
bool depthClampEnable : 1; bool depthClampEnable : 1;
bool scissorEnable : 1; bool scissorEnable : 1;
bool multisampleEnable : 1; bool multisampleEnable : 1;
bool antialisedLineEnable : 1; bool antialisedLineEnable : 1;
bool alphaToCoverageEnable : 1; bool alphaToCoverageEnable : 1;
Data() : Data() :
frontFaceClockwise(false), frontFaceClockwise(false),
depthClampEnable(false), depthClampEnable(false),
scissorEnable(false), scissorEnable(false),
multisampleEnable(false), multisampleEnable(false),
antialisedLineEnable(true), antialisedLineEnable(true),
alphaToCoverageEnable(false) alphaToCoverageEnable(false)
{} {}
}; };
// The unique default values for all the fields // The unique default values for all the fields
static const Data DEFAULT; static const Data DEFAULT;
void setFillMode(FillMode fill) { SET_FIELD(FILL_MODE, DEFAULT.fillMode, fill, _values.fillMode); } void setFillMode(FillMode fill) { SET_FIELD(FILL_MODE, DEFAULT.fillMode, fill, _values.fillMode); }
FillMode getFillMode() const { return FillMode(_values.fillMode); } FillMode getFillMode() const { return FillMode(_values.fillMode); }
void setCullMode(CullMode cull) { SET_FIELD(CULL_MODE, DEFAULT.cullMode, cull, _values.cullMode); } void setCullMode(CullMode cull) { SET_FIELD(CULL_MODE, DEFAULT.cullMode, cull, _values.cullMode); }
CullMode getCullMode() const { return CullMode(_values.cullMode); } CullMode getCullMode() const { return CullMode(_values.cullMode); }
void setFrontFaceClockwise(bool isClockwise) { SET_FIELD(FRONT_FACE_CLOCKWISE, DEFAULT.frontFaceClockwise, isClockwise, _values.frontFaceClockwise); } void setFrontFaceClockwise(bool isClockwise) { SET_FIELD(FRONT_FACE_CLOCKWISE, DEFAULT.frontFaceClockwise, isClockwise, _values.frontFaceClockwise); }
bool isFrontFaceClockwise() const { return _values.frontFaceClockwise; } bool isFrontFaceClockwise() const { return _values.frontFaceClockwise; }
void setDepthClampEnable(bool enable) { SET_FIELD(DEPTH_CLAMP_ENABLE, DEFAULT.depthClampEnable, enable, _values.depthClampEnable); } void setDepthClampEnable(bool enable) { SET_FIELD(DEPTH_CLAMP_ENABLE, DEFAULT.depthClampEnable, enable, _values.depthClampEnable); }
bool isDepthClampEnable() const { return _values.depthClampEnable; } bool isDepthClampEnable() const { return _values.depthClampEnable; }
void setScissorEnable(bool enable) { SET_FIELD(SCISSOR_ENABLE, DEFAULT.scissorEnable, enable, _values.scissorEnable); } void setScissorEnable(bool enable) { SET_FIELD(SCISSOR_ENABLE, DEFAULT.scissorEnable, enable, _values.scissorEnable); }
bool isScissorEnable() const { return _values.scissorEnable; } bool isScissorEnable() const { return _values.scissorEnable; }
void setMultisampleEnable(bool enable) { SET_FIELD(MULTISAMPLE_ENABLE, DEFAULT.multisampleEnable, enable, _values.multisampleEnable); } void setMultisampleEnable(bool enable) { SET_FIELD(MULTISAMPLE_ENABLE, DEFAULT.multisampleEnable, enable, _values.multisampleEnable); }
bool isMultisampleEnable() const { return _values.multisampleEnable; } bool isMultisampleEnable() const { return _values.multisampleEnable; }
void setAntialiasedLineEnable(bool enable) { SET_FIELD(ANTIALISED_LINE_ENABLE, DEFAULT.antialisedLineEnable, enable, _values.antialisedLineEnable); } void setAntialiasedLineEnable(bool enable) { SET_FIELD(ANTIALISED_LINE_ENABLE, DEFAULT.antialisedLineEnable, enable, _values.antialisedLineEnable); }
bool isAntialiasedLineEnable() const { return _values.antialisedLineEnable; } bool isAntialiasedLineEnable() const { return _values.antialisedLineEnable; }
// Depth Bias // Depth Bias
void setDepthBias(float bias) { SET_FIELD(DEPTH_BIAS, DEFAULT.depthBias, bias, _values.depthBias); } void setDepthBias(float bias) { SET_FIELD(DEPTH_BIAS, DEFAULT.depthBias, bias, _values.depthBias); }
float getDepthBias() const { return _values.depthBias; } float getDepthBias() const { return _values.depthBias; }
void setDepthBiasSlopeScale(float scale) { SET_FIELD(DEPTH_BIAS_SLOPE_SCALE, DEFAULT.depthBiasSlopeScale, scale, _values.depthBiasSlopeScale); } void setDepthBiasSlopeScale(float scale) { SET_FIELD(DEPTH_BIAS_SLOPE_SCALE, DEFAULT.depthBiasSlopeScale, scale, _values.depthBiasSlopeScale); }
float getDepthBiasSlopeScale() const { return _values.depthBiasSlopeScale; } float getDepthBiasSlopeScale() const { return _values.depthBiasSlopeScale; }
// Depth Test // Depth Test
void setDepthTest(DepthTest depthTest) { SET_FIELD(DEPTH_TEST, DEFAULT.depthTest, depthTest, _values.depthTest); } void setDepthTest(DepthTest depthTest) { SET_FIELD(DEPTH_TEST, DEFAULT.depthTest, depthTest, _values.depthTest); }
void setDepthTest(bool enable, bool writeMask, ComparisonFunction func) { setDepthTest(DepthTest(enable, writeMask, func)); } void setDepthTest(bool enable, bool writeMask, ComparisonFunction func) { setDepthTest(DepthTest(enable, writeMask, func)); }
DepthTest getDepthTest() const { return _values.depthTest; } DepthTest getDepthTest() const { return _values.depthTest; }
bool isDepthTestEnabled() const { return getDepthTest().isEnabled(); } bool isDepthTestEnabled() const { return getDepthTest().isEnabled(); }
bool getDepthTestWriteMask() const { return getDepthTest().getWriteMask(); } uint8 getDepthTestWriteMask() const { return getDepthTest().getWriteMask(); }
ComparisonFunction getDepthTestFunc() const { return getDepthTest().getFunction(); } ComparisonFunction getDepthTestFunc() const { return getDepthTest().getFunction(); }
// Stencil test // Stencil test
void setStencilTest(bool enabled, uint8 frontWriteMask, StencilTest frontTest, uint8 backWriteMask, StencilTest backTest) { void setStencilTest(bool enabled, uint8 frontWriteMask, StencilTest frontTest, uint8 backWriteMask, StencilTest backTest) {
SET_FIELD(STENCIL_ACTIVATION, DEFAULT.stencilActivation, StencilActivation(enabled, frontWriteMask, backWriteMask), _values.stencilActivation); SET_FIELD(STENCIL_ACTIVATION, DEFAULT.stencilActivation, StencilActivation(enabled, frontWriteMask, backWriteMask), _values.stencilActivation);
SET_FIELD(STENCIL_TEST_FRONT, DEFAULT.stencilTestFront, frontTest, _values.stencilTestFront); SET_FIELD(STENCIL_TEST_FRONT, DEFAULT.stencilTestFront, frontTest, _values.stencilTestFront);
SET_FIELD(STENCIL_TEST_BACK, DEFAULT.stencilTestBack, backTest, _values.stencilTestBack); } SET_FIELD(STENCIL_TEST_BACK, DEFAULT.stencilTestBack, backTest, _values.stencilTestBack); }
void setStencilTest(bool enabled, uint8 frontWriteMask, StencilTest frontTest) { void setStencilTest(bool enabled, uint8 frontWriteMask, StencilTest frontTest) {
setStencilTest(enabled, frontWriteMask, frontTest, frontWriteMask, frontTest); } setStencilTest(enabled, frontWriteMask, frontTest, frontWriteMask, frontTest); }
StencilActivation getStencilActivation() const { return _values.stencilActivation; } StencilActivation getStencilActivation() const { return _values.stencilActivation; }
StencilTest getStencilTestFront() const { return _values.stencilTestFront; } StencilTest getStencilTestFront() const { return _values.stencilTestFront; }
StencilTest getStencilTestBack() const { return _values.stencilTestBack; } StencilTest getStencilTestBack() const { return _values.stencilTestBack; }
bool isStencilEnabled() const { return getStencilActivation().isEnabled(); } bool isStencilEnabled() const { return getStencilActivation().isEnabled(); }
uint8 getStencilWriteMaskFront() const { return getStencilActivation().getWriteMaskFront(); } uint8 getStencilWriteMaskFront() const { return getStencilActivation().getWriteMaskFront(); }
uint8 getStencilWriteMaskBack() const { return getStencilActivation().getWriteMaskBack(); } uint8 getStencilWriteMaskBack() const { return getStencilActivation().getWriteMaskBack(); }
// Alpha to coverage // Alpha to coverage
void setAlphaToCoverageEnable(bool enable) { SET_FIELD(ALPHA_TO_COVERAGE_ENABLE, DEFAULT.alphaToCoverageEnable, enable, _values.alphaToCoverageEnable); } void setAlphaToCoverageEnable(bool enable) { SET_FIELD(ALPHA_TO_COVERAGE_ENABLE, DEFAULT.alphaToCoverageEnable, enable, _values.alphaToCoverageEnable); }
bool isAlphaToCoverageEnabled() const { return _values.alphaToCoverageEnable; } bool isAlphaToCoverageEnabled() const { return _values.alphaToCoverageEnable; }
// Sample mask // Sample mask
void setSampleMask(uint32 mask) { SET_FIELD(SAMPLE_MASK, DEFAULT.sampleMask, mask, _values.sampleMask); } void setSampleMask(uint32 mask) { SET_FIELD(SAMPLE_MASK, DEFAULT.sampleMask, mask, _values.sampleMask); }
uint32 getSampleMask() const { return _values.sampleMask; } uint32 getSampleMask() const { return _values.sampleMask; }
// Blend Function // Blend Function
void setBlendFunction(BlendFunction function) { SET_FIELD(BLEND_FUNCTION, DEFAULT.blendFunction, function, _values.blendFunction); } void setBlendFunction(BlendFunction function) { SET_FIELD(BLEND_FUNCTION, DEFAULT.blendFunction, function, _values.blendFunction); }
BlendFunction getBlendFunction() const { return _values.blendFunction; } BlendFunction getBlendFunction() const { return _values.blendFunction; }
void setBlendFunction(bool enabled, BlendArg sourceColor, BlendOp operationColor, BlendArg destinationColor, BlendArg sourceAlpha, BlendOp operationAlpha, BlendArg destinationAlpha) { void setBlendFunction(bool enabled, BlendArg sourceColor, BlendOp operationColor, BlendArg destinationColor, BlendArg sourceAlpha, BlendOp operationAlpha, BlendArg destinationAlpha) {
setBlendFunction(BlendFunction(enabled, sourceColor, operationColor, destinationColor, sourceAlpha, operationAlpha, destinationAlpha)); } setBlendFunction(BlendFunction(enabled, sourceColor, operationColor, destinationColor, sourceAlpha, operationAlpha, destinationAlpha)); }
void setBlendFunction(bool enabled, BlendArg source, BlendOp operation, BlendArg destination) { void setBlendFunction(bool enabled, BlendArg source, BlendOp operation, BlendArg destination) {
setBlendFunction(BlendFunction(enabled, source, operation, destination)); } setBlendFunction(BlendFunction(enabled, source, operation, destination)); }
bool isBlendEnabled() const { return getBlendFunction().isEnabled(); } bool isBlendEnabled() const { return getBlendFunction().isEnabled(); }
// Color write mask // Color write mask
void setColorWriteMask(uint8 mask) { SET_FIELD(COLOR_WRITE_MASK, DEFAULT.colorWriteMask, mask, _values.colorWriteMask); } void setColorWriteMask(uint8 mask) { SET_FIELD(COLOR_WRITE_MASK, DEFAULT.colorWriteMask, mask, _values.colorWriteMask); }
void setColorWriteMask(bool red, bool green, bool blue, bool alpha) { uint32 value = ((WRITE_RED * red) | (WRITE_GREEN * green) | (WRITE_BLUE * blue) | (WRITE_ALPHA * alpha)); SET_FIELD(COLOR_WRITE_MASK, DEFAULT.colorWriteMask, value, _values.colorWriteMask); } void setColorWriteMask(bool red, bool green, bool blue, bool alpha) { uint32 value = ((WRITE_RED * red) | (WRITE_GREEN * green) | (WRITE_BLUE * blue) | (WRITE_ALPHA * alpha)); SET_FIELD(COLOR_WRITE_MASK, DEFAULT.colorWriteMask, value, _values.colorWriteMask); }
uint8 getColorWriteMask() const { return _values.colorWriteMask; } uint8 getColorWriteMask() const { return _values.colorWriteMask; }
// All the possible fields // All the possible fields
enum Field { enum Field {
FILL_MODE, FILL_MODE,
CULL_MODE, CULL_MODE,
FRONT_FACE_CLOCKWISE, FRONT_FACE_CLOCKWISE,
DEPTH_CLAMP_ENABLE, DEPTH_CLAMP_ENABLE,
SCISSOR_ENABLE, SCISSOR_ENABLE,
MULTISAMPLE_ENABLE, MULTISAMPLE_ENABLE,
ANTIALISED_LINE_ENABLE, ANTIALISED_LINE_ENABLE,
DEPTH_BIAS, DEPTH_BIAS,
DEPTH_BIAS_SLOPE_SCALE, DEPTH_BIAS_SLOPE_SCALE,
DEPTH_TEST, DEPTH_TEST,
STENCIL_ACTIVATION, STENCIL_ACTIVATION,
STENCIL_TEST_FRONT, STENCIL_TEST_FRONT,
STENCIL_TEST_BACK, STENCIL_TEST_BACK,
SAMPLE_MASK, SAMPLE_MASK,
ALPHA_TO_COVERAGE_ENABLE, ALPHA_TO_COVERAGE_ENABLE,
BLEND_FUNCTION, BLEND_FUNCTION,
COLOR_WRITE_MASK, COLOR_WRITE_MASK,
NUM_FIELDS, // not a valid field, just the count NUM_FIELDS, // not a valid field, just the count
}; };
// The signature of the state tells which fields of the state are not default // The signature of the state tells which fields of the state are not default
// this way during rendering the Backend can compare it's current state and try to minimize the job to do // this way during rendering the Backend can compare it's current state and try to minimize the job to do
typedef std::bitset<NUM_FIELDS> Signature; typedef std::bitset<NUM_FIELDS> Signature;
Signature getSignature() const { return _signature; } Signature getSignature() const { return _signature; }
static Signature evalSignature(const Data& state); static Signature evalSignature(const Data& state);
// For convenience, create a State from the values directly // For convenience, create a State from the values directly
State(const Data& values); State(const Data& values);
const Data& getValues() const { return _values; } const Data& getValues() const { return _values; }
protected: protected:
State(const State& state); State(const State& state);
State& operator=(const State& state); State& operator=(const State& state);
Data _values; Data _values;
Signature _signature{0}; Signature _signature{0};
Stamp _stamp{0}; Stamp _stamp{0};
// This shouldn't be used by anything else than the Backend class with the proper casting. // This shouldn't be used by anything else than the Backend class with the proper casting.
mutable GPUObject* _gpuObject = nullptr; mutable GPUObject* _gpuObject = nullptr;
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; } void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
GPUObject* getGPUObject() const { return _gpuObject; } GPUObject* getGPUObject() const { return _gpuObject; }
friend class Backend; friend class Backend;
}; };
typedef std::shared_ptr< State > StatePointer; typedef std::shared_ptr< State > StatePointer;
typedef std::vector< StatePointer > States; typedef std::vector< StatePointer > States;
}; };
#endif #endif

View file

@ -92,7 +92,7 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) {
// dQ = Q1 * Q0^ // dQ = Q1 * Q0^
btQuaternion deltaQ = target * bodyRotation.inverse(); btQuaternion deltaQ = target * bodyRotation.inverse();
float angle = deltaQ.getAngle(); float angle = deltaQ.getAngle();
const float MIN_ANGLE = 1.0e-4; const float MIN_ANGLE = 1.0e-4f;
if (angle > MIN_ANGLE) { if (angle > MIN_ANGLE) {
targetVelocity = (angle / _angularTimeScale) * deltaQ.getAxis(); targetVelocity = (angle / _angularTimeScale) * deltaQ.getAxis();
} }

View file

@ -112,14 +112,14 @@ void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey key,
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vertexShader, pixelShader)); gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vertexShader, pixelShader));
gpu::Shader::makeProgram(*program, slotBindings); gpu::Shader::makeProgram(*program, slotBindings);
auto locations = std::make_shared<Locations>(); auto locations = std::make_shared<Locations>();
initLocations(program, *locations); initLocations(program, *locations);
auto state = std::make_shared<gpu::State>(); auto state = std::make_shared<gpu::State>();
// Backface on shadow // Backface on shadow
if (key.isShadow()) { if (key.isShadow()) {
state->setCullMode(gpu::State::CULL_FRONT); state->setCullMode(gpu::State::CULL_FRONT);
@ -140,36 +140,36 @@ void Model::RenderPipelineLib::addRenderPipeline(Model::RenderKey key,
// Good to go add the brand new pipeline // Good to go add the brand new pipeline
auto pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); auto pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state));
insert(value_type(key.getRaw(), RenderPipeline(pipeline, locations))); insert(value_type(key.getRaw(), RenderPipeline(pipeline, locations)));
if (!key.isWireFrame()) { if (!key.isWireFrame()) {
RenderKey wireframeKey(key.getRaw() | RenderKey::IS_WIREFRAME); RenderKey wireframeKey(key.getRaw() | RenderKey::IS_WIREFRAME);
auto wireframeState = std::make_shared<gpu::State>(state->getValues()); auto wireframeState = std::make_shared<gpu::State>(state->getValues());
wireframeState->setFillMode(gpu::State::FILL_LINE); wireframeState->setFillMode(gpu::State::FILL_LINE);
// create a new RenderPipeline with the same shader side and the mirrorState // create a new RenderPipeline with the same shader side and the mirrorState
auto wireframePipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, wireframeState)); auto wireframePipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, wireframeState));
insert(value_type(wireframeKey.getRaw(), RenderPipeline(wireframePipeline, locations))); 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 not a shadow pass, create the mirror version from the same state, just change the FrontFace
if (!key.isShadow()) { if (!key.isShadow()) {
RenderKey mirrorKey(key.getRaw() | RenderKey::IS_MIRROR); RenderKey mirrorKey(key.getRaw() | RenderKey::IS_MIRROR);
auto mirrorState = std::make_shared<gpu::State>(state->getValues()); auto mirrorState = std::make_shared<gpu::State>(state->getValues());
// create a new RenderPipeline with the same shader side and the mirrorState // create a new RenderPipeline with the same shader side and the mirrorState
auto mirrorPipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, mirrorState)); auto mirrorPipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, mirrorState));
insert(value_type(mirrorKey.getRaw(), RenderPipeline(mirrorPipeline, locations))); insert(value_type(mirrorKey.getRaw(), RenderPipeline(mirrorPipeline, locations)));
if (!key.isWireFrame()) { if (!key.isWireFrame()) {
RenderKey wireframeKey(key.getRaw() | RenderKey::IS_MIRROR | RenderKey::IS_WIREFRAME); RenderKey wireframeKey(key.getRaw() | RenderKey::IS_MIRROR | RenderKey::IS_WIREFRAME);
auto wireframeState = std::make_shared<gpu::State>(state->getValues()); auto wireframeState = std::make_shared<gpu::State>(state->getValues());
wireframeState->setFillMode(gpu::State::FILL_LINE); wireframeState->setFillMode(gpu::State::FILL_LINE);
// create a new RenderPipeline with the same shader side and the mirrorState // create a new RenderPipeline with the same shader side and the mirrorState
auto wireframePipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, wireframeState)); auto wireframePipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, wireframeState));
insert(value_type(wireframeKey.getRaw(), RenderPipeline(wireframePipeline, locations))); insert(value_type(wireframeKey.getRaw(), RenderPipeline(wireframePipeline, locations)));
@ -214,12 +214,12 @@ void Model::setScaleInternal(const glm::vec3& scale) {
} }
} }
void Model::setOffset(const glm::vec3& offset) { void Model::setOffset(const glm::vec3& offset) {
_offset = offset; _offset = offset;
// if someone manually sets our offset, then we are no longer snapped to center // if someone manually sets our offset, then we are no longer snapped to center
_snapModelToRegistrationPoint = false; _snapModelToRegistrationPoint = false;
_snappedToRegistrationPoint = false; _snappedToRegistrationPoint = false;
} }
QVector<JointState> Model::createJointStates(const FBXGeometry& geometry) { QVector<JointState> Model::createJointStates(const FBXGeometry& geometry) {
@ -267,7 +267,7 @@ void Model::init() {
auto modelLightmapNormalSpecularMapPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_lightmap_normal_specular_map_frag))); auto modelLightmapNormalSpecularMapPixel = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(model_lightmap_normal_specular_map_frag)));
// Fill the renderPipelineLib // Fill the renderPipelineLib
_renderPipelineLib.addRenderPipeline( _renderPipelineLib.addRenderPipeline(
RenderKey(0), RenderKey(0),
modelVertex, modelPixel); modelVertex, modelPixel);
@ -284,7 +284,7 @@ void Model::init() {
RenderKey(RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR), RenderKey(RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR),
modelNormalMapVertex, modelNormalSpecularMapPixel); modelNormalMapVertex, modelNormalSpecularMapPixel);
_renderPipelineLib.addRenderPipeline( _renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::IS_TRANSLUCENT), RenderKey(RenderKey::IS_TRANSLUCENT),
modelVertex, modelTranslucentPixel); modelVertex, modelTranslucentPixel);
@ -292,7 +292,7 @@ void Model::init() {
_renderPipelineLib.addRenderPipeline( _renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::IS_TRANSLUCENT | RenderKey::HAS_LIGHTMAP), RenderKey(RenderKey::IS_TRANSLUCENT | RenderKey::HAS_LIGHTMAP),
modelVertex, modelTranslucentPixel); modelVertex, modelTranslucentPixel);
_renderPipelineLib.addRenderPipeline( _renderPipelineLib.addRenderPipeline(
RenderKey(RenderKey::HAS_TANGENTS | RenderKey::IS_TRANSLUCENT), RenderKey(RenderKey::HAS_TANGENTS | RenderKey::IS_TRANSLUCENT),
modelNormalMapVertex, modelTranslucentPixel); modelNormalMapVertex, modelTranslucentPixel);
@ -440,15 +440,15 @@ bool Model::updateGeometry() {
} }
_geometry->setLoadPriority(this, -_lodDistance); _geometry->setLoadPriority(this, -_lodDistance);
_geometry->ensureLoading(); _geometry->ensureLoading();
if (needToRebuild) { if (needToRebuild) {
const FBXGeometry& fbxGeometry = geometry->getFBXGeometry(); const FBXGeometry& fbxGeometry = geometry->getFBXGeometry();
foreach (const FBXMesh& mesh, fbxGeometry.meshes) { foreach (const FBXMesh& mesh, fbxGeometry.meshes) {
MeshState state; MeshState state;
state.clusterMatrices.resize(mesh.clusters.size()); state.clusterMatrices.resize(mesh.clusters.size());
state.cauterizedClusterMatrices.resize(mesh.clusters.size()); state.cauterizedClusterMatrices.resize(mesh.clusters.size());
_meshStates.append(state); _meshStates.append(state);
auto buffer = std::make_shared<gpu::Buffer>(); auto buffer = std::make_shared<gpu::Buffer>();
if (!mesh.blendshapes.isEmpty()) { if (!mesh.blendshapes.isEmpty()) {
buffer->resize((mesh.vertices.size() + mesh.normals.size()) * sizeof(glm::vec3)); buffer->resize((mesh.vertices.size() + mesh.normals.size()) * sizeof(glm::vec3));
@ -486,7 +486,7 @@ void Model::initJointStates(QVector<JointState> states) {
rightShoulderJointIndex); rightShoulderJointIndex);
} }
bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const glm::vec3& direction, float& distance, bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const glm::vec3& direction, float& distance,
BoxFace& face, QString& extraInfo, bool pickAgainstTriangles) { BoxFace& face, QString& extraInfo, bool pickAgainstTriangles) {
bool intersectedSomething = false; bool intersectedSomething = false;
@ -495,7 +495,7 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
if (!isActive()) { if (!isActive()) {
return intersectedSomething; return intersectedSomething;
} }
// extents is the entity relative, scaled, centered extents of the entity // extents is the entity relative, scaled, centered extents of the entity
glm::vec3 position = _translation; glm::vec3 position = _translation;
glm::mat4 rotation = glm::mat4_cast(_rotation); glm::mat4 rotation = glm::mat4_cast(_rotation);
@ -504,7 +504,7 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
glm::mat4 worldToModelMatrix = glm::inverse(modelToWorldMatrix); glm::mat4 worldToModelMatrix = glm::inverse(modelToWorldMatrix);
Extents modelExtents = getMeshExtents(); // NOTE: unrotated Extents modelExtents = getMeshExtents(); // NOTE: unrotated
glm::vec3 dimensions = modelExtents.maximum - modelExtents.minimum; glm::vec3 dimensions = modelExtents.maximum - modelExtents.minimum;
glm::vec3 corner = -(dimensions * _registrationPoint); // since we're going to do the ray picking in the model frame of reference glm::vec3 corner = -(dimensions * _registrationPoint); // since we're going to do the ray picking in the model frame of reference
AABox modelFrameBox(corner, dimensions); AABox modelFrameBox(corner, dimensions);
@ -543,7 +543,7 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
int t = 0; int t = 0;
foreach (const Triangle& triangle, meshTriangles) { foreach (const Triangle& triangle, meshTriangles) {
t++; t++;
float thisTriangleDistance; float thisTriangleDistance;
if (findRayTriangleIntersection(origin, direction, triangle, thisTriangleDistance)) { if (findRayTriangleIntersection(origin, direction, triangle, thisTriangleDistance)) {
if (thisTriangleDistance < bestDistance) { if (thisTriangleDistance < bestDistance) {
@ -562,7 +562,7 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
extraInfo = geometry.getModelNameOfMesh(subMeshIndex); extraInfo = geometry.getModelNameOfMesh(subMeshIndex);
} }
} }
} }
subMeshIndex++; subMeshIndex++;
} }
_mutex.unlock(); _mutex.unlock();
@ -570,7 +570,7 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
if (intersectedSomething) { if (intersectedSomething) {
distance = bestDistance; distance = bestDistance;
} }
return intersectedSomething; return intersectedSomething;
} }
@ -582,22 +582,22 @@ bool Model::convexHullContains(glm::vec3 point) {
if (!isActive()) { if (!isActive()) {
return false; return false;
} }
// extents is the entity relative, scaled, centered extents of the entity // extents is the entity relative, scaled, centered extents of the entity
glm::vec3 position = _translation; glm::vec3 position = _translation;
glm::mat4 rotation = glm::mat4_cast(_rotation); glm::mat4 rotation = glm::mat4_cast(_rotation);
glm::mat4 translation = glm::translate(position); glm::mat4 translation = glm::translate(position);
glm::mat4 modelToWorldMatrix = translation * rotation; glm::mat4 modelToWorldMatrix = translation * rotation;
glm::mat4 worldToModelMatrix = glm::inverse(modelToWorldMatrix); glm::mat4 worldToModelMatrix = glm::inverse(modelToWorldMatrix);
Extents modelExtents = getMeshExtents(); // NOTE: unrotated Extents modelExtents = getMeshExtents(); // NOTE: unrotated
glm::vec3 dimensions = modelExtents.maximum - modelExtents.minimum; glm::vec3 dimensions = modelExtents.maximum - modelExtents.minimum;
glm::vec3 corner = -(dimensions * _registrationPoint); glm::vec3 corner = -(dimensions * _registrationPoint);
AABox modelFrameBox(corner, dimensions); AABox modelFrameBox(corner, dimensions);
glm::vec3 modelFramePoint = glm::vec3(worldToModelMatrix * glm::vec4(point, 1.0f)); glm::vec3 modelFramePoint = glm::vec3(worldToModelMatrix * glm::vec4(point, 1.0f));
// we can use the AABox's contains() by mapping our point into the model frame // we can use the AABox's contains() by mapping our point into the model frame
// and testing there. // and testing there.
if (modelFrameBox.contains(modelFramePoint)){ if (modelFrameBox.contains(modelFramePoint)){
@ -605,7 +605,7 @@ bool Model::convexHullContains(glm::vec3 point) {
if (!_calculatedMeshTrianglesValid) { if (!_calculatedMeshTrianglesValid) {
recalculateMeshBoxes(true); recalculateMeshBoxes(true);
} }
// If we are inside the models box, then consider the submeshes... // If we are inside the models box, then consider the submeshes...
int subMeshIndex = 0; int subMeshIndex = 0;
foreach(const AABox& subMeshBox, _calculatedMeshBoxes) { foreach(const AABox& subMeshBox, _calculatedMeshBoxes) {
@ -619,7 +619,7 @@ bool Model::convexHullContains(glm::vec3 point) {
insideMesh = false; insideMesh = false;
break; break;
} }
} }
if (insideMesh) { if (insideMesh) {
// It's inside this mesh, return true. // It's inside this mesh, return true.
@ -658,7 +658,7 @@ void Model::recalculateMeshPartOffsets() {
// Any script might trigger findRayIntersectionAgainstSubMeshes (and maybe convexHullContains), so these // Any script might trigger findRayIntersectionAgainstSubMeshes (and maybe convexHullContains), so these
// can occur multiple times. In addition, rendering does it's own ray picking in order to decide which // can occur multiple times. In addition, rendering does it's own ray picking in order to decide which
// entity-scripts to call. I think it would be best to do the picking once-per-frame (in cpu, or gpu if possible) // entity-scripts to call. I think it would be best to do the picking once-per-frame (in cpu, or gpu if possible)
// and then the calls use the most recent such result. // and then the calls use the most recent such result.
void Model::recalculateMeshBoxes(bool pickAgainstTriangles) { void Model::recalculateMeshBoxes(bool pickAgainstTriangles) {
PROFILE_RANGE(__FUNCTION__); PROFILE_RANGE(__FUNCTION__);
bool calculatedMeshTrianglesNeeded = pickAgainstTriangles && !_calculatedMeshTrianglesValid; bool calculatedMeshTrianglesNeeded = pickAgainstTriangles && !_calculatedMeshTrianglesValid;
@ -703,7 +703,7 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) {
glm::vec3 mv1 = glm::vec3(mesh.modelTransform * glm::vec4(mesh.vertices[i1], 1.0f)); glm::vec3 mv1 = glm::vec3(mesh.modelTransform * glm::vec4(mesh.vertices[i1], 1.0f));
glm::vec3 mv2 = glm::vec3(mesh.modelTransform * glm::vec4(mesh.vertices[i2], 1.0f)); glm::vec3 mv2 = glm::vec3(mesh.modelTransform * glm::vec4(mesh.vertices[i2], 1.0f));
glm::vec3 mv3 = glm::vec3(mesh.modelTransform * glm::vec4(mesh.vertices[i3], 1.0f)); glm::vec3 mv3 = glm::vec3(mesh.modelTransform * glm::vec4(mesh.vertices[i3], 1.0f));
// track the mesh parts in model space // track the mesh parts in model space
if (!atLeastOnePointInBounds) { if (!atLeastOnePointInBounds) {
thisPartBounds.setBox(mv0, 0.0f); thisPartBounds.setBox(mv0, 0.0f);
@ -719,18 +719,18 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) {
glm::vec3 v1 = calculateScaledOffsetPoint(mv1); glm::vec3 v1 = calculateScaledOffsetPoint(mv1);
glm::vec3 v2 = calculateScaledOffsetPoint(mv2); glm::vec3 v2 = calculateScaledOffsetPoint(mv2);
glm::vec3 v3 = calculateScaledOffsetPoint(mv3); glm::vec3 v3 = calculateScaledOffsetPoint(mv3);
// Sam's recommended triangle slices // Sam's recommended triangle slices
Triangle tri1 = { v0, v1, v3 }; Triangle tri1 = { v0, v1, v3 };
Triangle tri2 = { v1, v2, v3 }; Triangle tri2 = { v1, v2, v3 };
// NOTE: Random guy on the internet's recommended triangle slices // NOTE: Random guy on the internet's recommended triangle slices
//Triangle tri1 = { v0, v1, v2 }; //Triangle tri1 = { v0, v1, v2 };
//Triangle tri2 = { v2, v3, v0 }; //Triangle tri2 = { v2, v3, v0 };
thisMeshTriangles.push_back(tri1); thisMeshTriangles.push_back(tri1);
thisMeshTriangles.push_back(tri2); thisMeshTriangles.push_back(tri2);
} }
} }
@ -792,7 +792,7 @@ void Model::renderSetup(RenderArgs* args) {
_dilatedTextures.append(dilated); _dilatedTextures.append(dilated);
} }
} }
if (!_meshGroupsKnown && isLoaded()) { if (!_meshGroupsKnown && isLoaded()) {
segregateMeshGroups(); segregateMeshGroups();
} }
@ -805,7 +805,7 @@ public:
transparent(transparent), model(model), url(model->getURL()), meshIndex(meshIndex), partIndex(partIndex) { } transparent(transparent), model(model), url(model->getURL()), meshIndex(meshIndex), partIndex(partIndex) { }
typedef render::Payload<MeshPartPayload> Payload; typedef render::Payload<MeshPartPayload> Payload;
typedef Payload::DataPointer Pointer; typedef Payload::DataPointer Pointer;
bool transparent; bool transparent;
Model* model; Model* model;
QUrl url; QUrl url;
@ -814,14 +814,14 @@ public:
}; };
namespace render { namespace render {
template <> const ItemKey payloadGetKey(const MeshPartPayload::Pointer& payload) { template <> const ItemKey payloadGetKey(const MeshPartPayload::Pointer& payload) {
if (!payload->model->isVisible()) { if (!payload->model->isVisible()) {
return ItemKey::Builder().withInvisible().build(); return ItemKey::Builder().withInvisible().build();
} }
return payload->transparent ? ItemKey::Builder::transparentShape() : ItemKey::Builder::opaqueShape(); return payload->transparent ? ItemKey::Builder::transparentShape() : ItemKey::Builder::opaqueShape();
} }
template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload) { template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload) {
if (payload) { if (payload) {
return payload->model->getPartBounds(payload->meshIndex, payload->partIndex); return payload->model->getPartBounds(payload->meshIndex, payload->partIndex);
} }
@ -875,7 +875,7 @@ bool Model::addToScene(std::shared_ptr<render::Scene> scene, render::PendingChan
_renderItems.insert(item, renderPayload); _renderItems.insert(item, renderPayload);
somethingAdded = true; somethingAdded = true;
} }
_readyWhenAdded = readyToAddToScene(); _readyWhenAdded = readyToAddToScene();
return somethingAdded; return somethingAdded;
@ -907,7 +907,7 @@ bool Model::addToScene(std::shared_ptr<render::Scene> scene, render::PendingChan
_renderItems.insert(item, renderPayload); _renderItems.insert(item, renderPayload);
somethingAdded = true; somethingAdded = true;
} }
_readyWhenAdded = readyToAddToScene(); _readyWhenAdded = readyToAddToScene();
return somethingAdded; return somethingAdded;
@ -929,7 +929,7 @@ void Model::renderDebugMeshBoxes(gpu::Batch& batch) {
_debugMeshBoxesID = DependencyManager::get<GeometryCache>()->allocateID(); _debugMeshBoxesID = DependencyManager::get<GeometryCache>()->allocateID();
} }
QVector<glm::vec3> points; QVector<glm::vec3> points;
glm::vec3 brn = box.getCorner(); glm::vec3 brn = box.getCorner();
glm::vec3 bln = brn + glm::vec3(box.getDimensions().x, 0, 0); glm::vec3 bln = brn + glm::vec3(box.getDimensions().x, 0, 0);
glm::vec3 brf = brn + glm::vec3(0, 0, box.getDimensions().z); glm::vec3 brf = brn + glm::vec3(0, 0, box.getDimensions().z);
@ -963,12 +963,12 @@ void Model::renderDebugMeshBoxes(gpu::Batch& batch) {
{ 1.0f, 1.0f, 0.0f, 1.0f }, // yellow { 1.0f, 1.0f, 0.0f, 1.0f }, // yellow
{ 0.0f, 1.0f, 1.0f, 1.0f }, // cyan { 0.0f, 1.0f, 1.0f, 1.0f }, // cyan
{ 1.0f, 1.0f, 1.0f, 1.0f }, // white { 1.0f, 1.0f, 1.0f, 1.0f }, // white
{ 0.0f, 0.5f, 0.0f, 1.0f }, { 0.0f, 0.5f, 0.0f, 1.0f },
{ 0.0f, 0.0f, 0.5f, 1.0f }, { 0.0f, 0.0f, 0.5f, 1.0f },
{ 0.5f, 0.0f, 0.5f, 1.0f }, { 0.5f, 0.0f, 0.5f, 1.0f },
{ 0.5f, 0.5f, 0.0f, 1.0f }, { 0.5f, 0.5f, 0.0f, 1.0f },
{ 0.0f, 0.5f, 0.5f, 1.0f } }; { 0.0f, 0.5f, 0.5f, 1.0f } };
DependencyManager::get<GeometryCache>()->updateVertices(_debugMeshBoxesID, points, color[colorNdx]); DependencyManager::get<GeometryCache>()->updateVertices(_debugMeshBoxesID, points, color[colorNdx]);
DependencyManager::get<GeometryCache>()->renderVertices(batch, gpu::LINES, _debugMeshBoxesID); DependencyManager::get<GeometryCache>()->renderVertices(batch, gpu::LINES, _debugMeshBoxesID);
colorNdx++; colorNdx++;
@ -1003,7 +1003,7 @@ Extents Model::getUnscaledMeshExtents() const {
if (!isActive()) { if (!isActive()) {
return Extents(); return Extents();
} }
const Extents& extents = _geometry->getFBXGeometry().meshExtents; const Extents& extents = _geometry->getFBXGeometry().meshExtents;
// even though our caller asked for "unscaled" we need to include any fst scaling, translation, and rotation, which // even though our caller asked for "unscaled" we need to include any fst scaling, translation, and rotation, which
@ -1011,7 +1011,7 @@ Extents Model::getUnscaledMeshExtents() const {
glm::vec3 minimum = glm::vec3(_geometry->getFBXGeometry().offset * glm::vec4(extents.minimum, 1.0f)); glm::vec3 minimum = glm::vec3(_geometry->getFBXGeometry().offset * glm::vec4(extents.minimum, 1.0f));
glm::vec3 maximum = glm::vec3(_geometry->getFBXGeometry().offset * glm::vec4(extents.maximum, 1.0f)); glm::vec3 maximum = glm::vec3(_geometry->getFBXGeometry().offset * glm::vec4(extents.maximum, 1.0f));
Extents scaledExtents = { minimum, maximum }; Extents scaledExtents = { minimum, maximum };
return scaledExtents; return scaledExtents;
} }
@ -1020,12 +1020,12 @@ Extents Model::calculateScaledOffsetExtents(const Extents& extents) const {
glm::vec3 minimum = glm::vec3(_geometry->getFBXGeometry().offset * glm::vec4(extents.minimum, 1.0f)); glm::vec3 minimum = glm::vec3(_geometry->getFBXGeometry().offset * glm::vec4(extents.minimum, 1.0f));
glm::vec3 maximum = glm::vec3(_geometry->getFBXGeometry().offset * glm::vec4(extents.maximum, 1.0f)); glm::vec3 maximum = glm::vec3(_geometry->getFBXGeometry().offset * glm::vec4(extents.maximum, 1.0f));
Extents scaledOffsetExtents = { ((minimum + _offset) * _scale), Extents scaledOffsetExtents = { ((minimum + _offset) * _scale),
((maximum + _offset) * _scale) }; ((maximum + _offset) * _scale) };
Extents rotatedExtents = scaledOffsetExtents.getRotated(_rotation); Extents rotatedExtents = scaledOffsetExtents.getRotated(_rotation);
Extents translatedExtents = { rotatedExtents.minimum + _translation, Extents translatedExtents = { rotatedExtents.minimum + _translation,
rotatedExtents.maximum + _translation }; rotatedExtents.maximum + _translation };
return translatedExtents; return translatedExtents;
@ -1084,7 +1084,7 @@ void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bo
onInvalidate(); onInvalidate();
// if so instructed, keep the current geometry until the new one is loaded // if so instructed, keep the current geometry until the new one is loaded
_nextGeometry = DependencyManager::get<GeometryCache>()->getGeometry(url, fallback, delayLoad); _nextGeometry = DependencyManager::get<GeometryCache>()->getGeometry(url, fallback, delayLoad);
_nextLODHysteresis = NetworkGeometry::NO_HYSTERESIS; _nextLODHysteresis = NetworkGeometry::NO_HYSTERESIS;
if (!retainCurrent || !isActive() || (_nextGeometry && _nextGeometry->isLoaded())) { if (!retainCurrent || !isActive() || (_nextGeometry && _nextGeometry->isLoaded())) {
@ -1094,14 +1094,14 @@ void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bo
void Model::geometryRefreshed() { void Model::geometryRefreshed() {
QObject* sender = QObject::sender(); QObject* sender = QObject::sender();
if (sender == _geometry) { if (sender == _geometry) {
_readyWhenAdded = false; // reset out render items. _readyWhenAdded = false; // reset out render items.
_needsReload = true; _needsReload = true;
invalidCalculatedMeshBoxes(); invalidCalculatedMeshBoxes();
onInvalidate(); onInvalidate();
// if so instructed, keep the current geometry until the new one is loaded // if so instructed, keep the current geometry until the new one is loaded
_nextGeometry = DependencyManager::get<GeometryCache>()->getGeometry(_url); _nextGeometry = DependencyManager::get<GeometryCache>()->getGeometry(_url);
_nextLODHysteresis = NetworkGeometry::NO_HYSTERESIS; _nextLODHysteresis = NetworkGeometry::NO_HYSTERESIS;
@ -1121,7 +1121,7 @@ const QSharedPointer<NetworkGeometry> Model::getCollisionGeometry(bool delayLoad
if (_collisionGeometry && _collisionGeometry->isLoaded()) { if (_collisionGeometry && _collisionGeometry->isLoaded()) {
return _collisionGeometry; return _collisionGeometry;
} }
return QSharedPointer<NetworkGeometry>(); return QSharedPointer<NetworkGeometry>();
} }
@ -1176,11 +1176,11 @@ public:
Blender(Model* model, int blendNumber, const QWeakPointer<NetworkGeometry>& geometry, Blender(Model* model, int blendNumber, const QWeakPointer<NetworkGeometry>& geometry,
const QVector<FBXMesh>& meshes, const QVector<float>& blendshapeCoefficients); const QVector<FBXMesh>& meshes, const QVector<float>& blendshapeCoefficients);
virtual void run(); virtual void run();
private: private:
QPointer<Model> _model; QPointer<Model> _model;
int _blendNumber; int _blendNumber;
QWeakPointer<NetworkGeometry> _geometry; QWeakPointer<NetworkGeometry> _geometry;
@ -1254,10 +1254,10 @@ void Model::setScaleToFit(bool scaleToFit, float largestDimension, bool forceRes
} }
return; return;
} }
if (forceRescale || _scaleToFit != scaleToFit || glm::length(_scaleToFitDimensions) != largestDimension) { if (forceRescale || _scaleToFit != scaleToFit || glm::length(_scaleToFitDimensions) != largestDimension) {
_scaleToFit = scaleToFit; _scaleToFit = scaleToFit;
// we only need to do this work if we're "turning on" scale to fit. // we only need to do this work if we're "turning on" scale to fit.
if (scaleToFit) { if (scaleToFit) {
Extents modelMeshExtents = getUnscaledMeshExtents(); Extents modelMeshExtents = getUnscaledMeshExtents();
@ -1278,7 +1278,7 @@ void Model::scaleToFit() {
// we didn't yet have an active mesh. We can only enter this scaleToFit() in this state // we didn't yet have an active mesh. We can only enter this scaleToFit() in this state
// if we now do have an active mesh, so we take this opportunity to actually determine // if we now do have an active mesh, so we take this opportunity to actually determine
// the correct scale. // the correct scale.
if (_scaleToFit && _scaleToFitDimensions.y == FAKE_DIMENSION_PLACEHOLDER if (_scaleToFit && _scaleToFitDimensions.y == FAKE_DIMENSION_PLACEHOLDER
&& _scaleToFitDimensions.z == FAKE_DIMENSION_PLACEHOLDER) { && _scaleToFitDimensions.z == FAKE_DIMENSION_PLACEHOLDER) {
setScaleToFit(_scaleToFit, _scaleToFitDimensions.x); setScaleToFit(_scaleToFit, _scaleToFitDimensions.x);
} }
@ -1313,7 +1313,7 @@ void Model::simulate(float deltaTime, bool fullUpdate) {
PROFILE_RANGE(__FUNCTION__); PROFILE_RANGE(__FUNCTION__);
fullUpdate = updateGeometry() || fullUpdate || (_scaleToFit && !_scaledToFit) fullUpdate = updateGeometry() || fullUpdate || (_scaleToFit && !_scaledToFit)
|| (_snapModelToRegistrationPoint && !_snappedToRegistrationPoint); || (_snapModelToRegistrationPoint && !_snappedToRegistrationPoint);
if (isActive() && fullUpdate) { if (isActive() && fullUpdate) {
// NOTE: This is overly aggressive and we are invalidating the MeshBoxes when in fact they may not be invalid // NOTE: This is overly aggressive and we are invalidating the MeshBoxes when in fact they may not be invalid
// they really only become invalid if something about the transform to world space has changed. This is // they really only become invalid if something about the transform to world space has changed. This is
@ -1440,7 +1440,7 @@ void Model::setBlendedVertices(int blendNumber, const QWeakPointer<NetworkGeomet
return; return;
} }
_appliedBlendNumber = blendNumber; _appliedBlendNumber = blendNumber;
const FBXGeometry& fbxGeometry = _geometry->getFBXGeometry(); const FBXGeometry& fbxGeometry = _geometry->getFBXGeometry();
int index = 0; int index = 0;
for (int i = 0; i < fbxGeometry.meshes.size(); i++) { for (int i = 0; i < fbxGeometry.meshes.size(); i++) {
const FBXMesh& mesh = fbxGeometry.meshes.at(i); const FBXMesh& mesh = fbxGeometry.meshes.at(i);
@ -1461,7 +1461,7 @@ void Model::setGeometry(const QSharedPointer<NetworkGeometry>& newGeometry) {
if (_geometry == newGeometry) { if (_geometry == newGeometry) {
return; return;
} }
if (_geometry) { if (_geometry) {
_geometry->disconnect(_geometry.data(), &Resource::onRefresh, this, &Model::geometryRefreshed); _geometry->disconnect(_geometry.data(), &Resource::onRefresh, this, &Model::geometryRefreshed);
} }
@ -1474,10 +1474,10 @@ void Model::applyNextGeometry() {
deleteGeometry(); deleteGeometry();
_dilatedTextures.clear(); _dilatedTextures.clear();
_lodHysteresis = _nextLODHysteresis; _lodHysteresis = _nextLODHysteresis;
// we retain a reference to the base geometry so that its reference count doesn't fall to zero // we retain a reference to the base geometry so that its reference count doesn't fall to zero
setGeometry(_nextGeometry); setGeometry(_nextGeometry);
_meshGroupsKnown = false; _meshGroupsKnown = false;
_readyWhenAdded = false; // in case any of our users are using scenes _readyWhenAdded = false; // in case any of our users are using scenes
_needsReload = false; // we are loaded now! _needsReload = false; // we are loaded now!
@ -1509,9 +1509,9 @@ AABox Model::getPartBounds(int meshIndex, int partIndex) {
return calculateScaledOffsetAABox(_geometry->getFBXGeometry().meshExtents); return calculateScaledOffsetAABox(_geometry->getFBXGeometry().meshExtents);
} }
} }
if (_geometry->getFBXGeometry().meshes.size() > meshIndex) { if (_geometry->getFBXGeometry().meshes.size() > meshIndex) {
// FIX ME! - This is currently a hack because for some mesh parts our efforts to calculate the bounding // FIX ME! - This is currently a hack because for some mesh parts our efforts to calculate the bounding
// box of the mesh part fails. It seems to create boxes that are not consistent with where the // box of the mesh part fails. It seems to create boxes that are not consistent with where the
// geometry actually renders. If instead we make all the parts share the bounds of the entire subMesh // geometry actually renders. If instead we make all the parts share the bounds of the entire subMesh
@ -1536,7 +1536,7 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
if (!_readyWhenAdded) { if (!_readyWhenAdded) {
return; // bail asap return; // bail asap
} }
// We need to make sure we have valid offsets calculated before we can render // We need to make sure we have valid offsets calculated before we can render
if (!_calculatedMeshPartOffsetValid) { if (!_calculatedMeshPartOffsetValid) {
_mutex.lock(); _mutex.lock();
@ -1561,13 +1561,13 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
// guard against partially loaded meshes // guard against partially loaded meshes
if (meshIndex >= networkMeshes.size() || meshIndex >= geometry.meshes.size() || meshIndex >= _meshStates.size() ) { if (meshIndex >= networkMeshes.size() || meshIndex >= geometry.meshes.size() || meshIndex >= _meshStates.size() ) {
return; return;
} }
const NetworkMesh& networkMesh = networkMeshes.at(meshIndex); const NetworkMesh& networkMesh = networkMeshes.at(meshIndex);
const FBXMesh& mesh = geometry.meshes.at(meshIndex); const FBXMesh& mesh = geometry.meshes.at(meshIndex);
const MeshState& state = _meshStates.at(meshIndex); const MeshState& state = _meshStates.at(meshIndex);
bool translucentMesh = translucent; // networkMesh.getTranslucentPartCount(mesh) == networkMesh.parts.size(); bool translucentMesh = translucent; // networkMesh.getTranslucentPartCount(mesh) == networkMesh.parts.size();
bool hasTangents = !mesh.tangents.isEmpty(); bool hasTangents = !mesh.tangents.isEmpty();
bool hasSpecular = mesh.hasSpecularTexture(); bool hasSpecular = mesh.hasSpecularTexture();
@ -1597,7 +1597,7 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(batch, 1.0f, cubeColor); DependencyManager::get<DeferredLightingEffect>()->renderWireCube(batch, 1.0f, cubeColor);
} }
#endif //def DEBUG_BOUNDING_PARTS #endif //def DEBUG_BOUNDING_PARTS
if (wireframe) { if (wireframe) {
translucentMesh = hasTangents = hasSpecular = hasLightmap = isSkinned = false; translucentMesh = hasTangents = hasSpecular = hasLightmap = isSkinned = false;
} }
@ -1614,14 +1614,14 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
// if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown // if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown
// to false to rebuild out mesh groups. // to false to rebuild out mesh groups.
if (meshIndex < 0 || meshIndex >= networkMeshes.size() || meshIndex > geometry.meshes.size()) { if (meshIndex < 0 || meshIndex >= networkMeshes.size() || meshIndex > geometry.meshes.size()) {
_meshGroupsKnown = false; // regenerate these lists next time around. _meshGroupsKnown = false; // regenerate these lists next time around.
_readyWhenAdded = false; // in case any of our users are using scenes _readyWhenAdded = false; // in case any of our users are using scenes
invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid
return; // FIXME! return; // FIXME!
} }
batch.setIndexBuffer(gpu::UINT32, (networkMesh._indexBuffer), 0); batch.setIndexBuffer(gpu::UINT32, (networkMesh._indexBuffer), 0);
int vertexCount = mesh.vertices.size(); int vertexCount = mesh.vertices.size();
if (vertexCount == 0) { if (vertexCount == 0) {
@ -1633,7 +1633,7 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
if (_transforms.empty()) { if (_transforms.empty()) {
_transforms.push_back(Transform()); _transforms.push_back(Transform());
} }
if (isSkinned) { if (isSkinned) {
const float* bones; const float* bones;
if (_cauterizeBones) { if (_cauterizeBones) {
@ -1682,7 +1682,7 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
qCDebug(renderutils) << "WARNING: material == nullptr!!!"; qCDebug(renderutils) << "WARNING: material == nullptr!!!";
} }
#endif #endif
if (material != nullptr) { if (material != nullptr) {
// apply material properties // apply material properties
@ -1724,12 +1724,12 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
batch._glUniformMatrix4fv(locations->texcoordMatrices, 2, false, (const float*) &texcoordTransform); batch._glUniformMatrix4fv(locations->texcoordMatrices, 2, false, (const float*) &texcoordTransform);
} }
if (!mesh.tangents.isEmpty()) { if (!mesh.tangents.isEmpty()) {
NetworkTexture* normalMap = networkPart.normalTexture.data(); NetworkTexture* normalMap = networkPart.normalTexture.data();
batch.setResourceTexture(1, (!normalMap || !normalMap->isLoaded()) ? batch.setResourceTexture(1, (!normalMap || !normalMap->isLoaded()) ?
textureCache->getBlueTexture() : normalMap->getGPUTexture()); textureCache->getBlueTexture() : normalMap->getGPUTexture());
} }
if (locations->specularTextureUnit >= 0) { if (locations->specularTextureUnit >= 0) {
NetworkTexture* specularMap = networkPart.specularTexture.data(); NetworkTexture* specularMap = networkPart.specularTexture.data();
batch.setResourceTexture(locations->specularTextureUnit, (!specularMap || !specularMap->isLoaded()) ? batch.setResourceTexture(locations->specularTextureUnit, (!specularMap || !specularMap->isLoaded()) ?
@ -1747,18 +1747,18 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
float emissiveOffset = part.emissiveParams.x; float emissiveOffset = part.emissiveParams.x;
float emissiveScale = part.emissiveParams.y; float emissiveScale = part.emissiveParams.y;
batch._glUniform2f(locations->emissiveParams, emissiveOffset, emissiveScale); batch._glUniform2f(locations->emissiveParams, emissiveOffset, emissiveScale);
NetworkTexture* emissiveMap = networkPart.emissiveTexture.data(); NetworkTexture* emissiveMap = networkPart.emissiveTexture.data();
batch.setResourceTexture(locations->emissiveTextureUnit, (!emissiveMap || !emissiveMap->isLoaded()) ? batch.setResourceTexture(locations->emissiveTextureUnit, (!emissiveMap || !emissiveMap->isLoaded()) ?
textureCache->getGrayTexture() : emissiveMap->getGPUTexture()); textureCache->getGrayTexture() : emissiveMap->getGPUTexture());
} }
if (translucent && locations->lightBufferUnit >= 0) { if (translucent && locations->lightBufferUnit >= 0) {
DependencyManager::get<DeferredLightingEffect>()->setupTransparent(args, locations->lightBufferUnit); DependencyManager::get<DeferredLightingEffect>()->setupTransparent(args, locations->lightBufferUnit);
} }
} }
} }
qint64 offset; qint64 offset;
{ {
// FIXME_STUTTER: We should n't have any lock here // FIXME_STUTTER: We should n't have any lock here
@ -1798,7 +1798,7 @@ void Model::segregateMeshGroups() {
qDebug() << "WARNING!!!! Mesh Sizes don't match! We will not segregate mesh groups yet."; qDebug() << "WARNING!!!! Mesh Sizes don't match! We will not segregate mesh groups yet.";
return; return;
} }
_transparentRenderItems.clear(); _transparentRenderItems.clear();
_opaqueRenderItems.clear(); _opaqueRenderItems.clear();
@ -1807,7 +1807,6 @@ void Model::segregateMeshGroups() {
const NetworkMesh& networkMesh = networkMeshes.at(i); const NetworkMesh& networkMesh = networkMeshes.at(i);
const FBXMesh& mesh = geometry.meshes.at(i); const FBXMesh& mesh = geometry.meshes.at(i);
const MeshState& state = _meshStates.at(i); const MeshState& state = _meshStates.at(i);
bool translucentMesh = networkMesh.getTranslucentPartCount(mesh) == networkMesh.parts.size(); bool translucentMesh = networkMesh.getTranslucentPartCount(mesh) == networkMesh.parts.size();
bool hasTangents = !mesh.tangents.isEmpty(); bool hasTangents = !mesh.tangents.isEmpty();
@ -1815,7 +1814,7 @@ void Model::segregateMeshGroups() {
bool hasLightmap = mesh.hasEmissiveTexture(); bool hasLightmap = mesh.hasEmissiveTexture();
bool isSkinned = state.clusterMatrices.size() > 1; bool isSkinned = state.clusterMatrices.size() > 1;
bool wireframe = isWireframe(); bool wireframe = isWireframe();
if (wireframe) { if (wireframe) {
translucentMesh = hasTangents = hasSpecular = hasLightmap = isSkinned = false; translucentMesh = hasTangents = hasSpecular = hasLightmap = isSkinned = false;
} }
@ -1831,7 +1830,7 @@ void Model::segregateMeshGroups() {
} }
} }
_meshGroupsKnown = true; _meshGroupsKnown = true;
} }
void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args,
@ -1851,7 +1850,7 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f
gpu::ShaderPointer program = (*pipeline).second._pipeline->getProgram(); gpu::ShaderPointer program = (*pipeline).second._pipeline->getProgram();
locations = (*pipeline).second._locations.get(); locations = (*pipeline).second._locations.get();
// Setup the One pipeline // Setup the One pipeline
batch.setPipeline((*pipeline).second._pipeline); batch.setPipeline((*pipeline).second._pipeline);
@ -1865,7 +1864,7 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f
} }
if ((locations->normalFittingMapUnit > -1)) { if ((locations->normalFittingMapUnit > -1)) {
batch.setResourceTexture(locations->normalFittingMapUnit, batch.setResourceTexture(locations->normalFittingMapUnit,
DependencyManager::get<TextureCache>()->getNormalFittingTexture()); DependencyManager::get<TextureCache>()->getNormalFittingTexture());
} }
} }

View file

@ -44,7 +44,7 @@ const int16_t COLLISION_GROUP_OTHER_AVATAR = 1 << 6;
const int16_t COLLISION_GROUP_MY_ATTACHMENT = 1 << 7; const int16_t COLLISION_GROUP_MY_ATTACHMENT = 1 << 7;
const int16_t COLLISION_GROUP_OTHER_ATTACHMENT = 1 << 8; const int16_t COLLISION_GROUP_OTHER_ATTACHMENT = 1 << 8;
// ... // ...
const int16_t COLLISION_GROUP_COLLISIONLESS = 1 << 15; const int16_t COLLISION_GROUP_COLLISIONLESS = 1 << 14;
/* Note: In order for objectA to collide with objectB at the filter stage /* Note: In order for objectA to collide with objectB at the filter stage