Skip to content

Commit 4326e20

Browse files
vtfpp: rename particle sheet accessors to match image/thumbnail accessors, sanity check offset/dims
1 parent b1f59ec commit 4326e20

File tree

4 files changed

+28
-21
lines changed

4 files changed

+28
-21
lines changed

include/vtfpp/SHT.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ class SHT {
1515
struct Sequence {
1616
struct Frame {
1717
struct Bounds {
18-
float left;
19-
float top;
20-
float right;
21-
float bottom;
18+
float x1;
19+
float y1;
20+
float x2;
21+
float y2;
2222
};
2323

2424
float duration;

include/vtfpp/VTF.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -303,13 +303,13 @@ class VTF {
303303
[[nodiscard]] const Resource* getResource(Resource::Type type) const;
304304

305305
/// This is a convenience function. You're best off uploading the bounds to the GPU and scaling the UV there if trying to render a particle
306-
[[nodiscard]] std::vector<std::byte> getParticleSheetFrameRaw(uint16_t& spriteWidth, uint16_t& spriteHeight, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds = 0, uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0, uint16_t slice = 0) const;
306+
[[nodiscard]] std::vector<std::byte> getParticleSheetFrameDataRaw(uint16_t& spriteWidth, uint16_t& spriteHeight, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds = 0, uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0, uint16_t slice = 0) const;
307307

308308
/// This is a convenience function. You're best off uploading the bounds to the GPU and scaling the UV there if trying to render a particle
309-
[[nodiscard]] std::vector<std::byte> getParticleSheetFrameAs(ImageFormat newFormat, uint16_t& spriteWidth, uint16_t& spriteHeight, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds = 0, uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0, uint16_t slice = 0) const;
309+
[[nodiscard]] std::vector<std::byte> getParticleSheetFrameDataAs(ImageFormat newFormat, uint16_t& spriteWidth, uint16_t& spriteHeight, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds = 0, uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0, uint16_t slice = 0) const;
310310

311311
/// This is a convenience function. You're best off uploading the bounds to the GPU and scaling the UV there if trying to render a particle
312-
[[nodiscard]] std::vector<std::byte> getParticleSheetFrameAsRGBA8888(uint16_t& spriteWidth, uint16_t& spriteHeight, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds = 0, uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0, uint16_t slice = 0) const;
312+
[[nodiscard]] std::vector<std::byte> getParticleSheetFrameDataAsRGBA8888(uint16_t& spriteWidth, uint16_t& spriteHeight, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds = 0, uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0, uint16_t slice = 0) const;
313313

314314
void setParticleSheetResource(const SHT& value);
315315

src/vtfpp/SHT.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ SHT::SHT(std::span<const std::byte> shtData) {
2525
frame.duration = stream.read<float>();
2626
for (uint8_t i = 0; i < this->getFrameBoundsCount(); i++) {
2727
auto& bounds = frame.bounds[i];
28-
stream >> bounds.left >> bounds.top >> bounds.right >> bounds.bottom;
28+
stream >> bounds.x1 >> bounds.y1 >> bounds.x2 >> bounds.y2;
2929
}
3030
}
3131
}
@@ -105,7 +105,7 @@ std::vector<std::byte> SHT::bake() const {
105105

106106
for (uint8_t i = 0; i < this->getFrameBoundsCount(); i++) {
107107
auto& bounds = frame.bounds[i];
108-
stream << bounds.left << bounds.top << bounds.right << bounds.bottom;
108+
stream << bounds.x1 << bounds.y1 << bounds.x2 << bounds.y2;
109109
}
110110
}
111111
}

src/vtfpp/VTF.cpp

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <algorithm>
44
#include <cstring>
55
#include <unordered_map>
6+
#include <utility>
67

78
#ifdef SOURCEPP_BUILD_WITH_THREADS
89
#include <future>
@@ -949,7 +950,7 @@ void VTF::regenerateImageData(ImageFormat newFormat, uint16_t newWidth, uint16_t
949950
this->setResourceInternal(Resource::TYPE_IMAGE_DATA, newImageData);
950951
}
951952

952-
std::vector<std::byte> VTF::getParticleSheetFrameRaw(uint16_t& spriteWidth, uint16_t& spriteHeight, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice) const {
953+
std::vector<std::byte> VTF::getParticleSheetFrameDataRaw(uint16_t& spriteWidth, uint16_t& spriteHeight, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice) const {
953954
spriteWidth = 0;
954955
spriteHeight = 0;
955956

@@ -969,28 +970,34 @@ std::vector<std::byte> VTF::getParticleSheetFrameRaw(uint16_t& spriteWidth, uint
969970
// This will also break if any of the bounds are above 1 or below 0, but that
970971
// hasn't been observed in official textures
971972
const auto& bounds = sequence->frames[shtFrame].bounds[shtBounds];
972-
uint16_t left = std::floor(bounds.left * static_cast<float>(this->getWidth(mip)));
973-
uint16_t bottom = std::ceil(bounds.bottom * static_cast<float>(this->getHeight(mip)));
974-
uint16_t right = std::ceil(bounds.right * static_cast<float>(this->getWidth(mip)));
975-
uint16_t top = std::floor(bounds.top * static_cast<float>(this->getHeight(mip)));
973+
uint16_t x1 = std::clamp<uint16_t>(std::floor(bounds.x1 * static_cast<float>(this->getWidth(mip))), 0, this->getWidth(mip));
974+
uint16_t y1 = std::clamp<uint16_t>(std::ceil( bounds.y1 * static_cast<float>(this->getHeight(mip))), 0, this->getHeight(mip));
975+
uint16_t x2 = std::clamp<uint16_t>(std::ceil( bounds.x2 * static_cast<float>(this->getWidth(mip))), 0, this->getHeight(mip));
976+
uint16_t y2 = std::clamp<uint16_t>(std::floor(bounds.y2 * static_cast<float>(this->getHeight(mip))), 0, this->getWidth(mip));
976977

977-
spriteWidth = (right - left);
978-
spriteHeight = (bottom - top);
978+
if (x1 > x2) [[unlikely]] {
979+
std::swap(x1, x2);
980+
}
981+
if (y1 > y2) [[unlikely]] {
982+
std::swap(y1, y2);
983+
}
984+
spriteWidth = x2 - x1;
985+
spriteWidth = y2 - y1;
979986

980-
const auto out = ImageConversion::cropImageData(this->getImageDataRaw(mip, frame, face, slice), this->getFormat(), this->getWidth(mip), spriteWidth, left, this->getHeight(mip), spriteHeight, top);
987+
const auto out = ImageConversion::cropImageData(this->getImageDataRaw(mip, frame, face, slice), this->getFormat(), this->getWidth(mip), spriteWidth, x1, this->getHeight(mip), spriteHeight, y1);
981988
if (out.empty()) {
982989
spriteWidth = 0;
983990
spriteHeight = 0;
984991
}
985992
return out;
986993
}
987994

988-
std::vector<std::byte> VTF::getParticleSheetFrameAs(ImageFormat newFormat, uint16_t& spriteWidth, uint16_t& spriteHeight, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice) const {
989-
return ImageConversion::convertImageDataToFormat(this->getParticleSheetFrameRaw(spriteWidth, spriteHeight, shtSequenceID, shtFrame, shtBounds, mip, frame, face, slice), this->getFormat(), newFormat, spriteWidth, spriteHeight);
995+
std::vector<std::byte> VTF::getParticleSheetFrameDataAs(ImageFormat newFormat, uint16_t& spriteWidth, uint16_t& spriteHeight, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice) const {
996+
return ImageConversion::convertImageDataToFormat(this->getParticleSheetFrameDataRaw(spriteWidth, spriteHeight, shtSequenceID, shtFrame, shtBounds, mip, frame, face, slice), this->getFormat(), newFormat, spriteWidth, spriteHeight);
990997
}
991998

992-
std::vector<std::byte> VTF::getParticleSheetFrameAsRGBA8888(uint16_t& spriteWidth, uint16_t& spriteHeight, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice) const {
993-
return this->getParticleSheetFrameAs(ImageFormat::RGBA8888, spriteWidth, spriteHeight, shtSequenceID, shtFrame, shtBounds, mip, frame, face, slice);
999+
std::vector<std::byte> VTF::getParticleSheetFrameDataAsRGBA8888(uint16_t& spriteWidth, uint16_t& spriteHeight, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice) const {
1000+
return this->getParticleSheetFrameDataAs(ImageFormat::RGBA8888, spriteWidth, spriteHeight, shtSequenceID, shtFrame, shtBounds, mip, frame, face, slice);
9941001
}
9951002

9961003
void VTF::setParticleSheetResource(const SHT& value) {

0 commit comments

Comments
 (0)