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

This commit is contained in:
Sam Gateau 2014-10-24 09:28:13 -07:00
commit 5b0fd99115
13 changed files with 184 additions and 79 deletions

View file

@ -26,11 +26,14 @@ varying vec4 normal;
void main(void) { void main(void) {
// transform and store the normal for interpolation // transform and store the normal for interpolation
vec2 heightCoord = gl_MultiTexCoord0.st; vec2 heightCoord = gl_MultiTexCoord0.st;
float deltaX = texture2D(heightMap, heightCoord - vec2(heightScale, 0.0)).r - vec4 neighborHeights = vec4(texture2D(heightMap, heightCoord - vec2(heightScale, 0.0)).r,
texture2D(heightMap, heightCoord + vec2(heightScale, 0.0)).r; texture2D(heightMap, heightCoord + vec2(heightScale, 0.0)).r,
float deltaZ = texture2D(heightMap, heightCoord - vec2(0.0, heightScale)).r - texture2D(heightMap, heightCoord - vec2(0.0, heightScale)).r,
texture2D(heightMap, heightCoord + vec2(0.0, heightScale)).r; texture2D(heightMap, heightCoord + vec2(0.0, heightScale)).r);
normal = normalize(gl_ModelViewMatrix * vec4(deltaX, heightScale, deltaZ, 0.0)); vec4 neighborsZero = step(1.0 / 255.0, neighborHeights);
normal = normalize(gl_ModelViewMatrix * vec4(
(neighborHeights.x - neighborHeights.y) * neighborsZero.x * neighborsZero.y, heightScale,
(neighborHeights.z - neighborHeights.w) * neighborsZero.z * neighborsZero.w, 0.0));
// add the height to the position // add the height to the position
float height = texture2D(heightMap, heightCoord).r; float height = texture2D(heightMap, heightCoord).r;

View file

@ -434,6 +434,8 @@ Menu::Menu() :
QMenu* metavoxelOptionsMenu = developerMenu->addMenu("Metavoxels"); QMenu* metavoxelOptionsMenu = developerMenu->addMenu("Metavoxels");
addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::DisplayHermiteData, 0, false, addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::DisplayHermiteData, 0, false,
Application::getInstance()->getMetavoxels(), SLOT(refreshVoxelData())); Application::getInstance()->getMetavoxels(), SLOT(refreshVoxelData()));
addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::RenderHeightfields, 0, true);
addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::RenderDualContourSurfaces, 0, true);
addActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::NetworkSimulator, 0, this, addActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::NetworkSimulator, 0, this,
SLOT(showMetavoxelNetworkSimulator())); SLOT(showMetavoxelNetworkSimulator()));

View file

@ -447,8 +447,10 @@ namespace MenuOption {
const QString Quit = "Quit"; const QString Quit = "Quit";
const QString ReloadAllScripts = "Reload All Scripts"; const QString ReloadAllScripts = "Reload All Scripts";
const QString RenderBoundingCollisionShapes = "Show Bounding Collision Shapes"; const QString RenderBoundingCollisionShapes = "Show Bounding Collision Shapes";
const QString RenderDualContourSurfaces = "Render Dual Contour Surfaces";
const QString RenderFocusIndicator = "Show Eye Focus"; const QString RenderFocusIndicator = "Show Eye Focus";
const QString RenderHeadCollisionShapes = "Show Head Collision Shapes"; const QString RenderHeadCollisionShapes = "Show Head Collision Shapes";
const QString RenderHeightfields = "Render Heightfields";
const QString RenderLookAtVectors = "Show Look-at Vectors"; const QString RenderLookAtVectors = "Show Look-at Vectors";
const QString RenderSkeletonCollisionShapes = "Show Skeleton Collision Shapes"; const QString RenderSkeletonCollisionShapes = "Show Skeleton Collision Shapes";
const QString RenderUnleashFramerate = "Unleash Framerate"; const QString RenderUnleashFramerate = "Unleash Framerate";

View file

@ -2772,40 +2772,39 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox
glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
_baseHeightfieldProgram.bind(); if (Menu::getInstance()->isOptionChecked(MenuOption::RenderHeightfields)) {
_baseHeightfieldProgram.bind();
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
BufferRenderVisitor heightfieldRenderVisitor(Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute());
data.guide(heightfieldRenderVisitor);
_baseHeightfieldProgram.release();
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
BufferRenderVisitor heightfieldRenderVisitor(Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute());
data.guide(heightfieldRenderVisitor);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
_baseHeightfieldProgram.release();
}
glEnableClientState(GL_VERTEX_ARRAY); if (Menu::getInstance()->isOptionChecked(MenuOption::RenderDualContourSurfaces)) {
glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_NORMAL_ARRAY);
_baseVoxelProgram.bind(); _baseVoxelProgram.bind();
BufferRenderVisitor voxelRenderVisitor(Application::getInstance()->getMetavoxels()->getVoxelBufferAttribute()); BufferRenderVisitor voxelRenderVisitor(Application::getInstance()->getMetavoxels()->getVoxelBufferAttribute());
data.guide(voxelRenderVisitor); data.guide(voxelRenderVisitor);
_baseVoxelProgram.release(); _baseVoxelProgram.release();
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}
glDisable(GL_ALPHA_TEST); glDisable(GL_ALPHA_TEST);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false); Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false);
} }

View file

@ -166,6 +166,7 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) {
} }
// use data to update fake Faceshift blendshape coefficients // use data to update fake Faceshift blendshape coefficients
const float JAW_OPEN_SCALE = 0.015f; const float JAW_OPEN_SCALE = 0.015f;
const float JAW_OPEN_RATE = 0.9f; const float JAW_OPEN_RATE = 0.9f;
const float JAW_CLOSE_RATE = 0.90f; const float JAW_CLOSE_RATE = 0.90f;
@ -177,10 +178,28 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) {
} }
_audioJawOpen = glm::clamp(_audioJawOpen, 0.0f, 1.0f); _audioJawOpen = glm::clamp(_audioJawOpen, 0.0f, 1.0f);
// _mouth2 = "mmmm" shape
// _mouth3 = "funnel" shape
// _mouth4 = "smile" shape
const float FUNNEL_PERIOD = 0.985f;
const float FUNNEL_RANDOM_PERIOD = 0.01f;
const float MMMM_POWER = 0.25f;
const float MMMM_PERIOD = 0.91f;
const float MMMM_RANDOM_PERIOD = 0.15f;
const float SMILE_PERIOD = 0.925f;
const float SMILE_RANDOM_PERIOD = 0.05f;
_mouth3 = glm::mix(_audioJawOpen, _mouth3, FUNNEL_PERIOD + randFloat() * FUNNEL_RANDOM_PERIOD);
_mouth2 = glm::mix(_audioJawOpen * MMMM_POWER, _mouth2, MMMM_PERIOD + randFloat() * MMMM_RANDOM_PERIOD);
_mouth4 = glm::mix(_audioJawOpen, _mouth4, SMILE_PERIOD + randFloat() * SMILE_RANDOM_PERIOD);
Application::getInstance()->getFaceshift()->updateFakeCoefficients(_leftEyeBlink, Application::getInstance()->getFaceshift()->updateFakeCoefficients(_leftEyeBlink,
_rightEyeBlink, _rightEyeBlink,
_browAudioLift, _browAudioLift,
_audioJawOpen, _audioJawOpen,
_mouth2,
_mouth3,
_mouth4,
_blendshapeCoefficients); _blendshapeCoefficients);
} }

View file

@ -129,6 +129,9 @@ private:
float _longTermAverageLoudness; float _longTermAverageLoudness;
float _audioAttack; float _audioAttack;
float _audioJawOpen; float _audioJawOpen;
float _mouth2;
float _mouth3;
float _mouth4;
glm::vec3 _angularVelocity; glm::vec3 _angularVelocity;
bool _renderLookatVectors; bool _renderLookatVectors;
glm::vec3 _saccade; glm::vec3 _saccade;

View file

@ -125,8 +125,14 @@ void Faceshift::reset() {
} }
void Faceshift::updateFakeCoefficients(float leftBlink, float rightBlink, float browUp, void Faceshift::updateFakeCoefficients(float leftBlink, float rightBlink, float browUp,
float jawOpen, QVector<float>& coefficients) const { float jawOpen, float mouth2, float mouth3, float mouth4, QVector<float>& coefficients) const {
coefficients.resize(max((int)coefficients.size(), _jawOpenIndex + 1)); const int MMMM_BLENDSHAPE = 34;
const int FUNNEL_BLENDSHAPE = 40;
const int SMILE_LEFT_BLENDSHAPE = 28;
const int SMILE_RIGHT_BLENDSHAPE = 29;
const int MAX_FAKE_BLENDSHAPE = 40; // Largest modified blendshape from above and below
coefficients.resize(max((int)coefficients.size(), MAX_FAKE_BLENDSHAPE + 1));
qFill(coefficients.begin(), coefficients.end(), 0.0f); qFill(coefficients.begin(), coefficients.end(), 0.0f);
coefficients[_leftBlinkIndex] = leftBlink; coefficients[_leftBlinkIndex] = leftBlink;
coefficients[_rightBlinkIndex] = rightBlink; coefficients[_rightBlinkIndex] = rightBlink;
@ -134,6 +140,9 @@ void Faceshift::updateFakeCoefficients(float leftBlink, float rightBlink, float
coefficients[_browUpLeftIndex] = browUp; coefficients[_browUpLeftIndex] = browUp;
coefficients[_browUpRightIndex] = browUp; coefficients[_browUpRightIndex] = browUp;
coefficients[_jawOpenIndex] = jawOpen; coefficients[_jawOpenIndex] = jawOpen;
coefficients[SMILE_LEFT_BLENDSHAPE] = coefficients[SMILE_RIGHT_BLENDSHAPE] = mouth4;
coefficients[MMMM_BLENDSHAPE] = mouth2;
coefficients[FUNNEL_BLENDSHAPE] = mouth3;
} }
void Faceshift::setTCPEnabled(bool enabled) { void Faceshift::setTCPEnabled(bool enabled) {

View file

@ -61,8 +61,14 @@ public:
void update(); void update();
void reset(); void reset();
void updateFakeCoefficients(float leftBlink, float rightBlink, float browUp, void updateFakeCoefficients(float leftBlink,
float jawOpen, QVector<float>& coefficients) const; float rightBlink,
float browUp,
float jawOpen,
float mouth2,
float mouth3,
float mouth4,
QVector<float>& coefficients) const;
signals: signals:

View file

@ -9,6 +9,9 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include <qnetworkrequest.h>
#include <AddressManager.h>
#include <OAuthNetworkAccessManager.h> #include <OAuthNetworkAccessManager.h>
#include "DataWebPage.h" #include "DataWebPage.h"
@ -19,13 +22,22 @@ DataWebPage::DataWebPage(QObject* parent) :
// use an OAuthNetworkAccessManager instead of regular QNetworkAccessManager so our requests are authed // use an OAuthNetworkAccessManager instead of regular QNetworkAccessManager so our requests are authed
setNetworkAccessManager(OAuthNetworkAccessManager::getInstance()); setNetworkAccessManager(OAuthNetworkAccessManager::getInstance());
// have the page delegate external links so they can be captured by the Application in case they are a hifi link
setLinkDelegationPolicy(QWebPage::DelegateExternalLinks);
// give the page an empty stylesheet // give the page an empty stylesheet
settings()->setUserStyleSheetUrl(QUrl()); settings()->setUserStyleSheetUrl(QUrl());
} }
void DataWebPage::javaScriptConsoleMessage(const QString& message, int lineNumber, const QString& sourceID) { void DataWebPage::javaScriptConsoleMessage(const QString& message, int lineNumber, const QString& sourceID) {
qDebug() << "JS console message at line" << lineNumber << "from" << sourceID << "-" << message; qDebug() << "JS console message at line" << lineNumber << "from" << sourceID << "-" << message;
}
bool DataWebPage::acceptNavigationRequest(QWebFrame* frame, const QNetworkRequest& request, QWebPage::NavigationType type) {
if (!request.url().toString().startsWith(HIFI_URL_SCHEME)) {
return true;
} else {
// this is a hifi URL - have the AddressManager handle it
QMetaObject::invokeMethod(&AddressManager::getInstance(), "handleLookupString",
Qt::AutoConnection, Q_ARG(const QString&, request.url().toString()));
return false;
}
} }

View file

@ -19,6 +19,7 @@ public:
DataWebPage(QObject* parent = 0); DataWebPage(QObject* parent = 0);
protected: protected:
void javaScriptConsoleMessage(const QString & message, int lineNumber, const QString & sourceID); void javaScriptConsoleMessage(const QString & message, int lineNumber, const QString & sourceID);
bool acceptNavigationRequest(QWebFrame* frame, const QNetworkRequest& request, QWebPage::NavigationType type);
}; };
#endif // hifi_DataWebPage_h #endif // hifi_DataWebPage_h

View file

@ -212,7 +212,7 @@ void Player::loadRecording(RecordingPointer recording) {
void Player::play() { void Player::play() {
computeCurrentFrame(); computeCurrentFrame();
if (_currentFrame < 0 || (_currentFrame >= _recording->getFrameNumber() - 1)) { if (_currentFrame < 0 || (_currentFrame >= _recording->getFrameNumber() - 2)) { // -2 because of interpolation
if (_loop) { if (_loop) {
loopRecording(); loopRecording();
} else { } else {

View file

@ -2486,8 +2486,39 @@ bool Heightfield::intersects(const glm::vec3& start, const glm::vec3& end, float
if (!getBounds().findRayIntersection(start, direction, rayDistance) || rayDistance > 1.0f) { if (!getBounds().findRayIntersection(start, direction, rayDistance) || rayDistance > 1.0f) {
return false; return false;
} }
glm::vec3 entry = (start + direction * rayDistance - getBounds().minimum) / _increment; glm::vec3 entry = start + direction * rayDistance;
direction /= _increment; const float DISTANCE_THRESHOLD = 0.001f;
if (glm::abs(entry.x - getBounds().minimum.x) < DISTANCE_THRESHOLD) {
normal = glm::vec3(-1.0f, 0.0f, 0.0f);
distance = rayDistance;
return true;
} else if (glm::abs(entry.x - getBounds().maximum.x) < DISTANCE_THRESHOLD) {
normal = glm::vec3(1.0f, 0.0f, 0.0f);
distance = rayDistance;
return true;
} else if (glm::abs(entry.y - getBounds().minimum.y) < DISTANCE_THRESHOLD) {
normal = glm::vec3(0.0f, -1.0f, 0.0f);
distance = rayDistance;
return true;
} else if (glm::abs(entry.y - getBounds().maximum.y) < DISTANCE_THRESHOLD) {
normal = glm::vec3(0.0f, 1.0f, 0.0f);
distance = rayDistance;
return true;
} else if (glm::abs(entry.z - getBounds().minimum.z) < DISTANCE_THRESHOLD) {
normal = glm::vec3(0.0f, 0.0f, -1.0f);
distance = rayDistance;
return true;
} else if (glm::abs(entry.z - getBounds().maximum.z) < DISTANCE_THRESHOLD) {
normal = glm::vec3(0.0f, 0.0f, 1.0f);
distance = rayDistance;
return true;
}
entry = (entry - getBounds().minimum) / _increment;
glm::vec3 floors = glm::floor(entry); glm::vec3 floors = glm::floor(entry);
glm::vec3 ceils = glm::ceil(entry); glm::vec3 ceils = glm::ceil(entry);
if (floors.x == ceils.x) { if (floors.x == ceils.x) {

View file

@ -998,10 +998,13 @@ int HeightfieldClearFetchVisitor::visit(MetavoxelInfo& info) {
_spannerBounds.maximum = (glm::ceil(_bounds.maximum / increment) + glm::vec3(1.0f, 0.0f, 1.0f)) * increment; _spannerBounds.maximum = (glm::ceil(_bounds.maximum / increment) + glm::vec3(1.0f, 0.0f, 1.0f)) * increment;
_spannerBounds.minimum.y = bounds.minimum.y; _spannerBounds.minimum.y = bounds.minimum.y;
_spannerBounds.maximum.y = bounds.maximum.y; _spannerBounds.maximum.y = bounds.maximum.y;
_heightfieldWidth = (int)glm::round((_spannerBounds.maximum.x - _spannerBounds.minimum.x) / increment) + 1; _heightfieldWidth = (int)glm::round((_spannerBounds.maximum.x - _spannerBounds.minimum.x) / increment);
_heightfieldHeight = (int)glm::round((_spannerBounds.maximum.z - _spannerBounds.minimum.z) / increment) + 1; _heightfieldHeight = (int)glm::round((_spannerBounds.maximum.z - _spannerBounds.minimum.z) / increment);
int heightfieldArea = _heightfieldWidth * _heightfieldHeight; int heightfieldArea = _heightfieldWidth * _heightfieldHeight;
_spanner = spanner = new Heightfield(_spannerBounds, increment, QByteArray(heightfieldArea, 0), Box innerBounds = _spannerBounds;
innerBounds.maximum.x -= increment;
innerBounds.maximum.z -= increment;
_spanner = spanner = new Heightfield(innerBounds, increment, QByteArray(heightfieldArea, 0),
QByteArray(heightfieldArea * DataBlock::COLOR_BYTES, 0), QByteArray(heightfieldArea, 0), QByteArray(heightfieldArea * DataBlock::COLOR_BYTES, 0), QByteArray(heightfieldArea, 0),
QVector<SharedObjectPointer>()); QVector<SharedObjectPointer>());
} }
@ -1049,18 +1052,20 @@ int HeightfieldClearFetchVisitor::visit(MetavoxelInfo& info) {
} }
// if all is gone, clear the node // if all is gone, clear the node
if (!foundNonZero) { if (foundNonZero) {
info.outputValues[0] = AttributeValue(_outputs.at(0), HeightfieldHeightDataPointer newHeightPointer(new HeightfieldHeightData(contents));
encodeInline<HeightfieldHeightDataPointer>(HeightfieldHeightDataPointer())); info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline<HeightfieldHeightDataPointer>(newHeightPointer));
info.outputValues[1] = AttributeValue(_outputs.at(1),
encodeInline<HeightfieldColorDataPointer>(HeightfieldColorDataPointer())); } else {
info.outputValues[2] = AttributeValue(_outputs.at(2), info.outputValues[0] = AttributeValue(_outputs.at(0));
encodeInline<HeightfieldMaterialDataPointer>(HeightfieldMaterialDataPointer()));
return STOP_RECURSION;
} }
HeightfieldHeightDataPointer newHeightPointer(new HeightfieldHeightData(contents)); // allow a border for what we clear in terms of color/material
info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline<HeightfieldHeightDataPointer>(newHeightPointer)); innerBounds.minimum.x += increment;
innerBounds.minimum.z += increment;
innerBounds.maximum.x -= increment;
innerBounds.maximum.z -= increment;
innerOverlap = bounds.getIntersection(innerBounds);
HeightfieldColorDataPointer colorPointer = info.inputValues.at(1).getInlineValue<HeightfieldColorDataPointer>(); HeightfieldColorDataPointer colorPointer = info.inputValues.at(1).getInlineValue<HeightfieldColorDataPointer>();
if (colorPointer) { if (colorPointer) {
@ -1083,18 +1088,25 @@ int HeightfieldClearFetchVisitor::visit(MetavoxelInfo& info) {
memcpy(dest, src, destWidth * DataBlock::COLOR_BYTES); memcpy(dest, src, destWidth * DataBlock::COLOR_BYTES);
} }
destX = (innerOverlap.minimum.x - info.minimum.x) * heightScale; if (foundNonZero) {
destY = (innerOverlap.minimum.z - info.minimum.z) * heightScale; destX = (innerOverlap.minimum.x - info.minimum.x) * heightScale;
destWidth = glm::ceil((innerOverlap.maximum.x - innerOverlap.minimum.x) * heightScale); destY = (innerOverlap.minimum.z - info.minimum.z) * heightScale;
destHeight = glm::ceil((innerOverlap.maximum.z - innerOverlap.minimum.z) * heightScale); destWidth = glm::ceil((innerOverlap.maximum.x - innerOverlap.minimum.x) * heightScale);
dest = contents.data() + (destY * size + destX) * DataBlock::COLOR_BYTES; destHeight = glm::ceil((innerOverlap.maximum.z - innerOverlap.minimum.z) * heightScale);
if (destWidth > 0 && destHeight > 0) {
for (int y = 0; y < destHeight; y++, dest += size * DataBlock::COLOR_BYTES) { dest = contents.data() + (destY * size + destX) * DataBlock::COLOR_BYTES;
memset(dest, 0, destWidth * DataBlock::COLOR_BYTES);
for (int y = 0; y < destHeight; y++, dest += size * DataBlock::COLOR_BYTES) {
memset(dest, 0, destWidth * DataBlock::COLOR_BYTES);
}
HeightfieldColorDataPointer newColorPointer(new HeightfieldColorData(contents));
info.outputValues[1] = AttributeValue(_outputs.at(1),
encodeInline<HeightfieldColorDataPointer>(newColorPointer));
}
} else {
info.outputValues[1] = AttributeValue(_outputs.at(1));
} }
HeightfieldColorDataPointer newColorPointer(new HeightfieldColorData(contents));
info.outputValues[1] = AttributeValue(_outputs.at(1), encodeInline<HeightfieldColorDataPointer>(newColorPointer));
} }
HeightfieldMaterialDataPointer materialPointer = info.inputValues.at(2).getInlineValue<HeightfieldMaterialDataPointer>(); HeightfieldMaterialDataPointer materialPointer = info.inputValues.at(2).getInlineValue<HeightfieldMaterialDataPointer>();
@ -1130,20 +1142,26 @@ int HeightfieldClearFetchVisitor::visit(MetavoxelInfo& info) {
} }
} }
destX = (innerOverlap.minimum.x - info.minimum.x) * heightScale; if (foundNonZero) {
destY = (innerOverlap.minimum.z - info.minimum.z) * heightScale; destX = (innerOverlap.minimum.x - info.minimum.x) * heightScale;
destWidth = glm::ceil((innerOverlap.maximum.x - innerOverlap.minimum.x) * heightScale); destY = (innerOverlap.minimum.z - info.minimum.z) * heightScale;
destHeight = glm::ceil((innerOverlap.maximum.z - innerOverlap.minimum.z) * heightScale); destWidth = glm::ceil((innerOverlap.maximum.x - innerOverlap.minimum.x) * heightScale);
dest = (uchar*)contents.data() + destY * size + destX; destHeight = glm::ceil((innerOverlap.maximum.z - innerOverlap.minimum.z) * heightScale);
if (destWidth > 0 && destHeight > 0) {
for (int y = 0; y < destHeight; y++, dest += size) { dest = (uchar*)contents.data() + destY * size + destX;
memset(dest, 0, destWidth);
for (int y = 0; y < destHeight; y++, dest += size) {
memset(dest, 0, destWidth);
}
clearUnusedMaterials(materials, contents);
HeightfieldMaterialDataPointer newMaterialPointer(new HeightfieldMaterialData(contents, materials));
info.outputValues[2] = AttributeValue(_outputs.at(2),
encodeInline<HeightfieldMaterialDataPointer>(newMaterialPointer));
}
} else {
info.outputValues[2] = AttributeValue(_outputs.at(2));
} }
clearUnusedMaterials(materials, contents);
HeightfieldMaterialDataPointer newMaterialPointer(new HeightfieldMaterialData(contents, materials));
info.outputValues[2] = AttributeValue(_outputs.at(2),
encodeInline<HeightfieldMaterialDataPointer>(newMaterialPointer));
} }
return STOP_RECURSION; return STOP_RECURSION;