diff --git a/src/depthMapEntity/DepthMapEntity.cpp b/src/depthMapEntity/DepthMapEntity.cpp index 7309826..36d28df 100644 --- a/src/depthMapEntity/DepthMapEntity.cpp +++ b/src/depthMapEntity/DepthMapEntity.cpp @@ -9,13 +9,7 @@ #include #include #include -#include -// #include -#include -#include -#include -#include #include #include #include @@ -30,7 +24,6 @@ namespace oiio = OIIO; -// #define QTOIIO_DEPTHMAP_USE_INDEXES 1 namespace depthMapEntity { @@ -81,10 +74,10 @@ inline Vec3f cross(const Vec3f& a, const Vec3f& b) DepthMapEntity::DepthMapEntity(Qt3DCore::QNode* parent) : Qt3DCore::QEntity(parent) , _displayMode(DisplayMode::Unknown) + , _pointSizeParameter(new Qt3DRender::QParameter) { - std::cout << "[DepthMapEntity] DepthMapEntity" << std::endl; qDebug() << "[DepthMapEntity] DepthMapEntity"; - setDisplayMode(DisplayMode::Triangles); + createMaterials(); } void DepthMapEntity::setSource(const QUrl& value) @@ -101,9 +94,7 @@ void DepthMapEntity::setDisplayMode(const DepthMapEntity::DisplayMode& value) if(_displayMode == value) return; _displayMode = value; - - createMaterials(); - loadDepthMap(); + updateMaterial(); Q_EMIT displayModeChanged(); } @@ -113,110 +104,61 @@ void DepthMapEntity::setDisplayColor(bool value) if(_displayColor == value) return; _displayColor = value; - - createMaterials(); - loadDepthMap(); + updateMaterial(); Q_EMIT displayColorChanged(); } -// private -void DepthMapEntity::createMaterials() +void DepthMapEntity::updateMaterial() { - using namespace Qt3DRender; - using namespace Qt3DExtras; + Qt3DRender::QMaterial* newMaterial = nullptr; switch(_displayMode) { case DisplayMode::Points: - { - _cloudMaterial = new QMaterial(this); + newMaterial = _cloudMaterial; + _meshRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Points); + break; + case DisplayMode::Triangles: + _meshRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles); + if(_displayColor) + newMaterial = _colorMaterial; + else + newMaterial = _diffuseMaterial; + break; + default: + newMaterial = _diffuseMaterial; + } - // configure cloud material - QEffect* effect = new QEffect; - QTechnique* technique = new QTechnique; - QRenderPass* renderPass = new QRenderPass; - QShaderProgram* shaderProgram = new QShaderProgram; + if(newMaterial == _currentMaterial) + return; - // set vertex shader - shaderProgram->setVertexShaderCode(R"(#version 330 core - uniform mat4 modelViewProjection; - in vec3 vertexPosition; - in vec3 vertexColor; - out vec3 colors; - in float pixelSize; - out float pixelSizes; - void main(void) - { - gl_Position = modelViewProjection * vec4(vertexPosition, 1.0f); - colors = vertexColor; - pixelSizes = pixelSize; - } - )"); + if(_currentMaterial) + removeComponent(_currentMaterial); - // set fragment shader - shaderProgram->setFragmentShaderCode(R"(#version 330 core - in vec3 color; - out vec4 fragColor; - void main(void) - { - fragColor = vec4(color, 1.0); - } - )"); + _currentMaterial = newMaterial; + addComponent(_currentMaterial); +} - // set geometry shader - shaderProgram->setGeometryShaderCode(R"(#version 330 - layout(points) in; - layout(triangle_strip) out; - layout(max_vertices = 4) out; - uniform mat4 projectionMatrix; - in float pixelSizes[]; - in vec3 colors[]; - out vec3 color; - void main(void) - { - float pixelSize = 0.4 * pixelSizes[0]; - vec4 right = vec4(0, pixelSize, 0, 0); - vec4 up = vec4(pixelSize, 0, 0, 0); - color = colors[0]; - gl_Position = gl_in[0].gl_Position - projectionMatrix*(right + up); - EmitVertex(); - gl_Position = gl_in[0].gl_Position - projectionMatrix*(right - up); - EmitVertex(); - gl_Position = gl_in[0].gl_Position + projectionMatrix*(right - up); - EmitVertex(); - gl_Position = gl_in[0].gl_Position + projectionMatrix*(right + up); - EmitVertex(); - EndPrimitive(); - } - )"); +void DepthMapEntity::setPointSize(const float& value) +{ + if(_pointSize == value) + return; + _pointSize = value; + _pointSizeParameter->setValue(value); + _cloudMaterial->setEnabled(_pointSize > 0.0f); + Q_EMIT pointSizeChanged(); +} + +// private +void DepthMapEntity::createMaterials() +{ + using namespace Qt3DRender; + using namespace Qt3DExtras; - // build the material - renderPass->setShaderProgram(shaderProgram); - technique->addRenderPass(renderPass); - effect->addTechnique(technique); - _cloudMaterial->setEffect(effect); - break; - } - case DisplayMode::Triangles: { - std::cout << "[DepthMapEntity] DisplayMode::Triangles:" << std::endl; - if(_displayColor) - { - std::cout << "[DepthMapEntity] QPerVertexColorMaterial" << std::endl; - _cloudMaterial = new QPerVertexColorMaterial(this); - } - else - { - std::cout << "[DepthMapEntity] QDiffuseSpecularMaterial" << std::endl; - QDiffuseSpecularMaterial* cloudMaterial = new QDiffuseSpecularMaterial(this); - cloudMaterial->setAmbient(QColor(0, 0, 0)); - cloudMaterial->setDiffuse(QColor(255, 255, 255)); - cloudMaterial->setSpecular(QColor(0, 0, 0)); - cloudMaterial->setShininess(0.0); - _cloudMaterial = cloudMaterial; - } - /* + _cloudMaterial = new QMaterial(this); + // configure cloud material QEffect* effect = new QEffect; QTechnique* technique = new QTechnique; @@ -224,320 +166,52 @@ void DepthMapEntity::createMaterials() QShaderProgram* shaderProgram = new QShaderProgram; // set vertex shader - shaderProgram->setVertexShaderCode(R"(#version 330 core - uniform mat4 modelViewProjection; - in vec3 vertexPosition; - in vec3 vertexColor; - out vec3 colors; - in float pixelSize; - out float pixelSizes; - void main(void) - { - gl_Position = modelViewProjection * vec4(vertexPosition, 1.0f); - colors = vertexColor; - pixelSizes = pixelSize; - } + shaderProgram->setVertexShaderCode(R"(#version 130 + in vec3 vertexPosition; + in vec3 vertexColor; + out vec3 color; + uniform mat4 mvp; + uniform mat4 projectionMatrix; + uniform mat4 viewportMatrix; + uniform float pointSize; + void main() + { + color = vertexColor; + gl_Position = mvp * vec4(vertexPosition, 1.0); + gl_PointSize = max(viewportMatrix[1][1] * projectionMatrix[1][1] * pointSize / gl_Position.w, 1.0); + } )"); // set fragment shader - shaderProgram->setFragmentShaderCode(R"(#version 330 core + shaderProgram->setFragmentShaderCode(R"(#version 130 in vec3 color; out vec4 fragColor; void main(void) { fragColor = vec4(color, 1.0); } - )");*/ - - /* - _cloudMaterial = new QMaterial(this); - - // configure cloud material - QEffect* effect = new QEffect; - QTechnique* technique = new QTechnique; - QRenderPass* renderPass = new QRenderPass; - QShaderProgram* shaderProgram = new QShaderProgram; - - // set vertex shader - shaderProgram->setVertexShaderCode(R"( - #version 330 core - - in vec3 vertexPosition; - in vec3 vertexNormal; - - out EyeSpaceVertex { - vec3 position; - vec3 normal; - } vs_out; - - uniform mat4 modelView; - uniform mat3 modelViewNormal; - uniform mat4 mvp; - - void main() - { - vs_out.normal = normalize( modelViewNormal * vertexNormal ); - vs_out.position = vec3( modelView * vec4( vertexPosition, 1.0 ) ); - - gl_Position = mvp * vec4( vertexPosition, 1.0 ); - } )"); - // set fragment shader - shaderProgram->setFragmentShaderCode(R"( - #version 330 core - - uniform struct LightInfo { - vec4 position; - vec3 intensity; - } light; - - uniform struct LineInfo { - float width; - vec4 color; - } line; - - uniform vec3 ka; // Ambient reflectivity - uniform vec3 kd; // Diffuse reflectivity - uniform vec3 ks; // Specular reflectivity - uniform float shininess; // Specular shininess factor - - in WireframeVertex { - vec3 position; - vec3 normal; - noperspective vec4 edgeA; - noperspective vec4 edgeB; - flat int configuration; - } fs_in; - - out vec4 fragColor; - - vec3 adsModel( const in vec3 pos, const in vec3 n ) - { - // Calculate the vector from the light to the fragment - vec3 s = normalize( vec3( light.position ) - pos ); - - // Calculate the vector from the fragment to the eye position (the - // origin since this is in "eye" or "camera" space - vec3 v = normalize( -pos ); - - // Refleft the light beam using the normal at this fragment - vec3 r = reflect( -s, n ); - - // Calculate the diffus component - vec3 diffuse = vec3( max( dot( s, n ), 0.0 ) ); - - // Calculate the specular component - vec3 specular = vec3( pow( max( dot( r, v ), 0.0 ), shininess ) ); - - // Combine the ambient, diffuse and specular contributions - return light.intensity * ( ka + kd * diffuse + ks * specular ); - } - - vec4 shadeLine( const in vec4 color ) - { - // Find the smallest distance between the fragment and a triangle edge - float d; - if ( fs_in.configuration == 0 ) - { - // Common configuration - d = min( fs_in.edgeA.x, fs_in.edgeA.y ); - d = min( d, fs_in.edgeA.z ); - } - else - { - // Handle configuration where screen space projection breaks down - // Compute and compare the squared distances - vec2 AF = gl_FragCoord.xy - fs_in.edgeA.xy; - float sqAF = dot( AF, AF ); - float AFcosA = dot( AF, fs_in.edgeA.zw ); - d = abs( sqAF - AFcosA * AFcosA ); - - vec2 BF = gl_FragCoord.xy - fs_in.edgeB.xy; - float sqBF = dot( BF, BF ); - float BFcosB = dot( BF, fs_in.edgeB.zw ); - d = min( d, abs( sqBF - BFcosB * BFcosB ) ); - - // Only need to care about the 3rd edge for some configurations. - if ( fs_in.configuration == 1 || fs_in.configuration == 2 || fs_in.configuration == 4 ) - { - float AFcosA0 = dot( AF, normalize( fs_in.edgeB.xy - fs_in.edgeA.xy ) ); - d = min( d, abs( sqAF - AFcosA0 * AFcosA0 ) ); - } - - d = sqrt( d ); - } - - // Blend between line color and phong color - float mixVal; - if ( d < line.width - 1.0 ) - { - mixVal = 1.0; - } - else if ( d > line.width + 1.0 ) - { - mixVal = 0.0; - } - else - { - float x = d - ( line.width - 1.0 ); - mixVal = exp2( -2.0 * ( x * x ) ); - } - - return mix( color, line.color, mixVal ); - } - - void main() - { - // Calculate the color from the phong model - vec4 color = vec4( adsModel( fs_in.position, normalize( fs_in.normal ) ), 1.0 ); - fragColor = shadeLine( color ); - } - )"); - - // set geometry shader - shaderProgram->setGeometryShaderCode(R"( - #version 330 core - - layout( triangles ) in; - layout( triangle_strip, max_vertices = 3 ) out; - - in EyeSpaceVertex { - vec3 position; - vec3 normal; - } gs_in[]; - - out WireframeVertex { - vec3 position; - vec3 normal; - noperspective vec4 edgeA; - noperspective vec4 edgeB; - flat int configuration; - } gs_out; - - uniform mat4 viewportMatrix; - - const int infoA[] = int[]( 0, 0, 0, 0, 1, 1, 2 ); - const int infoB[] = int[]( 1, 1, 2, 0, 2, 1, 2 ); - const int infoAd[] = int[]( 2, 2, 1, 1, 0, 0, 0 ); - const int infoBd[] = int[]( 2, 2, 1, 2, 0, 2, 1 ); - - vec2 transformToViewport( const in vec4 p ) - { - return vec2( viewportMatrix * ( p / p.w ) ); - } - - void main() - { - gs_out.configuration = int(gl_in[0].gl_Position.z < 0) * int(4) - + int(gl_in[1].gl_Position.z < 0) * int(2) - + int(gl_in[2].gl_Position.z < 0); - - // If all vertices are behind us, cull the primitive - if (gs_out.configuration == 7) - return; - - // Transform each vertex into viewport space - vec2 p[3]; - p[0] = transformToViewport( gl_in[0].gl_Position ); - p[1] = transformToViewport( gl_in[1].gl_Position ); - p[2] = transformToViewport( gl_in[2].gl_Position ); - - if (gs_out.configuration == 0) - { - // Common configuration where all vertices are within the viewport - gs_out.edgeA = vec4(0.0); - gs_out.edgeB = vec4(0.0); - - // Calculate lengths of 3 edges of triangle - float a = length( p[1] - p[2] ); - float b = length( p[2] - p[0] ); - float c = length( p[1] - p[0] ); - - // Calculate internal angles using the cosine rule - float alpha = acos( ( b * b + c * c - a * a ) / ( 2.0 * b * c ) ); - float beta = acos( ( a * a + c * c - b * b ) / ( 2.0 * a * c ) ); - - // Calculate the perpendicular distance of each vertex from the opposing edge - float ha = abs( c * sin( beta ) ); - float hb = abs( c * sin( alpha ) ); - float hc = abs( b * sin( alpha ) ); - - // Now add this perpendicular distance as a per-vertex property in addition to - // the position and normal calculated in the vertex shader. - - // Vertex 0 (a) - gs_out.edgeA = vec4( ha, 0.0, 0.0, 0.0 ); - gs_out.normal = gs_in[0].normal; - gs_out.position = gs_in[0].position; - gl_Position = gl_in[0].gl_Position; - EmitVertex(); - - // Vertex 1 (b) - gs_out.edgeA = vec4( 0.0, hb, 0.0, 0.0 ); - gs_out.normal = gs_in[1].normal; - gs_out.position = gs_in[1].position; - gl_Position = gl_in[1].gl_Position; - EmitVertex(); - - // Vertex 2 (c) - gs_out.edgeA = vec4( 0.0, 0.0, hc, 0.0 ); - gs_out.normal = gs_in[2].normal; - gs_out.position = gs_in[2].position; - gl_Position = gl_in[2].gl_Position; - EmitVertex(); - - // Finish the primitive off - EndPrimitive(); - } - else - { - // Viewport projection breaks down for one or two vertices. - // Caclulate what we can here and defer rest to fragment shader. - // Since this is coherent for the entire primitive the conditional - // in the fragment shader is still cheap as all concurrent - // fragment shader invocations will take the same code path. - - // Copy across the viewport-space points for the (up to) two vertices - // in the viewport - gs_out.edgeA.xy = p[infoA[gs_out.configuration]]; - gs_out.edgeB.xy = p[infoB[gs_out.configuration]]; - - // Copy across the viewport-space edge vectors for the (up to) two vertices - // in the viewport - gs_out.edgeA.zw = normalize( gs_out.edgeA.xy - p[ infoAd[gs_out.configuration] ] ); - gs_out.edgeB.zw = normalize( gs_out.edgeB.xy - p[ infoBd[gs_out.configuration] ] ); - - // Pass through the other vertex attributes - gs_out.normal = gs_in[0].normal; - gs_out.position = gs_in[0].position; - gl_Position = gl_in[0].gl_Position; - EmitVertex(); - - gs_out.normal = gs_in[1].normal; - gs_out.position = gs_in[1].position; - gl_Position = gl_in[1].gl_Position; - EmitVertex(); - - gs_out.normal = gs_in[2].normal; - gs_out.position = gs_in[2].position; - gl_Position = gl_in[2].gl_Position; - EmitVertex(); - - // Finish the primitive off - EndPrimitive(); - } - } - )"); + // add a pointSize uniform + _pointSizeParameter->setName("pointSize"); + _pointSizeParameter->setValue(_pointSize); + _cloudMaterial->addParameter(_pointSizeParameter); // build the material renderPass->setShaderProgram(shaderProgram); technique->addRenderPass(renderPass); effect->addTechnique(technique); _cloudMaterial->setEffect(effect); - */ - break; } + { + _colorMaterial = new QPerVertexColorMaterial(this); + } + { + _diffuseMaterial = new QDiffuseSpecularMaterial(this); + _diffuseMaterial->setAmbient(QColor(0, 0, 0)); + _diffuseMaterial->setDiffuse(QColor(255, 255, 255)); + _diffuseMaterial->setSpecular(QColor(0, 0, 0)); + _diffuseMaterial->setShininess(0.0); } } @@ -559,6 +233,14 @@ bool validTriangleRatio(const Vec3f& a, const Vec3f& b, const Vec3f& c) // private void DepthMapEntity::loadDepthMap() { + + if(_meshRenderer) + { + removeComponent(_meshRenderer); + _meshRenderer->deleteLater(); + _meshRenderer = nullptr; + } + qDebug() << "[DepthMapEntity] loadDepthMap"; if(!_source.isValid()) return; @@ -585,7 +267,6 @@ void DepthMapEntity::loadDepthMap() { qDebug() << "[DepthMapEntity] CArr: " << cParam->nvalues(); std::copy_n((const double*)cParam->data(), 3, CArr.m); - CArr.doprintf(); } else { @@ -598,7 +279,6 @@ void DepthMapEntity::loadDepthMap() { qDebug() << "[DepthMapEntity] iCamArr: " << icParam->nvalues(); std::copy_n((const double*)icParam->data(), 9, iCamArr.m); - iCamArr.doprintf(); } else { @@ -607,11 +287,13 @@ void DepthMapEntity::loadDepthMap() const QUrl simPath = QUrl::fromLocalFile(_source.path().replace("depthMap", "simMap")); oiio::ImageBuf simBuf; - if(_displayColor && simPath.isValid()) + + if(simPath.isValid()) { qDebug() << "[DepthMapEntity] Load Sim Map: " << simPath; simBuf.reset(simPath.toLocalFile().toStdString(), 0, 0, NULL, &configSpec); } + const oiio::ImageSpec& simSpec = simBuf.spec(); const bool validSimMap = (simSpec.width == inSpec.width) && (simSpec.height == inSpec.height); @@ -621,7 +303,6 @@ void DepthMapEntity::loadDepthMap() std::vector indexPerPixel(inSpec.width * inSpec.height, -1); std::vector positions; std::vector colors; - std::vector pixelSizes; for(int y = 0; y < inSpec.height; ++y) { @@ -633,15 +314,11 @@ void DepthMapEntity::loadDepthMap() continue; point3d p = CArr + (iCamArr * point2d((double)x, (double)y)).normalize() * depthValue; - - point3d vect = (iCamArr * point2d(x+1, y)).normalize(); - const double pixelSize = pointLineDistance3D(p, CArr, vect); - Vec3f position(p.x, p.y, p.z); indexPerPixel[y * inSpec.width + x] = positions.size(); positions.push_back(position); - pixelSizes.push_back(pixelSize); + if(validSimMap) { float simValue = 0.0f; @@ -660,256 +337,121 @@ void DepthMapEntity::loadDepthMap() qDebug() << "[DepthMapEntity] Valid Depth Values: " << positions.size(); - // create a new geometry renderer - QGeometryRenderer* customMeshRenderer = new QGeometryRenderer; + // create geometry QGeometry* customGeometry = new QGeometry; // vertices buffer std::vector trianglesIndexes; - if(_displayMode == DisplayMode::Triangles) + trianglesIndexes.reserve(2*3*positions.size()); + for(int y = 0; y < inSpec.height-1; ++y) { - trianglesIndexes.reserve(2*3*positions.size()); - for(int y = 0; y < inSpec.height-1; ++y) + for(int x = 0; x < inSpec.width-1; ++x) { - for(int x = 0; x < inSpec.width-1; ++x) + int pixelIndexA = indexPerPixel[y * inSpec.width + x]; + int pixelIndexB = indexPerPixel[(y + 1) * inSpec.width + x]; + int pixelIndexC = indexPerPixel[(y + 1) * inSpec.width + x + 1]; + int pixelIndexD = indexPerPixel[y * inSpec.width + x + 1]; + if(pixelIndexA != -1 && + pixelIndexB != -1 && + pixelIndexC != -1 && + validTriangleRatio(positions[pixelIndexA], positions[pixelIndexB], positions[pixelIndexC])) { - int pixelIndexA = indexPerPixel[y * inSpec.width + x]; - int pixelIndexB = indexPerPixel[(y + 1) * inSpec.width + x]; - int pixelIndexC = indexPerPixel[(y + 1) * inSpec.width + x + 1]; - int pixelIndexD = indexPerPixel[y * inSpec.width + x + 1]; - if(pixelIndexA != -1 && - pixelIndexB != -1 && - pixelIndexC != -1 && - validTriangleRatio(positions[pixelIndexA], positions[pixelIndexB], positions[pixelIndexC])) - { - trianglesIndexes.push_back(pixelIndexA); - trianglesIndexes.push_back(pixelIndexB); - trianglesIndexes.push_back(pixelIndexC); - } - if(pixelIndexC != -1 && - pixelIndexD != -1 && - pixelIndexA != -1 && - validTriangleRatio(positions[pixelIndexC], positions[pixelIndexD], positions[pixelIndexA])) - { - trianglesIndexes.push_back(pixelIndexC); - trianglesIndexes.push_back(pixelIndexD); - trianglesIndexes.push_back(pixelIndexA); - } + trianglesIndexes.push_back(pixelIndexA); + trianglesIndexes.push_back(pixelIndexB); + trianglesIndexes.push_back(pixelIndexC); + } + if(pixelIndexC != -1 && + pixelIndexD != -1 && + pixelIndexA != -1 && + validTriangleRatio(positions[pixelIndexC], positions[pixelIndexD], positions[pixelIndexA])) + { + trianglesIndexes.push_back(pixelIndexC); + trianglesIndexes.push_back(pixelIndexD); + trianglesIndexes.push_back(pixelIndexA); } } - qDebug() << "[DepthMapEntity] Nb triangles: " << trianglesIndexes.size(); - } -#ifndef QTOIIO_DEPTHMAP_USE_INDEXES - if(_displayMode == DisplayMode::Triangles) - { - std::vector triangles; - triangles.resize(trianglesIndexes.size()); - for(int i = 0; i < trianglesIndexes.size(); ++i) - { - triangles[i] = positions[trianglesIndexes[i]]; - } - std::vector normals; - normals.resize(triangles.size()); - for(int i = 0; i < trianglesIndexes.size(); i+=3) - { - Vec3f normal = cross(triangles[i+1]-triangles[i], triangles[i+2]-triangles[i]); - for(int t = 0; t < 3; ++t) - normals[i+t] = normal; - } - - QBuffer* vertexBuffer = new QBuffer(QBuffer::VertexBuffer); - QByteArray trianglesData((const char*)&triangles[0], triangles.size() * sizeof(Vec3f)); - vertexBuffer->setData(trianglesData); - - QBuffer* normalBuffer = new QBuffer(QBuffer::VertexBuffer); - QByteArray normalsData((const char*)&normals[0], normals.size() * sizeof(Vec3f)); - normalBuffer->setData(normalsData); - - QAttribute* positionAttribute = new QAttribute(this); - positionAttribute->setName(QAttribute::defaultPositionAttributeName()); - positionAttribute->setAttributeType(QAttribute::VertexAttribute); - positionAttribute->setBuffer(vertexBuffer); - positionAttribute->setDataType(QAttribute::Float); - positionAttribute->setDataSize(3); - positionAttribute->setByteOffset(0); - positionAttribute->setByteStride(sizeof(Vec3f)); - positionAttribute->setCount(triangles.size()); - - QAttribute* normalAttribute = new QAttribute(this); - normalAttribute->setName(QAttribute::defaultNormalAttributeName()); - normalAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); - normalAttribute->setBuffer(normalBuffer); - normalAttribute->setDataType(QAttribute::Float); - normalAttribute->setDataSize(3); - normalAttribute->setByteOffset(0); - normalAttribute->setByteStride(sizeof(Vec3f)); - normalAttribute->setCount(normals.size()); - - customGeometry->addAttribute(positionAttribute); - customGeometry->addAttribute(normalAttribute); - // customGeometry->setBoundingVolumePositionAttribute(positionAttribute); - } - else -#endif - { - QByteArray positionData((const char*)positions[0].m, positions.size() * 3 * sizeof(float)); - QBuffer* vertexDataBuffer = new QBuffer(QBuffer::VertexBuffer); - vertexDataBuffer->setData(positionData); - QAttribute* positionAttribute = new QAttribute; - positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName()); - positionAttribute->setAttributeType(QAttribute::VertexAttribute); - positionAttribute->setBuffer(vertexDataBuffer); - positionAttribute->setDataType(QAttribute::Float); - positionAttribute->setDataSize(3); - positionAttribute->setByteOffset(0); - positionAttribute->setByteStride(3 * sizeof(float)); - positionAttribute->setCount(positions.size()); - - customGeometry->addAttribute(positionAttribute); - // customGeometry->setBoundingVolumePositionAttribute(positionAttribute); - } - - // colors buffer - if(_displayColor) - { -#ifdef QTOIIO_DEPTHMAP_USE_INDEXES - // read color data - QBuffer* colorDataBuffer = new QBuffer(QBuffer::VertexBuffer); - QByteArray colorData((const char*)colors[0].m, colors.size() * 3 * sizeof(float)); - colorDataBuffer->setData(colorData); - - QAttribute* colorAttribute = new QAttribute; - qDebug() << "Qt3DRender::QAttribute::defaultColorAttributeName(): " << Qt3DRender::QAttribute::defaultColorAttributeName().toStdString(); - colorAttribute->setName(Qt3DRender::QAttribute::defaultColorAttributeName()); - colorAttribute->setAttributeType(QAttribute::VertexAttribute); - colorAttribute->setBuffer(colorDataBuffer); - colorAttribute->setDataType(QAttribute::Float); - colorAttribute->setDataSize(3); - colorAttribute->setByteOffset(0); - colorAttribute->setByteStride(3 * sizeof(float)); - colorAttribute->setCount(positions.size()); - customGeometry->addAttribute(colorAttribute); -#else - // Duplicate colors as we cannot use indexes! - std::vector colorsFlat; - colorsFlat.reserve(trianglesIndexes.size()); - for(int i = 0; i < trianglesIndexes.size(); ++i) - { - colorsFlat.push_back(colors[trianglesIndexes[i]]); - } - - // read color data - QBuffer* colorDataBuffer = new QBuffer(QBuffer::VertexBuffer); - QByteArray colorData((const char*)colorsFlat[0].m, colorsFlat.size() * 3 * sizeof(float)); - colorDataBuffer->setData(colorData); - - QAttribute* colorAttribute = new QAttribute; - qDebug() << "Qt3DRender::QAttribute::defaultColorAttributeName(): " << Qt3DRender::QAttribute::defaultColorAttributeName(); - colorAttribute->setName(Qt3DRender::QAttribute::defaultColorAttributeName()); - colorAttribute->setAttributeType(QAttribute::VertexAttribute); - colorAttribute->setBuffer(colorDataBuffer); - colorAttribute->setDataType(QAttribute::Float); - colorAttribute->setDataSize(3); - colorAttribute->setByteOffset(0); - colorAttribute->setByteStride(3 * sizeof(float)); - colorAttribute->setCount(colorsFlat.size()); - customGeometry->addAttribute(colorAttribute); -#endif } + qDebug() << "[DepthMapEntity] Nb triangles: " << trianglesIndexes.size(); - // Pixel Sizes buffer -#ifdef QTOIIO_DEPTHMAP_USE_INDEXES + std::vector triangles; + triangles.resize(trianglesIndexes.size()); + for(int i = 0; i < trianglesIndexes.size(); ++i) { - QBuffer* pixelSizeBuffer = new QBuffer(QBuffer::VertexBuffer); - QByteArray pixelSizeData((const char*)&pixelSizes[0], pixelSizes.size() * sizeof(float)); - pixelSizeBuffer->setData(pixelSizeData); - - QAttribute* pixelSizeAttribute = new QAttribute; - pixelSizeAttribute->setName("pixelSize"); - pixelSizeAttribute->setAttributeType(QAttribute::VertexAttribute); - pixelSizeAttribute->setBuffer(pixelSizeBuffer); - pixelSizeAttribute->setDataType(QAttribute::Float); - pixelSizeAttribute->setDataSize(1); - pixelSizeAttribute->setByteOffset(0); - pixelSizeAttribute->setByteStride(sizeof(float)); - pixelSizeAttribute->setCount(pixelSizes.size()); - customGeometry->addAttribute(pixelSizeAttribute); + triangles[i] = positions[trianglesIndexes[i]]; } -#else + std::vector normals; + normals.resize(triangles.size()); + for(int i = 0; i < trianglesIndexes.size(); i+=3) { - // Duplicate pixelSize as we cannot use indexes! - std::vector pixelSizesFlat; - pixelSizesFlat.reserve(trianglesIndexes.size()); - for(int i = 0; i < trianglesIndexes.size(); ++i) - { - pixelSizesFlat.push_back(pixelSizes[trianglesIndexes[i]]); - } - - QBuffer* pixelSizeBuffer = new QBuffer(QBuffer::VertexBuffer); - QByteArray pixelSizeData((const char*)&pixelSizes[0], pixelSizes.size() * sizeof(float)); - pixelSizeBuffer->setData(pixelSizeData); - - QAttribute* pixelSizeAttribute = new QAttribute; - pixelSizeAttribute->setName("pixelSize"); - pixelSizeAttribute->setAttributeType(QAttribute::VertexAttribute); - pixelSizeAttribute->setBuffer(pixelSizeBuffer); - pixelSizeAttribute->setDataType(QAttribute::Float); - pixelSizeAttribute->setDataSize(1); - pixelSizeAttribute->setByteOffset(0); - pixelSizeAttribute->setByteStride(sizeof(float)); - pixelSizeAttribute->setCount(pixelSizes.size()); - customGeometry->addAttribute(pixelSizeAttribute); + Vec3f normal = cross(triangles[i+1]-triangles[i], triangles[i+2]-triangles[i]); + for(int t = 0; t < 3; ++t) + normals[i+t] = normal; } -#endif - // Triangles -#ifdef QTOIIO_DEPTHMAP_USE_INDEXES - if(_displayMode == DisplayMode::Triangles) + QBuffer* vertexBuffer = new QBuffer(QBuffer::VertexBuffer); + QByteArray trianglesData((const char*)&triangles[0], triangles.size() * sizeof(Vec3f)); + vertexBuffer->setData(trianglesData); + + QBuffer* normalBuffer = new QBuffer(QBuffer::VertexBuffer); + QByteArray normalsData((const char*)&normals[0], normals.size() * sizeof(Vec3f)); + normalBuffer->setData(normalsData); + + QAttribute* positionAttribute = new QAttribute(this); + positionAttribute->setName(QAttribute::defaultPositionAttributeName()); + positionAttribute->setAttributeType(QAttribute::VertexAttribute); + positionAttribute->setBuffer(vertexBuffer); + positionAttribute->setDataType(QAttribute::Float); + positionAttribute->setDataSize(3); + positionAttribute->setByteOffset(0); + positionAttribute->setByteStride(sizeof(Vec3f)); + positionAttribute->setCount(triangles.size()); + + QAttribute* normalAttribute = new QAttribute(this); + normalAttribute->setName(QAttribute::defaultNormalAttributeName()); + normalAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); + normalAttribute->setBuffer(normalBuffer); + normalAttribute->setDataType(QAttribute::Float); + normalAttribute->setDataSize(3); + normalAttribute->setByteOffset(0); + normalAttribute->setByteStride(sizeof(Vec3f)); + normalAttribute->setCount(normals.size()); + + customGeometry->addAttribute(positionAttribute); + customGeometry->addAttribute(normalAttribute); + // customGeometry->setBoundingVolumePositionAttribute(positionAttribute); + + // Duplicate colors as we cannot use indexes! + std::vector colorsFlat; + colorsFlat.reserve(trianglesIndexes.size()); + for(int i = 0; i < trianglesIndexes.size(); ++i) { - QBuffer* trianglesBuffer = new QBuffer(QBuffer::IndexBuffer); - QByteArray trianglesData((const char*)&trianglesIndexes[0], trianglesIndexes.size() * sizeof(int)); - trianglesBuffer->setData(trianglesData); - - QAttribute *indexAttribute = new QAttribute(); - // indexAttribute->setName(Qt3DRender::QAttribute::defaultJointIndicesAttributeName()); - indexAttribute->setAttributeType(QAttribute::IndexAttribute); - indexAttribute->setBuffer(trianglesBuffer); - indexAttribute->setDataType(QAttribute::Int); - // indexAttribute->setDataSize(1); - // indexAttribute->setByteOffset(0); - // indexAttribute->setByteStride(sizeof(int)); - indexAttribute->setCount(trianglesIndexes.size()); - - customGeometry->addAttribute(indexAttribute); - //customMeshRenderer->setVertexCount(triangles.size()); + colorsFlat.push_back(colors[trianglesIndexes[i]]); } -#endif - // geometry renderer settings - switch(_displayMode) - { - case DisplayMode::Points: - customMeshRenderer->setPrimitiveType(QGeometryRenderer::Points); - break; - case DisplayMode::Triangles: - customMeshRenderer->setPrimitiveType(QGeometryRenderer::Triangles); - break; - } - // customMeshRenderer->setInstanceCount(1); - // customMeshRenderer->setIndexOffset(0); - // customMeshRenderer->setFirstInstance(0); - // customMeshRenderer->setFirstVertex(0); - // customMeshRenderer->setIndexBufferByteOffset(0); - customMeshRenderer->setGeometry(customGeometry); + // read color data + QBuffer* colorDataBuffer = new QBuffer(QBuffer::VertexBuffer); + QByteArray colorData((const char*)colorsFlat[0].m, colorsFlat.size() * 3 * sizeof(float)); + colorDataBuffer->setData(colorData); + + QAttribute* colorAttribute = new QAttribute; + qDebug() << "Qt3DRender::QAttribute::defaultColorAttributeName(): " << Qt3DRender::QAttribute::defaultColorAttributeName(); + colorAttribute->setName(Qt3DRender::QAttribute::defaultColorAttributeName()); + colorAttribute->setAttributeType(QAttribute::VertexAttribute); + colorAttribute->setBuffer(colorDataBuffer); + colorAttribute->setDataType(QAttribute::Float); + colorAttribute->setDataSize(3); + colorAttribute->setByteOffset(0); + colorAttribute->setByteStride(3 * sizeof(float)); + colorAttribute->setCount(colorsFlat.size()); + customGeometry->addAttribute(colorAttribute); + + // create the geometry renderer + _meshRenderer = new QGeometryRenderer; + _meshRenderer->setGeometry(customGeometry); // add components - Qt3DCore::QTransform* transform = new Qt3DCore::QTransform; - // QMatrix4x4 qmat; - // transform->setMatrix(qmat); - - addComponent(_cloudMaterial); - addComponent(transform); - addComponent(customMeshRenderer); + addComponent(_meshRenderer); + updateMaterial(); qDebug() << "DepthMapEntity: Mesh Renderer added."; } diff --git a/src/depthMapEntity/DepthMapEntity.hpp b/src/depthMapEntity/DepthMapEntity.hpp index 6398e00..2cde6c6 100644 --- a/src/depthMapEntity/DepthMapEntity.hpp +++ b/src/depthMapEntity/DepthMapEntity.hpp @@ -6,6 +6,9 @@ #include #include #include +#include +#include +#include namespace depthMapEntity { @@ -18,6 +21,7 @@ class DepthMapEntity : public Qt3DCore::QEntity Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged); Q_PROPERTY(DisplayMode displayMode READ displayMode WRITE setDisplayMode NOTIFY displayModeChanged); Q_PROPERTY(bool displayColor READ displayColor WRITE setDisplayColor NOTIFY displayColorChanged); + Q_PROPERTY(float pointSize READ pointSize WRITE setPointSize NOTIFY pointSizeChanged); public: DepthMapEntity(Qt3DCore::QNode* = nullptr); @@ -39,21 +43,31 @@ class DepthMapEntity : public Qt3DCore::QEntity Q_SLOT bool displayColor() const { return _displayColor; } Q_SLOT void setDisplayColor(bool); + Q_SLOT float pointSize() const { return _pointSize; } + Q_SLOT void setPointSize(const float& value); + private: void loadDepthMap(); void createMaterials(); + void updateMaterial(); public: Q_SIGNAL void sourceChanged(); Q_SIGNAL void displayModeChanged(); Q_SIGNAL void displayColorChanged(); + Q_SIGNAL void pointSizeChanged(); private: QUrl _source; DisplayMode _displayMode = DisplayMode::Triangles; bool _displayColor = true; - + float _pointSize = 0.5f; + Qt3DRender::QParameter* _pointSizeParameter; Qt3DRender::QMaterial* _cloudMaterial; + Qt3DExtras::QDiffuseSpecularMaterial* _diffuseMaterial; + Qt3DExtras::QPerVertexColorMaterial* _colorMaterial; + Qt3DRender::QMaterial* _currentMaterial = nullptr; + Qt3DRender::QGeometryRenderer* _meshRenderer = nullptr; }; } diff --git a/src/depthMapEntity/plugin.hpp b/src/depthMapEntity/plugin.hpp index bf3adcd..14c27b3 100644 --- a/src/depthMapEntity/plugin.hpp +++ b/src/depthMapEntity/plugin.hpp @@ -17,7 +17,7 @@ class DepthMapEntityQmlPlugin : public QQmlExtensionPlugin void registerTypes(const char* uri) override { Q_ASSERT(uri == QLatin1String("DepthMapEntity")); - qmlRegisterType(uri, 1, 0, "DepthMapEntity"); + qmlRegisterType(uri, 2, 0, "DepthMapEntity"); } };