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

This commit is contained in:
Andrzej Kapolka 2014-07-14 10:58:01 -07:00
commit eab0fa4c27
4 changed files with 137 additions and 42 deletions

View file

@ -441,13 +441,11 @@ Menu::Menu() :
QMenu* timingMenu = developerMenu->addMenu("Timing and Statistics Tools"); QMenu* timingMenu = developerMenu->addMenu("Timing and Statistics Tools");
QMenu* perfTimerMenu = timingMenu->addMenu("Performance Timer"); QMenu* perfTimerMenu = timingMenu->addMenu("Performance Timer");
addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::DisplayTimingDetails, 0, true); addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::DisplayTimingDetails, 0, true);
addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::ExpandDisplaySideTiming, 0, false);
addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::ExpandAvatarSimulateTiming, 0, false);
addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::ExpandAvatarUpdateTiming, 0, false);
addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::ExpandMiscAvatarTiming, 0, false);
addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::ExpandIdleTiming, 0, false);
addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::ExpandPaintGLTiming, 0, false);
addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::ExpandUpdateTiming, 0, false); addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::ExpandUpdateTiming, 0, false);
addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::ExpandMyAvatarTiming, 0, false);
addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::ExpandMyAvatarSimulateTiming, 0, false);
addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::ExpandOtherAvatarTiming, 0, false);
addCheckableActionToQMenuAndActionHash(perfTimerMenu, MenuOption::ExpandPaintGLTiming, 0, false);
addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::TestPing, 0, true); addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::TestPing, 0, true);
addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::FrameTimer); addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::FrameTimer);

View file

@ -357,13 +357,11 @@ namespace MenuOption {
const QString EnableGlowEffect = "Enable Glow Effect (Warning: Poor Oculus Performance)"; const QString EnableGlowEffect = "Enable Glow Effect (Warning: Poor Oculus Performance)";
const QString Enable3DTVMode = "Enable 3DTV Mode"; const QString Enable3DTVMode = "Enable 3DTV Mode";
const QString EnableVRMode = "Enable VR Mode"; const QString EnableVRMode = "Enable VR Mode";
const QString ExpandMiscAvatarTiming = "Expand Misc MyAvatar Timing"; const QString ExpandMyAvatarSimulateTiming = "Expand /myAvatar/simulation";
const QString ExpandAvatarUpdateTiming = "Expand MyAvatar update Timing"; const QString ExpandMyAvatarTiming = "Expand /myAvatar";
const QString ExpandAvatarSimulateTiming = "Expand MyAvatar simulate Timing"; const QString ExpandOtherAvatarTiming = "Expand /otherAvatar";
const QString ExpandDisplaySideTiming = "Expand Display Side Timing"; const QString ExpandPaintGLTiming = "Expand /paintGL";
const QString ExpandIdleTiming = "Expand Idle Timing"; const QString ExpandUpdateTiming = "Expand /update";
const QString ExpandPaintGLTiming = "Expand PaintGL Timing";
const QString ExpandUpdateTiming = "Expand Update Timing";
const QString Faceplus = "Faceplus"; const QString Faceplus = "Faceplus";
const QString Faceshift = "Faceshift"; const QString Faceshift = "Faceshift";
const QString FilterSixense = "Smooth Sixense Movement"; const QString FilterSixense = "Smooth Sixense Movement";

View file

@ -162,36 +162,25 @@ void Stats::drawBackground(unsigned int rgba, int x, int y, int width, int heigh
} }
bool Stats::includeTimingRecord(const QString& name) { bool Stats::includeTimingRecord(const QString& name) {
bool included = false;
if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayTimingDetails)) { if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayTimingDetails)) {
if (name.startsWith("/idle/update/")) {
if (name == "idle/update") { if (name.startsWith("/idle/update/myAvatar/")) {
included = Menu::getInstance()->isOptionChecked(MenuOption::ExpandUpdateTiming) || if (name.startsWith("/idle/update/myAvatar/simulate/")) {
Menu::getInstance()->isOptionChecked(MenuOption::ExpandIdleTiming); return Menu::getInstance()->isOptionChecked(MenuOption::ExpandMyAvatarSimulateTiming);
} else if (name == "idle/updateGL") { }
included = Menu::getInstance()->isOptionChecked(MenuOption::ExpandIdleTiming); return Menu::getInstance()->isOptionChecked(MenuOption::ExpandMyAvatarTiming);
} else if (name.startsWith("idle/update")) { } else if (name.startsWith("/idle/update/otherAvatars/")) {
included = Menu::getInstance()->isOptionChecked(MenuOption::ExpandUpdateTiming); return Menu::getInstance()->isOptionChecked(MenuOption::ExpandOtherAvatarTiming);
} else if (name.startsWith("idle/")) { }
included = Menu::getInstance()->isOptionChecked(MenuOption::ExpandIdleTiming); return Menu::getInstance()->isOptionChecked(MenuOption::ExpandUpdateTiming);
} else if (name.startsWith("MyAvatar::simulate")) { } else if (name.startsWith("/idle/updateGL/paintGL/")) {
included = Menu::getInstance()->isOptionChecked(MenuOption::ExpandAvatarSimulateTiming); return Menu::getInstance()->isOptionChecked(MenuOption::ExpandPaintGLTiming);
} else if (name.startsWith("MyAvatar::update/") || name.startsWith("updateMyAvatar")) { } else if (name.startsWith("/paintGL/")) {
included = Menu::getInstance()->isOptionChecked(MenuOption::ExpandAvatarUpdateTiming); return Menu::getInstance()->isOptionChecked(MenuOption::ExpandPaintGLTiming);
} else if (name.startsWith("MyAvatar::")) {
included = Menu::getInstance()->isOptionChecked(MenuOption::ExpandMiscAvatarTiming);
} else if (name == "paintGL/displaySide") {
included = Menu::getInstance()->isOptionChecked(MenuOption::ExpandDisplaySideTiming) ||
Menu::getInstance()->isOptionChecked(MenuOption::ExpandPaintGLTiming);
} else if (name.startsWith("paintGL/displaySide/")) {
included = Menu::getInstance()->isOptionChecked(MenuOption::ExpandDisplaySideTiming);
} else if (name.startsWith("paintGL/")) {
included = Menu::getInstance()->isOptionChecked(MenuOption::ExpandPaintGLTiming);
} else {
included = true; // include everything else
} }
return true;
} }
return included; return false;
} }
// display expanded or contracted stats // display expanded or contracted stats

View file

@ -357,15 +357,23 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
processedBytes = 0; processedBytes = 0;
// the first part of the data is our octcode... // the first part of the data is our octcode...
int octets = numberOfThreeBitSectionsInCode(data); int octets = numberOfThreeBitSectionsInCode(data, length);
int lengthOfOctcode = bytesRequiredForCodeLength(octets); int lengthOfOctcode = bytesRequiredForCodeLength(octets);
// we don't actually do anything with this octcode... // we don't actually do anything with this octcode...
dataAt += lengthOfOctcode; dataAt += lengthOfOctcode;
processedBytes += lengthOfOctcode; processedBytes += lengthOfOctcode;
// id // id
uint32_t editID; uint32_t editID;
// check to make sure we have enough content to keep reading...
if (processedBytes + sizeof(editID) > length) {
valid = false;
processedBytes = length;
return newParticle; // fail as if we read the entire buffer
}
memcpy(&editID, dataAt, sizeof(editID)); memcpy(&editID, dataAt, sizeof(editID));
dataAt += sizeof(editID); dataAt += sizeof(editID);
processedBytes += sizeof(editID); processedBytes += sizeof(editID);
@ -377,6 +385,14 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
// If this is a NEW_PARTICLE, then we assume that there's an additional uint32_t creatorToken, that // If this is a NEW_PARTICLE, then we assume that there's an additional uint32_t creatorToken, that
// we want to send back to the creator as an map to the actual id // we want to send back to the creator as an map to the actual id
uint32_t creatorTokenID; uint32_t creatorTokenID;
// check to make sure we have enough content to keep reading...
if (processedBytes + sizeof(creatorTokenID) > length) {
valid = false;
processedBytes = length;
return newParticle; // fail as if we read the entire buffer
}
memcpy(&creatorTokenID, dataAt, sizeof(creatorTokenID)); memcpy(&creatorTokenID, dataAt, sizeof(creatorTokenID));
dataAt += sizeof(creatorTokenID); dataAt += sizeof(creatorTokenID);
processedBytes += sizeof(creatorTokenID); processedBytes += sizeof(creatorTokenID);
@ -409,6 +425,12 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
} }
// lastEdited // lastEdited
// check to make sure we have enough content to keep reading...
if (processedBytes + sizeof(newParticle._lastEdited) > length) {
valid = false;
processedBytes = length;
return newParticle; // fail as if we read the entire buffer
}
memcpy(&newParticle._lastEdited, dataAt, sizeof(newParticle._lastEdited)); memcpy(&newParticle._lastEdited, dataAt, sizeof(newParticle._lastEdited));
dataAt += sizeof(newParticle._lastEdited); dataAt += sizeof(newParticle._lastEdited);
processedBytes += sizeof(newParticle._lastEdited); processedBytes += sizeof(newParticle._lastEdited);
@ -417,6 +439,11 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
// properties included bits // properties included bits
uint16_t packetContainsBits = 0; uint16_t packetContainsBits = 0;
if (!isNewParticle) { if (!isNewParticle) {
if (processedBytes + sizeof(packetContainsBits) > length) {
valid = false;
processedBytes = length;
return newParticle; // fail as if we read the entire buffer
}
memcpy(&packetContainsBits, dataAt, sizeof(packetContainsBits)); memcpy(&packetContainsBits, dataAt, sizeof(packetContainsBits));
dataAt += sizeof(packetContainsBits); dataAt += sizeof(packetContainsBits);
processedBytes += sizeof(packetContainsBits); processedBytes += sizeof(packetContainsBits);
@ -425,6 +452,11 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
// radius // radius
if (isNewParticle || ((packetContainsBits & CONTAINS_RADIUS) == CONTAINS_RADIUS)) { if (isNewParticle || ((packetContainsBits & CONTAINS_RADIUS) == CONTAINS_RADIUS)) {
if (processedBytes + sizeof(newParticle._radius) > length) {
valid = false;
processedBytes = length;
return newParticle; // fail as if we read the entire buffer
}
memcpy(&newParticle._radius, dataAt, sizeof(newParticle._radius)); memcpy(&newParticle._radius, dataAt, sizeof(newParticle._radius));
dataAt += sizeof(newParticle._radius); dataAt += sizeof(newParticle._radius);
processedBytes += sizeof(newParticle._radius); processedBytes += sizeof(newParticle._radius);
@ -432,6 +464,11 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
// position // position
if (isNewParticle || ((packetContainsBits & CONTAINS_POSITION) == CONTAINS_POSITION)) { if (isNewParticle || ((packetContainsBits & CONTAINS_POSITION) == CONTAINS_POSITION)) {
if (processedBytes + sizeof(newParticle._position) > length) {
valid = false;
processedBytes = length;
return newParticle; // fail as if we read the entire buffer
}
memcpy(&newParticle._position, dataAt, sizeof(newParticle._position)); memcpy(&newParticle._position, dataAt, sizeof(newParticle._position));
dataAt += sizeof(newParticle._position); dataAt += sizeof(newParticle._position);
processedBytes += sizeof(newParticle._position); processedBytes += sizeof(newParticle._position);
@ -439,6 +476,11 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
// color // color
if (isNewParticle || ((packetContainsBits & CONTAINS_COLOR) == CONTAINS_COLOR)) { if (isNewParticle || ((packetContainsBits & CONTAINS_COLOR) == CONTAINS_COLOR)) {
if (processedBytes + sizeof(newParticle._color) > length) {
valid = false;
processedBytes = length;
return newParticle; // fail as if we read the entire buffer
}
memcpy(newParticle._color, dataAt, sizeof(newParticle._color)); memcpy(newParticle._color, dataAt, sizeof(newParticle._color));
dataAt += sizeof(newParticle._color); dataAt += sizeof(newParticle._color);
processedBytes += sizeof(newParticle._color); processedBytes += sizeof(newParticle._color);
@ -446,6 +488,11 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
// velocity // velocity
if (isNewParticle || ((packetContainsBits & CONTAINS_VELOCITY) == CONTAINS_VELOCITY)) { if (isNewParticle || ((packetContainsBits & CONTAINS_VELOCITY) == CONTAINS_VELOCITY)) {
if (processedBytes + sizeof(newParticle._velocity) > length) {
valid = false;
processedBytes = length;
return newParticle; // fail as if we read the entire buffer
}
memcpy(&newParticle._velocity, dataAt, sizeof(newParticle._velocity)); memcpy(&newParticle._velocity, dataAt, sizeof(newParticle._velocity));
dataAt += sizeof(newParticle._velocity); dataAt += sizeof(newParticle._velocity);
processedBytes += sizeof(newParticle._velocity); processedBytes += sizeof(newParticle._velocity);
@ -453,6 +500,11 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
// gravity // gravity
if (isNewParticle || ((packetContainsBits & CONTAINS_GRAVITY) == CONTAINS_GRAVITY)) { if (isNewParticle || ((packetContainsBits & CONTAINS_GRAVITY) == CONTAINS_GRAVITY)) {
if (processedBytes + sizeof(newParticle._gravity) > length) {
valid = false;
processedBytes = length;
return newParticle; // fail as if we read the entire buffer
}
memcpy(&newParticle._gravity, dataAt, sizeof(newParticle._gravity)); memcpy(&newParticle._gravity, dataAt, sizeof(newParticle._gravity));
dataAt += sizeof(newParticle._gravity); dataAt += sizeof(newParticle._gravity);
processedBytes += sizeof(newParticle._gravity); processedBytes += sizeof(newParticle._gravity);
@ -460,6 +512,11 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
// damping // damping
if (isNewParticle || ((packetContainsBits & CONTAINS_DAMPING) == CONTAINS_DAMPING)) { if (isNewParticle || ((packetContainsBits & CONTAINS_DAMPING) == CONTAINS_DAMPING)) {
if (processedBytes + sizeof(newParticle._damping) > length) {
valid = false;
processedBytes = length;
return newParticle; // fail as if we read the entire buffer
}
memcpy(&newParticle._damping, dataAt, sizeof(newParticle._damping)); memcpy(&newParticle._damping, dataAt, sizeof(newParticle._damping));
dataAt += sizeof(newParticle._damping); dataAt += sizeof(newParticle._damping);
processedBytes += sizeof(newParticle._damping); processedBytes += sizeof(newParticle._damping);
@ -467,6 +524,11 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
// lifetime // lifetime
if (isNewParticle || ((packetContainsBits & CONTAINS_LIFETIME) == CONTAINS_LIFETIME)) { if (isNewParticle || ((packetContainsBits & CONTAINS_LIFETIME) == CONTAINS_LIFETIME)) {
if (processedBytes + sizeof(newParticle._lifetime) > length) {
valid = false;
processedBytes = length;
return newParticle; // fail as if we read the entire buffer
}
memcpy(&newParticle._lifetime, dataAt, sizeof(newParticle._lifetime)); memcpy(&newParticle._lifetime, dataAt, sizeof(newParticle._lifetime));
dataAt += sizeof(newParticle._lifetime); dataAt += sizeof(newParticle._lifetime);
processedBytes += sizeof(newParticle._lifetime); processedBytes += sizeof(newParticle._lifetime);
@ -475,6 +537,11 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
// TODO: make inHand and shouldDie into single bits // TODO: make inHand and shouldDie into single bits
// inHand // inHand
if (isNewParticle || ((packetContainsBits & CONTAINS_INHAND) == CONTAINS_INHAND)) { if (isNewParticle || ((packetContainsBits & CONTAINS_INHAND) == CONTAINS_INHAND)) {
if (processedBytes + sizeof(newParticle._inHand) > length) {
valid = false;
processedBytes = length;
return newParticle; // fail as if we read the entire buffer
}
memcpy(&newParticle._inHand, dataAt, sizeof(newParticle._inHand)); memcpy(&newParticle._inHand, dataAt, sizeof(newParticle._inHand));
dataAt += sizeof(newParticle._inHand); dataAt += sizeof(newParticle._inHand);
processedBytes += sizeof(newParticle._inHand); processedBytes += sizeof(newParticle._inHand);
@ -482,6 +549,11 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
// shouldDie // shouldDie
if (isNewParticle || ((packetContainsBits & CONTAINS_SHOULDDIE) == CONTAINS_SHOULDDIE)) { if (isNewParticle || ((packetContainsBits & CONTAINS_SHOULDDIE) == CONTAINS_SHOULDDIE)) {
if (processedBytes + sizeof(newParticle._shouldDie) > length) {
valid = false;
processedBytes = length;
return newParticle; // fail as if we read the entire buffer
}
memcpy(&newParticle._shouldDie, dataAt, sizeof(newParticle._shouldDie)); memcpy(&newParticle._shouldDie, dataAt, sizeof(newParticle._shouldDie));
dataAt += sizeof(newParticle._shouldDie); dataAt += sizeof(newParticle._shouldDie);
processedBytes += sizeof(newParticle._shouldDie); processedBytes += sizeof(newParticle._shouldDie);
@ -490,9 +562,20 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
// script // script
if (isNewParticle || ((packetContainsBits & CONTAINS_SCRIPT) == CONTAINS_SCRIPT)) { if (isNewParticle || ((packetContainsBits & CONTAINS_SCRIPT) == CONTAINS_SCRIPT)) {
uint16_t scriptLength; uint16_t scriptLength;
if (processedBytes + sizeof(scriptLength) > length) {
valid = false;
processedBytes = length;
return newParticle; // fail as if we read the entire buffer
}
memcpy(&scriptLength, dataAt, sizeof(scriptLength)); memcpy(&scriptLength, dataAt, sizeof(scriptLength));
dataAt += sizeof(scriptLength); dataAt += sizeof(scriptLength);
processedBytes += sizeof(scriptLength); processedBytes += sizeof(scriptLength);
if (processedBytes + scriptLength > length) {
valid = false;
processedBytes = length;
return newParticle; // fail as if we read the entire buffer
}
QString tempString((const char*)dataAt); QString tempString((const char*)dataAt);
newParticle._script = tempString; newParticle._script = tempString;
dataAt += scriptLength; dataAt += scriptLength;
@ -502,9 +585,20 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
// modelURL // modelURL
if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_URL) == CONTAINS_MODEL_URL)) { if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_URL) == CONTAINS_MODEL_URL)) {
uint16_t modelURLLength; uint16_t modelURLLength;
if (processedBytes + sizeof(modelURLLength) > length) {
valid = false;
processedBytes = length;
return newParticle; // fail as if we read the entire buffer
}
memcpy(&modelURLLength, dataAt, sizeof(modelURLLength)); memcpy(&modelURLLength, dataAt, sizeof(modelURLLength));
dataAt += sizeof(modelURLLength); dataAt += sizeof(modelURLLength);
processedBytes += sizeof(modelURLLength); processedBytes += sizeof(modelURLLength);
if (processedBytes + modelURLLength > length) {
valid = false;
processedBytes = length;
return newParticle; // fail as if we read the entire buffer
}
QString tempString((const char*)dataAt); QString tempString((const char*)dataAt);
newParticle._modelURL = tempString; newParticle._modelURL = tempString;
dataAt += modelURLLength; dataAt += modelURLLength;
@ -513,6 +607,11 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
// modelScale // modelScale
if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_SCALE) == CONTAINS_MODEL_SCALE)) { if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_SCALE) == CONTAINS_MODEL_SCALE)) {
if (processedBytes + sizeof(newParticle._modelScale) > length) {
valid = false;
processedBytes = length;
return newParticle; // fail as if we read the entire buffer
}
memcpy(&newParticle._modelScale, dataAt, sizeof(newParticle._modelScale)); memcpy(&newParticle._modelScale, dataAt, sizeof(newParticle._modelScale));
dataAt += sizeof(newParticle._modelScale); dataAt += sizeof(newParticle._modelScale);
processedBytes += sizeof(newParticle._modelScale); processedBytes += sizeof(newParticle._modelScale);
@ -520,6 +619,11 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
// modelTranslation // modelTranslation
if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_TRANSLATION) == CONTAINS_MODEL_TRANSLATION)) { if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_TRANSLATION) == CONTAINS_MODEL_TRANSLATION)) {
if (processedBytes + sizeof(newParticle._modelTranslation) > length) {
valid = false;
processedBytes = length;
return newParticle; // fail as if we read the entire buffer
}
memcpy(&newParticle._modelTranslation, dataAt, sizeof(newParticle._modelTranslation)); memcpy(&newParticle._modelTranslation, dataAt, sizeof(newParticle._modelTranslation));
dataAt += sizeof(newParticle._modelTranslation); dataAt += sizeof(newParticle._modelTranslation);
processedBytes += sizeof(newParticle._modelTranslation); processedBytes += sizeof(newParticle._modelTranslation);
@ -527,6 +631,12 @@ Particle Particle::fromEditPacket(const unsigned char* data, int length, int& pr
// modelRotation // modelRotation
if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_ROTATION) == CONTAINS_MODEL_ROTATION)) { if (isNewParticle || ((packetContainsBits & CONTAINS_MODEL_ROTATION) == CONTAINS_MODEL_ROTATION)) {
const int expectedBytesForPackedQuat = sizeof(uint16_t) * 4; // this is how we pack the quats
if (processedBytes + expectedBytesForPackedQuat > length) {
valid = false;
processedBytes = length;
return newParticle; // fail as if we read the entire buffer
}
int bytes = unpackOrientationQuatFromBytes(dataAt, newParticle._modelRotation); int bytes = unpackOrientationQuatFromBytes(dataAt, newParticle._modelRotation);
dataAt += bytes; dataAt += bytes;
processedBytes += bytes; processedBytes += bytes;