mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:24:00 +02:00
first round of hacking on implementing rendering of models for detailed ray picking
This commit is contained in:
parent
11f10f9512
commit
b6fd3628c8
6 changed files with 468 additions and 2 deletions
25
interface/resources/shaders/select.frag
Normal file
25
interface/resources/shaders/select.frag
Normal file
|
@ -0,0 +1,25 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// simple.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 9/15/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 normal;
|
||||
|
||||
// the glow intensity
|
||||
uniform float glowIntensity;
|
||||
|
||||
void main(void) {
|
||||
// set the diffuse, normal, specular data
|
||||
gl_FragData[0] = vec4(1.0f, 1.0f, 0.0f, 0.0f); //vec4(gl_Color.rgb, glowIntensity);
|
||||
gl_FragData[1] = vec4(1.0f, 1.0f, 0.0f, 0.0f); //normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
|
||||
gl_FragData[2] = vec4(1.0f, 1.0f, 0.0f, 0.0f); //vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0);
|
||||
}
|
26
interface/resources/shaders/select.vert
Normal file
26
interface/resources/shaders/select.vert
Normal file
|
@ -0,0 +1,26 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// simple.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 9/15/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 normal;
|
||||
|
||||
void main(void) {
|
||||
// transform and store the normal for interpolation
|
||||
normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
|
||||
|
||||
// pass along the diffuse color
|
||||
gl_FrontColor = vec4(1.0f, 0.0f, 0.0f, 0.0f); //gl_Color;
|
||||
|
||||
// use standard pipeline transform
|
||||
gl_Position = ftransform();
|
||||
}
|
|
@ -133,6 +133,9 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
|||
getModel(renderer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (_model) {
|
||||
// handle animations..
|
||||
if (hasAnimation()) {
|
||||
|
@ -257,7 +260,386 @@ EntityItemProperties RenderableModelEntityItem::getProperties() const {
|
|||
return properties;
|
||||
}
|
||||
|
||||
bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
||||
void** intersectedObject) const {
|
||||
|
||||
// extents is the entity relative, scaled, centered extents of the entity
|
||||
glm::mat4 rotation = glm::mat4_cast(getRotation());
|
||||
glm::mat4 translation = glm::translate(getPosition());
|
||||
glm::mat4 entityToWorldMatrix = translation * rotation;
|
||||
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
|
||||
|
||||
glm::vec3 entityFrameOrigin = glm::vec3(worldToEntityMatrix * glm::vec4(origin, 1.0f));
|
||||
glm::vec3 entityFrameDirection = glm::vec3(worldToEntityMatrix * glm::vec4(direction, 0.0f));
|
||||
|
||||
float depth = depthOfRayIntersection(entityFrameOrigin, entityFrameDirection);
|
||||
|
||||
return true; // we only got here if we intersected our non-aabox
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void RenderableModelEntityItem::renderEntityAsBillboard() {
|
||||
TextureCache* textureCache = Application->getInstance()->getTextureCache();
|
||||
textureCache->getPrimaryFramebufferObject()->bind();
|
||||
|
||||
const int BILLBOARD_SIZE = 64;
|
||||
renderRearViewMirror(QRect(0, _glWidget->getDeviceHeight() - BILLBOARD_SIZE, BILLBOARD_SIZE, BILLBOARD_SIZE), true);
|
||||
|
||||
//QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32);
|
||||
//glReadPixels(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE, GL_BGRA, GL_UNSIGNED_BYTE, image.bits());
|
||||
|
||||
textureCache->getPrimaryFramebufferObject()->release();
|
||||
|
||||
return image;
|
||||
}
|
||||
*/
|
||||
|
||||
float RenderableModelEntityItem::depthOfRayIntersection(const glm::vec3& entityFrameOrigin, const glm::vec3& entityFrameDirection) const {
|
||||
qDebug() << "RenderableModelEntityItem::depthOfRayIntersection()....";
|
||||
|
||||
Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject()->bind();
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glEnable(GL_LIGHTING); // enable?
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND); // we don't need blending
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
|
||||
// * we know the direction that the ray is coming into our bounding box.
|
||||
// * we know the location on our bounding box that the ray intersected
|
||||
// * because this API is theoretically called for things that aren't on the screen,
|
||||
// or could be off in the distance, but with an original ray pick origin ALSO off
|
||||
// in the distance, we don't really know the "pixel" size of the model at that
|
||||
// place in space. In fact that concept really doesn't make sense at all... so
|
||||
// we need to pick our own "scale" based on whatever level of precision makes
|
||||
// sense... what makes sense?
|
||||
// * we could say that we allow ray intersections down to some N meters (say 1cm
|
||||
// or 0.01 meters) in real space. The model's bounds in meters are known.
|
||||
//
|
||||
//
|
||||
float renderGranularity = 0.01f; // 1cm of render granularity - this could be ridiculous for large models
|
||||
|
||||
qDebug() << " renderGranularity:" << renderGranularity;
|
||||
|
||||
// note: these are in tree units, not meters
|
||||
glm::vec3 dimensions = getDimensions();
|
||||
glm::vec3 registrationPoint = getRegistrationPoint();
|
||||
glm::vec3 corner = -(dimensions * registrationPoint);
|
||||
|
||||
AABox entityFrameBox(corner, dimensions);
|
||||
entityFrameBox.scale((float)TREE_SCALE);
|
||||
|
||||
// rotationBetween(v1, v2) -- Helper function return the rotation from the first vector onto the second
|
||||
//glm::quat viewRotation = rotationBetween(entityFrameDirection, IDENTITY_FRONT);
|
||||
//glm::quat viewRotation = rotationBetween(IDENTITY_FRONT, entityFrameDirection);
|
||||
glm::quat viewRotation = rotationBetween(glm::vec3(0.0f, 1.0f, 0.0f), IDENTITY_FRONT);
|
||||
//glm::quat viewRotation = rotationBetween(IDENTITY_FRONT, IDENTITY_FRONT);
|
||||
|
||||
// I'd like to calculate the tightest bounding box around the entity for
|
||||
// the direction of the
|
||||
glm::vec3 minima(FLT_MAX, FLT_MAX, FLT_MAX);
|
||||
glm::vec3 maxima(-FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||
const int VERTEX_COUNT = 8;
|
||||
for (int j = 0; j < VERTEX_COUNT; j++) {
|
||||
glm::vec3 vertex = entityFrameBox.getVertex((BoxVertex)j);
|
||||
qDebug() << " vertex[" << j <<"]:" << vertex;
|
||||
|
||||
glm::vec3 rotated = viewRotation * vertex;
|
||||
qDebug() << " rotated[" << j <<"]:" << rotated;
|
||||
|
||||
minima = glm::min(minima, rotated);
|
||||
maxima = glm::max(maxima, rotated);
|
||||
}
|
||||
|
||||
qDebug() << " minima:" << minima;
|
||||
qDebug() << " maxima:" << maxima;
|
||||
|
||||
int width = glm::round((maxima.x - minima.x) / renderGranularity);
|
||||
int height = glm::round((maxima.y - minima.y) / renderGranularity);
|
||||
|
||||
qDebug() << " width:" << width;
|
||||
qDebug() << " height:" << height;
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
glScissor(0, 0, width, height);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glLoadIdentity();
|
||||
glOrtho(minima.x, maxima.x, minima.y, maxima.y, -maxima.z, -minima.z);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glm::vec3 axis = glm::axis(viewRotation);
|
||||
glRotatef(glm::degrees(glm::angle(viewRotation)), axis.x, axis.y, axis.z);
|
||||
|
||||
glm::vec3 entityFrameOriginInMeters = entityFrameOrigin * (float)TREE_SCALE;
|
||||
glm::vec3 entityFrameDirectionInMeters = entityFrameDirection * (float)TREE_SCALE;
|
||||
//glTranslatef(entityFrameOriginInMerters.x, entityFrameOriginInMerters.y, entityFrameOriginInMerters.z);
|
||||
|
||||
Application::getInstance()->setupWorldLight();
|
||||
Application::getInstance()->updateUntranslatedViewMatrix();
|
||||
|
||||
|
||||
bool renderAsModel = true;
|
||||
|
||||
if (renderAsModel) {
|
||||
const float alpha = 1.0f;
|
||||
|
||||
glm::vec3 position = getPositionInMeters();
|
||||
glm::vec3 center = getCenterInMeters();
|
||||
dimensions = getDimensions() * (float)TREE_SCALE;
|
||||
glm::quat rotation = getRotation();
|
||||
|
||||
const float MAX_COLOR = 255.0f;
|
||||
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
glPushMatrix();
|
||||
{
|
||||
//glTranslatef(position.x, position.y, position.z);
|
||||
//glm::vec3 axis = glm::axis(rotation);
|
||||
//glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||
|
||||
|
||||
glPushMatrix();
|
||||
glm::vec3 positionToCenter = center - position;
|
||||
//glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
|
||||
|
||||
//glScalef(dimensions.x, dimensions.y, dimensions.z);
|
||||
//Application::getInstance()->getDeferredLightingEffect()->renderSolidSphere(0.5f, 15, 15);
|
||||
|
||||
//_model->setRotation(rotation);
|
||||
//_model->setScaleToFit(true, glm::vec3(1.0f,1.0f,1.0f));
|
||||
|
||||
//glm::vec3(0.0f,2.0f,0.0f)
|
||||
_model->setSnapModelToRegistrationPoint(true, glm::vec3(0.5f,0.5f,0.5f));
|
||||
_model->setTranslation(glm::vec3(0.0f,0.0f,0.0f));
|
||||
_model->simulate(0.0f);
|
||||
_model->render(alpha, Model::DEFAULT_RENDER_MODE);
|
||||
|
||||
//_model->render(1.0f, Model::DEFAULT_RENDER_MODE);
|
||||
|
||||
//_model->setScaleToFit(true, dimensions);
|
||||
_model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
|
||||
_model->setTranslation(position);
|
||||
_model->simulate(0.0f);
|
||||
|
||||
glPushMatrix();
|
||||
glScalef(dimensions.x, dimensions.y, dimensions.z);
|
||||
Application::getInstance()->getDeferredLightingEffect()->renderWireSphere(0.5f, 15, 15);
|
||||
glPopMatrix();
|
||||
|
||||
/*
|
||||
glBegin(GL_LINES);
|
||||
|
||||
// low-z side - blue
|
||||
glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
glVertex3f(-0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, -0.5f, -0.5f);
|
||||
|
||||
// high-z side - cyan
|
||||
glColor4f(0.0f, 1.0f, 1.0f, 1.0f);
|
||||
glVertex3f(-0.5f, -0.5f, 0.5f);
|
||||
glVertex3f( 0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, 0.5f);
|
||||
glVertex3f( 0.5f, 0.5f, 0.5f);
|
||||
glVertex3f( 0.5f, 0.5f, 0.5f);
|
||||
glVertex3f( 0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, -0.5f, 0.5f);
|
||||
|
||||
// low-x side - yellow
|
||||
glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
|
||||
glVertex3f(-0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, -0.5f, 0.5f);
|
||||
|
||||
glVertex3f(-0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, 0.5f);
|
||||
|
||||
glVertex3f(-0.5f, 0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, -0.5f);
|
||||
|
||||
glVertex3f(-0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, -0.5f, -0.5f);
|
||||
|
||||
// high-x side - red
|
||||
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
glVertex3f(0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(0.5f, 0.5f, 0.5f);
|
||||
glVertex3f(0.5f, 0.5f, 0.5f);
|
||||
glVertex3f(0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, -0.5f, -0.5f);
|
||||
|
||||
|
||||
// origin and direction - green
|
||||
float distanceToHit;
|
||||
BoxFace ignoreFace;
|
||||
|
||||
entityFrameBox.findRayIntersection(entityFrameOriginInMeters, entityFrameDirectionInMeters, distanceToHit, ignoreFace);
|
||||
glm::vec3 pointOfIntersection = entityFrameOriginInMeters + (entityFrameDirectionInMeters * distanceToHit);
|
||||
|
||||
qDebug() << "distanceToHit: " << distanceToHit;
|
||||
qDebug() << "pointOfIntersection: " << pointOfIntersection;
|
||||
|
||||
glm::vec3 pointA = pointOfIntersection + (entityFrameDirectionInMeters * -1.0f);
|
||||
glm::vec3 pointB = pointOfIntersection + (entityFrameDirectionInMeters * 1.0f);
|
||||
qDebug() << "pointA: " << pointA;
|
||||
qDebug() << "pointB: " << pointB;
|
||||
|
||||
glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
glVertex3f(pointA.x, pointA.y, pointA.z);
|
||||
glVertex3f(pointB.x, pointB.y, pointB.z);
|
||||
|
||||
glEnd();
|
||||
*/
|
||||
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
glPopMatrix();
|
||||
|
||||
|
||||
} else {
|
||||
glm::vec3 position = getPositionInMeters();
|
||||
glm::vec3 center = getCenterInMeters();
|
||||
dimensions = getDimensions() * (float)TREE_SCALE;
|
||||
glm::quat rotation = getRotation();
|
||||
|
||||
glColor4f(1.0f, 0.0f, 1.0f, 1.0f);
|
||||
glLineWidth(2.0f);
|
||||
|
||||
glPushMatrix();
|
||||
{
|
||||
//glTranslatef(position.x, position.y, position.z);
|
||||
glm::vec3 axis = glm::axis(rotation);
|
||||
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||
|
||||
|
||||
glPushMatrix();
|
||||
glm::vec3 positionToCenter = center - position;
|
||||
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
|
||||
|
||||
glScalef(dimensions.x, dimensions.y, dimensions.z);
|
||||
//Application::getInstance()->getDeferredLightingEffect()->renderWireCube(1.0f);
|
||||
Application::getInstance()->getDeferredLightingEffect()->renderWireSphere(0.5f, 15, 15);
|
||||
|
||||
glBegin(GL_LINES);
|
||||
|
||||
// low-z side - blue
|
||||
glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
glVertex3f(-0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, -0.5f, -0.5f);
|
||||
|
||||
// high-z side - cyan
|
||||
glColor4f(0.0f, 1.0f, 1.0f, 1.0f);
|
||||
glVertex3f(-0.5f, -0.5f, 0.5f);
|
||||
glVertex3f( 0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, 0.5f);
|
||||
glVertex3f( 0.5f, 0.5f, 0.5f);
|
||||
glVertex3f( 0.5f, 0.5f, 0.5f);
|
||||
glVertex3f( 0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, -0.5f, 0.5f);
|
||||
|
||||
// low-x side - yellow
|
||||
glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
|
||||
glVertex3f(-0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, -0.5f, 0.5f);
|
||||
|
||||
glVertex3f(-0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, 0.5f);
|
||||
|
||||
glVertex3f(-0.5f, 0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, -0.5f);
|
||||
|
||||
glVertex3f(-0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, -0.5f, -0.5f);
|
||||
|
||||
// high-x side - red
|
||||
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
glVertex3f(0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(0.5f, 0.5f, 0.5f);
|
||||
glVertex3f(0.5f, 0.5f, 0.5f);
|
||||
glVertex3f(0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, -0.5f, -0.5f);
|
||||
|
||||
|
||||
// origin and direction - green
|
||||
float distanceToHit;
|
||||
BoxFace ignoreFace;
|
||||
|
||||
entityFrameBox.findRayIntersection(entityFrameOriginInMeters, entityFrameDirectionInMeters, distanceToHit, ignoreFace);
|
||||
glm::vec3 pointOfIntersection = entityFrameOriginInMeters + (entityFrameDirectionInMeters * distanceToHit);
|
||||
|
||||
qDebug() << "distanceToHit: " << distanceToHit;
|
||||
qDebug() << "pointOfIntersection: " << pointOfIntersection;
|
||||
|
||||
glm::vec3 pointA = pointOfIntersection + (entityFrameDirectionInMeters * -1.0f);
|
||||
glm::vec3 pointB = pointOfIntersection + (entityFrameDirectionInMeters * 1.0f);
|
||||
qDebug() << "pointA: " << pointA;
|
||||
qDebug() << "pointB: " << pointB;
|
||||
|
||||
glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
glVertex3f(pointA.x, pointA.y, pointA.z);
|
||||
glVertex3f(pointB.x, pointB.y, pointB.z);
|
||||
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
QImage colorData(width, height, QImage::Format_ARGB32);
|
||||
QVector<float> depthData(width * height);
|
||||
|
||||
glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, colorData.bits());
|
||||
glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, depthData.data());
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject()->release();
|
||||
|
||||
glViewport(0, 0, Application::getInstance()->getGLWidget()->width(), Application::getInstance()->getGLWidget()->height());
|
||||
|
||||
QImage imageData = colorData.mirrored(false,true);
|
||||
|
||||
bool saved = imageData.save("/Users/zappoman/Development/foo.bmp");
|
||||
|
||||
qDebug() << " saved:" << saved;
|
||||
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
#include <ModelEntityItem.h>
|
||||
#include <BoxEntityItem.h>
|
||||
|
||||
#include <QOpenGLFramebufferObject>
|
||||
#include <QRgb>
|
||||
|
||||
class RenderableModelEntityItem : public ModelEntityItem {
|
||||
public:
|
||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
@ -51,6 +54,11 @@ public:
|
|||
virtual void somethingChangedNotification() { _needsInitialSimulation = true; }
|
||||
|
||||
virtual void render(RenderArgs* args);
|
||||
virtual bool supportsDetailedRayIntersection() const { return true; }
|
||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
|
||||
void** intersectedObject) const;
|
||||
|
||||
Model* getModel(EntityTreeRenderer* renderer);
|
||||
private:
|
||||
void remapTextures();
|
||||
|
@ -63,6 +71,9 @@ private:
|
|||
QString _currentTextures;
|
||||
QStringList _originalTextures;
|
||||
bool _originalTexturesRead;
|
||||
|
||||
float depthOfRayIntersection(const glm::vec3& entityFrameOrigin, const glm::vec3& entityFrameDirection) const;
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_RenderableModelEntityItem_h
|
||||
|
|
|
@ -103,6 +103,9 @@ Model::SkinLocations Model::_skinNormalSpecularMapLocations;
|
|||
Model::SkinLocations Model::_skinShadowLocations;
|
||||
Model::SkinLocations Model::_skinTranslucentLocations;
|
||||
|
||||
ProgramObject Model::_selectProgram;
|
||||
Model::Locations Model::_selectLocations;
|
||||
|
||||
void Model::setScale(const glm::vec3& scale) {
|
||||
setScaleInternal(scale);
|
||||
// if anyone sets scale manually, then we are no longer scaled to fit
|
||||
|
@ -269,7 +272,7 @@ void Model::init() {
|
|||
_program.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/model.vert");
|
||||
_program.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/model.frag");
|
||||
_program.link();
|
||||
|
||||
|
||||
initProgram(_program, _locations);
|
||||
|
||||
_normalMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
|
@ -387,6 +390,14 @@ void Model::init() {
|
|||
_skinTranslucentProgram.link();
|
||||
|
||||
initSkinProgram(_skinTranslucentProgram, _skinTranslucentLocations);
|
||||
|
||||
|
||||
// select/ray picking program
|
||||
_selectProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/select.vert");
|
||||
_selectProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/select.frag");
|
||||
_selectProgram.link();
|
||||
initProgram(_selectProgram, _selectLocations);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2148,6 +2159,13 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f
|
|||
ProgramObject* activeProgram = program;
|
||||
Locations* activeLocations = locations;
|
||||
|
||||
// XXXBHG - hack to render yellow
|
||||
if (mode == SELECT_RENDER_MODE) {
|
||||
//activeProgram = &_selectProgram;
|
||||
//activeLocations = &_selectLocations;
|
||||
// need skin version
|
||||
}
|
||||
|
||||
if (isSkinned) {
|
||||
activeProgram = skinProgram;
|
||||
activeLocations = skinLocations;
|
||||
|
|
|
@ -86,7 +86,7 @@ public:
|
|||
void reset();
|
||||
virtual void simulate(float deltaTime, bool fullUpdate = true);
|
||||
|
||||
enum RenderMode { DEFAULT_RENDER_MODE, SHADOW_RENDER_MODE, DIFFUSE_RENDER_MODE, NORMAL_RENDER_MODE };
|
||||
enum RenderMode { DEFAULT_RENDER_MODE, SHADOW_RENDER_MODE, DIFFUSE_RENDER_MODE, NORMAL_RENDER_MODE, SELECT_RENDER_MODE };
|
||||
|
||||
bool render(float alpha = 1.0f, RenderMode mode = DEFAULT_RENDER_MODE, RenderArgs* args = NULL);
|
||||
|
||||
|
@ -318,6 +318,8 @@ private:
|
|||
static ProgramObject _skinTranslucentProgram;
|
||||
|
||||
static ProgramObject _skinShadowProgram;
|
||||
|
||||
static ProgramObject _selectProgram;
|
||||
|
||||
static int _normalMapTangentLocation;
|
||||
static int _normalSpecularMapTangentLocation;
|
||||
|
@ -343,6 +345,8 @@ private:
|
|||
static Locations _lightmapSpecularMapLocations;
|
||||
static Locations _lightmapNormalSpecularMapLocations;
|
||||
|
||||
static Locations _selectLocations;
|
||||
|
||||
static void initProgram(ProgramObject& program, Locations& locations, int specularTextureUnit = 1);
|
||||
|
||||
class SkinLocations : public Locations {
|
||||
|
|
Loading…
Reference in a new issue