support for painting with quads, including per-vertex normals and colors

This commit is contained in:
ericrius1 2015-06-29 15:56:40 -07:00
parent cf720f9e2e
commit 9fd30581d1
8 changed files with 74 additions and 23 deletions

View file

@ -48,6 +48,7 @@ void RenderableLineEntityItem::render(RenderArgs* args) {
gpu::Batch& batch = *args->_batch;
Transform transform = Transform();
transform.setTranslation(getPosition());
transform.setRotation(getRotation());
batch.setModelTransform(transform);
batch._glLineWidth(getLineWidth());

View file

@ -37,9 +37,11 @@ gpu::PipelinePointer RenderableQuadEntityItem::_pipeline;
gpu::Stream::FormatPointer RenderableQuadEntityItem::_format;
void RenderableQuadEntityItem::createPipeline() {
static const int COLOR_OFFSET = 12;
static const int NORMAL_OFFSET = 12;
static const int COLOR_OFFSET = 24;
_format.reset(new gpu::Stream::Format());
_format->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
_format->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), NORMAL_OFFSET);
_format->setAttribute(gpu::Stream::COLOR, 0, gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA), COLOR_OFFSET);
auto VS = DependencyManager::get<DeferredLightingEffect>()->getSimpleVertexShader();
@ -68,28 +70,21 @@ int generateColor() {
}
void RenderableQuadEntityItem::updateGeometry() {
if(_points.size() < 1) {
return;
}
int compactColor = generateColor();
if (_pointsChanged) {
int compactColor = generateColor();
_numVertices = 0;
_verticesBuffer.reset(new gpu::Buffer());
glm::vec3 point, v1, v2;
for (int i = 0; i < _points.size(); i++) {
if(i % 2 == 0) {
compactColor = generateColor();
}
point = _points.at(i);
v1 = {point.x - _lineWidth, point.y, point.z};
v2 = {point.x + _lineWidth, point.y, point.z};
_verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&v1);
int vertexIndex = 0;
for (int i = 0; i < _normals.size(); i++) {
compactColor = generateColor();
_verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_vertices.at(vertexIndex++));
_verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_normals.at(i));
_verticesBuffer->append(sizeof(int), (gpu::Byte*)&compactColor);
_verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&v2);
_verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_vertices.at(vertexIndex++));
_verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_normals.at(i));
_verticesBuffer->append(sizeof(int), (gpu::Byte*)&compactColor);
_numVertices +=2;
}
_pointsChanged = false;
@ -99,9 +94,10 @@ void RenderableQuadEntityItem::updateGeometry() {
void RenderableQuadEntityItem::render(RenderArgs* args) {
if (_points.size() < 2 ) {
if (_points.size() < 2 || _vertices.size() != _normals.size() * 2) {
return;
}
if (!_pipeline) {
createPipeline();
}
@ -116,8 +112,10 @@ void RenderableQuadEntityItem::render(RenderArgs* args) {
gpu::Batch& batch = *args->_batch;
Transform transform = Transform();
transform.setTranslation(getPosition());
transform.setRotation(getRotation());
batch.setModelTransform(transform);
batch.setPipeline(_pipeline);
batch.setInputFormat(_format);

View file

@ -28,6 +28,7 @@
#include "ZoneEntityItem.h"
#include "PolyVoxEntityItem.h"
#include "LineEntityItem.h"
#include "QuadEntityItem.h"
AtmospherePropertyGroup EntityItemProperties::_staticAtmosphere;
SkyboxPropertyGroup EntityItemProperties::_staticSkybox;
@ -100,6 +101,7 @@ CONSTRUCT_PROPERTY(sourceUrl, ""),
CONSTRUCT_PROPERTY(lineWidth, LineEntityItem::DEFAULT_LINE_WIDTH),
CONSTRUCT_PROPERTY(linePoints, QVector<glm::vec3>()),
CONSTRUCT_PROPERTY(faceCamera, TextEntityItem::DEFAULT_FACE_CAMERA),
CONSTRUCT_PROPERTY(normals, QVector<glm::vec3>()),
_id(UNKNOWN_ENTITY_ID),
@ -353,6 +355,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
CHECK_PROPERTY_CHANGE(PROP_HREF, href);
CHECK_PROPERTY_CHANGE(PROP_DESCRIPTION, description);
CHECK_PROPERTY_CHANGE(PROP_FACE_CAMERA, faceCamera);
CHECK_PROPERTY_CHANGE(PROP_NORMALS, normals);
changedProperties += _stage.getChangedProperties();
changedProperties += _atmosphere.getChangedProperties();
@ -450,6 +453,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
COPY_PROPERTY_TO_QSCRIPTVALUE(href);
COPY_PROPERTY_TO_QSCRIPTVALUE(description);
COPY_PROPERTY_TO_QSCRIPTVALUE(faceCamera);
COPY_PROPERTY_TO_QSCRIPTVALUE(normals);
// Sitting properties support
if (!skipDefaults) {
@ -563,6 +567,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
COPY_PROPERTY_FROM_QSCRIPTVALUE(href, QString, setHref);
COPY_PROPERTY_FROM_QSCRIPTVALUE(description, QString, setDescription);
COPY_PROPERTY_FROM_QSCRIPTVALUE(faceCamera, bool, setFaceCamera);
COPY_PROPERTY_FROM_QSCRIPTVALUE(normals, qVectorVec3, setNormals);
if (!honorReadOnly) {
// this is used by the json reader to set things that we don't want javascript to able to affect.
@ -814,6 +819,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
if (properties.getType() == EntityTypes::Quad) {
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, properties.getLineWidth());
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, properties.getLinePoints());
APPEND_ENTITY_PROPERTY(PROP_NORMALS, properties.getNormals());
}
APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, properties.getMarketplaceID());
@ -1070,6 +1076,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
if (properties.getType() == EntityTypes::Quad) {
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_WIDTH, float, setLineWidth);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NORMALS, QVector<glm::vec3>, setNormals);
}
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MARKETPLACE_ID, QString, setMarketplaceID);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NAME, QString, setName);
@ -1188,6 +1195,8 @@ void EntityItemProperties::markAllChanged() {
_faceCameraChanged = true;
_normalsChanged = true;
}
/// The maximum bounding cube for the entity, independent of it's rotation.

View file

@ -153,6 +153,7 @@ public:
DEFINE_PROPERTY_REF(PROP_HREF, Href, href, QString);
DEFINE_PROPERTY_REF(PROP_DESCRIPTION, Description, description, QString);
DEFINE_PROPERTY(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool);
DEFINE_PROPERTY(PROP_NORMALS, Normals, normals, QVector<glm::vec3>);
static QString getBackgroundModeString(BackgroundMode mode);

View file

@ -125,6 +125,8 @@ enum EntityPropertyList {
PROP_FACE_CAMERA,
PROP_SCRIPT_TIMESTAMP,
//Used by quad entity
PROP_NORMALS,
////////////////////////////////////////////////////////////////////////////////////////////////////
// ATTENTION: add new properties to end of list just ABOVE this line
PROP_AFTER_LAST_ITEM,

View file

@ -35,7 +35,8 @@ QuadEntityItem::QuadEntityItem(const EntityItemID& entityItemID, const EntityIte
EntityItem(entityItemID) ,
_lineWidth(DEFAULT_LINE_WIDTH),
_pointsChanged(true),
_points(QVector<glm::vec3>(0))
_points(QVector<glm::vec3>(0)),
_vertices(QVector<glm::vec3>(0))
{
_type = EntityTypes::Quad;
_created = properties.getCreated();
@ -52,8 +53,8 @@ EntityItemProperties QuadEntityItem::getProperties() const {
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineWidth, getLineWidth);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(linePoints, getLinePoints);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(normals, getNormals);
properties._glowLevel = getGlowLevel();
@ -69,6 +70,7 @@ bool QuadEntityItem::setProperties(const EntityItemProperties& properties) {
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lineWidth, setLineWidth);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(linePoints, setLinePoints);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(normals, setNormals);
if (somethingChanged) {
@ -99,6 +101,36 @@ bool QuadEntityItem::appendPoint(const glm::vec3& point) {
return true;
}
bool QuadEntityItem::setNormals(const QVector<glm::vec3> &normals) {
if (_points.size () < 2) {
return false;
}
_normals = normals;
qDebug() << "NORMALS: " << normals;
_vertices.clear();
//Go through and create vertices for triangle strip based on normals
if (_normals.size() != _points.size()) {
return false;
}
glm::vec3 v1, v2, tangent, binormal, point;
for (int i = 0; i < _points.size()-1; i++) {
point = _points.at(i);
//Get tangent
tangent = _points.at(i+1) - point;
binormal = glm::normalize(glm::cross(tangent, normals.at(i))) * _lineWidth;
v1 = point + binormal;
v2 = point - binormal;
_vertices << v1 << v2;
}
//for last point we can just assume binormals are same since it represents last two vertices of quad
point = _points.at(_points.size() - 1);
v1 = point + binormal;
v2 = point - binormal;
_vertices << v1 << v2;
return true;
}
bool QuadEntityItem::setLinePoints(const QVector<glm::vec3>& points) {
if (points.size() > MAX_POINTS_PER_LINE) {
return false;
@ -147,6 +179,7 @@ int QuadEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor);
READ_ENTITY_PROPERTY(PROP_LINE_WIDTH, float, setLineWidth);
READ_ENTITY_PROPERTY(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
READ_ENTITY_PROPERTY(PROP_NORMALS, QVector<glm::vec3>, setNormals);
return bytesRead;
@ -159,6 +192,7 @@ EntityPropertyFlags QuadEntityItem::getEntityProperties(EncodeBitstreamParams& p
requestedProperties += PROP_COLOR;
requestedProperties += PROP_LINE_WIDTH;
requestedProperties += PROP_LINE_POINTS;
requestedProperties += PROP_NORMALS;
return requestedProperties;
}
@ -175,6 +209,7 @@ void QuadEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits
APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor());
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, getLineWidth());
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, getLinePoints());
APPEND_ENTITY_PROPERTY(PROP_NORMALS, getNormals());
}
void QuadEntityItem::debugDump() const {

View file

@ -56,10 +56,12 @@ class QuadEntityItem : public EntityItem {
bool setLinePoints(const QVector<glm::vec3>& points);
bool appendPoint(const glm::vec3& point);
const QVector<glm::vec3>& getLinePoints() const{ return _points; }
bool setNormals(const QVector<glm::vec3>& normals);
const QVector<glm::vec3>& getNormals() const{ return _normals; }
virtual ShapeType getShapeType() const { return SHAPE_TYPE_LINE; }
// never have a ray intersection pick a QuadEntityItem.
@ -77,6 +79,8 @@ class QuadEntityItem : public EntityItem {
float _lineWidth;
bool _pointsChanged;
QVector<glm::vec3> _points;
QVector<glm::vec3> _vertices;
QVector<glm::vec3> _normals;
};
#endif // hifi_QuadEntityItem_h

View file

@ -186,5 +186,6 @@ const PacketVersion VERSION_ENTITIES_LINE_POINTS = 29;
const PacketVersion VERSION_ENTITIES_FACE_CAMERA = 30;
const PacketVersion VERSION_ENTITIES_SCRIPT_TIMESTAMP = 31;
const PacketVersion VERSION_ENTITIES_SCRIPT_TIMESTAMP_FIX = 32;
const PacketVersion VERSION_ENTITIES_NORMALS = 33;
#endif // hifi_PacketHeaders_h