History

Merge branch 'master' of https://github.com/highfidelity/hifi into mirrorTest

ZappoMan committed 11 years ago

Commit d3aacc32 parents e68e3fe 0ad361f22 files · +1965 −544Browse files

Showing the changes to interface/src/MetavoxelSystem.cpp (1 of 22 files). Show all

Unified · Split

interface/src/MetavoxelSystem.cpp+213−187
@@ -461,6 +461,34 @@ void MetavoxelSystem::render() { · 460 unmodified lines
461461 _voxelBaseBatches.clear();
462462 }
463463
464+ if (!_hermiteBatches.isEmpty() && Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData)) {
465+ Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true);
466+
467+ glEnableClientState(GL_VERTEX_ARRAY);
468+
469+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
470+ glNormal3f(0.0f, 1.0f, 0.0f);
471+
472+ Application::getInstance()->getDeferredLightingEffect()->bindSimpleProgram();
473+
474+ foreach (const HermiteBatch& batch, _hermiteBatches) {
475+ batch.vertexBuffer->bind();
476+
477+ glVertexPointer(3, GL_FLOAT, 0, 0);
478+
479+ glDrawArrays(GL_LINES, 0, batch.vertexCount);
480+
481+ batch.vertexBuffer->release();
482+ }
483+
484+ Application::getInstance()->getDeferredLightingEffect()->releaseSimpleProgram();
485+
486+ glDisableClientState(GL_VERTEX_ARRAY);
487+
488+ Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false);
489+ }
490+ _hermiteBatches.clear();
491+
464492 // give external parties a chance to join in
465493 emit rendering();
466494 }
@@ -550,10 +578,53 @@ void MetavoxelSystem::setVoxelMaterial(const SharedObjectPointer& spanner, const · 83 unmodified lines
550578 applyMaterialEdit(edit, true);
551579 }
552580
553−class SpannerCursorRenderVisitor : public SpannerVisitor {
581+void MetavoxelSystem::deleteTextures(int heightTextureID, int colorTextureID, int materialTextureID) const {
582+ glDeleteTextures(1, (const GLuint*)&heightTextureID);
583+ glDeleteTextures(1, (const GLuint*)&colorTextureID);
584+ glDeleteTextures(1, (const GLuint*)&materialTextureID);
585+}
586+
587+class SpannerRenderVisitor : public SpannerVisitor {
588+public:
589+
590+ SpannerRenderVisitor(const MetavoxelLOD& lod);
591+
592+ virtual int visit(MetavoxelInfo& info);
593+ virtual bool visit(Spanner* spanner);
594+
595+protected:
596+
597+ int _containmentDepth;
598+};
599+
600+SpannerRenderVisitor::SpannerRenderVisitor(const MetavoxelLOD& lod) :
601+ SpannerVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getSpannersAttribute(),
602+ QVector<AttributePointer>(), QVector<AttributePointer>(), lod,
603+ encodeOrder(Application::getInstance()->getViewFrustum()->getDirection())),
604+ _containmentDepth(INT_MAX) {
605+}
606+
607+int SpannerRenderVisitor::visit(MetavoxelInfo& info) {
608+ if (_containmentDepth >= _depth) {
609+ Frustum::IntersectionType intersection = Application::getInstance()->getMetavoxels()->getFrustum().getIntersectionType(
610+ info.getBounds());
611+ if (intersection == Frustum::NO_INTERSECTION) {
612+ return STOP_RECURSION;
613+ }
614+ _containmentDepth = (intersection == Frustum::CONTAINS_INTERSECTION) ? _depth : INT_MAX;
615+ }
616+ return SpannerVisitor::visit(info);
617+}
618+
619+bool SpannerRenderVisitor::visit(Spanner* spanner) {
620+ spanner->getRenderer()->render(_lod, _containmentDepth <= _depth);
621+ return true;
622+}
623+
624+class SpannerCursorRenderVisitor : public SpannerRenderVisitor {
554625 public:
555626
556− SpannerCursorRenderVisitor(const Box& bounds);
627+ SpannerCursorRenderVisitor(const MetavoxelLOD& lod, const Box& bounds);
557628
558629 virtual bool visit(Spanner* spanner);
559630
@@ -564,20 +635,20 @@ private: · 4 unmodified lines
564635 Box _bounds;
565636 };
566637
567−SpannerCursorRenderVisitor::SpannerCursorRenderVisitor(const Box& bounds) :
568− SpannerVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getSpannersAttribute()),
638+SpannerCursorRenderVisitor::SpannerCursorRenderVisitor(const MetavoxelLOD& lod, const Box& bounds) :
639+ SpannerRenderVisitor(lod),
569640 _bounds(bounds) {
570641 }
571642
572643 bool SpannerCursorRenderVisitor::visit(Spanner* spanner) {
573644 if (spanner->isHeightfield()) {
574− spanner->getRenderer()->render(true);
645+ spanner->getRenderer()->render(_lod, _containmentDepth <= _depth, true);
575646 }
576647 return true;
577648 }
578649
579650 int SpannerCursorRenderVisitor::visit(MetavoxelInfo& info) {
580− return info.getBounds().intersects(_bounds) ? SpannerVisitor::visit(info) : STOP_RECURSION;
651+ return info.getBounds().intersects(_bounds) ? SpannerRenderVisitor::visit(info) : STOP_RECURSION;
581652 }
582653
583654 void MetavoxelSystem::renderHeightfieldCursor(const glm::vec3& position, float radius) {
@@ -604,7 +675,7 @@ void MetavoxelSystem::renderHeightfieldCursor(const glm::vec3& position, float r · 20 unmodified lines
604675 glActiveTexture(GL_TEXTURE0);
605676
606677 glm::vec3 extents(radius, radius, radius);
607− SpannerCursorRenderVisitor visitor(Box(position - extents, position + extents));
678+ SpannerCursorRenderVisitor visitor(getLOD(), Box(position - extents, position + extents));
608679 guide(visitor);
609680
610681 _heightfieldCursorProgram.release();
@@ -678,7 +749,7 @@ void MetavoxelSystem::renderVoxelCursor(const glm::vec3& position, float radius) · 67 unmodified lines
678749
679750 _heightfieldCursorProgram.bind();
680751
681− SpannerCursorRenderVisitor spannerVisitor(bounds);
752+ SpannerCursorRenderVisitor spannerVisitor(getLOD(), bounds);
682753 guide(spannerVisitor);
683754
684755 _heightfieldCursorProgram.release();
@@ -1192,31 +1263,18 @@ void VoxelBuffer::render(bool cursor) { · 507 unmodified lines
11921263 }
11931264 }
11941265
1195− if (_hermiteCount > 0 && Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData)) {
1266+ if (_hermiteCount > 0) {
11961267 if (!_hermiteBuffer.isCreated()) {
11971268 _hermiteBuffer.create();
11981269 _hermiteBuffer.bind();
1199− _hermiteBuffer.allocate(_hermite.constData(), _hermite.size() * sizeof(glm::vec3));
1270+ _hermiteBuffer.allocate(_hermite.constData(), _hermite.size() * sizeof(glm::vec3));
1271+ _hermiteBuffer.release();
12001272 _hermite.clear();
1201−
1202− } else {
1203− _hermiteBuffer.bind();
12041273 }
1205−
1206− glVertexPointer(3, GL_FLOAT, 0, 0);
1207−
1208− Application::getInstance()->getDeferredLightingEffect()->getSimpleProgram().bind();
1209−
1210− glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1211− glNormal3f(0.0f, 1.0f, 0.0f);
1212−
1213− glLineWidth(1.0f);
1214−
1215− glDrawArrays(GL_LINES, 0, _hermiteCount);
1216−
1217− Application::getInstance()->getDeferredLightingEffect()->getSimpleProgram().release();
1218−
1219− _hermiteBuffer.release();
1274+ HermiteBatch hermiteBatch;
1275+ hermiteBatch.vertexBuffer = &_hermiteBuffer;
1276+ hermiteBatch.vertexCount = _hermiteCount;
1277+ Application::getInstance()->getMetavoxels()->addHermiteBatch(hermiteBatch);
12201278 }
12211279 }
12221280
@@ -1880,43 +1938,6 @@ void DefaultMetavoxelRendererImplementation::simulate(MetavoxelData& data, float · 657 unmodified lines
18801938 data.guide(spannerSimulateVisitor);
18811939 }
18821940
1883−class SpannerRenderVisitor : public SpannerVisitor {
1884−public:
1885−
1886− SpannerRenderVisitor(const MetavoxelLOD& lod);
1887−
1888− virtual int visit(MetavoxelInfo& info);
1889− virtual bool visit(Spanner* spanner);
1890−
1891−private:
1892−
1893− int _containmentDepth;
1894−};
1895−
1896−SpannerRenderVisitor::SpannerRenderVisitor(const MetavoxelLOD& lod) :
1897− SpannerVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getSpannersAttribute(),
1898− QVector<AttributePointer>(), QVector<AttributePointer>(), lod,
1899− encodeOrder(Application::getInstance()->getDisplayViewFrustum()->getDirection())),
1900− _containmentDepth(INT_MAX) {
1901−}
1902−
1903−int SpannerRenderVisitor::visit(MetavoxelInfo& info) {
1904− if (_containmentDepth >= _depth) {
1905− Frustum::IntersectionType intersection = Application::getInstance()->getMetavoxels()->getFrustum().getIntersectionType(
1906− info.getBounds());
1907− if (intersection == Frustum::NO_INTERSECTION) {
1908− return STOP_RECURSION;
1909− }
1910− _containmentDepth = (intersection == Frustum::CONTAINS_INTERSECTION) ? _depth : INT_MAX;
1911− }
1912− return SpannerVisitor::visit(info);
1913−}
1914−
1915−bool SpannerRenderVisitor::visit(Spanner* spanner) {
1916− spanner->getRenderer()->render();
1917− return true;
1918−}
1919−
19201941 class BufferRenderVisitor : public MetavoxelVisitor {
19211942 public:
19221943
@@ -1970,7 +1991,7 @@ SphereRenderer::SphereRenderer() { · 47 unmodified lines
19701991 }
19711992
19721993
1973−void SphereRenderer::render(bool cursor) {
1994+void SphereRenderer::render(const MetavoxelLOD& lod, bool contained, bool cursor) {
19741995 Sphere* sphere = static_cast<Sphere*>(_spanner);
19751996 const QColor& color = sphere->getColor();
19761997 glColor4f(color.redF(), color.greenF(), color.blueF(), color.alphaF());
@@ -1990,7 +2011,7 @@ void SphereRenderer::render(bool cursor) { · 13 unmodified lines
19902011 CuboidRenderer::CuboidRenderer() {
19912012 }
19922013
1993−void CuboidRenderer::render(bool cursor) {
2014+void CuboidRenderer::render(const MetavoxelLOD& lod, bool contained, bool cursor) {
19942015 Cuboid* cuboid = static_cast<Cuboid*>(_spanner);
19952016 const QColor& color = cuboid->getColor();
19962017 glColor4f(color.redF(), color.greenF(), color.blueF(), color.alphaF());
@@ -2041,7 +2062,7 @@ void StaticModelRenderer::simulate(float deltaTime) { · 44 unmodified lines
20412062 _model->simulate(deltaTime);
20422063 }
20432064
2044−void StaticModelRenderer::render(bool cursor) {
2065+void StaticModelRenderer::render(const MetavoxelLOD& lod, bool contained, bool cursor) {
20452066 _model->render();
20462067 }
20472068
@@ -2073,57 +2094,66 @@ void StaticModelRenderer::applyURL(const QUrl& url) { · 25 unmodified lines
20732094 }
20742095
20752096 HeightfieldRenderer::HeightfieldRenderer() {
2076− glGenTextures(1, &_heightTextureID);
2077− glBindTexture(GL_TEXTURE_2D, _heightTextureID);
2078− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2079− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2080− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2081− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2082−
2083− glGenTextures(1, &_colorTextureID);
2084− glBindTexture(GL_TEXTURE_2D, _colorTextureID);
2085− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2086− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2087− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2088−
2089− glGenTextures(1, &_materialTextureID);
2090− glBindTexture(GL_TEXTURE_2D, _materialTextureID);
2091− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2092− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2093− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2094− glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2095−
2096− glBindTexture(GL_TEXTURE_2D, 0);
20972097 }
20982098
2099−HeightfieldRenderer::~HeightfieldRenderer() {
2100− glDeleteTextures(1, &_heightTextureID);
2101− glDeleteTextures(1, &_colorTextureID);
2102− glDeleteTextures(1, &_materialTextureID);
2099+const int X_MAXIMUM_FLAG = 1;
2100+const int Y_MAXIMUM_FLAG = 2;
2101+
2102+static void renderNode(const HeightfieldNodePointer& node, Heightfield* heightfield, const MetavoxelLOD& lod,
2103+ const glm::vec2& minimum, float size, bool contained, bool cursor) {
2104+ const glm::quat& rotation = heightfield->getRotation();
2105+ glm::vec3 scale(heightfield->getScale() * size, heightfield->getScale() * heightfield->getAspectY(),
2106+ heightfield->getScale() * heightfield->getAspectZ() * size);
2107+ glm::vec3 translation = heightfield->getTranslation() + rotation * glm::vec3(minimum.x * heightfield->getScale(),
2108+ 0.0f, minimum.y * heightfield->getScale() * heightfield->getAspectZ());
2109+ if (!contained) {
2110+ Frustum::IntersectionType type = Application::getInstance()->getMetavoxels()->getFrustum().getIntersectionType(
2111+ glm::translate(translation) * glm::mat4_cast(rotation) * Box(glm::vec3(), scale));
2112+ if (type == Frustum::NO_INTERSECTION) {
2113+ return;
2114+ }
2115+ if (type == Frustum::CONTAINS_INTERSECTION) {
2116+ contained = true;
2117+ }
2118+ }
2119+ if (!node->isLeaf() && lod.shouldSubdivide(minimum, size)) {
2120+ float nextSize = size * 0.5f;
2121+ for (int i = 0; i < HeightfieldNode::CHILD_COUNT; i++) {
2122+ renderNode(node->getChild(i), heightfield, lod, minimum + glm::vec2(i & X_MAXIMUM_FLAG ? nextSize : 0.0f,
2123+ i & Y_MAXIMUM_FLAG ? nextSize : 0.0f), nextSize, contained, cursor);
2124+ }
2125+ return;
2126+ }
2127+ HeightfieldNodeRenderer* renderer = static_cast<HeightfieldNodeRenderer*>(node->getRenderer());
2128+ if (!renderer) {
2129+ node->setRenderer(renderer = new HeightfieldNodeRenderer());
2130+ }
2131+ renderer->render(node, translation, rotation, scale, cursor);
21032132 }
21042133
2105−void HeightfieldRenderer::init(Spanner* spanner) {
2106− SpannerRenderer::init(spanner);
2107−
2108− Heightfield* heightfield = static_cast<Heightfield*>(spanner);
2109− applyHeight(heightfield->getHeight());
2110− applyColor(heightfield->getColor());
2111− applyMaterial(heightfield->getMaterial());
2112−
2113− connect(heightfield, &Heightfield::heightChanged, this, &HeightfieldRenderer::applyHeight);
2114− connect(heightfield, &Heightfield::colorChanged, this, &HeightfieldRenderer::applyColor);
2115− connect(heightfield, &Heightfield::materialChanged, this, &HeightfieldRenderer::applyMaterial);
2134+void HeightfieldRenderer::render(const MetavoxelLOD& lod, bool contained, bool cursor) {
2135+ Heightfield* heightfield = static_cast<Heightfield*>(_spanner);
2136+ renderNode(heightfield->getRoot(), heightfield, heightfield->transformLOD(lod), glm::vec2(), 1.0f, contained, cursor);
21162137 }
21172138
2118−void HeightfieldRenderer::render(bool cursor) {
2119− // create the buffer objects lazily
2120− Heightfield* heightfield = static_cast<Heightfield*>(_spanner);
2121− if (!heightfield->getHeight()) {
2139+HeightfieldNodeRenderer::HeightfieldNodeRenderer() :
2140+ _heightTextureID(0),
2141+ _colorTextureID(0),
2142+ _materialTextureID(0) {
2143+}
2144+
2145+HeightfieldNodeRenderer::~HeightfieldNodeRenderer() {
2146+ QMetaObject::invokeMethod(Application::getInstance()->getMetavoxels(), "deleteTextures", Q_ARG(int, _heightTextureID),
2147+ Q_ARG(int, _colorTextureID), Q_ARG(int, _materialTextureID));
2148+}
2149+
2150+void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const glm::vec3& translation,
2151+ const glm::quat& rotation, const glm::vec3& scale, bool cursor) {
2152+ if (!node->getHeight()) {
21222153 return;
21232154 }
2124− int width = heightfield->getHeight()->getWidth();
2125− int height = heightfield->getHeight()->getContents().size() / width;
2126−
2155+ int width = node->getHeight()->getWidth();
2156+ int height = node->getHeight()->getContents().size() / width;
21272157 int innerWidth = width - 2 * HeightfieldHeight::HEIGHT_BORDER;
21282158 int innerHeight = height - 2 * HeightfieldHeight::HEIGHT_BORDER;
21292159 int vertexCount = width * height;
@@ -2180,17 +2210,71 @@ void HeightfieldRenderer::render(bool cursor) { · 50 unmodified lines
21802210 bufferPair.second.allocate(indices.constData(), indexCount * sizeof(int));
21812211 bufferPair.second.release();
21822212 }
2213+ if (_heightTextureID == 0) {
2214+ glGenTextures(1, &_heightTextureID);
2215+ glBindTexture(GL_TEXTURE_2D, _heightTextureID);
2216+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2217+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2218+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2219+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2220+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2221+ const QVector<quint16>& heightContents = node->getHeight()->getContents();
2222+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, width, height, 0,
2223+ GL_RED, GL_UNSIGNED_SHORT, heightContents.constData());
2224+
2225+ glGenTextures(1, &_colorTextureID);
2226+ glBindTexture(GL_TEXTURE_2D, _colorTextureID);
2227+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2228+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2229+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2230+ if (node->getColor()) {
2231+ const QByteArray& contents = node->getColor()->getContents();
2232+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, node->getColor()->getWidth(),
2233+ contents.size() / (node->getColor()->getWidth() * DataBlock::COLOR_BYTES),
2234+ 0, GL_RGB, GL_UNSIGNED_BYTE, contents.constData());
2235+
2236+ } else {
2237+ const quint8 WHITE_COLOR[] = { 255, 255, 255 };
2238+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, WHITE_COLOR);
2239+ }
2240+
2241+ glGenTextures(1, &_materialTextureID);
2242+ glBindTexture(GL_TEXTURE_2D, _materialTextureID);
2243+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2244+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2245+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2246+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2247+ if (node->getMaterial()) {
2248+ const QByteArray& contents = node->getMaterial()->getContents();
2249+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, node->getMaterial()->getWidth(),
2250+ contents.size() / node->getMaterial()->getWidth(),
2251+ 0, GL_RED, GL_UNSIGNED_BYTE, contents.constData());
2252+
2253+ const QVector<SharedObjectPointer>& materials = node->getMaterial()->getMaterials();
2254+ _networkTextures.resize(materials.size());
2255+ for (int i = 0; i < materials.size(); i++) {
2256+ const SharedObjectPointer& material = materials.at(i);
2257+ if (material) {
2258+ _networkTextures[i] = Application::getInstance()->getTextureCache()->getTexture(
2259+ static_cast<MaterialObject*>(material.data())->getDiffuse(), SPLAT_TEXTURE);
2260+ }
2261+ }
2262+ } else {
2263+ const quint8 ZERO_VALUE = 0;
2264+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 1, 1, 0, GL_RED, GL_UNSIGNED_BYTE, &ZERO_VALUE);
2265+ }
2266+ glBindTexture(GL_TEXTURE_2D, 0);
2267+ }
21832268
2184− float xScale = heightfield->getScale(), zScale = xScale * heightfield->getAspectZ();
21852269 if (cursor) {
21862270 bufferPair.first.bind();
21872271 bufferPair.second.bind();
21882272
21892273 glPushMatrix();
2190− glTranslatef(heightfield->getTranslation().x, heightfield->getTranslation().y, heightfield->getTranslation().z);
2191− glm::vec3 axis = glm::axis(heightfield->getRotation());
2192− glRotatef(glm::degrees(glm::angle(heightfield->getRotation())), axis.x, axis.y, axis.z);
2193− glScalef(xScale, xScale * heightfield->getAspectY(), zScale);
2274+ glTranslatef(translation.x, translation.y, translation.z);
2275+ glm::vec3 axis = glm::axis(rotation);
2276+ glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
2277+ glScalef(scale.x, scale.y, scale.z);
21942278
21952279 HeightfieldPoint* point = 0;
21962280 glVertexPointer(3, GL_FLOAT, sizeof(HeightfieldPoint), &point->vertex);
@@ -2208,13 +2292,12 @@ void HeightfieldRenderer::render(bool cursor) { · 11 unmodified lines
22082292 bufferPair.second.release();
22092293 return;
22102294 }
2211−
22122295 HeightfieldBaseLayerBatch baseBatch;
22132296 baseBatch.vertexBuffer = &bufferPair.first;
22142297 baseBatch.indexBuffer = &bufferPair.second;
2215− baseBatch.translation = heightfield->getTranslation();
2216− baseBatch.rotation = heightfield->getRotation();
2217− baseBatch.scale = glm::vec3(xScale, xScale * heightfield->getAspectY(), zScale);
2298+ baseBatch.translation = translation;
2299+ baseBatch.rotation = rotation;
2300+ baseBatch.scale = scale;
22182301 baseBatch.vertexCount = vertexCount;
22192302 baseBatch.indexCount = indexCount;
22202303 baseBatch.heightTextureID = _heightTextureID;
@@ -2223,13 +2306,13 @@ void HeightfieldRenderer::render(bool cursor) { · 2 unmodified lines
22232306 baseBatch.colorScale = glm::vec2((float)width / innerWidth, (float)height / innerHeight);
22242307 Application::getInstance()->getMetavoxels()->addHeightfieldBaseBatch(baseBatch);
22252308
2226− if (heightfield->getMaterial() && !_networkTextures.isEmpty()) {
2309+ if (!_networkTextures.isEmpty()) {
22272310 HeightfieldSplatBatch splatBatch;
22282311 splatBatch.vertexBuffer = &bufferPair.first;
22292312 splatBatch.indexBuffer = &bufferPair.second;
2230− splatBatch.translation = heightfield->getTranslation();
2231− splatBatch.rotation = heightfield->getRotation();
2232− splatBatch.scale = glm::vec3(xScale, xScale * heightfield->getAspectY(), zScale);
2313+ splatBatch.translation = translation;
2314+ splatBatch.rotation = rotation;
2315+ splatBatch.scale = scale;
22332316 splatBatch.vertexCount = vertexCount;
22342317 splatBatch.indexCount = indexCount;
22352318 splatBatch.heightTextureID = _heightTextureID;
@@ -2237,10 +2320,10 @@ void HeightfieldRenderer::render(bool cursor) { · 1 unmodified line
22372320 splatBatch.materialTextureID = _materialTextureID;
22382321 splatBatch.textureScale = glm::vec2((float)width / innerWidth, (float)height / innerHeight);
22392322 splatBatch.splatTextureOffset = glm::vec2(
2240− glm::dot(heightfield->getTranslation(), heightfield->getRotation() * glm::vec3(1.0f, 0.0f, 0.0f)) / xScale,
2241− glm::dot(heightfield->getTranslation(), heightfield->getRotation() * glm::vec3(0.0f, 0.0f, 1.0f)) / zScale);
2323+ glm::dot(translation, rotation * glm::vec3(1.0f, 0.0f, 0.0f)) / scale.x,
2324+ glm::dot(translation, rotation * glm::vec3(0.0f, 0.0f, 1.0f)) / scale.z);
22422325
2243− const QVector<SharedObjectPointer>& materials = heightfield->getMaterial()->getMaterials();
2326+ const QVector<SharedObjectPointer>& materials = node->getMaterial()->getMaterials();
22442327 for (int i = 0; i < materials.size(); i += SPLAT_COUNT) {
22452328 for (int j = 0; j < SPLAT_COUNT; j++) {
22462329 int index = i + j;
@@ -2248,8 +2331,8 @@ void HeightfieldRenderer::render(bool cursor) { · 1 unmodified line
22482331 const NetworkTexturePointer& texture = _networkTextures.at(index);
22492332 if (texture) {
22502333 MaterialObject* material = static_cast<MaterialObject*>(materials.at(index).data());
2251− splatBatch.splatTextureScalesS[j] = xScale / material->getScaleS();
2252− splatBatch.splatTextureScalesT[j] = zScale / material->getScaleT();
2334+ splatBatch.splatTextureScalesS[j] = scale.x / material->getScaleS();
2335+ splatBatch.splatTextureScalesT[j] = scale.z / material->getScaleT();
22532336 splatBatch.splatTextureIDs[j] = texture->getID();
22542337
22552338 } else {
@@ -2265,62 +2348,5 @@ void HeightfieldRenderer::render(bool cursor) { · 9 unmodified lines
22652348 }
22662349 }
22672350
2268−void HeightfieldRenderer::applyHeight(const HeightfieldHeightPointer& height) {
2269− glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2270− glBindTexture(GL_TEXTURE_2D, _heightTextureID);
2271− if (height) {
2272− const QVector<quint16>& contents = height->getContents();
2273− glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, height->getWidth(), contents.size() / height->getWidth(), 0,
2274− GL_RED, GL_UNSIGNED_SHORT, contents.constData());
2275−
2276− } else {
2277− const quint16 ZERO_VALUE = 0;
2278− glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, 1, 1, 0, GL_RED, GL_UNSIGNED_SHORT, &ZERO_VALUE);
2279− }
2280− glBindTexture(GL_TEXTURE_2D, 0);
2281−}
2282−
2283−void HeightfieldRenderer::applyColor(const HeightfieldColorPointer& color) {
2284− glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2285− glBindTexture(GL_TEXTURE_2D, _colorTextureID);
2286− if (color) {
2287− const QByteArray& contents = color->getContents();
2288− glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, color->getWidth(),
2289− contents.size() / (color->getWidth() * DataBlock::COLOR_BYTES), 0, GL_RGB, GL_UNSIGNED_BYTE, contents.constData());
2290−
2291− } else {
2292− const quint8 WHITE_COLOR[] = { 255, 255, 255 };
2293− glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, WHITE_COLOR);
2294− }
2295− glBindTexture(GL_TEXTURE_2D, 0);
2296−}
2297−
2298−void HeightfieldRenderer::applyMaterial(const HeightfieldMaterialPointer& material) {
2299− glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2300− glBindTexture(GL_TEXTURE_2D, _materialTextureID);
2301− if (material) {
2302− const QByteArray& contents = material->getContents();
2303− glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, material->getWidth(), contents.size() / material->getWidth(), 0,
2304− GL_RED, GL_UNSIGNED_BYTE, contents.constData());
2305−
2306− const QVector<SharedObjectPointer>& materials = material->getMaterials();
2307− _networkTextures.resize(materials.size());
2308− for (int i = 0; i < materials.size(); i++) {
2309− const SharedObjectPointer& material = materials.at(i);
2310− if (material) {
2311− _networkTextures[i] = Application::getInstance()->getTextureCache()->getTexture(
2312− static_cast<MaterialObject*>(material.data())->getDiffuse(), SPLAT_TEXTURE);
2313− } else {
2314− _networkTextures[i].clear();
2315− }
2316− }
2317− } else {
2318− const quint8 ZERO_VALUE = 0;
2319− glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 1, 1, 0, GL_RED, GL_UNSIGNED_BYTE, &ZERO_VALUE);
2320− _networkTextures.clear();
2321− }
2322− glBindTexture(GL_TEXTURE_2D, 0);
2323−}
2324−
2325−QHash<HeightfieldRenderer::IntPair, HeightfieldRenderer::BufferPair> HeightfieldRenderer::_bufferPairs;
2351+QHash<HeightfieldNodeRenderer::IntPair, HeightfieldNodeRenderer::BufferPair> HeightfieldNodeRenderer::_bufferPairs;
23262352