mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:24:00 +02:00
commit
9f8fad0b8f
16 changed files with 257 additions and 236 deletions
|
@ -1175,13 +1175,22 @@ void OctreeServer::aboutToFinish() {
|
|||
if (_jurisdictionSender) {
|
||||
_jurisdictionSender->terminating();
|
||||
}
|
||||
|
||||
QSet<SharedNodePointer> nodesToShutdown;
|
||||
|
||||
// force a shutdown of all of our OctreeSendThreads - at this point it has to be impossible for a
|
||||
// linkedDataCreateCallback to be called for a new node
|
||||
nodeList->eachNode([this](const SharedNodePointer& node) {
|
||||
// Force a shutdown of all of our OctreeSendThreads.
|
||||
// At this point it has to be impossible for a linkedDataCreateCallback to be called for a new node
|
||||
nodeList->eachNode([&nodesToShutdown](const SharedNodePointer& node) {
|
||||
nodesToShutdown << node;
|
||||
});
|
||||
|
||||
// What follows is a hack to force OctreeSendThreads to cleanup before the OctreeServer is gone.
|
||||
// I would prefer to allow the SharedNodePointer ref count drop to zero to do this automatically
|
||||
// but that isn't possible as long as the OctreeSendThread has an OctreeServer* that it uses.
|
||||
for (auto& node : nodesToShutdown) {
|
||||
qDebug() << qPrintable(_safeServerName) << "server about to finish while node still connected node:" << *node;
|
||||
forceNodeShutdown(node);
|
||||
});
|
||||
}
|
||||
|
||||
if (_persistThread) {
|
||||
_persistThread->aboutToFinish();
|
||||
|
|
|
@ -318,11 +318,15 @@ var toolBar = (function () {
|
|||
print("Resize failed: timed out waiting for model (" + url + ") to load");
|
||||
}
|
||||
} else {
|
||||
entityProperties.dimensions = naturalDimensions;
|
||||
Entities.editEntity(entityId, entityProperties);
|
||||
Entities.editEntity(entityId, { dimensions: naturalDimensions });
|
||||
|
||||
// Reset selection so that the selection overlays will be updated
|
||||
selectionManager.setSelections([entityId]);
|
||||
}
|
||||
}
|
||||
|
||||
selectionManager.setSelections([entityId]);
|
||||
|
||||
Script.setTimeout(resize, RESIZE_INTERVAL);
|
||||
} else {
|
||||
print("Can't add model: Model would be out of bounds.");
|
||||
|
|
|
@ -882,7 +882,7 @@ void Application::paintGL() {
|
|||
// NOTE: There is no batch associated with this renderArgs
|
||||
// the ApplicationOverlay class assumes it's viewport is setup to be the device size
|
||||
QSize size = qApp->getDeviceSize();
|
||||
renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height());
|
||||
renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height());
|
||||
_applicationOverlay.renderOverlay(&renderArgs);
|
||||
}
|
||||
|
||||
|
@ -959,7 +959,7 @@ void Application::paintGL() {
|
|||
batch.setFramebuffer(primaryFbo);
|
||||
// clear the normal and specular buffers
|
||||
batch.clearFramebuffer(
|
||||
gpu::Framebuffer::BUFFER_COLOR0 |
|
||||
gpu::Framebuffer::BUFFER_COLOR0 |
|
||||
gpu::Framebuffer::BUFFER_COLOR1 |
|
||||
gpu::Framebuffer::BUFFER_COLOR2 |
|
||||
gpu::Framebuffer::BUFFER_DEPTH,
|
||||
|
@ -1798,6 +1798,13 @@ void Application::idle() {
|
|||
}
|
||||
double timeSinceLastUpdate = (double)_lastTimeUpdated.nsecsElapsed() / 1000000.0;
|
||||
if (timeSinceLastUpdate > targetFramePeriod) {
|
||||
|
||||
{
|
||||
static const int IDLE_EVENT_PROCESS_MAX_TIME_MS = 2;
|
||||
PerformanceTimer perfTimer("processEvents");
|
||||
processEvents(QEventLoop::AllEvents, IDLE_EVENT_PROCESS_MAX_TIME_MS);
|
||||
}
|
||||
|
||||
_lastTimeUpdated.start();
|
||||
{
|
||||
PerformanceTimer perfTimer("update");
|
||||
|
@ -1822,11 +1829,19 @@ void Application::idle() {
|
|||
_idleLoopMeasuredJitter = _idleLoopStdev.getStDev();
|
||||
_idleLoopStdev.reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// After finishing all of the above work, ensure the idle timer is set to the proper interval,
|
||||
// depending on whether we're throttling or not
|
||||
idleTimer->start(_glWidget->isThrottleRendering() ? THROTTLED_IDLE_TIMER_DELAY : 1);
|
||||
// depending on whether we're throttling or not.
|
||||
// Once rendering is off on another thread we should be able to have Application::idle run at start(0) in
|
||||
// perpetuity and not expect events to get backed up.
|
||||
|
||||
static const int IDLE_TIMER_DELAY_MS = 0;
|
||||
int desiredInterval = _glWidget->isThrottleRendering() ? THROTTLED_IDLE_TIMER_DELAY : IDLE_TIMER_DELAY_MS;
|
||||
|
||||
if (idleTimer->interval() != desiredInterval) {
|
||||
idleTimer->start(desiredInterval);
|
||||
}
|
||||
}
|
||||
|
||||
// check for any requested background downloads.
|
||||
|
@ -3414,9 +3429,6 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi
|
|||
renderArgs->_context->render(batch);
|
||||
}
|
||||
|
||||
bool updateViewFrustum = false;
|
||||
loadViewFrustum(_mirrorCamera, _viewFrustum);
|
||||
|
||||
// render rear mirror view
|
||||
displaySide(renderArgs, _mirrorCamera, true, billboard);
|
||||
|
||||
|
|
|
@ -317,15 +317,14 @@ void Avatar::removeFromScene(AvatarSharedPointer self, std::shared_ptr<render::S
|
|||
}
|
||||
}
|
||||
|
||||
void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, bool postLighting) {
|
||||
void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
|
||||
if (_referential) {
|
||||
_referential->update();
|
||||
}
|
||||
|
||||
auto& batch = *renderArgs->_batch;
|
||||
|
||||
if (postLighting &&
|
||||
glm::distance(DependencyManager::get<AvatarManager>()->getMyAvatar()->getPosition(), _position) < 10.0f) {
|
||||
if (glm::distance(DependencyManager::get<AvatarManager>()->getMyAvatar()->getPosition(), _position) < 10.0f) {
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
auto deferredLighting = DependencyManager::get<DeferredLightingEffect>();
|
||||
|
||||
|
@ -415,9 +414,9 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo
|
|||
: GLOW_FROM_AVERAGE_LOUDNESS;
|
||||
|
||||
// render body
|
||||
renderBody(renderArgs, frustum, postLighting, glowLevel);
|
||||
renderBody(renderArgs, frustum, glowLevel);
|
||||
|
||||
if (!postLighting && renderArgs->_renderMode != RenderArgs::SHADOW_RENDER_MODE) {
|
||||
if (renderArgs->_renderMode != RenderArgs::SHADOW_RENDER_MODE) {
|
||||
// add local lights
|
||||
const float BASE_LIGHT_DISTANCE = 2.0f;
|
||||
const float LIGHT_EXPONENT = 1.0f;
|
||||
|
@ -432,21 +431,17 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo
|
|||
}
|
||||
}
|
||||
|
||||
if (postLighting) {
|
||||
bool renderSkeleton = Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionShapes);
|
||||
bool renderHead = Menu::getInstance()->isOptionChecked(MenuOption::RenderHeadCollisionShapes);
|
||||
bool renderBounding = Menu::getInstance()->isOptionChecked(MenuOption::RenderBoundingCollisionShapes);
|
||||
|
||||
if (renderSkeleton) {
|
||||
_skeletonModel.renderJointCollisionShapes(0.7f);
|
||||
}
|
||||
|
||||
if (renderHead && shouldRenderHead(renderArgs)) {
|
||||
getHead()->getFaceModel().renderJointCollisionShapes(0.7f);
|
||||
}
|
||||
if (renderBounding && shouldRenderHead(renderArgs)) {
|
||||
_skeletonModel.renderBoundingCollisionShapes(*renderArgs->_batch, 0.7f);
|
||||
}
|
||||
bool renderSkeleton = Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionShapes);
|
||||
bool renderHead = Menu::getInstance()->isOptionChecked(MenuOption::RenderHeadCollisionShapes);
|
||||
bool renderBounding = Menu::getInstance()->isOptionChecked(MenuOption::RenderBoundingCollisionShapes);
|
||||
if (renderSkeleton) {
|
||||
_skeletonModel.renderJointCollisionShapes(0.7f);
|
||||
}
|
||||
if (renderHead && shouldRenderHead(renderArgs)) {
|
||||
getHead()->getFaceModel().renderJointCollisionShapes(0.7f);
|
||||
}
|
||||
if (renderBounding && shouldRenderHead(renderArgs)) {
|
||||
_skeletonModel.renderBoundingCollisionShapes(*renderArgs->_batch, 0.7f);
|
||||
}
|
||||
|
||||
// Stack indicator spheres
|
||||
|
@ -570,24 +565,20 @@ void Avatar::fixupModelsInScene() {
|
|||
scene->enqueuePendingChanges(pendingChanges);
|
||||
}
|
||||
|
||||
void Avatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bool postLighting, float glowLevel) {
|
||||
void Avatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel) {
|
||||
|
||||
fixupModelsInScene();
|
||||
|
||||
{
|
||||
if (_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
|
||||
if (postLighting || renderArgs->_renderMode == RenderArgs::SHADOW_RENDER_MODE) {
|
||||
// render the billboard until both models are loaded
|
||||
renderBillboard(renderArgs);
|
||||
}
|
||||
// render the billboard until both models are loaded
|
||||
renderBillboard(renderArgs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (postLighting) {
|
||||
getHand()->render(renderArgs, false);
|
||||
}
|
||||
getHand()->render(renderArgs, false);
|
||||
}
|
||||
getHead()->render(renderArgs, 1.0f, renderFrustum, postLighting);
|
||||
getHead()->render(renderArgs, 1.0f, renderFrustum);
|
||||
}
|
||||
|
||||
bool Avatar::shouldRenderHead(const RenderArgs* renderArgs) const {
|
||||
|
@ -832,7 +823,7 @@ QVector<glm::quat> Avatar::getJointRotations() const {
|
|||
}
|
||||
QVector<glm::quat> jointRotations(_skeletonModel.getJointStateCount());
|
||||
for (int i = 0; i < _skeletonModel.getJointStateCount(); ++i) {
|
||||
_skeletonModel.getJointState(i, jointRotations[i]);
|
||||
_skeletonModel.getJointRotation(i, jointRotations[i]);
|
||||
}
|
||||
return jointRotations;
|
||||
}
|
||||
|
@ -842,7 +833,7 @@ glm::quat Avatar::getJointRotation(int index) const {
|
|||
return AvatarData::getJointRotation(index);
|
||||
}
|
||||
glm::quat rotation;
|
||||
_skeletonModel.getJointState(index, rotation);
|
||||
_skeletonModel.getJointRotation(index, rotation);
|
||||
return rotation;
|
||||
}
|
||||
|
||||
|
|
|
@ -81,8 +81,7 @@ public:
|
|||
void init();
|
||||
void simulate(float deltaTime);
|
||||
|
||||
virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPosition,
|
||||
bool postLighting = false);
|
||||
virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPosition);
|
||||
|
||||
bool addToScene(AvatarSharedPointer self, std::shared_ptr<render::Scene> scene,
|
||||
render::PendingChanges& pendingChanges);
|
||||
|
@ -235,7 +234,7 @@ protected:
|
|||
|
||||
Transform calculateDisplayNameTransform(const ViewFrustum& frustum, float fontSize, const glm::ivec4& viewport) const;
|
||||
void renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, const glm::ivec4& viewport) const;
|
||||
virtual void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bool postLighting, float glowLevel = 0.0f);
|
||||
virtual void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel = 0.0f);
|
||||
virtual bool shouldRenderHead(const RenderArgs* renderArgs) const;
|
||||
virtual void fixupModelsInScene();
|
||||
|
||||
|
|
|
@ -293,7 +293,7 @@ void Head::relaxLean(float deltaTime) {
|
|||
_deltaLeanForward *= relaxationFactor;
|
||||
}
|
||||
|
||||
void Head::render(RenderArgs* renderArgs, float alpha, ViewFrustum* renderFrustum, bool postLighting) {
|
||||
void Head::render(RenderArgs* renderArgs, float alpha, ViewFrustum* renderFrustum) {
|
||||
if (_renderLookatVectors) {
|
||||
renderLookatVectors(renderArgs, _leftEyePosition, _rightEyePosition, getCorrectedLookAtPosition());
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public:
|
|||
void init();
|
||||
void reset();
|
||||
void simulate(float deltaTime, bool isMine, bool billboard = false);
|
||||
void render(RenderArgs* renderArgs, float alpha, ViewFrustum* renderFrustum, bool postLighting);
|
||||
void render(RenderArgs* renderArgs, float alpha, ViewFrustum* renderFrustum);
|
||||
void setScale(float scale);
|
||||
void setPosition(glm::vec3 position) { _position = position; }
|
||||
void setAverageLoudness(float averageLoudness) { _averageLoudness = averageLoudness; }
|
||||
|
|
|
@ -216,10 +216,10 @@ void MyAvatar::simulate(float deltaTime) {
|
|||
{
|
||||
PerformanceTimer perfTimer("joints");
|
||||
// copy out the skeleton joints from the model
|
||||
_jointData.resize(_skeletonModel.getJointStateCount());
|
||||
_jointData.resize(_rig->getJointStateCount());
|
||||
for (int i = 0; i < _jointData.size(); i++) {
|
||||
JointData& data = _jointData[i];
|
||||
data.valid = _skeletonModel.getJointState(i, data.rotation);
|
||||
data.valid = _rig->getJointStateRotation(i, data.rotation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -333,13 +333,13 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
|
|||
|
||||
|
||||
// virtual
|
||||
void MyAvatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, bool postLighting) {
|
||||
void MyAvatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) {
|
||||
// don't render if we've been asked to disable local rendering
|
||||
if (!_shouldRender) {
|
||||
return; // exit early
|
||||
}
|
||||
|
||||
Avatar::render(renderArgs, cameraPosition, postLighting);
|
||||
Avatar::render(renderArgs, cameraPosition);
|
||||
|
||||
// don't display IK constraints in shadow mode
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::ShowIKConstraints) &&
|
||||
|
@ -1227,7 +1227,7 @@ void MyAvatar::attach(const QString& modelURL, const QString& jointName, const g
|
|||
Avatar::attach(modelURL, jointName, translation, rotation, scale, allowDuplicates, useSaved);
|
||||
}
|
||||
|
||||
void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bool postLighting, float glowLevel) {
|
||||
void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel) {
|
||||
|
||||
if (!(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
|
||||
return; // wait until all models are loaded
|
||||
|
@ -1237,7 +1237,7 @@ void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bo
|
|||
|
||||
// Render head so long as the camera isn't inside it
|
||||
if (shouldRenderHead(renderArgs)) {
|
||||
getHead()->render(renderArgs, 1.0f, renderFrustum, postLighting);
|
||||
getHead()->render(renderArgs, 1.0f, renderFrustum);
|
||||
}
|
||||
getHand()->render(renderArgs, true);
|
||||
}
|
||||
|
|
|
@ -46,8 +46,8 @@ public:
|
|||
void preRender(RenderArgs* renderArgs);
|
||||
void updateFromTrackers(float deltaTime);
|
||||
|
||||
virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, bool postLighting = false) override;
|
||||
virtual void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bool postLighting, float glowLevel = 0.0f) override;
|
||||
virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPositio) override;
|
||||
virtual void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel = 0.0f) override;
|
||||
virtual bool shouldRenderHead(const RenderArgs* renderArgs) const override;
|
||||
|
||||
// setters
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <QMultiMap>
|
||||
|
||||
#include <CapsuleShape.h>
|
||||
#include <DeferredLightingEffect.h>
|
||||
#include <SphereShape.h>
|
||||
|
||||
#include "Application.h"
|
||||
|
@ -787,31 +788,34 @@ void SkeletonModel::resetShapePositionsToDefaultPose() {
|
|||
void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float alpha) {
|
||||
const int BALL_SUBDIVISIONS = 10;
|
||||
if (_shapes.isEmpty()) {
|
||||
// the bounding shape has not been propery computed
|
||||
// the bounding shape has not been properly computed
|
||||
// so no need to render it
|
||||
return;
|
||||
}
|
||||
|
||||
// draw a blue sphere at the capsule endpoint
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
auto deferredLighting = DependencyManager::get<DeferredLightingEffect>();
|
||||
Transform transform; // = Transform();
|
||||
|
||||
// draw a blue sphere at the capsule end point
|
||||
glm::vec3 endPoint;
|
||||
_boundingShape.getEndPoint(endPoint);
|
||||
endPoint = endPoint + _translation;
|
||||
Transform transform = Transform();
|
||||
transform.setTranslation(endPoint);
|
||||
batch.setModelTransform(transform);
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
geometryCache->renderSphere(batch, _boundingShape.getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS,
|
||||
deferredLighting->bindSimpleProgram(batch);
|
||||
geometryCache->renderSphere(batch, _boundingShape.getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS,
|
||||
glm::vec4(0.6f, 0.6f, 0.8f, alpha));
|
||||
|
||||
// draw a yellow sphere at the capsule startpoint
|
||||
// draw a yellow sphere at the capsule start point
|
||||
glm::vec3 startPoint;
|
||||
_boundingShape.getStartPoint(startPoint);
|
||||
startPoint = startPoint + _translation;
|
||||
glm::vec3 axis = endPoint - startPoint;
|
||||
Transform axisTransform = Transform();
|
||||
axisTransform.setTranslation(-axis);
|
||||
batch.setModelTransform(axisTransform);
|
||||
geometryCache->renderSphere(batch, _boundingShape.getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS,
|
||||
transform.setTranslation(startPoint);
|
||||
batch.setModelTransform(transform);
|
||||
deferredLighting->bindSimpleProgram(batch);
|
||||
geometryCache->renderSphere(batch, _boundingShape.getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS,
|
||||
glm::vec4(0.8f, 0.8f, 0.6f, alpha));
|
||||
|
||||
// draw a green cylinder between the two points
|
||||
|
|
|
@ -91,6 +91,7 @@ void BillboardOverlay::render(RenderArgs* args) {
|
|||
if (batch) {
|
||||
Transform transform = _transform;
|
||||
transform.postScale(glm::vec3(getDimensions(), 1.0f));
|
||||
transform.setRotation(rotation);
|
||||
|
||||
batch->setModelTransform(transform);
|
||||
batch->setResourceTexture(0, _texture->getGPUTexture());
|
||||
|
|
|
@ -41,6 +41,14 @@ bool Rig::isRunningAnimation(AnimationHandlePointer animationHandle) {
|
|||
return _runningAnimations.contains(animationHandle);
|
||||
}
|
||||
|
||||
void Rig::deleteAnimations() {
|
||||
for (QSet<AnimationHandlePointer>::iterator it = _animationHandles.begin(); it != _animationHandles.end(); ) {
|
||||
(*it)->clearJoints();
|
||||
it = _animationHandles.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float Rig::initJointStates(QVector<JointState> states, glm::mat4 parentTransform) {
|
||||
_jointStates = states;
|
||||
initJointTransforms(parentTransform);
|
||||
|
@ -235,7 +243,12 @@ glm::mat4 Rig::getJointVisibleTransform(int jointIndex) const {
|
|||
return _jointStates[jointIndex].getVisibleTransform();
|
||||
}
|
||||
|
||||
void Rig::simulateInternal(glm::mat4 parentTransform) {
|
||||
void Rig::simulateInternal(float deltaTime, glm::mat4 parentTransform) {
|
||||
// update animations
|
||||
foreach (const AnimationHandlePointer& handle, _runningAnimations) {
|
||||
handle->simulate(deltaTime);
|
||||
}
|
||||
|
||||
for (int i = 0; i < _jointStates.size(); i++) {
|
||||
updateJointState(i, parentTransform);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ public:
|
|||
void addRunningAnimation(AnimationHandlePointer animationHandle);
|
||||
bool isRunningAnimation(AnimationHandlePointer animationHandle);
|
||||
const QList<AnimationHandlePointer>& getRunningAnimations() const { return _runningAnimations; }
|
||||
void deleteAnimations();
|
||||
|
||||
float initJointStates(QVector<JointState> states, glm::mat4 parentTransform);
|
||||
bool jointStatesEmpty() { return _jointStates.isEmpty(); };
|
||||
|
@ -81,7 +82,7 @@ public:
|
|||
void setJointTransform(int jointIndex, glm::mat4 newTransform);
|
||||
glm::mat4 getJointVisibleTransform(int jointIndex) const;
|
||||
void setJointVisibleTransform(int jointIndex, glm::mat4 newTransform);
|
||||
void simulateInternal(glm::mat4 parentTransform);
|
||||
void simulateInternal(float deltaTime, glm::mat4 parentTransform);
|
||||
bool setJointPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation, bool useRotation,
|
||||
int lastFreeIndex, bool allIntermediatesFree, const glm::vec3& alignment, float priority,
|
||||
const QVector<int>& freeLineage, glm::mat4 parentTransform);
|
||||
|
|
|
@ -43,9 +43,18 @@ btConvexHullShape* ShapeFactory::createConvexHull(const QVector<glm::vec3>& poin
|
|||
|
||||
const float MIN_MARGIN = 0.01f;
|
||||
glm::vec3 diagonal = maxCorner - minCorner;
|
||||
float minDimension = glm::min(diagonal[0], diagonal[1]);
|
||||
minDimension = glm::min(minDimension, diagonal[2]);
|
||||
margin = glm::min(glm::max(0.5f * minDimension, MIN_MARGIN), margin);
|
||||
float smallestDimension = glm::min(diagonal[0], diagonal[1]);
|
||||
smallestDimension = glm::min(smallestDimension, diagonal[2]);
|
||||
const float MIN_DIMENSION = 2.0f * MIN_MARGIN + 0.001f;
|
||||
if (smallestDimension < MIN_DIMENSION) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
if (diagonal[i] < MIN_DIMENSION) {
|
||||
diagonal[i] = MIN_DIMENSION;
|
||||
}
|
||||
}
|
||||
smallestDimension = MIN_DIMENSION;
|
||||
}
|
||||
margin = glm::min(glm::max(0.5f * smallestDimension, MIN_MARGIN), margin);
|
||||
hull->setMargin(margin);
|
||||
|
||||
// add the points, correcting for margin
|
||||
|
|
|
@ -1365,18 +1365,13 @@ void Model::updateClusterMatrices() {
|
|||
|
||||
void Model::simulateInternal(float deltaTime) {
|
||||
// update the world space transforms for all joints
|
||||
|
||||
// update animations
|
||||
foreach (const AnimationHandlePointer& handle, _runningAnimations) {
|
||||
handle->simulate(deltaTime);
|
||||
}
|
||||
|
||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset;
|
||||
_rig->simulateInternal(parentTransform);
|
||||
_rig->simulateInternal(deltaTime, parentTransform);
|
||||
|
||||
_shapesAreDirty = !_shapes.isEmpty();
|
||||
|
||||
|
||||
glm::mat4 modelToWorld = glm::mat4_cast(_rotation);
|
||||
for (int i = 0; i < _meshStates.size(); i++) {
|
||||
MeshState& state = _meshStates[i];
|
||||
|
@ -1512,21 +1507,13 @@ void Model::deleteGeometry() {
|
|||
_rig->clearJointStates();
|
||||
_meshStates.clear();
|
||||
clearShapes();
|
||||
|
||||
for (QSet<WeakAnimationHandlePointer>::iterator it = _animationHandles.begin(); it != _animationHandles.end(); ) {
|
||||
AnimationHandlePointer handle = it->lock();
|
||||
if (handle) {
|
||||
handle->clearJoints();
|
||||
it++;
|
||||
} else {
|
||||
it = _animationHandles.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_rig->deleteAnimations();
|
||||
|
||||
if (_geometry) {
|
||||
_geometry->clearLoadPriority(this);
|
||||
}
|
||||
|
||||
|
||||
_blendedBlendshapeCoefficients.clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ inline uint qHash(const std::shared_ptr<MeshPartPayload>& a, uint seed) {
|
|||
/// A generic 3D model displaying geometry loaded from a URL.
|
||||
class Model : public QObject, public PhysicsEntity {
|
||||
Q_OBJECT
|
||||
|
||||
|
||||
public:
|
||||
|
||||
typedef RenderArgs::RenderMode RenderMode;
|
||||
|
@ -66,58 +66,7 @@ public:
|
|||
|
||||
Model(RigPointer rig, QObject* parent = nullptr);
|
||||
virtual ~Model();
|
||||
|
||||
/// enables/disables scale to fit behavior, the model will be automatically scaled to the specified largest dimension
|
||||
void setScaleToFit(bool scaleToFit, float largestDimension = 0.0f, bool forceRescale = false);
|
||||
bool getScaleToFit() const { return _scaleToFit; } /// is scale to fit enabled
|
||||
bool getIsScaledToFit() const { return _scaledToFit; } /// is model scaled to fit
|
||||
const glm::vec3& getScaleToFitDimensions() const { return _scaleToFitDimensions; } /// the dimensions model is scaled to
|
||||
void setScaleToFit(bool scaleToFit, const glm::vec3& dimensions);
|
||||
|
||||
void setSnapModelToCenter(bool snapModelToCenter) {
|
||||
setSnapModelToRegistrationPoint(snapModelToCenter, glm::vec3(0.5f,0.5f,0.5f));
|
||||
};
|
||||
bool getSnapModelToCenter() {
|
||||
return _snapModelToRegistrationPoint && _registrationPoint == glm::vec3(0.5f,0.5f,0.5f);
|
||||
}
|
||||
|
||||
void setSnapModelToRegistrationPoint(bool snapModelToRegistrationPoint, const glm::vec3& registrationPoint);
|
||||
bool getSnapModelToRegistrationPoint() { return _snapModelToRegistrationPoint; }
|
||||
|
||||
void setScale(const glm::vec3& scale);
|
||||
const glm::vec3& getScale() const { return _scale; }
|
||||
|
||||
void setOffset(const glm::vec3& offset);
|
||||
const glm::vec3& getOffset() const { return _offset; }
|
||||
|
||||
void setPupilDilation(float dilation) { _pupilDilation = dilation; }
|
||||
float getPupilDilation() const { return _pupilDilation; }
|
||||
|
||||
void setBlendshapeCoefficients(const QVector<float>& coefficients) { _blendshapeCoefficients = coefficients; }
|
||||
const QVector<float>& getBlendshapeCoefficients() const { return _blendshapeCoefficients; }
|
||||
|
||||
bool isActive() const { return _geometry && _geometry->isLoaded(); }
|
||||
|
||||
bool isRenderable() const { return !_meshStates.isEmpty() || (isActive() && _geometry->getMeshes().isEmpty()); }
|
||||
|
||||
void setVisibleInScene(bool newValue, std::shared_ptr<render::Scene> scene);
|
||||
bool isVisible() const { return _isVisible; }
|
||||
|
||||
bool isLoaded() const { return _geometry && _geometry->isLoaded(); }
|
||||
bool isLoadedWithTextures() const { return _geometry && _geometry->isLoadedWithTextures(); }
|
||||
|
||||
void init();
|
||||
void reset();
|
||||
virtual void simulate(float deltaTime, bool fullUpdate = true);
|
||||
|
||||
void renderSetup(RenderArgs* args);
|
||||
|
||||
// new Scene/Engine rendering support
|
||||
bool needsFixupInScene() { return !_readyWhenAdded && readyToAddToScene(); }
|
||||
bool readyToAddToScene(RenderArgs* renderArgs = nullptr) { return !_needsReload && isRenderable() && isActive() && isLoaded(); }
|
||||
bool addToScene(std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
|
||||
bool addToScene(std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges, render::Item::Status::Getters& statusGetters);
|
||||
void removeFromScene(std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
|
||||
|
||||
/// Sets the URL of the model to render.
|
||||
/// \param fallback the URL of a fallback model to render if the requested model fails to load
|
||||
|
@ -127,22 +76,127 @@ public:
|
|||
bool retainCurrent = false, bool delayLoad = false);
|
||||
const QUrl& getURL() const { return _url; }
|
||||
|
||||
// new Scene/Engine rendering support
|
||||
void setVisibleInScene(bool newValue, std::shared_ptr<render::Scene> scene);
|
||||
bool needsFixupInScene() { return !_readyWhenAdded && readyToAddToScene(); }
|
||||
bool readyToAddToScene(RenderArgs* renderArgs = nullptr) {
|
||||
return !_needsReload && isRenderable() && isActive() && isLoaded();
|
||||
}
|
||||
bool initWhenReady(render::ScenePointer scene);
|
||||
bool addToScene(std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
|
||||
bool addToScene(std::shared_ptr<render::Scene> scene,
|
||||
render::PendingChanges& pendingChanges,
|
||||
render::Item::Status::Getters& statusGetters);
|
||||
void removeFromScene(std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges);
|
||||
void renderSetup(RenderArgs* args);
|
||||
bool isRenderable() const { return !_meshStates.isEmpty() || (isActive() && _geometry->getMeshes().isEmpty()); }
|
||||
virtual void renderJointCollisionShapes(float alpha);
|
||||
|
||||
bool isVisible() const { return _isVisible; }
|
||||
|
||||
AABox getPartBounds(int meshIndex, int partIndex);
|
||||
void renderPart(RenderArgs* args, int meshIndex, int partIndex, bool translucent);
|
||||
|
||||
bool maybeStartBlender();
|
||||
|
||||
/// Sets blended vertices computed in a separate thread.
|
||||
void setBlendedVertices(int blendNumber, const QWeakPointer<NetworkGeometry>& geometry,
|
||||
const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& normals);
|
||||
|
||||
bool isLoaded() const { return _geometry && _geometry->isLoaded(); }
|
||||
bool isLoadedWithTextures() const { return _geometry && _geometry->isLoadedWithTextures(); }
|
||||
|
||||
void setIsWireframe(bool isWireframe) { _isWireframe = isWireframe; }
|
||||
bool isWireframe() const { return _isWireframe; }
|
||||
|
||||
void init();
|
||||
void reset();
|
||||
|
||||
void setScaleToFit(bool scaleToFit, const glm::vec3& dimensions);
|
||||
|
||||
void setSnapModelToRegistrationPoint(bool snapModelToRegistrationPoint, const glm::vec3& registrationPoint);
|
||||
bool getSnapModelToRegistrationPoint() { return _snapModelToRegistrationPoint; }
|
||||
|
||||
virtual void simulate(float deltaTime, bool fullUpdate = true);
|
||||
|
||||
/// Returns a reference to the shared geometry.
|
||||
const QSharedPointer<NetworkGeometry>& getGeometry() const { return _geometry; }
|
||||
|
||||
bool isActive() const { return _geometry && _geometry->isLoaded(); }
|
||||
|
||||
Q_INVOKABLE void setTextureWithNameToURL(const QString& name, const QUrl& url)
|
||||
{ _geometry->setTextureWithNameToURL(name, url); }
|
||||
|
||||
bool convexHullContains(glm::vec3 point);
|
||||
|
||||
QStringList getJointNames() const;
|
||||
|
||||
/// Sets the joint state at the specified index.
|
||||
void setJointState(int index, bool valid, const glm::quat& rotation = glm::quat(), float priority = 1.0f);
|
||||
|
||||
bool findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
||||
BoxFace& face, QString& extraInfo, bool pickAgainstTriangles = false);
|
||||
|
||||
// Set the model to use for collisions
|
||||
Q_INVOKABLE void setCollisionModelURL(const QUrl& url);
|
||||
const QUrl& getCollisionURL() const { return _collisionUrl; }
|
||||
|
||||
void setIsWireframe(bool isWireframe) { _isWireframe = isWireframe; }
|
||||
bool isWireframe() const { return _isWireframe; }
|
||||
|
||||
|
||||
/// Returns a reference to the shared collision geometry.
|
||||
const QSharedPointer<NetworkGeometry> getCollisionGeometry(bool delayLoad = true);
|
||||
|
||||
void setOffset(const glm::vec3& offset);
|
||||
const glm::vec3& getOffset() const { return _offset; }
|
||||
|
||||
/// Sets the distance parameter used for LOD computations.
|
||||
void setLODDistance(float distance) { _lodDistance = distance; }
|
||||
|
||||
|
||||
const QList<AnimationHandlePointer>& getRunningAnimations() const { return _rig->getRunningAnimations(); }
|
||||
/// Clear the joint animation priority
|
||||
void clearJointAnimationPriority(int index);
|
||||
|
||||
void setScaleToFit(bool scaleToFit, float largestDimension = 0.0f, bool forceRescale = false);
|
||||
bool getScaleToFit() const { return _scaleToFit; } /// is scale to fit enabled
|
||||
|
||||
void setSnapModelToCenter(bool snapModelToCenter) {
|
||||
setSnapModelToRegistrationPoint(snapModelToCenter, glm::vec3(0.5f,0.5f,0.5f));
|
||||
};
|
||||
bool getSnapModelToCenter() {
|
||||
return _snapModelToRegistrationPoint && _registrationPoint == glm::vec3(0.5f,0.5f,0.5f);
|
||||
}
|
||||
|
||||
/// Returns the number of joint states in the model.
|
||||
int getJointStateCount() const { return _rig->getJointStateCount(); }
|
||||
bool getJointPositionInWorldFrame(int jointIndex, glm::vec3& position) const;
|
||||
bool getJointRotationInWorldFrame(int jointIndex, glm::quat& rotation) const;
|
||||
bool getJointCombinedRotation(int jointIndex, glm::quat& rotation) const;
|
||||
/// \param jointIndex index of joint in model structure
|
||||
/// \param rotation[out] rotation of joint in model-frame
|
||||
/// \return true if joint exists
|
||||
bool getJointRotation(int jointIndex, glm::quat& rotation) const;
|
||||
|
||||
void inverseKinematics(int jointIndex, glm::vec3 position, const glm::quat& rotation, float priority);
|
||||
|
||||
/// Returns the extents of the model in its bind pose.
|
||||
Extents getBindExtents() const;
|
||||
|
||||
/// Returns the extents of the model's mesh
|
||||
Extents getMeshExtents() const;
|
||||
|
||||
void setScale(const glm::vec3& scale);
|
||||
const glm::vec3& getScale() const { return _scale; }
|
||||
|
||||
/// enables/disables scale to fit behavior, the model will be automatically scaled to the specified largest dimension
|
||||
bool getIsScaledToFit() const { return _scaledToFit; } /// is model scaled to fit
|
||||
const glm::vec3& getScaleToFitDimensions() const { return _scaleToFitDimensions; } /// the dimensions model is scaled to
|
||||
|
||||
protected:
|
||||
|
||||
void setPupilDilation(float dilation) { _pupilDilation = dilation; }
|
||||
float getPupilDilation() const { return _pupilDilation; }
|
||||
|
||||
void setBlendshapeCoefficients(const QVector<float>& coefficients) { _blendshapeCoefficients = coefficients; }
|
||||
const QVector<float>& getBlendshapeCoefficients() const { return _blendshapeCoefficients; }
|
||||
|
||||
/// Returns the unscaled extents of the model's mesh
|
||||
Extents getUnscaledMeshExtents() const;
|
||||
|
||||
|
@ -155,15 +209,6 @@ public:
|
|||
/// Returns the scaled equivalent of a point in model space.
|
||||
glm::vec3 calculateScaledOffsetPoint(const glm::vec3& point) const;
|
||||
|
||||
/// Returns a reference to the shared geometry.
|
||||
const QSharedPointer<NetworkGeometry>& getGeometry() const { return _geometry; }
|
||||
|
||||
/// Returns a reference to the shared collision geometry.
|
||||
const QSharedPointer<NetworkGeometry> getCollisionGeometry(bool delayLoad = true);
|
||||
|
||||
/// Returns the number of joint states in the model.
|
||||
int getJointStateCount() const { return _rig->getJointStateCount(); }
|
||||
|
||||
/// Fetches the joint state at the specified index.
|
||||
/// \return whether or not the joint state is "valid" (that is, non-default)
|
||||
bool getJointState(int index, glm::quat& rotation) const;
|
||||
|
@ -171,25 +216,15 @@ public:
|
|||
/// Fetches the visible joint state at the specified index.
|
||||
/// \return whether or not the joint state is "valid" (that is, non-default)
|
||||
bool getVisibleJointState(int index, glm::quat& rotation) const;
|
||||
|
||||
|
||||
/// Clear the joint states
|
||||
void clearJointState(int index);
|
||||
|
||||
/// Clear the joint animation priority
|
||||
void clearJointAnimationPriority(int index);
|
||||
|
||||
/// Sets the joint state at the specified index.
|
||||
void setJointState(int index, bool valid, const glm::quat& rotation = glm::quat(), float priority = 1.0f);
|
||||
|
||||
|
||||
/// Returns the index of the parent of the indexed joint, or -1 if not found.
|
||||
int getParentJointIndex(int jointIndex) const;
|
||||
|
||||
|
||||
/// Returns the index of the last free ancestor of the indexed joint, or -1 if not found.
|
||||
int getLastFreeJointIndex(int jointIndex) const;
|
||||
|
||||
bool getJointPositionInWorldFrame(int jointIndex, glm::vec3& position) const;
|
||||
bool getJointRotationInWorldFrame(int jointIndex, glm::quat& rotation) const;
|
||||
bool getJointCombinedRotation(int jointIndex, glm::quat& rotation) const;
|
||||
|
||||
bool getVisibleJointPositionInWorldFrame(int jointIndex, glm::vec3& position) const;
|
||||
bool getVisibleJointRotationInWorldFrame(int jointIndex, glm::quat& rotation) const;
|
||||
|
@ -199,52 +234,15 @@ public:
|
|||
/// \return true if joint exists
|
||||
bool getJointPosition(int jointIndex, glm::vec3& position) const;
|
||||
|
||||
/// \param jointIndex index of joint in model structure
|
||||
/// \param rotation[out] rotation of joint in model-frame
|
||||
/// \return true if joint exists
|
||||
bool getJointRotation(int jointIndex, glm::quat& rotation) const;
|
||||
|
||||
QStringList getJointNames() const;
|
||||
|
||||
AnimationHandlePointer createAnimationHandle();
|
||||
|
||||
const QList<AnimationHandlePointer>& getRunningAnimations() const { return _runningAnimations; }
|
||||
|
||||
// virtual overrides from PhysicsEntity
|
||||
virtual void buildShapes();
|
||||
virtual void updateShapePositions();
|
||||
|
||||
virtual void renderJointCollisionShapes(float alpha);
|
||||
|
||||
bool maybeStartBlender();
|
||||
|
||||
/// Sets blended vertices computed in a separate thread.
|
||||
void setBlendedVertices(int blendNumber, const QWeakPointer<NetworkGeometry>& geometry,
|
||||
const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& normals);
|
||||
|
||||
void setShowTrueJointTransforms(bool show) { _showTrueJointTransforms = show; }
|
||||
|
||||
// QVector<JointState>& getJointStates() { return _rig->getJointStates(); }
|
||||
// const QVector<JointState>& getJointStates() const { return _jointStates; }
|
||||
|
||||
void inverseKinematics(int jointIndex, glm::vec3 position, const glm::quat& rotation, float priority);
|
||||
|
||||
Q_INVOKABLE void setTextureWithNameToURL(const QString& name, const QUrl& url)
|
||||
{ _geometry->setTextureWithNameToURL(name, url); }
|
||||
|
||||
bool findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
||||
BoxFace& face, QString& extraInfo, bool pickAgainstTriangles = false);
|
||||
bool convexHullContains(glm::vec3 point);
|
||||
|
||||
AABox getPartBounds(int meshIndex, int partIndex);
|
||||
void renderPart(RenderArgs* args, int meshIndex, int partIndex, bool translucent);
|
||||
|
||||
bool initWhenReady(render::ScenePointer scene);
|
||||
|
||||
protected:
|
||||
QSharedPointer<NetworkGeometry> _geometry;
|
||||
void setGeometry(const QSharedPointer<NetworkGeometry>& newGeometry);
|
||||
|
||||
|
||||
glm::vec3 _scale;
|
||||
glm::vec3 _offset;
|
||||
|
||||
|
@ -257,21 +255,21 @@ protected:
|
|||
bool _snapModelToRegistrationPoint; /// is the model's offset automatically adjusted to a registration point in model space
|
||||
bool _snappedToRegistrationPoint; /// are we currently snapped to a registration point
|
||||
glm::vec3 _registrationPoint = glm::vec3(0.5f); /// the point in model space our center is snapped to
|
||||
|
||||
|
||||
bool _showTrueJointTransforms;
|
||||
|
||||
class MeshState {
|
||||
public:
|
||||
QVector<glm::mat4> clusterMatrices;
|
||||
};
|
||||
|
||||
|
||||
QVector<MeshState> _meshStates;
|
||||
|
||||
|
||||
// returns 'true' if needs fullUpdate after geometry change
|
||||
bool updateGeometry();
|
||||
|
||||
virtual void initJointStates(QVector<JointState> states);
|
||||
|
||||
|
||||
void setScaleInternal(const glm::vec3& scale);
|
||||
void scaleToFit();
|
||||
void snapToRegistrationPoint();
|
||||
|
@ -298,11 +296,11 @@ protected:
|
|||
/// the original position
|
||||
/// \return true if the joint was found
|
||||
bool restoreJointPosition(int jointIndex, float fraction = 1.0f, float priority = 0.0f);
|
||||
|
||||
|
||||
/// Computes and returns the extended length of the limb terminating at the specified joint and starting at the joint's
|
||||
/// first free ancestor.
|
||||
float getLimbLength(int jointIndex) const;
|
||||
|
||||
|
||||
/// Allow sub classes to force invalidating the bboxes
|
||||
void invalidCalculatedMeshBoxes() {
|
||||
_calculatedMeshBoxesValid = false;
|
||||
|
@ -316,28 +314,25 @@ protected:
|
|||
// hook for derived classes to be notified when setUrl invalidates the current model.
|
||||
virtual void onInvalidate() {};
|
||||
|
||||
protected slots:
|
||||
void geometryRefreshed();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
friend class AnimationHandle;
|
||||
|
||||
|
||||
void applyNextGeometry();
|
||||
void deleteGeometry();
|
||||
QVector<JointState> createJointStates(const FBXGeometry& geometry);
|
||||
void initJointTransforms();
|
||||
|
||||
|
||||
QSharedPointer<NetworkGeometry> _nextGeometry;
|
||||
float _lodDistance;
|
||||
float _lodHysteresis;
|
||||
float _nextLODHysteresis;
|
||||
|
||||
QSharedPointer<NetworkGeometry> _collisionGeometry;
|
||||
|
||||
|
||||
float _pupilDilation;
|
||||
QVector<float> _blendshapeCoefficients;
|
||||
|
||||
|
||||
QUrl _url;
|
||||
QUrl _collisionUrl;
|
||||
bool _isVisible;
|
||||
|
@ -347,10 +342,6 @@ private:
|
|||
gpu::Batch _renderBatch;
|
||||
|
||||
QVector<QVector<QSharedPointer<Texture> > > _dilatedTextures;
|
||||
|
||||
QSet<WeakAnimationHandlePointer> _animationHandles;
|
||||
|
||||
QList<AnimationHandlePointer> _runningAnimations;
|
||||
|
||||
QVector<float> _blendedBlendshapeCoefficients;
|
||||
int _blendNumber;
|
||||
|
@ -375,12 +366,12 @@ private:
|
|||
QHash<QPair<int,int>, AABox> _calculatedMeshPartBoxes; // world coordinate AABoxes for all sub mesh part boxes
|
||||
QHash<QPair<int,int>, qint64> _calculatedMeshPartOffset;
|
||||
bool _calculatedMeshPartOffsetValid;
|
||||
|
||||
|
||||
|
||||
|
||||
bool _calculatedMeshPartBoxesValid;
|
||||
QVector<AABox> _calculatedMeshBoxes; // world coordinate AABoxes for all sub mesh boxes
|
||||
bool _calculatedMeshBoxesValid;
|
||||
|
||||
|
||||
QVector< QVector<Triangle> > _calculatedMeshTriangles; // world coordinate triangles for all sub meshes
|
||||
bool _calculatedMeshTrianglesValid;
|
||||
QMutex _mutex;
|
||||
|
@ -420,10 +411,10 @@ private:
|
|||
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,
|
||||
};
|
||||
|
||||
|
||||
enum Flag {
|
||||
IS_TRANSLUCENT = (1 << IS_TRANSLUCENT_FLAG),
|
||||
HAS_LIGHTMAP = (1 << HAS_LIGHTMAP_FLAG),
|
||||
|
@ -489,7 +480,7 @@ private:
|
|||
RenderKey(int bitmask) : _flags(bitmask) {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
class RenderPipeline {
|
||||
public:
|
||||
gpu::PipelinePointer _pipeline;
|
||||
|
@ -503,7 +494,7 @@ private:
|
|||
public:
|
||||
typedef RenderKey Key;
|
||||
|
||||
|
||||
|
||||
void addRenderPipeline(Key key, gpu::ShaderPointer& vertexShader, gpu::ShaderPointer& pixelShader);
|
||||
|
||||
void initLocations(gpu::ShaderPointer& program, Locations& locations);
|
||||
|
@ -511,8 +502,8 @@ private:
|
|||
static RenderPipelineLib _renderPipelineLib;
|
||||
|
||||
bool _renderCollisionHull;
|
||||
|
||||
|
||||
|
||||
|
||||
QSet<std::shared_ptr<MeshPartPayload>> _transparentRenderItems;
|
||||
QSet<std::shared_ptr<MeshPartPayload>> _opaqueRenderItems;
|
||||
QMap<render::ItemID, render::PayloadPointer> _renderItems;
|
||||
|
|
Loading…
Reference in a new issue