mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 16:36:54 +02:00
More progress on rendering.
This commit is contained in:
parent
135e3bf574
commit
de4776ef08
3 changed files with 138 additions and 59 deletions
|
@ -2294,6 +2294,9 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g
|
||||||
glm::vec3 step(1.0f / innerStackWidth, scale.x / (innerStackWidth * scale.y),
|
glm::vec3 step(1.0f / innerStackWidth, scale.x / (innerStackWidth * scale.y),
|
||||||
1.0f / innerStackHeight);
|
1.0f / innerStackHeight);
|
||||||
|
|
||||||
|
const int EDGES_PER_CUBE = 12;
|
||||||
|
EdgeCrossing crossings[EDGES_PER_CUBE];
|
||||||
|
|
||||||
for (int z = 0; z <= stackHeight; z++) {
|
for (int z = 0; z <= stackHeight; z++) {
|
||||||
pos.x = 0.0f;
|
pos.x = 0.0f;
|
||||||
const StackArray* lineSrc = src;
|
const StackArray* lineSrc = src;
|
||||||
|
@ -2324,9 +2327,9 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g
|
||||||
hermiteSegments.append(start + normal * step);
|
hermiteSegments.append(start + normal * step);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int alpha0 = entry->rgba[3];
|
int alpha0 = qAlpha(entry->color);
|
||||||
int alpha2 = lineSrc->getEntryAlpha(y + 1);
|
int alpha2 = lineSrc->getEntryAlpha(y + 1);
|
||||||
int alpha1 = alpha0, alpha4 = alpha0, alpha6 = alpha0;
|
int alpha1 = alpha0, alpha3 = alpha2, alpha4 = alpha0, alpha6 = alpha2;
|
||||||
int alphaTotal = alpha0 + alpha2;
|
int alphaTotal = alpha0 + alpha2;
|
||||||
int possibleTotal = 2 * numeric_limits<uchar>::max();
|
int possibleTotal = 2 * numeric_limits<uchar>::max();
|
||||||
|
|
||||||
|
@ -2341,10 +2344,73 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g
|
||||||
alphaTotal += (alpha6 = lineSrc[stackWidth].getEntryAlpha(y + 1));
|
alphaTotal += (alpha6 = lineSrc[stackWidth].getEntryAlpha(y + 1));
|
||||||
possibleTotal += numeric_limits<uchar>::max();
|
possibleTotal += numeric_limits<uchar>::max();
|
||||||
}
|
}
|
||||||
|
int alpha5 = alpha4, alpha7 = alpha6;
|
||||||
|
if (middleX) {
|
||||||
|
alphaTotal += (alpha1 = lineSrc[1].getEntryAlpha(y));
|
||||||
|
possibleTotal += numeric_limits<uchar>::max();
|
||||||
|
|
||||||
|
alphaTotal += (alpha3 = lineSrc[1].getEntryAlpha(y + 1));
|
||||||
|
possibleTotal += numeric_limits<uchar>::max();
|
||||||
|
|
||||||
|
if (middleZ) {
|
||||||
|
alphaTotal += (alpha5 = lineSrc[stackWidth + 1].getEntryAlpha(y));
|
||||||
|
possibleTotal += numeric_limits<uchar>::max();
|
||||||
|
|
||||||
|
alphaTotal += (alpha7 = lineSrc[stackWidth + 1].getEntryAlpha(y + 1));
|
||||||
|
possibleTotal += numeric_limits<uchar>::max();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (alphaTotal == 0 || alphaTotal == possibleTotal) {
|
if (alphaTotal == 0 || alphaTotal == possibleTotal) {
|
||||||
continue; // no corners set/all corners set
|
continue; // no corners set/all corners set
|
||||||
}
|
}
|
||||||
|
// the terrifying conditional code that follows checks each cube edge for a crossing, gathering
|
||||||
|
// its properties (color, material, normal) if one is present; as before, boundary edges are excluded
|
||||||
|
int crossingCount = 0;
|
||||||
|
if (middleX) {
|
||||||
|
if (alpha0 != alpha1) {
|
||||||
|
EdgeCrossing& crossing = crossings[crossingCount++];
|
||||||
|
float distance = entry->getHermiteX(crossing.normal);
|
||||||
|
if (alpha0 == 0) {
|
||||||
|
const StackArray::Entry& nextEntry = lineSrc[1].getEntry(y);
|
||||||
|
crossing.color = nextEntry.color;
|
||||||
|
crossing.material = nextEntry.material;
|
||||||
|
} else {
|
||||||
|
crossing.color = entry->color;
|
||||||
|
crossing.material = entry->material;
|
||||||
|
}
|
||||||
|
crossing.point = glm::vec3(distance, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (alpha0 != alpha2) {
|
||||||
|
EdgeCrossing& crossing = crossings[crossingCount++];
|
||||||
|
float distance = entry->getHermiteY(crossing.normal);
|
||||||
|
if (alpha0 == 0) {
|
||||||
|
const StackArray::Entry& nextEntry = lineSrc->getEntry(y + 1);
|
||||||
|
crossing.color = nextEntry.color;
|
||||||
|
crossing.material = nextEntry.material;
|
||||||
|
} else {
|
||||||
|
crossing.color = entry->color;
|
||||||
|
crossing.material = entry->material;
|
||||||
|
}
|
||||||
|
crossing.point = glm::vec3(0.0f, distance, 0.0f);
|
||||||
|
}
|
||||||
|
if (middleZ) {
|
||||||
|
if (alpha0 != alpha4) {
|
||||||
|
EdgeCrossing& crossing = crossings[crossingCount++];
|
||||||
|
float distance = entry->getHermiteZ(crossing.normal);
|
||||||
|
if (alpha0 == 0) {
|
||||||
|
const StackArray::Entry& nextEntry = lineSrc[stackWidth].getEntry(y);
|
||||||
|
crossing.color = nextEntry.color;
|
||||||
|
crossing.material = nextEntry.material;
|
||||||
|
} else {
|
||||||
|
crossing.color = entry->color;
|
||||||
|
crossing.material = entry->material;
|
||||||
|
}
|
||||||
|
crossing.point = glm::vec3(0.0f, 0.0f, distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (x != 0) {
|
if (x != 0) {
|
||||||
|
|
|
@ -1153,31 +1153,32 @@ static QVector<StackArray> decodeHeightfieldStack(const QByteArray& encoded,
|
||||||
return contents;
|
return contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool isZero(const uchar values[4]) {
|
StackArray::Entry::Entry() :
|
||||||
return *(const quint32*)values == 0;
|
color(0),
|
||||||
|
material(0),
|
||||||
|
hermiteX(0),
|
||||||
|
hermiteY(0),
|
||||||
|
hermiteZ(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StackArray::Entry::isZero() const {
|
bool StackArray::Entry::isZero() const {
|
||||||
return ::isZero(rgba) && material == 0 && ::isZero(hermiteX) && ::isZero(hermiteY) && ::isZero(hermiteZ);
|
return color == 0 && material == 0 && hermiteX == 0 && hermiteY == 0 && hermiteZ == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StackArray::Entry::isMergeable(const Entry& other) const {
|
bool StackArray::Entry::isMergeable(const Entry& other) const {
|
||||||
return *(const quint32*)rgba == *(const quint32*)other.rgba && material == other.material &&
|
return color == other.color && material == other.material && hermiteX == 0 && hermiteY == 0 && hermiteZ == 0;
|
||||||
::isZero(hermiteX) && ::isZero(hermiteY) && ::isZero(hermiteZ);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void setHermite(uchar values[4], const glm::vec3& normal, float position) {
|
static inline void setHermite(quint32& value, const glm::vec3& normal, float position) {
|
||||||
values[0] = normal.x * numeric_limits<qint8>::max();
|
value = qRgba(normal.x * numeric_limits<qint8>::max(), normal.y * numeric_limits<qint8>::max(),
|
||||||
values[1] = normal.y * numeric_limits<qint8>::max();
|
normal.z * numeric_limits<qint8>::max(), position * numeric_limits<quint8>::max());
|
||||||
values[2] = normal.z * numeric_limits<qint8>::max();
|
|
||||||
values[3] = position * numeric_limits<quint8>::max();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float getHermite(const uchar values[4], glm::vec3& normal) {
|
static inline float getHermite(QRgb value, glm::vec3& normal) {
|
||||||
normal.x = (char)values[0] / (float)numeric_limits<qint8>::max();
|
normal.x = (char)qRed(value) / (float)numeric_limits<qint8>::max();
|
||||||
normal.y = (char)values[1] / (float)numeric_limits<qint8>::max();
|
normal.y = (char)qGreen(value) / (float)numeric_limits<qint8>::max();
|
||||||
normal.z = (char)values[2] / (float)numeric_limits<qint8>::max();
|
normal.z = (char)qBlue(value) / (float)numeric_limits<qint8>::max();
|
||||||
return values[3] / (float)numeric_limits<qint8>::max();
|
return qAlpha(value) / (float)numeric_limits<qint8>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StackArray::Entry::setHermiteX(const glm::vec3& normal, float position) {
|
void StackArray::Entry::setHermiteX(const glm::vec3& normal, float position) {
|
||||||
|
@ -1210,7 +1211,27 @@ int StackArray::getEntryAlpha(int y) const {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int relative = y - getPosition();
|
int relative = y - getPosition();
|
||||||
return (relative < count) ? getEntryData()[qMax(relative, 0)].rgba[3] : 0;
|
return (relative < count) ? qAlpha(getEntryData()[qMax(relative, 0)].color) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
StackArray::Entry& StackArray::getEntry(int y) {
|
||||||
|
static Entry emptyEntry;
|
||||||
|
int count = getEntryCount();
|
||||||
|
if (count == 0) {
|
||||||
|
return emptyEntry;
|
||||||
|
}
|
||||||
|
int relative = y - getPosition();
|
||||||
|
return (relative < count) ? getEntryData()[qMax(relative, 0)] : emptyEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
const StackArray::Entry& StackArray::getEntry(int y) const {
|
||||||
|
static Entry emptyEntry;
|
||||||
|
int count = getEntryCount();
|
||||||
|
if (count == 0) {
|
||||||
|
return emptyEntry;
|
||||||
|
}
|
||||||
|
int relative = y - getPosition();
|
||||||
|
return (relative < count) ? getEntryData()[qMax(relative, 0)] : emptyEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
HeightfieldStack::HeightfieldStack(int width, const QVector<StackArray>& contents,
|
HeightfieldStack::HeightfieldStack(int width, const QVector<StackArray>& contents,
|
||||||
|
@ -2214,8 +2235,8 @@ HeightfieldNode* HeightfieldNode::setMaterial(const glm::vec3& translation, cons
|
||||||
glm::vec3 voxelStepZ = glm::vec3(transform * glm::vec4(0.0f, 0.0f, 1.0f, 0.0f));
|
glm::vec3 voxelStepZ = glm::vec3(transform * glm::vec4(0.0f, 0.0f, 1.0f, 0.0f));
|
||||||
int newTop = start.y * voxelScale;
|
int newTop = start.y * voxelScale;
|
||||||
int newBottom = end.y * voxelScale;
|
int newBottom = end.y * voxelScale;
|
||||||
char r = color.red(), g = color.green(), b = color.blue(), a = color.alpha();
|
QRgb rgba = color.rgba();
|
||||||
bool erase = (a == 0);
|
bool erase = (color.alpha() == 0);
|
||||||
uchar materialMaterialIndex = getMaterialIndex(material, newMaterialMaterials, newMaterialContents);
|
uchar materialMaterialIndex = getMaterialIndex(material, newMaterialMaterials, newMaterialContents);
|
||||||
QByteArray dummyContents;
|
QByteArray dummyContents;
|
||||||
uchar stackMaterialIndex = getMaterialIndex(material, newStackMaterials, dummyContents);
|
uchar stackMaterialIndex = getMaterialIndex(material, newStackMaterials, dummyContents);
|
||||||
|
@ -2246,8 +2267,8 @@ HeightfieldNode* HeightfieldNode::setMaterial(const glm::vec3& translation, cons
|
||||||
float stackZ = (z - HeightfieldHeight::HEIGHT_BORDER) * innerStackHeight / innerHeightHeight;
|
float stackZ = (z - HeightfieldHeight::HEIGHT_BORDER) * innerStackHeight / innerHeightHeight;
|
||||||
|
|
||||||
int topHeight = -1;
|
int topHeight = -1;
|
||||||
char topR = 0, topG = 0, topB = 0;
|
QRgb topColor = 0;
|
||||||
uchar topMaterial;
|
uchar topMaterial = 0;
|
||||||
|
|
||||||
if (stackX >= 0.0f && stackX <= innerStackWidth && stackZ >= 0.0f && stackZ <= innerStackHeight) {
|
if (stackX >= 0.0f && stackX <= innerStackWidth && stackZ >= 0.0f && stackZ <= innerStackHeight) {
|
||||||
StackArray* stackDest = newStackContents.data() + (int)stackZ * stackWidth + (int)stackX;
|
StackArray* stackDest = newStackContents.data() + (int)stackZ * stackWidth + (int)stackX;
|
||||||
|
@ -2259,7 +2280,7 @@ HeightfieldNode* HeightfieldNode::setMaterial(const glm::vec3& translation, cons
|
||||||
StackArray::Entry* entryDest = stackDest->getEntryData();
|
StackArray::Entry* entryDest = stackDest->getEntryData();
|
||||||
|
|
||||||
if (colorDest) {
|
if (colorDest) {
|
||||||
entryDest->setRGB(colorDest);
|
entryDest->color = qRgb(colorDest[0], colorDest[1], colorDest[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (materialDest) {
|
if (materialDest) {
|
||||||
|
@ -2295,7 +2316,7 @@ HeightfieldNode* HeightfieldNode::setMaterial(const glm::vec3& translation, cons
|
||||||
stackDest->getEntryCount() * sizeof(StackArray::Entry));
|
stackDest->getEntryCount() * sizeof(StackArray::Entry));
|
||||||
for (StackArray::Entry* entryDest = newStack.getEntryData(), *end = entryDest + prepend;
|
for (StackArray::Entry* entryDest = newStack.getEntryData(), *end = entryDest + prepend;
|
||||||
entryDest != end; entryDest++) {
|
entryDest != end; entryDest++) {
|
||||||
entryDest->setRGBA(end->rgba);
|
entryDest->color = end->color;
|
||||||
entryDest->material = end->material;
|
entryDest->material = end->material;
|
||||||
}
|
}
|
||||||
*stackDest = newStack;
|
*stackDest = newStack;
|
||||||
|
@ -2311,10 +2332,10 @@ HeightfieldNode* HeightfieldNode::setMaterial(const glm::vec3& translation, cons
|
||||||
bool oldCurrentSet = entryDest->isSet();
|
bool oldCurrentSet = entryDest->isSet();
|
||||||
if (spanner->contains(pos)) {
|
if (spanner->contains(pos)) {
|
||||||
if (hasOwnColors && !erase) {
|
if (hasOwnColors && !erase) {
|
||||||
entryDest->setRGBA(spanner->getColorAt(pos));
|
entryDest->color = spanner->getColorAt(pos);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
entryDest->setRGBA(r, g, b, a);
|
entryDest->color = rgba;
|
||||||
}
|
}
|
||||||
if (hasOwnMaterials && !erase) {
|
if (hasOwnMaterials && !erase) {
|
||||||
int index = spanner->getMaterialAt(pos);
|
int index = spanner->getMaterialAt(pos);
|
||||||
|
@ -2337,14 +2358,14 @@ HeightfieldNode* HeightfieldNode::setMaterial(const glm::vec3& translation, cons
|
||||||
if (nextStackX <= innerStackWidth) {
|
if (nextStackX <= innerStackWidth) {
|
||||||
bool nextSetX = isSet(newStackContents, stackWidth, nextStackX, y, (int)stackZ);
|
bool nextSetX = isSet(newStackContents, stackWidth, nextStackX, y, (int)stackZ);
|
||||||
if (nextSetX == currentSet) {
|
if (nextSetX == currentSet) {
|
||||||
entryDest->clearHermiteX();
|
entryDest->hermiteX = 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
bool flipped = (erase == nextSetX);
|
bool flipped = (erase == nextSetX);
|
||||||
float oldDistance = flipped ? 0.0f : 1.0f;
|
float oldDistance = flipped ? 0.0f : 1.0f;
|
||||||
if (currentSet == oldCurrentSet && nextSetX == isSet(oldStackContents, stackWidth,
|
if (currentSet == oldCurrentSet && nextSetX == isSet(oldStackContents, stackWidth,
|
||||||
nextStackX, y, (int)stackZ)) {
|
nextStackX, y, (int)stackZ)) {
|
||||||
oldDistance = entryDest->hermiteX[3] / (float)numeric_limits<quint8>::max();
|
oldDistance = qAlpha(entryDest->hermiteX) / (float)numeric_limits<quint8>::max();
|
||||||
}
|
}
|
||||||
if (flipped ? (spanner->intersects(pos + voxelStepX, pos, distance, normal) &&
|
if (flipped ? (spanner->intersects(pos + voxelStepX, pos, distance, normal) &&
|
||||||
(distance = 1.0f - distance) >= oldDistance) :
|
(distance = 1.0f - distance) >= oldDistance) :
|
||||||
|
@ -2357,14 +2378,14 @@ HeightfieldNode* HeightfieldNode::setMaterial(const glm::vec3& translation, cons
|
||||||
bool nextSetY = (entryDest != stackDest->getEntryData() + stackDest->getEntryCount() - 1 &&
|
bool nextSetY = (entryDest != stackDest->getEntryData() + stackDest->getEntryCount() - 1 &&
|
||||||
(entryDest + 1)->isSet());
|
(entryDest + 1)->isSet());
|
||||||
if (nextSetY == currentSet) {
|
if (nextSetY == currentSet) {
|
||||||
entryDest->clearHermiteY();
|
entryDest->hermiteY = 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
bool flipped = (erase == nextSetY);
|
bool flipped = (erase == nextSetY);
|
||||||
float oldDistance = flipped ? 0.0f : 1.0f;
|
float oldDistance = flipped ? 0.0f : 1.0f;
|
||||||
if (currentSet == oldCurrentSet && nextSetY == isSet(oldStackContents, stackWidth,
|
if (currentSet == oldCurrentSet && nextSetY == isSet(oldStackContents, stackWidth,
|
||||||
(int)stackX, y + 1, (int)stackZ)) {
|
(int)stackX, y + 1, (int)stackZ)) {
|
||||||
oldDistance = entryDest->hermiteY[3] / (float)numeric_limits<quint8>::max();
|
oldDistance = qAlpha(entryDest->hermiteY) / (float)numeric_limits<quint8>::max();
|
||||||
}
|
}
|
||||||
if (flipped ? (spanner->intersects(pos + voxelStepY, pos, distance, normal) &&
|
if (flipped ? (spanner->intersects(pos + voxelStepY, pos, distance, normal) &&
|
||||||
(distance = 1.0f - distance) >= oldDistance) :
|
(distance = 1.0f - distance) >= oldDistance) :
|
||||||
|
@ -2377,14 +2398,14 @@ HeightfieldNode* HeightfieldNode::setMaterial(const glm::vec3& translation, cons
|
||||||
if (nextStackZ <= innerStackHeight) {
|
if (nextStackZ <= innerStackHeight) {
|
||||||
bool nextSetZ = isSet(newStackContents, stackWidth, (int)stackX, y, nextStackZ);
|
bool nextSetZ = isSet(newStackContents, stackWidth, (int)stackX, y, nextStackZ);
|
||||||
if (nextSetZ == currentSet) {
|
if (nextSetZ == currentSet) {
|
||||||
entryDest->clearHermiteZ();
|
entryDest->hermiteZ = 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
bool flipped = (erase == nextSetZ);
|
bool flipped = (erase == nextSetZ);
|
||||||
float oldDistance = flipped ? 0.0f : 1.0f;
|
float oldDistance = flipped ? 0.0f : 1.0f;
|
||||||
if (currentSet == oldCurrentSet && nextSetZ == isSet(oldStackContents, stackWidth,
|
if (currentSet == oldCurrentSet && nextSetZ == isSet(oldStackContents, stackWidth,
|
||||||
(int)stackX, y, nextStackZ)) {
|
(int)stackX, y, nextStackZ)) {
|
||||||
oldDistance = entryDest->hermiteZ[3] / (float)numeric_limits<quint8>::max();
|
oldDistance = qAlpha(entryDest->hermiteZ) / (float)numeric_limits<quint8>::max();
|
||||||
}
|
}
|
||||||
if (flipped ? (spanner->intersects(pos + voxelStepZ, pos, distance, normal) &&
|
if (flipped ? (spanner->intersects(pos + voxelStepZ, pos, distance, normal) &&
|
||||||
(distance = 1.0f - distance) >= oldDistance) :
|
(distance = 1.0f - distance) >= oldDistance) :
|
||||||
|
@ -2413,10 +2434,8 @@ HeightfieldNode* HeightfieldNode::setMaterial(const glm::vec3& translation, cons
|
||||||
StackArray::Entry* topEntry = stackDest->getEntryData() + topIndex;
|
StackArray::Entry* topEntry = stackDest->getEntryData() + topIndex;
|
||||||
if (topEntry->isSet()) {
|
if (topEntry->isSet()) {
|
||||||
topHeight = ((stackDest->getPosition() + topIndex) +
|
topHeight = ((stackDest->getPosition() + topIndex) +
|
||||||
topEntry->hermiteY[3] / (float)numeric_limits<quint8>::max()) / voxelScale;
|
qAlpha(topEntry->hermiteY) / (float)numeric_limits<quint8>::max()) / voxelScale;
|
||||||
topR = topEntry->rgba[0];
|
topColor = topEntry->color;
|
||||||
topG = topEntry->rgba[1];
|
|
||||||
topB = topEntry->rgba[2];
|
|
||||||
topMaterial = topEntry->material;
|
topMaterial = topEntry->material;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -2436,9 +2455,9 @@ HeightfieldNode* HeightfieldNode::setMaterial(const glm::vec3& translation, cons
|
||||||
if (topHeight != -1) {
|
if (topHeight != -1) {
|
||||||
*heightLineDest = topHeight;
|
*heightLineDest = topHeight;
|
||||||
if (colorDest) {
|
if (colorDest) {
|
||||||
colorDest[0] = topR;
|
colorDest[0] = qRed(topColor);
|
||||||
colorDest[1] = topG;
|
colorDest[1] = qGreen(topColor);
|
||||||
colorDest[2] = topB;
|
colorDest[2] = qBlue(topColor);
|
||||||
}
|
}
|
||||||
if (materialDest) {
|
if (materialDest) {
|
||||||
if (topMaterial != 0) {
|
if (topMaterial != 0) {
|
||||||
|
@ -2467,9 +2486,9 @@ HeightfieldNode* HeightfieldNode::setMaterial(const glm::vec3& translation, cons
|
||||||
colorDest[2] = qBlue(spannerColor);
|
colorDest[2] = qBlue(spannerColor);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
colorDest[0] = r;
|
colorDest[0] = color.red();
|
||||||
colorDest[1] = g;
|
colorDest[1] = color.green();
|
||||||
colorDest[2] = b;
|
colorDest[2] = color.blue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -477,35 +477,26 @@ public:
|
||||||
/// A single entry within the array.
|
/// A single entry within the array.
|
||||||
class Entry {
|
class Entry {
|
||||||
public:
|
public:
|
||||||
uchar rgba[4];
|
quint32 color;
|
||||||
uchar material;
|
uchar material;
|
||||||
uchar hermiteX[4];
|
quint32 hermiteX;
|
||||||
uchar hermiteY[4];
|
quint32 hermiteY;
|
||||||
uchar hermiteZ[4];
|
quint32 hermiteZ;
|
||||||
|
|
||||||
void setRGBA(int r, int g, int b, int a = 0xFF) { rgba[0] = r; rgba[1] = g; rgba[2] = b; rgba[3] = a; }
|
|
||||||
void setRGBA(const uchar* orgba) { setRGBA(orgba[0], orgba[1], orgba[2], orgba[3]); }
|
|
||||||
void setRGB(const uchar* rgb) { setRGBA(rgb[0], rgb[1], rgb[2]); }
|
|
||||||
void setRGBA(QRgb rgb) { setRGBA(qRed(rgb), qGreen(rgb), qBlue(rgb), qAlpha(rgb)); }
|
|
||||||
|
|
||||||
bool isSet() const { return rgba[3] != 0; }
|
Entry();
|
||||||
|
|
||||||
|
bool isSet() const { return qAlpha(color) != 0; }
|
||||||
|
|
||||||
bool isZero() const;
|
bool isZero() const;
|
||||||
bool isMergeable(const Entry& other) const;
|
bool isMergeable(const Entry& other) const;
|
||||||
|
|
||||||
void setHermiteX(int x, int y, int z, int w) { hermiteX[0] = x; hermiteX[1] = y; hermiteX[2] = z; hermiteX[3] = w; }
|
|
||||||
void setHermiteX(const glm::vec3& normal, float position);
|
void setHermiteX(const glm::vec3& normal, float position);
|
||||||
void clearHermiteX() { setHermiteX(0, 0, 0, 0); }
|
|
||||||
float getHermiteX(glm::vec3& normal) const;
|
float getHermiteX(glm::vec3& normal) const;
|
||||||
|
|
||||||
void setHermiteY(int x, int y, int z, int w) { hermiteY[0] = x; hermiteY[1] = y; hermiteY[2] = z; hermiteY[3] = w; }
|
|
||||||
void setHermiteY(const glm::vec3& normal, float position);
|
void setHermiteY(const glm::vec3& normal, float position);
|
||||||
void clearHermiteY() { setHermiteY(0, 0, 0, 0); }
|
|
||||||
float getHermiteY(glm::vec3& normal) const;
|
float getHermiteY(glm::vec3& normal) const;
|
||||||
|
|
||||||
void setHermiteZ(int x, int y, int z, int w) { hermiteZ[0] = x; hermiteZ[1] = y; hermiteZ[2] = z; hermiteZ[3] = w; }
|
|
||||||
void setHermiteZ(const glm::vec3& normal, float position);
|
void setHermiteZ(const glm::vec3& normal, float position);
|
||||||
void clearHermiteZ() { setHermiteZ(0, 0, 0, 0); }
|
|
||||||
float getHermiteZ(glm::vec3& normal) const;
|
float getHermiteZ(glm::vec3& normal) const;
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
@ -529,6 +520,9 @@ public:
|
||||||
|
|
||||||
int getEntryAlpha(int y) const;
|
int getEntryAlpha(int y) const;
|
||||||
|
|
||||||
|
Entry& getEntry(int y);
|
||||||
|
const Entry& getEntry(int y) const;
|
||||||
|
|
||||||
void removeEntries(int position, int count) { remove(sizeof(quint16) + position * sizeof(Entry), count * sizeof(Entry)); }
|
void removeEntries(int position, int count) { remove(sizeof(quint16) + position * sizeof(Entry), count * sizeof(Entry)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue