Merge pull request #306 from tomaz82/math

Cleaning up a lot of math functions
This commit is contained in:
Jools Wills 2017-11-16 18:37:22 +00:00 committed by GitHub
commit 0d2dc86a90
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
45 changed files with 697 additions and 550 deletions

View file

@ -447,7 +447,7 @@ SystemData* SystemData::getRandomSystem()
}
// get random number in range
int target = (int) std::round(((double)std::rand() / (double)RAND_MAX) * (total - 1));
int target = (int) Math::round(((double)std::rand() / (double)RAND_MAX) * (total - 1));
for (auto it = sSystemVector.cbegin(); it != sSystemVector.cend(); it++)
{
if ((*it)->isGameSystem())
@ -475,7 +475,7 @@ FileData* SystemData::getRandomGame()
// get random number in range
if (total == 0)
return NULL;
target = (int) std::round(((double)std::rand() / (double)RAND_MAX) * (total - 1));
target = (int) Math::round(((double)std::rand() / (double)RAND_MAX) * (total - 1));
return list.at(target);
}

View file

@ -1,5 +1,6 @@
#include "VolumeControl.h"
#include "math/Misc.h"
#include "Log.h"
#include "Settings.h"
#ifdef WIN32
@ -299,7 +300,7 @@ int VolumeControl::getVolume() const
mixerControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
if (mixerGetControlDetails((HMIXEROBJ)mixerHandle, &mixerControlDetails, MIXER_GETCONTROLDETAILSF_VALUE) == MMSYSERR_NOERROR)
{
volume = (uint8_t)round((value.dwValue * 100) / 65535);
volume = (uint8_t)Math::round((value.dwValue * 100) / 65535);
}
else
{
@ -312,7 +313,7 @@ int VolumeControl::getVolume() const
float floatVolume = 0.0f; //0-1
if (endpointVolume->GetMasterVolumeLevelScalar(&floatVolume) == S_OK)
{
volume = (uint8_t)round(floatVolume * 100.0f);
volume = (uint8_t)Math::round(floatVolume * 100.0f);
LOG(LogInfo) << " getting volume as " << volume << " ( from float " << floatVolume << ")";
}
else

View file

@ -41,18 +41,18 @@ public:
{
cameraOut = Transform4x4f::Identity();
float zoom = lerp<float>(1.0, 4.25f, t*t);
float zoom = Math::lerp(1.0, 4.25f, t*t);
cameraOut.scale(zoom);
const float sw = (float)Renderer::getScreenWidth() / zoom;
const float sh = (float)Renderer::getScreenHeight() / zoom;
Vector3f centerPoint = lerp<Vector3f>(-mCameraStart.translation() + Vector3f(Renderer::getScreenWidth() / 2.0f, Renderer::getScreenHeight() / 2.0f, 0),
mTarget, smoothStep(0.0, 1.0, t));
const Vector2f startPoint = Vector2f(-mCameraStart.translation()) + Vector2f(Renderer::getScreenWidth() / 2.0f, Renderer::getScreenHeight() / 2.0f);
const Vector2f centerPoint = Vector2f().lerp(startPoint, Vector2f(mTarget), Math::smootherStep(0.0, 1.0, t));
cameraOut.translate(Vector3f((sw / 2) - centerPoint.x(), (sh / 2) - centerPoint.y(), 0));
fadeOut = lerp<float>(0.0, 1.0, t*t);
fadeOut = Math::lerp(0.0, 1.0, t*t);
}
private:

View file

@ -15,7 +15,7 @@ public:
{
// cubic ease out
t -= 1;
cameraOut.translation() = -lerp<Vector3f>(-mCameraStart.translation(), mTarget, t*t*t + 1);
cameraOut.translation() = -Vector3f().lerp(-mCameraStart.translation(), mTarget, t*t*t + 1);
}
private:

View file

@ -41,7 +41,7 @@ void AsyncReqComponent::render(const Transform4x4f& parentTrans)
trans = trans.translate(Vector3f(Renderer::getScreenWidth() / 2.0f, Renderer::getScreenHeight() / 2.0f, 0));
Renderer::setMatrix(trans);
Vector3f point(cos(mTime * 0.01f) * 12, sin(mTime * 0.01f) * 12, 0);
Vector3f point(Math::cos(mTime * 0.01f) * 12, Math::sin(mTime * 0.01f) * 12, 0);
Renderer::drawRect((int)point.x(), (int)point.y(), 8, 8, 0x0000FFFF);
}

View file

@ -64,7 +64,7 @@ void RatingComponent::onSizeChanged()
if(mSize.y() > 0)
{
size_t heightPx = (size_t)round(mSize.y());
size_t heightPx = (size_t)Math::round(mSize.y());
if (mFilledTexture)
mFilledTexture->rasterizeAt(heightPx, heightPx);
if(mUnfilledTexture)
@ -78,9 +78,9 @@ void RatingComponent::updateVertices()
{
const float numStars = NUM_RATING_STARS;
const float h = round(getSize().y()); // is the same as a single star's width
const float w = round(h * mValue * numStars);
const float fw = round(h * numStars);
const float h = Math::round(getSize().y()); // is the same as a single star's width
const float w = Math::round(h * mValue * numStars);
const float fw = Math::round(h * numStars);
mVertices[0].pos = Vector2f(0.0f, 0.0f);
mVertices[0].tex = Vector2f(0.0f, 1.0f);

View file

@ -137,7 +137,7 @@ void TextListComponent<T>::render(const Transform4x4f& parentTrans)
if(size() == 0)
return;
const float entrySize = std::max(font->getHeight(1.0), (float)font->getSize()) * mLineSpacing;
const float entrySize = Math::max(font->getHeight(1.0), (float)font->getSize()) * mLineSpacing;
int startEntry = 0;
@ -316,7 +316,7 @@ void TextListComponent<T>::update(int deltaTime)
while(mMarqueeTime > maxTime)
mMarqueeTime -= maxTime;
mMarqueeOffset = Math::scroll_loop(delay, scrollTime + returnTime, mMarqueeTime, scrollLength + returnLength);
mMarqueeOffset = Math::Scroll::loop(delay, scrollTime + returnTime, mMarqueeTime, scrollLength + returnLength);
if(mMarqueeOffset > (scrollLength - (limit - returnLength)))
mMarqueeOffset2 = mMarqueeOffset - (scrollLength + returnLength);
@ -373,7 +373,7 @@ void TextListComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme, c
}
setFont(Font::getFromTheme(elem, properties, mFont));
const float selectorHeight = std::max(mFont->getHeight(1.0), (float)mFont->getSize()) * mLineSpacing;
const float selectorHeight = Math::max(mFont->getHeight(1.0), (float)mFont->getSize()) * mLineSpacing;
setSelectorHeight(selectorHeight);
if(properties & SOUND && elem->has("scrollSound"))

View file

@ -14,7 +14,7 @@ GuiGeneralScreensaverOptions::GuiGeneralScreensaverOptions(Window* window, const
screensaver_time->setValue((float)(Settings::getInstance()->getInt("ScreenSaverTime") / (1000 * 60)));
addWithLabel("SCREENSAVER AFTER", screensaver_time);
addSaveFunc([screensaver_time] {
Settings::getInstance()->setInt("ScreenSaverTime", (int)round(screensaver_time->getValue()) * (1000 * 60));
Settings::getInstance()->setInt("ScreenSaverTime", (int)Math::round(screensaver_time->getValue()) * (1000 * 60));
PowerSaver::updateTimeouts();
});

View file

@ -90,7 +90,7 @@ void GuiMenu::openSoundSettings()
auto volume = std::make_shared<SliderComponent>(mWindow, 0.f, 100.f, 1.f, "%");
volume->setValue((float)VolumeControl::getInstance()->getVolume());
s->addWithLabel("SYSTEM VOLUME", volume);
s->addSaveFunc([volume] { VolumeControl::getInstance()->setVolume((int)round(volume->getValue())); });
s->addSaveFunc([volume] { VolumeControl::getInstance()->setVolume((int)Math::round(volume->getValue())); });
if (ViewController::get()->isUIModeFull())
{
@ -317,7 +317,7 @@ void GuiMenu::openOtherSettings()
auto max_vram = std::make_shared<SliderComponent>(mWindow, 0.f, 1000.f, 10.f, "Mb");
max_vram->setValue((float)(Settings::getInstance()->getInt("MaxVRAM")));
s->addWithLabel("VRAM LIMIT", max_vram);
s->addSaveFunc([max_vram] { Settings::getInstance()->setInt("MaxVRAM", (int)round(max_vram->getValue())); });
s->addSaveFunc([max_vram] { Settings::getInstance()->setInt("MaxVRAM", (int)Math::round(max_vram->getValue())); });
// power saver
auto power_saver = std::make_shared< OptionListComponent<std::string> >(mWindow, "POWER SAVER MODES", false);

View file

@ -156,7 +156,7 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window, MetaDataList* md, const std::vector
mGrid.setEntry(mButtons, Vector2i(0, 2), true, false);
// resize + center
float width = (float) std::min(Renderer::getScreenHeight(), (unsigned int) (Renderer::getScreenWidth() * 0.90f));
float width = (float) Math::min(Renderer::getScreenHeight(), (unsigned int) (Renderer::getScreenWidth() * 0.90f));
setSize(width, Renderer::getScreenHeight() * 0.82f);
setPosition((Renderer::getScreenWidth() - mSize.x()) / 2, (Renderer::getScreenHeight() - mSize.y()) / 2);
}

View file

@ -15,7 +15,7 @@ GuiSlideshowScreensaverOptions::GuiSlideshowScreensaverOptions(Window* window, c
sss_image_sec->setValue((float)(Settings::getInstance()->getInt("ScreenSaverSwapImageTimeout") / (1000)));
addWithLabel(row, "SWAP IMAGE AFTER (SECS)", sss_image_sec);
addSaveFunc([sss_image_sec] {
int playNextTimeout = (int)round(sss_image_sec->getValue()) * (1000);
int playNextTimeout = (int)Math::round(sss_image_sec->getValue()) * (1000);
Settings::getInstance()->setInt("ScreenSaverSwapImageTimeout", playNextTimeout);
PowerSaver::updateTimeouts();
});

View file

@ -13,7 +13,7 @@ GuiVideoScreensaverOptions::GuiVideoScreensaverOptions(Window* window, const cha
swap->setValue((float)(Settings::getInstance()->getInt("ScreenSaverSwapVideoTimeout") / (1000)));
addWithLabel("SWAP VIDEO AFTER (SECS)", swap);
addSaveFunc([swap] {
int playNextTimeout = (int)round(swap->getValue()) * (1000);
int playNextTimeout = (int)Math::round(swap->getValue()) * (1000);
Settings::getInstance()->setInt("ScreenSaverSwapVideoTimeout", playNextTimeout);
PowerSaver::updateTimeouts();
});

View file

@ -240,7 +240,7 @@ void SystemView::onCursorChanged(const CursorState& state)
Animation* infoFadeOut = new LambdaAnimation(
[infoStartOpacity, this] (float t)
{
mSystemInfo.setOpacity((unsigned char)(lerp<float>(infoStartOpacity, 0.f, t) * 255));
mSystemInfo.setOpacity((unsigned char)(Math::lerp(infoStartOpacity, 0.f, t) * 255));
}, (int)(infoStartOpacity * (goFast ? 10 : 150)));
unsigned int gameCount = getSelected()->getDisplayedGameCount();
@ -260,7 +260,7 @@ void SystemView::onCursorChanged(const CursorState& state)
Animation* infoFadeIn = new LambdaAnimation(
[this](float t)
{
mSystemInfo.setOpacity((unsigned char)(lerp<float>(0.f, 1.f, t) * 255));
mSystemInfo.setOpacity((unsigned char)(Math::lerp(0.f, 1.f, t) * 255));
}, goFast ? 10 : 300);
// wait 600ms to fade in
@ -279,7 +279,7 @@ void SystemView::onCursorChanged(const CursorState& state)
[this, startExtrasFade, startPos, endPos, posMax, move_carousel](float t)
{
t -= 1;
float f = lerp<float>(startPos, endPos, t*t*t + 1);
float f = Math::lerp(startPos, endPos, t*t*t + 1);
if(f < 0)
f += posMax;
if(f >= posMax)
@ -289,11 +289,11 @@ void SystemView::onCursorChanged(const CursorState& state)
t += 1;
if(t < 0.3f)
this->mExtrasFadeOpacity = lerp<float>(0.0f, 1.0f, t / 0.3f + startExtrasFade);
this->mExtrasFadeOpacity = Math::lerp(0.0f, 1.0f, t / 0.3f + startExtrasFade);
else if(t < 0.7f)
this->mExtrasFadeOpacity = 1.0f;
else
this->mExtrasFadeOpacity = lerp<float>(1.0f, 0.0f, (t - 0.7f) / 0.3f);
this->mExtrasFadeOpacity = Math::lerp(1.0f, 0.0f, (t - 0.7f) / 0.3f);
if(t > 0.5f)
this->mExtrasCamOffset = endPos;
@ -305,7 +305,7 @@ void SystemView::onCursorChanged(const CursorState& state)
[this, startPos, endPos, posMax, move_carousel](float t)
{
t -= 1;
float f = lerp<float>(startPos, endPos, t*t*t + 1);
float f = Math::lerp(startPos, endPos, t*t*t + 1);
if(f < 0)
f += posMax;
if(f >= posMax)
@ -320,7 +320,7 @@ void SystemView::onCursorChanged(const CursorState& state)
[this, startPos, endPos, posMax, move_carousel ](float t)
{
t -= 1;
float f = lerp<float>(startPos, endPos, t*t*t + 1);
float f = Math::lerp(startPos, endPos, t*t*t + 1);
if(f < 0)
f += posMax;
if(f >= posMax)
@ -472,7 +472,7 @@ void SystemView::renderCarousel(const Transform4x4f& trans)
}
int center = (int)(mCamOffset);
int logoCount = std::min(mCarousel.maxLogoCount, (int)mEntries.size());
int logoCount = Math::min(mCarousel.maxLogoCount, (int)mEntries.size());
// Adding texture loading buffers depending on scrolling speed and status
int bufferIndex = getScrollingVelocity() + 1;
@ -498,11 +498,11 @@ void SystemView::renderCarousel(const Transform4x4f& trans)
float distance = i - mCamOffset;
float scale = 1.0f + ((mCarousel.logoScale - 1.0f) * (1.0f - fabs(distance)));
scale = std::min(mCarousel.logoScale, std::max(1.0f, scale));
scale = Math::min(mCarousel.logoScale, Math::max(1.0f, scale));
scale /= mCarousel.logoScale;
int opacity = (int) round(0x80 + ((0xFF - 0x80) * (1.0f - fabs(distance))));
opacity = std::max((int) 0x80, opacity);
int opacity = (int) Math::round(0x80 + ((0xFF - 0x80) * (1.0f - fabs(distance))));
opacity = Math::max((int) 0x80, opacity);
const std::shared_ptr<GuiComponent> &comp = mEntries.at(index).data.logo;
if (mCarousel.type == VERTICAL_WHEEL) {
@ -631,7 +631,7 @@ void SystemView::getCarouselFromTheme(const ThemeData::ThemeElement* elem)
if (elem->has("logoSize"))
mCarousel.logoSize = elem->get<Vector2f>("logoSize") * mSize;
if (elem->has("maxLogoCount"))
mCarousel.maxLogoCount = (int) std::round(elem->get<float>("maxLogoCount"));
mCarousel.maxLogoCount = (int) Math::round(elem->get<float>("maxLogoCount"));
if (elem->has("zIndex"))
mCarousel.zIndex = elem->get<float>("zIndex");
if (elem->has("logoRotation"))

View file

@ -149,7 +149,7 @@ void ViewController::playViewTransition()
cancelAnimation(0);
auto fadeFunc = [this](float t) {
mFadeOpacity = lerp<float>(0, 1, t);
mFadeOpacity = Math::lerp(0, 1, t);
};
const static int FADE_DURATION = 240; // fade in/out time
@ -217,7 +217,7 @@ void ViewController::launch(FileData* game, Vector3f center)
{
// fade out, launch game, fade back in
auto fadeFunc = [this](float t) {
mFadeOpacity = lerp<float>(0.0f, 1.0f, t);
mFadeOpacity = Math::lerp(0.0f, 1.0f, t);
};
setAnimation(new LambdaAnimation(fadeFunc, 800), 0, [this, game, fadeFunc]
{

View file

@ -228,7 +228,7 @@ void DetailedGameListView::updateInfoPanel()
{
auto func = [comp](float t)
{
comp->setOpacity((unsigned char)(lerp<float>(0.0f, 1.0f, t)*255));
comp->setOpacity((unsigned char)(Math::lerp(0.0f, 1.0f, t)*255));
};
comp->setAnimation(new LambdaAnimation(func, 150), 0, nullptr, fadingOut);
}

View file

@ -286,7 +286,7 @@ void VideoGameListView::updateInfoPanel()
{
auto func = [comp](float t)
{
comp->setOpacity((unsigned char)(lerp<float>(0.0f, 1.0f, t)*255));
comp->setOpacity((unsigned char)(Math::lerp(0.0f, 1.0f, t)*255));
};
comp->setAnimation(new LambdaAnimation(func, 150), 0, nullptr, fadingOut);
}

View file

@ -54,6 +54,14 @@ set(CORE_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMsgBox.h
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiTextEditPopup.h
# Math
${CMAKE_CURRENT_SOURCE_DIR}/src/math/Misc.h
${CMAKE_CURRENT_SOURCE_DIR}/src/math/Transform4x4f.h
${CMAKE_CURRENT_SOURCE_DIR}/src/math/Vector2f.h
${CMAKE_CURRENT_SOURCE_DIR}/src/math/Vector2i.h
${CMAKE_CURRENT_SOURCE_DIR}/src/math/Vector3f.h
${CMAKE_CURRENT_SOURCE_DIR}/src/math/Vector4f.h
# Resources
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/Font.h
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/ResourceManager.h
@ -114,6 +122,14 @@ set(CORE_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiMsgBox.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guis/GuiTextEditPopup.cpp
# Math
${CMAKE_CURRENT_SOURCE_DIR}/src/math/Misc.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/math/Transform4x4f.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/math/Vector2f.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/math/Vector2i.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/math/Vector3f.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/math/Vector4f.cpp
# Resources
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/Font.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/resources/ResourceManager.cpp

View file

@ -1,7 +1,7 @@
#include "Renderer.h"
#include "math/Misc.h"
#include "Log.h"
#include <math.h>
#include <stack>
namespace Renderer {
@ -92,7 +92,7 @@ namespace Renderer {
void drawRect(float x, float y, float w, float h, unsigned int color, GLenum blend_sfactor, GLenum blend_dfactor)
{
drawRect((int)round(x), (int)round(y), (int)round(w), (int)round(h), color, blend_sfactor, blend_dfactor);
drawRect((int)Math::round(x), (int)Math::round(y), (int)Math::round(w), (int)Math::round(h), color, blend_sfactor, blend_dfactor);
}
void drawRect(int x, int y, int w, int h, unsigned int color, GLenum blend_sfactor, GLenum blend_dfactor)

View file

@ -29,13 +29,6 @@ std::string strToUpper(const std::string& str)
return strToUpper(str.c_str());
}
#if defined(_WIN32) && _MSC_VER < 1800
float round(float num)
{
return (float)((int)(num + 0.5f));
}
#endif
// embedded resources, e.g. ":/font.ttf", need to be properly handled too
std::string getCanonicalPath(const std::string& path)
{

View file

@ -9,10 +9,6 @@ std::string strToUpper(const char* from);
std::string& strToUpper(std::string& str);
std::string strToUpper(const std::string& str);
#if defined(_WIN32) && _MSC_VER < 1800
float round(float num);
#endif
std::string getCanonicalPath(const std::string& str);
boost::filesystem::path removeCommonPathUsingStrings(const boost::filesystem::path& path, const boost::filesystem::path& relativeTo, bool& contains);

View file

@ -308,8 +308,8 @@ void Window::renderLoadingScreen()
auto& font = mDefaultFonts.at(1);
TextCache* cache = font->buildTextCache("LOADING...", 0, 0, 0x656565FF);
trans = trans.translate(Vector3f(round((Renderer::getScreenWidth() - cache->metrics.size.x()) / 2.0f),
round(Renderer::getScreenHeight() * 0.835f), 0.0f));
trans = trans.translate(Vector3f(Math::round((Renderer::getScreenWidth() - cache->metrics.size.x()) / 2.0f),
Math::round(Renderer::getScreenHeight() * 0.835f), 0.0f));
Renderer::setMatrix(trans);
font->renderTextCache(cache);
delete cache;

View file

@ -9,37 +9,4 @@ public:
virtual void apply(float t) = 0;
};
// useful helper/interpolation functions
inline float clamp(float min, float max, float val)
{
if(val < min)
val = min;
else if(val > max)
val = max;
return val;
}
//http://en.wikipedia.org/wiki/Smoothstep
inline float smoothStep(float edge0, float edge1, float x)
{
// Scale, and clamp x to 0..1 range
x = clamp(0, 1, (x - edge0)/(edge1 - edge0));
// Evaluate polynomial
return x*x*x*(x*(x*6 - 15) + 10);
}
template<typename T>
T lerp(const T& start, const T& end, float t)
{
if(t <= 0.0f)
return start;
if(t >= 1.0f)
return end;
return (start * (1 - t) + end * t);
}
#endif // ES_CORE_ANIMATIONS_ANIMATION_H

View file

@ -46,7 +46,7 @@ void ButtonComponent::setText(const std::string& text, const std::string& helpTe
mTextCache = std::unique_ptr<TextCache>(mFont->buildTextCache(mText, 0, 0, getCurTextColor()));
float minWidth = mFont->sizeText("DELETE").x() + 12;
setSize(std::max(mTextCache->metrics.size.x() + 12, minWidth), mTextCache->metrics.size.y());
setSize(Math::max(mTextCache->metrics.size.x() + 12, minWidth), mTextCache->metrics.size.y());
updateHelpPrompts();
}

View file

@ -169,10 +169,10 @@ void ComponentList::render(const Transform4x4f& parentTrans)
Vector3f dim(mSize.x(), mSize.y(), 0);
dim = trans * dim - trans.translation();
Renderer::pushClipRect(Vector2i((int)trans.translation().x(), (int)trans.translation().y()),
Vector2i((int)round(dim.x()), (int)round(dim.y() + 1)));
Vector2i((int)Math::round(dim.x()), (int)Math::round(dim.y() + 1)));
// scroll the camera
trans.translate(Vector3f(0, -round(mCameraOffset), 0));
trans.translate(Vector3f(0, -Math::round(mCameraOffset), 0));
// draw our entries
std::vector<GuiComponent*> drawAfterCursor;

View file

@ -67,7 +67,7 @@ void HelpComponent::updateGrid()
std::vector< std::shared_ptr<TextComponent> > labels;
float width = 0;
const float height = round(font->getLetterHeight() * 1.25f);
const float height = Math::round(font->getLetterHeight() * 1.25f);
for(auto it = mPrompts.cbegin(); it != mPrompts.cend(); it++)
{
auto icon = std::make_shared<ImageComponent>(mWindow);

View file

@ -59,7 +59,7 @@ void ImageComponent::resize()
}
// for SVG rasterization, always calculate width from rounded height (see comment above)
mSize[1] = round(mSize[1]);
mSize[1] = Math::round(mSize[1]);
mSize[0] = (mSize[1] / textureSize.y()) * textureSize.x();
}else{
@ -71,17 +71,17 @@ void ImageComponent::resize()
// for SVG rasterization, we always calculate width from rounded height (see comment above)
if(!mTargetSize.x() && mTargetSize.y())
{
mSize[1] = round(mTargetSize.y());
mSize[1] = Math::round(mTargetSize.y());
mSize[0] = (mSize.y() / textureSize.y()) * textureSize.x();
}else if(mTargetSize.x() && !mTargetSize.y())
{
mSize[1] = round((mTargetSize.x() / textureSize.x()) * textureSize.y());
mSize[1] = Math::round((mTargetSize.x() / textureSize.x()) * textureSize.y());
mSize[0] = (mSize.y() / textureSize.y()) * textureSize.x();
}
}
}
// mSize.y() should already be rounded
mTexture->rasterizeAt((int)round(mSize.x()), (int)round(mSize.y()));
mTexture->rasterizeAt((int)Math::round(mSize.x()), (int)Math::round(mSize.y()));
onSizeChanged();
}
@ -177,7 +177,7 @@ void ImageComponent::updateVertices()
// we go through this mess to make sure everything is properly rounded
// if we just round vertices at the end, edge cases occur near sizes of 0.5
Vector2f topLeft(0.0, 0.0);
Vector2f bottomRight(round(mSize.x()), round(mSize.y()));
Vector2f bottomRight(Math::round(mSize.x()), Math::round(mSize.y()));
mVertices[0].pos = Vector2f(topLeft.x(), topLeft.y());
mVertices[1].pos = Vector2f(topLeft.x(), bottomRight.y());

View file

@ -62,7 +62,7 @@ void MenuComponent::updateSize()
}
}
float width = (float) std::min(Renderer::getScreenHeight(), (unsigned int) (Renderer::getScreenWidth() * 0.90f));
float width = (float) Math::min(Renderer::getScreenHeight(), (unsigned int) (Renderer::getScreenWidth() * 0.90f));
setSize(width, height);
}
@ -128,6 +128,6 @@ std::shared_ptr<ImageComponent> makeArrow(Window* window)
{
auto bracket = std::make_shared<ImageComponent>(window);
bracket->setImage(":/arrow.svg");
bracket->setResize(0, round(Font::get(FONT_SIZE_MEDIUM)->getLetterHeight()));
bracket->setResize(0, Math::round(Font::get(FONT_SIZE_MEDIUM)->getLetterHeight()));
return bracket;
}

View file

@ -107,7 +107,7 @@ void TextComponent::render(const Transform4x4f& parentTrans)
if(mTextCache)
{
const Vector2f& textSize = mTextCache->metrics.size;
float yOff;
float yOff = 0;
switch(mVerticalAlignment)
{
case ALIGN_TOP:

View file

@ -101,7 +101,7 @@ void VideoVlcComponent::resize()
}
// for SVG rasterization, always calculate width from rounded height (see comment above)
mSize[1] = round(mSize[1]);
mSize[1] = Math::round(mSize[1]);
mSize[0] = (mSize[1] / textureSize.y()) * textureSize.x();
}else{
@ -113,17 +113,17 @@ void VideoVlcComponent::resize()
// for SVG rasterization, we always calculate width from rounded height (see comment above)
if(!mTargetSize.x() && mTargetSize.y())
{
mSize[1] = round(mTargetSize.y());
mSize[1] = Math::round(mTargetSize.y());
mSize[0] = (mSize.y() / textureSize.y()) * textureSize.x();
}else if(mTargetSize.x() && !mTargetSize.y())
{
mSize[1] = round((mTargetSize.x() / textureSize.x()) * textureSize.y());
mSize[1] = Math::round((mTargetSize.x() / textureSize.x()) * textureSize.y());
mSize[0] = (mSize.y() / textureSize.y()) * textureSize.x();
}
}
// mSize.y() should already be rounded
mTexture->rasterizeAt((int)round(mSize.x()), (int)round(mSize.y()));
mTexture->rasterizeAt((int)Math::round(mSize.x()), (int)Math::round(mSize.y()));
onSizeChanged();
}
@ -327,8 +327,8 @@ void VideoVlcComponent::startVideo()
mVideoWidth = (unsigned int) (mVideoWidth * resizeScale.y());
mVideoHeight = (unsigned int) (mVideoHeight * resizeScale.y());
}
mVideoHeight = (unsigned int) round(mVideoHeight);
mVideoWidth = (unsigned int) round(mVideoWidth);
mVideoHeight = (unsigned int) Math::round(mVideoHeight);
mVideoWidth = (unsigned int) Math::round(mVideoWidth);
}
}
#endif

View file

@ -47,13 +47,13 @@ GuiMsgBox::GuiMsgBox(Window* window, const std::string& text,
if(mMsg->getSize().x() < width && mButtonGrid->getSize().x() < width)
{
// mMsg and buttons are narrower than width
width = std::max(mButtonGrid->getSize().x(), mMsg->getSize().x());
width = std::max(width, minWidth);
width = Math::max(mButtonGrid->getSize().x(), mMsg->getSize().x());
width = Math::max(width, minWidth);
}
// now that we know width, we can find height
mMsg->setSize(width, 0); // mMsg->getSize.y() now returns the proper length
const float msgHeight = std::max(Font::get(FONT_SIZE_LARGE)->getHeight(), mMsg->getSize().y()*1.225f);
const float msgHeight = Math::max(Font::get(FONT_SIZE_LARGE)->getHeight(), mMsg->getSize().y()*1.225f);
setSize(width + HORIZONTAL_PADDING_PX*2, msgHeight + mButtonGrid->getSize().y());
// center for good measure

117
es-core/src/math/Misc.cpp Normal file
View file

@ -0,0 +1,117 @@
#include "math/Misc.h"
#include <math.h>
namespace Math
{
// added here to avoid including math.h whenever these are used
double cos(const double _num)
{
return ::cos(_num);
} // Math::cos
double sin(const double _num)
{
return ::sin(_num);
} // Math::sin
float min(const float _num1, const float _num2)
{
return (_num1 < _num2) ? _num1 : _num2;
} // Math::min
float max(const float _num1, const float _num2)
{
return (_num1 > _num2) ? _num1 : _num2;
} // Math::max
float clamp(const float _min, const float _max, const float _num)
{
return max(min(_num, _max), _min);
} // Math::clamp
float round(const float _num)
{
return (int)(_num + 0.5);
} // Math::round
float lerp(const float _start, const float _end, const float _fraction)
{
return (_start + ((_end - _start) * clamp(0, 1, _fraction)));
} // Math::lerp
float smoothStep(const float _left, const float _right, const float _x)
{
const float x = clamp(0, 1, (_x - _left)/(_right - _left));
return x * x * (3 - (2 * x));
} // Math::smoothStep
float smootherStep(const float _left, const float _right, const float _x)
{
const float x = clamp(0, 1, (_x - _left)/(_right - _left));
return x * x * x * (x * ((x * 6) - 15) + 10);
} // Math::smootherStep
namespace Scroll
{
float bounce(const float _delayTime, const float _scrollTime, const float _currentTime, const int _scrollLength)
{
if(_currentTime < _delayTime)
{
// wait
return 0;
}
else if(_currentTime < (_delayTime + _scrollTime))
{
// lerp from 0 to scrollLength
const float fraction = (_currentTime - _delayTime) / _scrollTime;
return lerp(0.0f, _scrollLength, smootherStep(0, 1, fraction));
}
else if(_currentTime < (_delayTime + _scrollTime + _delayTime))
{
// wait some more
return _scrollLength;
}
else if(_currentTime < (_delayTime + _scrollTime + _delayTime + _scrollTime))
{
// lerp back from scrollLength to 0
const float fraction = (_currentTime - _delayTime - _scrollTime - _delayTime) / _scrollTime;
return lerp(_scrollLength, 0.0f, smootherStep(0, 1, fraction));
}
// and back to waiting
return 0;
} // Math::Scroll::bounce
float loop(const float _delayTime, const float _scrollTime, const float _currentTime, const int _scrollLength)
{
if(_currentTime < _delayTime)
{
// wait
return 0;
}
else if(_currentTime < (_delayTime + _scrollTime))
{
// lerp from 0 to scrollLength
const float fraction = (_currentTime - _delayTime) / _scrollTime;
return lerp(0.0f, _scrollLength, fraction);
}
// and back to waiting
return 0;
} // Math::Scroll::loop
} // Math::Scroll::
} // Math::

View file

@ -2,60 +2,31 @@
#ifndef ES_CORE_MATH_MISC_H
#define ES_CORE_MATH_MISC_H
#include <math.h>
#define ES_PI (3.1415926535897932384626433832795028841971693993751058209749445923)
#define ES_RAD_TO_DEG(x) ((x) * (180.0 / ES_PI))
#define ES_DEG_TO_RAD(x) ((x) * (ES_PI / 180.0))
namespace Math
{
inline float scroll_bounce(const float delayTime, const float scrollTime, const float currentTime, const int scrollLength)
// added here to avoid including math.h whenever these are used
double cos(const double _num);
double sin(const double _num);
float min(const float _num1, const float _num2);
float max(const float _num1, const float _num2);
float clamp(const float _num, const float _min, const float _max);
float round(const float _num);
float lerp(const float _start, const float _end, const float _fraction);
float smoothStep(const float _left, const float _right, const float _x);
float smootherStep(const float _left, const float _right, const float _x);
namespace Scroll
{
if(currentTime < delayTime)
{
// wait
return 0;
}
else if(currentTime < (delayTime + scrollTime))
{
// lerp from 0 to scrollLength
const float fraction = (currentTime - delayTime) / scrollTime;
return (float)(((1.0 - cos(ES_PI * fraction)) * 0.5) * scrollLength);
}
else if(currentTime < (delayTime + scrollTime + delayTime))
{
// wait some more
return scrollLength;
}
else if(currentTime < (delayTime + scrollTime + delayTime + scrollTime))
{
// lerp back from scrollLength to 0
const float fraction = 1.0 - (currentTime - delayTime - scrollTime - delayTime) / scrollTime;
return (float)(((1.0 - cos(ES_PI * fraction)) * 0.5) * scrollLength);
}
float bounce(const float _delayTime, const float _scrollTime, const float _currentTime, const int _scrollLength);
float loop(const float _delayTime, const float _scrollTime, const float _currentTime, const int _scrollLength);
// and back to waiting
return 0;
}
} // Math::Scroll::
inline float scroll_loop(const float delayTime, const float scrollTime, const float currentTime, const int scrollLength)
{
if(currentTime < delayTime)
{
// wait
return 0;
}
else if(currentTime < (delayTime + scrollTime))
{
// lerp from 0 to scrollLength
const float fraction = (currentTime - delayTime) / scrollTime;
return fraction * scrollLength;
}
// and back to waiting
return 0;
}
}
} // Math::
#endif // ES_CORE_MATH_MISC_H

View file

@ -0,0 +1,278 @@
#include "math/Transform4x4f.h"
const Transform4x4f Transform4x4f::operator*(const Transform4x4f& _other) const
{
const float* tm = (float*)this;
const float* om = (float*)&_other;
return
{
{
tm[ 0] * om[ 0] + tm[ 1] * om[ 4] + tm[ 2] * om[ 8],
tm[ 0] * om[ 1] + tm[ 1] * om[ 5] + tm[ 2] * om[ 9],
tm[ 0] * om[ 2] + tm[ 1] * om[ 6] + tm[ 2] * om[10],
0
},
{
tm[ 4] * om[ 0] + tm[ 5] * om[ 4] + tm[ 6] * om[ 8],
tm[ 4] * om[ 1] + tm[ 5] * om[ 5] + tm[ 6] * om[ 9],
tm[ 4] * om[ 2] + tm[ 5] * om[ 6] + tm[ 6] * om[10],
0
},
{
tm[ 8] * om[ 0] + tm[ 9] * om[ 4] + tm[10] * om[ 8],
tm[ 8] * om[ 1] + tm[ 9] * om[ 5] + tm[10] * om[ 9],
tm[ 8] * om[ 2] + tm[ 9] * om[ 6] + tm[10] * om[10],
0
},
{
tm[ 0] * om[12] + tm[ 4] * om[13] + tm[ 8] * om[14] + tm[12],
tm[ 1] * om[12] + tm[ 5] * om[13] + tm[ 9] * om[14] + tm[13],
tm[ 2] * om[12] + tm[ 6] * om[13] + tm[10] * om[14] + tm[14],
1
}
};
} // operator*
const Vector3f Transform4x4f::operator*(const Vector3f& _other) const
{
const float* tm = (float*)this;
const float* ov = (float*)&_other;
return
{
tm[ 0] * ov[0] + tm[ 4] * ov[1] + tm[ 8] * ov[2] + tm[12],
tm[ 1] * ov[0] + tm[ 5] * ov[1] + tm[ 9] * ov[2] + tm[13],
tm[ 2] * ov[0] + tm[ 6] * ov[1] + tm[10] * ov[2] + tm[14]
};
} // operator*
Transform4x4f& Transform4x4f::invert(const Transform4x4f& _other)
{
float* tm = (float*)this;
const float* om = (float*)&_other;
// Full invert
// tm[ 0] = ((om[ 5] * (om[10] * om[15] - om[11] * om[14])) - (om[ 9] * (om[ 6] * om[15] - om[ 7] * om[14])) + (om[13] * (om[ 6] * om[11] - om[ 7] * om[10])));
// tm[ 1] = -((om[ 1] * (om[10] * om[15] - om[11] * om[14])) - (om[ 9] * (om[ 2] * om[15] - om[ 3] * om[14])) + (om[13] * (om[ 2] * om[11] - om[ 3] * om[10])));
// tm[ 2] = ((om[ 1] * (om[ 6] * om[15] - om[ 7] * om[14])) - (om[ 5] * (om[ 2] * om[15] - om[ 3] * om[14])) + (om[13] * (om[ 2] * om[ 7] - om[ 3] * om[ 6])));
// tm[ 3] = -((om[ 1] * (om[ 6] * om[11] - om[ 7] * om[10])) - (om[ 5] * (om[ 2] * om[11] - om[ 3] * om[10])) + (om[ 9] * (om[ 2] * om[ 7] - om[ 3] * om[ 6])));
// tm[ 4] = -((om[ 4] * (om[10] * om[15] - om[11] * om[14])) - (om[ 8] * (om[ 6] * om[15] - om[ 7] * om[14])) + (om[12] * (om[ 6] * om[11] - om[ 7] * om[10])));
// tm[ 5] = ((om[ 0] * (om[10] * om[15] - om[11] * om[14])) - (om[ 8] * (om[ 2] * om[15] - om[ 3] * om[14])) + (om[12] * (om[ 2] * om[11] - om[ 3] * om[10])));
// tm[ 6] = -((om[ 0] * (om[ 6] * om[15] - om[ 7] * om[14])) - (om[ 4] * (om[ 2] * om[15] - om[ 3] * om[14])) + (om[12] * (om[ 2] * om[ 7] - om[ 3] * om[ 6])));
// tm[ 7] = ((om[ 0] * (om[ 6] * om[11] - om[ 7] * om[10])) - (om[ 4] * (om[ 2] * om[11] - om[ 3] * om[10])) + (om[ 8] * (om[ 2] * om[ 7] - om[ 3] * om[ 6])));
// tm[ 8] = ((om[ 4] * (om[ 9] * om[15] - om[11] * om[13])) - (om[ 8] * (om[ 5] * om[15] - om[ 7] * om[13])) + (om[12] * (om[ 5] * om[11] - om[ 7] * om[ 9])));
// tm[ 9] = -((om[ 0] * (om[ 9] * om[15] - om[11] * om[13])) - (om[ 8] * (om[ 1] * om[15] - om[ 3] * om[13])) + (om[12] * (om[ 1] * om[11] - om[ 3] * om[ 9])));
// tm[10] = ((om[ 0] * (om[ 5] * om[15] - om[ 7] * om[13])) - (om[ 4] * (om[ 1] * om[15] - om[ 3] * om[13])) + (om[12] * (om[ 1] * om[ 7] - om[ 3] * om[ 5])));
// tm[11] = -((om[ 0] * (om[ 5] * om[11] - om[ 7] * om[ 9])) - (om[ 4] * (om[ 1] * om[11] - om[ 3] * om[ 9])) + (om[ 8] * (om[ 1] * om[ 7] - om[ 3] * om[ 5])));
// tm[12] = -((om[ 4] * (om[ 9] * om[14] - om[10] * om[13])) - (om[ 8] * (om[ 5] * om[14] - om[ 6] * om[13])) + (om[12] * (om[ 5] * om[10] - om[ 6] * om[ 9])));
// tm[13] = ((om[ 0] * (om[ 9] * om[14] - om[10] * om[13])) - (om[ 8] * (om[ 1] * om[14] - om[ 2] * om[13])) + (om[12] * (om[ 1] * om[10] - om[ 2] * om[ 9])));
// tm[14] = -((om[ 0] * (om[ 5] * om[14] - om[ 6] * om[13])) - (om[ 4] * (om[ 1] * om[14] - om[ 2] * om[13])) + (om[12] * (om[ 1] * om[ 6] - om[ 2] * om[ 5])));
// tm[15] = ((om[ 0] * (om[ 5] * om[10] - om[ 6] * om[ 9])) - (om[ 4] * (om[ 1] * om[10] - om[ 2] * om[ 9])) + (om[ 8] * (om[ 1] * om[ 6] - om[ 2] * om[ 5])));
// Optimized invert ( om[3, 7 and 11] is always 0, and om[15] is always 1 )
tm[ 0] = ((om[ 5] * om[10]) - (om[ 9] * om[ 6]));
tm[ 1] = -((om[ 1] * om[10]) - (om[ 9] * om[ 2]));
tm[ 2] = ((om[ 1] * om[ 6]) - (om[ 5] * om[ 2]));
tm[ 3] = 0;
tm[ 4] = -((om[ 4] * om[10]) - (om[ 8] * om[ 6]));
tm[ 5] = ((om[ 0] * om[10]) - (om[ 8] * om[ 2]));
tm[ 6] = -((om[ 0] * om[ 6]) - (om[ 4] * om[ 2]));
tm[ 7] = 0;
tm[ 8] = ((om[ 4] * om[ 9]) - (om[ 8] * om[ 5]));
tm[ 9] = -((om[ 0] * om[ 9]) - (om[ 8] * om[ 1]));
tm[10] = ((om[ 0] * om[ 5]) - (om[ 4] * om[ 1]));
tm[11] = 0;
tm[12] = -((om[ 4] * (om[ 9] * om[14] - om[10] * om[13])) - (om[ 8] * (om[ 5] * om[14] - om[ 6] * om[13])) + (om[12] * (om[ 5] * om[10] - om[ 6] * om[ 9])));
tm[13] = ((om[ 0] * (om[ 9] * om[14] - om[10] * om[13])) - (om[ 8] * (om[ 1] * om[14] - om[ 2] * om[13])) + (om[12] * (om[ 1] * om[10] - om[ 2] * om[ 9])));
tm[14] = -((om[ 0] * (om[ 5] * om[14] - om[ 6] * om[13])) - (om[ 4] * (om[ 1] * om[14] - om[ 2] * om[13])) + (om[12] * (om[ 1] * om[ 6] - om[ 2] * om[ 5])));
tm[15] = 1;
float Determinant = om[ 0] * tm[ 0] +
om[ 4] * tm[ 1] +
om[ 8] * tm[ 2] +
om[12] * tm[ 3];
if(Determinant != 0)
Determinant = 1 / Determinant;
tm[ 0] *= Determinant;
tm[ 1] *= Determinant;
tm[ 2] *= Determinant;
tm[ 4] *= Determinant;
tm[ 5] *= Determinant;
tm[ 6] *= Determinant;
tm[ 8] *= Determinant;
tm[ 9] *= Determinant;
tm[10] *= Determinant;
tm[12] *= Determinant;
tm[13] *= Determinant;
tm[14] *= Determinant;
return *this;
} // invert
Transform4x4f& Transform4x4f::scale(const Vector3f& _scale)
{
float* tm = (float*)this;
const float* sv = (float*)&_scale;
tm[ 0] *= sv[0];
tm[ 1] *= sv[1];
tm[ 2] *= sv[2];
tm[ 4] *= sv[0];
tm[ 5] *= sv[1];
tm[ 6] *= sv[2];
tm[ 8] *= sv[0];
tm[ 9] *= sv[1];
tm[10] *= sv[2];
return *this;
} // scale
Transform4x4f& Transform4x4f::rotate(const float _angle, const Vector3f& _axis)
{
float* tm = (float*)this;
const float* av = (float*)&_axis;
const float s = Math::sin(-_angle);
const float c = Math::cos(-_angle);
const float t = 1 - c;
const float x = av[0];
const float y = av[1];
const float z = av[2];
const float tx = t * x;
const float ty = t * y;
const float tz = t * z;
const float sx = s * x;
const float sy = s * y;
const float sz = s * z;
const float r[9] = { tx * x + c,
tx * y - sz,
tx * z + sy,
ty * x + sz,
ty * y + c,
ty * z - sx,
tz * x - sy,
tz * y + sx,
tz * z + c };
const float temp[9] = { tm[ 0] * r[0] + tm[ 1] * r[3] + tm[ 2] * r[6],
tm[ 0] * r[1] + tm[ 1] * r[4] + tm[ 2] * r[7],
tm[ 0] * r[2] + tm[ 1] * r[5] + tm[ 2] * r[8],
tm[ 4] * r[0] + tm[ 5] * r[3] + tm[ 6] * r[6],
tm[ 4] * r[1] + tm[ 5] * r[4] + tm[ 6] * r[7],
tm[ 4] * r[2] + tm[ 5] * r[5] + tm[ 6] * r[8],
tm[ 8] * r[0] + tm[ 9] * r[3] + tm[10] * r[6],
tm[ 8] * r[1] + tm[ 9] * r[4] + tm[10] * r[7],
tm[ 8] * r[2] + tm[ 9] * r[5] + tm[10] * r[8] };
tm[ 0] = temp[0];
tm[ 1] = temp[1];
tm[ 2] = temp[2];
tm[ 4] = temp[3];
tm[ 5] = temp[4];
tm[ 6] = temp[5];
tm[ 8] = temp[6];
tm[ 9] = temp[7];
tm[10] = temp[8];
return *this;
}; // rotate
Transform4x4f& Transform4x4f::rotateX(const float _angle)
{
float* tm = (float*)this;
const float s = Math::sin(-_angle);
const float c = Math::cos(-_angle);
const float temp[6] = { tm[ 1] * c + tm[ 2] * s,
tm[ 1] * -s + tm[ 2] * c,
tm[ 5] * c + tm[ 6] * s,
tm[ 5] * -s + tm[ 6] * c,
tm[ 9] * c + tm[10] * s,
tm[ 9] * -s + tm[10] * c };
tm[ 1] = temp[0];
tm[ 2] = temp[1];
tm[ 5] = temp[2];
tm[ 6] = temp[3];
tm[ 9] = temp[4];
tm[10] = temp[5];
return *this;
}; // rotateX
Transform4x4f& Transform4x4f::rotateY(const float _angle)
{
float* tm = (float*)this;
const float s = Math::sin(-_angle);
const float c = Math::cos(-_angle);
const float temp[6] = { tm[ 0] * c + tm[ 2] * -s,
tm[ 0] * s + tm[ 2] * c,
tm[ 4] * c + tm[ 6] * -s,
tm[ 4] * s + tm[ 6] * c,
tm[ 8] * c + tm[10] * -s,
tm[ 8] * s + tm[10] * c };
tm[ 0] = temp[0];
tm[ 2] = temp[1];
tm[ 4] = temp[2];
tm[ 6] = temp[3];
tm[ 8] = temp[4];
tm[10] = temp[5];
return *this;
}; // rotateY
Transform4x4f& Transform4x4f::rotateZ(const float _angle)
{
float* tm = (float*)this;
const float s = Math::sin(-_angle);
const float c = Math::cos(-_angle);
const float temp[6] = { tm[ 0] * c + tm[ 1] * s,
tm[ 0] * -s + tm[ 1] * c,
tm[ 4] * c + tm[ 5] * s,
tm[ 4] * -s + tm[ 5] * c,
tm[ 8] * c + tm[ 9] * s,
tm[ 8] * -s + tm[ 9] * c };
tm[ 0] = temp[0];
tm[ 1] = temp[1];
tm[ 4] = temp[2];
tm[ 5] = temp[3];
tm[ 8] = temp[4];
tm[ 9] = temp[5];
return *this;
}; // rotateZ
Transform4x4f& Transform4x4f::translate(const Vector3f& _translation)
{
float* tm = (float*)this;
const float* tv = (float*)&_translation;
tm[12] += tm[ 0] * tv[0] + tm[ 4] * tv[1] + tm[ 8] * tv[2];
tm[13] += tm[ 1] * tv[0] + tm[ 5] * tv[1] + tm[ 9] * tv[2];
tm[14] += tm[ 2] * tv[0] + tm[ 6] * tv[1] + tm[10] * tv[2];
return *this;
} // translate
Transform4x4f& Transform4x4f::round()
{
float* tm = (float*)this;
tm[12] = (int)(tm[12] + 0.5f);
tm[13] = (int)(tm[13] + 0.5f);
tm[14] = (int)(tm[14] + 0.5f);
return *this;
} // round

View file

@ -4,63 +4,17 @@
#include "math/Vector4f.h"
#include "math/Vector3f.h"
#include <math.h>
class Transform4x4f
{
public:
Transform4x4f() { }
Transform4x4f(const Vector4f& r0, const Vector4f& r1, const Vector4f& r2, const Vector4f& r3) : mR0(r0), mR1(r1), mR2(r2), mR3(r3) { }
Transform4x4f() { }
Transform4x4f(const Vector4f& _r0, const Vector4f& _r1, const Vector4f& _r2, const Vector4f& _r3) : mR0(_r0), mR1(_r1), mR2(_r2), mR3(_r3) { }
const Transform4x4f operator*(const Transform4x4f& other) const
{
const float* tm = (float*)this;
const float* om = (float*)&other;
return
{
{
tm[ 0] * om[ 0] + tm[ 1] * om[ 4] + tm[ 2] * om[ 8],
tm[ 0] * om[ 1] + tm[ 1] * om[ 5] + tm[ 2] * om[ 9],
tm[ 0] * om[ 2] + tm[ 1] * om[ 6] + tm[ 2] * om[10],
0
},
{
tm[ 4] * om[ 0] + tm[ 5] * om[ 4] + tm[ 6] * om[ 8],
tm[ 4] * om[ 1] + tm[ 5] * om[ 5] + tm[ 6] * om[ 9],
tm[ 4] * om[ 2] + tm[ 5] * om[ 6] + tm[ 6] * om[10],
0
},
{
tm[ 8] * om[ 0] + tm[ 9] * om[ 4] + tm[10] * om[ 8],
tm[ 8] * om[ 1] + tm[ 9] * om[ 5] + tm[10] * om[ 9],
tm[ 8] * om[ 2] + tm[ 9] * om[ 6] + tm[10] * om[10],
0
},
{
tm[ 0] * om[12] + tm[ 4] * om[13] + tm[ 8] * om[14] + tm[12],
tm[ 1] * om[12] + tm[ 5] * om[13] + tm[ 9] * om[14] + tm[13],
tm[ 2] * om[12] + tm[ 6] * om[13] + tm[10] * om[14] + tm[14],
1
}
};
}
const Vector3f operator*(const Vector3f& other) const
{
const float* tm = (float*)this;
const float* ov = (float*)&other;
return
{
tm[ 0] * ov[0] + tm[ 4] * ov[1] + tm[ 8] * ov[2] + tm[12],
tm[ 1] * ov[0] + tm[ 5] * ov[1] + tm[ 9] * ov[2] + tm[13],
tm[ 2] * ov[0] + tm[ 6] * ov[1] + tm[10] * ov[2] + tm[14]
};
}
Transform4x4f& operator*=(const Transform4x4f& other) { *this = *this * other; return *this; }
const Transform4x4f operator*(const Transform4x4f& _other) const;
const Vector3f operator*(const Vector3f& _other) const;
Transform4x4f& operator*=(const Transform4x4f& _other) { *this = *this * _other; return *this; }
inline Vector4f& r0() { return mR0; }
inline Vector4f& r1() { return mR1; }
@ -71,225 +25,14 @@ public:
inline const Vector4f& r2() const { return mR2; }
inline const Vector4f& r3() const { return mR3; }
inline Transform4x4f& invert(const Transform4x4f& other)
{
float* tm = (float*)this;
const float* om = (float*)&other;
// Full invert
// tm[ 0] = ((om[ 5] * (om[10] * om[15] - om[11] * om[14])) - (om[ 9] * (om[ 6] * om[15] - om[ 7] * om[14])) + (om[13] * (om[ 6] * om[11] - om[ 7] * om[10])));
// tm[ 1] = -((om[ 1] * (om[10] * om[15] - om[11] * om[14])) - (om[ 9] * (om[ 2] * om[15] - om[ 3] * om[14])) + (om[13] * (om[ 2] * om[11] - om[ 3] * om[10])));
// tm[ 2] = ((om[ 1] * (om[ 6] * om[15] - om[ 7] * om[14])) - (om[ 5] * (om[ 2] * om[15] - om[ 3] * om[14])) + (om[13] * (om[ 2] * om[ 7] - om[ 3] * om[ 6])));
// tm[ 3] = -((om[ 1] * (om[ 6] * om[11] - om[ 7] * om[10])) - (om[ 5] * (om[ 2] * om[11] - om[ 3] * om[10])) + (om[ 9] * (om[ 2] * om[ 7] - om[ 3] * om[ 6])));
// tm[ 4] = -((om[ 4] * (om[10] * om[15] - om[11] * om[14])) - (om[ 8] * (om[ 6] * om[15] - om[ 7] * om[14])) + (om[12] * (om[ 6] * om[11] - om[ 7] * om[10])));
// tm[ 5] = ((om[ 0] * (om[10] * om[15] - om[11] * om[14])) - (om[ 8] * (om[ 2] * om[15] - om[ 3] * om[14])) + (om[12] * (om[ 2] * om[11] - om[ 3] * om[10])));
// tm[ 6] = -((om[ 0] * (om[ 6] * om[15] - om[ 7] * om[14])) - (om[ 4] * (om[ 2] * om[15] - om[ 3] * om[14])) + (om[12] * (om[ 2] * om[ 7] - om[ 3] * om[ 6])));
// tm[ 7] = ((om[ 0] * (om[ 6] * om[11] - om[ 7] * om[10])) - (om[ 4] * (om[ 2] * om[11] - om[ 3] * om[10])) + (om[ 8] * (om[ 2] * om[ 7] - om[ 3] * om[ 6])));
// tm[ 8] = ((om[ 4] * (om[ 9] * om[15] - om[11] * om[13])) - (om[ 8] * (om[ 5] * om[15] - om[ 7] * om[13])) + (om[12] * (om[ 5] * om[11] - om[ 7] * om[ 9])));
// tm[ 9] = -((om[ 0] * (om[ 9] * om[15] - om[11] * om[13])) - (om[ 8] * (om[ 1] * om[15] - om[ 3] * om[13])) + (om[12] * (om[ 1] * om[11] - om[ 3] * om[ 9])));
// tm[10] = ((om[ 0] * (om[ 5] * om[15] - om[ 7] * om[13])) - (om[ 4] * (om[ 1] * om[15] - om[ 3] * om[13])) + (om[12] * (om[ 1] * om[ 7] - om[ 3] * om[ 5])));
// tm[11] = -((om[ 0] * (om[ 5] * om[11] - om[ 7] * om[ 9])) - (om[ 4] * (om[ 1] * om[11] - om[ 3] * om[ 9])) + (om[ 8] * (om[ 1] * om[ 7] - om[ 3] * om[ 5])));
// tm[12] = -((om[ 4] * (om[ 9] * om[14] - om[10] * om[13])) - (om[ 8] * (om[ 5] * om[14] - om[ 6] * om[13])) + (om[12] * (om[ 5] * om[10] - om[ 6] * om[ 9])));
// tm[13] = ((om[ 0] * (om[ 9] * om[14] - om[10] * om[13])) - (om[ 8] * (om[ 1] * om[14] - om[ 2] * om[13])) + (om[12] * (om[ 1] * om[10] - om[ 2] * om[ 9])));
// tm[14] = -((om[ 0] * (om[ 5] * om[14] - om[ 6] * om[13])) - (om[ 4] * (om[ 1] * om[14] - om[ 2] * om[13])) + (om[12] * (om[ 1] * om[ 6] - om[ 2] * om[ 5])));
// tm[15] = ((om[ 0] * (om[ 5] * om[10] - om[ 6] * om[ 9])) - (om[ 4] * (om[ 1] * om[10] - om[ 2] * om[ 9])) + (om[ 8] * (om[ 1] * om[ 6] - om[ 2] * om[ 5])));
// Optimized invert ( om[3, 7 and 11] is always 0, and om[15] is always 1 )
tm[ 0] = ((om[ 5] * om[10]) - (om[ 9] * om[ 6]));
tm[ 1] = -((om[ 1] * om[10]) - (om[ 9] * om[ 2]));
tm[ 2] = ((om[ 1] * om[ 6]) - (om[ 5] * om[ 2]));
tm[ 3] = 0;
tm[ 4] = -((om[ 4] * om[10]) - (om[ 8] * om[ 6]));
tm[ 5] = ((om[ 0] * om[10]) - (om[ 8] * om[ 2]));
tm[ 6] = -((om[ 0] * om[ 6]) - (om[ 4] * om[ 2]));
tm[ 7] = 0;
tm[ 8] = ((om[ 4] * om[ 9]) - (om[ 8] * om[ 5]));
tm[ 9] = -((om[ 0] * om[ 9]) - (om[ 8] * om[ 1]));
tm[10] = ((om[ 0] * om[ 5]) - (om[ 4] * om[ 1]));
tm[11] = 0;
tm[12] = -((om[ 4] * (om[ 9] * om[14] - om[10] * om[13])) - (om[ 8] * (om[ 5] * om[14] - om[ 6] * om[13])) + (om[12] * (om[ 5] * om[10] - om[ 6] * om[ 9])));
tm[13] = ((om[ 0] * (om[ 9] * om[14] - om[10] * om[13])) - (om[ 8] * (om[ 1] * om[14] - om[ 2] * om[13])) + (om[12] * (om[ 1] * om[10] - om[ 2] * om[ 9])));
tm[14] = -((om[ 0] * (om[ 5] * om[14] - om[ 6] * om[13])) - (om[ 4] * (om[ 1] * om[14] - om[ 2] * om[13])) + (om[12] * (om[ 1] * om[ 6] - om[ 2] * om[ 5])));
tm[15] = 1;
float Determinant = om[ 0] * tm[ 0] +
om[ 4] * tm[ 1] +
om[ 8] * tm[ 2] +
om[12] * tm[ 3];
if(Determinant != 0)
Determinant = 1 / Determinant;
tm[ 0] *= Determinant;
tm[ 1] *= Determinant;
tm[ 2] *= Determinant;
tm[ 4] *= Determinant;
tm[ 5] *= Determinant;
tm[ 6] *= Determinant;
tm[ 8] *= Determinant;
tm[ 9] *= Determinant;
tm[10] *= Determinant;
tm[12] *= Determinant;
tm[13] *= Determinant;
tm[14] *= Determinant;
return *this;
}
inline Transform4x4f& scale(const Vector3f& scale)
{
float* tm = (float*)this;
const float* sv = (float*)&scale;
tm[ 0] *= sv[0];
tm[ 1] *= sv[1];
tm[ 2] *= sv[2];
tm[ 4] *= sv[0];
tm[ 5] *= sv[1];
tm[ 6] *= sv[2];
tm[ 8] *= sv[0];
tm[ 9] *= sv[1];
tm[10] *= sv[2];
return *this;
}
inline Transform4x4f& rotate(const float angle, const Vector3f& axis)
{
float* tm = (float*)this;
const float* av = (float*)&axis;
const float s = sin(-angle);
const float c = cos(-angle);
const float t = 1 - c;
const float x = av[0];
const float y = av[1];
const float z = av[2];
const float tx = t * x;
const float ty = t * y;
const float tz = t * z;
const float sx = s * x;
const float sy = s * y;
const float sz = s * z;
const float r[9] = { tx * x + c,
tx * y - sz,
tx * z + sy,
ty * x + sz,
ty * y + c,
ty * z - sx,
tz * x - sy,
tz * y + sx,
tz * z + c };
const float temp[9] = { tm[ 0] * r[0] + tm[ 1] * r[3] + tm[ 2] * r[6],
tm[ 0] * r[1] + tm[ 1] * r[4] + tm[ 2] * r[7],
tm[ 0] * r[2] + tm[ 1] * r[5] + tm[ 2] * r[8],
tm[ 4] * r[0] + tm[ 5] * r[3] + tm[ 6] * r[6],
tm[ 4] * r[1] + tm[ 5] * r[4] + tm[ 6] * r[7],
tm[ 4] * r[2] + tm[ 5] * r[5] + tm[ 6] * r[8],
tm[ 8] * r[0] + tm[ 9] * r[3] + tm[10] * r[6],
tm[ 8] * r[1] + tm[ 9] * r[4] + tm[10] * r[7],
tm[ 8] * r[2] + tm[ 9] * r[5] + tm[10] * r[8] };
tm[ 0] = temp[0];
tm[ 1] = temp[1];
tm[ 2] = temp[2];
tm[ 4] = temp[3];
tm[ 5] = temp[4];
tm[ 6] = temp[5];
tm[ 8] = temp[6];
tm[ 9] = temp[7];
tm[10] = temp[8];
return *this;
};
inline Transform4x4f& rotateX(const float angle)
{
float* tm = (float*)this;
const float s = sin(-angle);
const float c = cos(-angle);
const float temp[6] = { tm[ 1] * c + tm[ 2] * s,
tm[ 1] * -s + tm[ 2] * c,
tm[ 5] * c + tm[ 6] * s,
tm[ 5] * -s + tm[ 6] * c,
tm[ 9] * c + tm[10] * s,
tm[ 9] * -s + tm[10] * c };
tm[ 1] = temp[0];
tm[ 2] = temp[1];
tm[ 5] = temp[2];
tm[ 6] = temp[3];
tm[ 9] = temp[4];
tm[10] = temp[5];
return *this;
};
inline Transform4x4f& rotateY(const float angle)
{
float* tm = (float*)this;
const float s = sin(-angle);
const float c = cos(-angle);
const float temp[6] = { tm[ 0] * c + tm[ 2] * -s,
tm[ 0] * s + tm[ 2] * c,
tm[ 4] * c + tm[ 6] * -s,
tm[ 4] * s + tm[ 6] * c,
tm[ 8] * c + tm[10] * -s,
tm[ 8] * s + tm[10] * c };
tm[ 0] = temp[0];
tm[ 2] = temp[1];
tm[ 4] = temp[2];
tm[ 6] = temp[3];
tm[ 8] = temp[4];
tm[10] = temp[5];
return *this;
};
inline Transform4x4f& rotateZ(const float angle)
{
float* tm = (float*)this;
const float s = sin(-angle);
const float c = cos(-angle);
const float temp[6] = { tm[ 0] * c + tm[ 1] * s,
tm[ 0] * -s + tm[ 1] * c,
tm[ 4] * c + tm[ 5] * s,
tm[ 4] * -s + tm[ 5] * c,
tm[ 8] * c + tm[ 9] * s,
tm[ 8] * -s + tm[ 9] * c };
tm[ 0] = temp[0];
tm[ 1] = temp[1];
tm[ 4] = temp[2];
tm[ 5] = temp[3];
tm[ 8] = temp[4];
tm[ 9] = temp[5];
return *this;
};
inline Transform4x4f& translate(const Vector3f& translation)
{
float* tm = (float*)this;
const float* tv = (float*)&translation;
tm[12] += tm[ 0] * tv[0] + tm[ 4] * tv[1] + tm[ 8] * tv[2];
tm[13] += tm[ 1] * tv[0] + tm[ 5] * tv[1] + tm[ 9] * tv[2];
tm[14] += tm[ 2] * tv[0] + tm[ 6] * tv[1] + tm[10] * tv[2];
return *this;
}
inline Transform4x4f& round()
{
float* tm = (float*)this;
tm[12] = (int)(tm[12] + 0.5f);
tm[13] = (int)(tm[13] + 0.5f);
tm[14] = (int)(tm[14] + 0.5f);
return *this;
}
Transform4x4f& invert(const Transform4x4f& _other);
Transform4x4f& scale(const Vector3f& _scale);
Transform4x4f& rotate(const float _angle, const Vector3f& _axis);
Transform4x4f& rotateX(const float _angle);
Transform4x4f& rotateY(const float _angle);
Transform4x4f& rotateZ(const float _angle);
Transform4x4f& translate(const Vector3f& _translation);
Transform4x4f& round();
inline Vector3f& translation() { return mR3.v3(); }
inline const Vector3f& translation() const { return mR3.v3(); }
@ -303,6 +46,6 @@ protected:
Vector4f mR2;
Vector4f mR3;
};
}; // Transform4x4f
#endif // ES_CORE_MATH_TRANSFORM4X4F_H

View file

@ -0,0 +1,19 @@
#include "math/Vector2f.h"
Vector2f& Vector2f::round()
{
mX = (int)(mX + 0.5f);
mY = (int)(mY + 0.5f);
return *this;
} // round
Vector2f& Vector2f::lerp(const Vector2f& _start, const Vector2f& _end, const float _fraction)
{
mX = Math::lerp(_start.x(), _end.x(), _fraction);
mY = Math::lerp(_start.y(), _end.y(), _fraction);
return *this;
} // lerp

View file

@ -2,6 +2,7 @@
#ifndef ES_CORE_MATH_VECTOR2F_H
#define ES_CORE_MATH_VECTOR2F_H
#include "math/Misc.h"
#include <assert.h>
class Vector3f;
@ -11,46 +12,47 @@ class Vector2f
{
public:
Vector2f() { }
Vector2f(const float f) : mX(f), mY(f) { }
Vector2f(const float x, const float y) : mX(x), mY(y) { }
explicit Vector2f(const Vector3f& v) : mX(((Vector2f&)v).mX), mY(((Vector2f&)v).mY) { }
explicit Vector2f(const Vector4f& v) : mX(((Vector2f&)v).mX), mY(((Vector2f&)v).mY) { }
Vector2f() { }
Vector2f(const float _f) : mX(_f), mY(_f) { }
Vector2f(const float _x, const float _y) : mX(_x), mY(_y) { }
explicit Vector2f(const Vector3f& _v) : mX(((Vector2f&)_v).mX), mY(((Vector2f&)_v).mY) { }
explicit Vector2f(const Vector4f& _v) : mX(((Vector2f&)_v).mX), mY(((Vector2f&)_v).mY) { }
const bool operator==(const Vector2f& other) const { return ((mX == other.mX) && (mY == other.mY)); }
const bool operator!=(const Vector2f& other) const { return ((mX != other.mX) || (mY != other.mY)); }
const bool operator==(const Vector2f& _other) const { return ((mX == _other.mX) && (mY == _other.mY)); }
const bool operator!=(const Vector2f& _other) const { return ((mX != _other.mX) || (mY != _other.mY)); }
const Vector2f operator+(const Vector2f& other) const { return { mX + other.mX, mY + other.mY }; }
const Vector2f operator-(const Vector2f& other) const { return { mX - other.mX, mY - other.mY }; }
const Vector2f operator*(const Vector2f& other) const { return { mX * other.mX, mY * other.mY }; }
const Vector2f operator/(const Vector2f& other) const { return { mX / other.mX, mY / other.mY }; }
const Vector2f operator+(const Vector2f& _other) const { return { mX + _other.mX, mY + _other.mY }; }
const Vector2f operator-(const Vector2f& _other) const { return { mX - _other.mX, mY - _other.mY }; }
const Vector2f operator*(const Vector2f& _other) const { return { mX * _other.mX, mY * _other.mY }; }
const Vector2f operator/(const Vector2f& _other) const { return { mX / _other.mX, mY / _other.mY }; }
const Vector2f operator+(const float& other) const { return { mX + other, mY + other }; }
const Vector2f operator-(const float& other) const { return { mX - other, mY - other }; }
const Vector2f operator*(const float& other) const { return { mX * other, mY * other }; }
const Vector2f operator/(const float& other) const { return { mX / other, mY / other }; }
const Vector2f operator+(const float& _other) const { return { mX + _other, mY + _other }; }
const Vector2f operator-(const float& _other) const { return { mX - _other, mY - _other }; }
const Vector2f operator*(const float& _other) const { return { mX * _other, mY * _other }; }
const Vector2f operator/(const float& _other) const { return { mX / _other, mY / _other }; }
const Vector2f operator-() const { return { -mX , -mY }; }
Vector2f& operator+=(const Vector2f& other) { *this = *this + other; return *this; }
Vector2f& operator-=(const Vector2f& other) { *this = *this - other; return *this; }
Vector2f& operator*=(const Vector2f& other) { *this = *this * other; return *this; }
Vector2f& operator/=(const Vector2f& other) { *this = *this / other; return *this; }
Vector2f& operator+=(const Vector2f& _other) { *this = *this + _other; return *this; }
Vector2f& operator-=(const Vector2f& _other) { *this = *this - _other; return *this; }
Vector2f& operator*=(const Vector2f& _other) { *this = *this * _other; return *this; }
Vector2f& operator/=(const Vector2f& _other) { *this = *this / _other; return *this; }
Vector2f& operator+=(const float& other) { *this = *this + other; return *this; }
Vector2f& operator-=(const float& other) { *this = *this - other; return *this; }
Vector2f& operator*=(const float& other) { *this = *this * other; return *this; }
Vector2f& operator/=(const float& other) { *this = *this / other; return *this; }
Vector2f& operator+=(const float& _other) { *this = *this + _other; return *this; }
Vector2f& operator-=(const float& _other) { *this = *this - _other; return *this; }
Vector2f& operator*=(const float& _other) { *this = *this * _other; return *this; }
Vector2f& operator/=(const float& _other) { *this = *this / _other; return *this; }
float& operator[](const int index) { assert(index < 2 && "index out of range"); return (&mX)[index]; }
const float& operator[](const int index) const { assert(index < 2 && "index out of range"); return (&mX)[index]; }
float& operator[](const int _index) { assert(_index < 2 && "index out of range"); return (&mX)[_index]; }
const float& operator[](const int _index) const { assert(_index < 2 && "index out of range"); return (&mX)[_index]; }
float& x() { return mX; }
float& y() { return mY; }
const float& x() const { return mX; }
const float& y() const { return mY; }
inline Vector2f& round() { mX = (int)(mX + 0.5f); mY = (int)(mY + 0.5f); return *this; }
Vector2f& round();
Vector2f& lerp(const Vector2f& _start, const Vector2f& _end, const float _fraction);
static const Vector2f Zero() { return { 0, 0 }; }
static const Vector2f UnitX() { return { 1, 0 }; }
@ -61,6 +63,6 @@ private:
float mX;
float mY;
};
}; // Vector2f
#endif // ES_CORE_MATH_VECTOR2F_H

View file

@ -0,0 +1 @@
#include "math/Vector2i.h"

View file

@ -8,37 +8,37 @@ class Vector2i
{
public:
Vector2i() { }
Vector2i(const int i) : mX(i), mY(i) { }
Vector2i(const int x, const int y) : mX(x), mY(y) { }
Vector2i() { }
Vector2i(const int _i) : mX(_i), mY(_i) { }
Vector2i(const int _x, const int _y) : mX(_x), mY(_y) { }
const bool operator==(const Vector2i& other) const { return ((mX == other.mX) && (mY == other.mY)); }
const bool operator!=(const Vector2i& other) const { return ((mX != other.mX) || (mY != other.mY)); }
const bool operator==(const Vector2i& _other) const { return ((mX == _other.mX) && (mY == _other.mY)); }
const bool operator!=(const Vector2i& _other) const { return ((mX != _other.mX) || (mY != _other.mY)); }
const Vector2i operator+(const Vector2i& other) const { return { mX + other.mX, mY + other.mY }; }
const Vector2i operator-(const Vector2i& other) const { return { mX - other.mX, mY - other.mY }; }
const Vector2i operator*(const Vector2i& other) const { return { mX * other.mX, mY * other.mY }; }
const Vector2i operator/(const Vector2i& other) const { return { mX / other.mX, mY / other.mY }; }
const Vector2i operator+(const Vector2i& _other) const { return { mX + _other.mX, mY + _other.mY }; }
const Vector2i operator-(const Vector2i& _other) const { return { mX - _other.mX, mY - _other.mY }; }
const Vector2i operator*(const Vector2i& _other) const { return { mX * _other.mX, mY * _other.mY }; }
const Vector2i operator/(const Vector2i& _other) const { return { mX / _other.mX, mY / _other.mY }; }
const Vector2i operator+(const int& other) const { return { mX + other, mY + other }; }
const Vector2i operator-(const int& other) const { return { mX - other, mY - other }; }
const Vector2i operator*(const int& other) const { return { mX * other, mY * other }; }
const Vector2i operator/(const int& other) const { return { mX / other, mY / other }; }
const Vector2i operator+(const int& _other) const { return { mX + _other, mY + _other }; }
const Vector2i operator-(const int& _other) const { return { mX - _other, mY - _other }; }
const Vector2i operator*(const int& _other) const { return { mX * _other, mY * _other }; }
const Vector2i operator/(const int& _other) const { return { mX / _other, mY / _other }; }
const Vector2i operator-() const { return { -mX , -mY }; }
Vector2i& operator+=(const Vector2i& other) { *this = *this + other; return *this; }
Vector2i& operator-=(const Vector2i& other) { *this = *this - other; return *this; }
Vector2i& operator*=(const Vector2i& other) { *this = *this * other; return *this; }
Vector2i& operator/=(const Vector2i& other) { *this = *this / other; return *this; }
Vector2i& operator+=(const Vector2i& _other) { *this = *this + _other; return *this; }
Vector2i& operator-=(const Vector2i& _other) { *this = *this - _other; return *this; }
Vector2i& operator*=(const Vector2i& _other) { *this = *this * _other; return *this; }
Vector2i& operator/=(const Vector2i& _other) { *this = *this / _other; return *this; }
Vector2i& operator+=(const int& other) { *this = *this + other; return *this; }
Vector2i& operator-=(const int& other) { *this = *this - other; return *this; }
Vector2i& operator*=(const int& other) { *this = *this * other; return *this; }
Vector2i& operator/=(const int& other) { *this = *this / other; return *this; }
Vector2i& operator+=(const int& _other) { *this = *this + _other; return *this; }
Vector2i& operator-=(const int& _other) { *this = *this - _other; return *this; }
Vector2i& operator*=(const int& _other) { *this = *this * _other; return *this; }
Vector2i& operator/=(const int& _other) { *this = *this / _other; return *this; }
int& operator[](const int index) { assert(index < 2 && "index out of range"); return (&mX)[index]; }
const int& operator[](const int index) const { assert(index < 2 && "index out of range"); return (&mX)[index]; }
int& operator[](const int _index) { assert(_index < 2 && "index out of range"); return (&mX)[_index]; }
const int& operator[](const int _index) const { assert(_index < 2 && "index out of range"); return (&mX)[_index]; }
int& x() { return mX; }
int& y() { return mY; }
@ -54,6 +54,6 @@ private:
int mX;
int mY;
};
}; // Vector2i
#endif // ES_CORE_MATH_VECTOR2I_H

View file

@ -0,0 +1,21 @@
#include "math/Vector3f.h"
Vector3f& Vector3f::round()
{
mX = (int)(mX + 0.5f);
mY = (int)(mY + 0.5f);
mZ = (int)(mZ + 0.5f);
return *this;
} // round
Vector3f& Vector3f::lerp(const Vector3f& _start, const Vector3f& _end, const float _fraction)
{
mX = Math::lerp(_start.x(), _end.x(), _fraction);
mY = Math::lerp(_start.y(), _end.y(), _fraction);
mZ = Math::lerp(_start.z(), _end.z(), _fraction);
return *this;
} // lerp

View file

@ -2,6 +2,7 @@
#ifndef ES_CORE_MATH_VECTOR3F_H
#define ES_CORE_MATH_VECTOR3F_H
#include "math/Misc.h"
#include <assert.h>
class Vector2f;
@ -11,40 +12,40 @@ class Vector3f
{
public:
Vector3f() { }
Vector3f(const float f) : mX(f), mY(f), mZ(f) { }
Vector3f(const float x, const float y, const float z) : mX(x), mY(y), mZ(z) { }
explicit Vector3f(const Vector2f& v) : mX(((Vector3f&)v).mX), mY(((Vector3f&)v).mY), mZ(0) { }
explicit Vector3f(const Vector2f& v, const float z) : mX(((Vector3f&)v).mX), mY(((Vector3f&)v).mY), mZ(z) { }
explicit Vector3f(const Vector4f& v) : mX(((Vector3f&)v).mX), mY(((Vector3f&)v).mY), mZ(((Vector3f&)v).mZ) { }
Vector3f() { }
Vector3f(const float _f) : mX(_f), mY(_f), mZ(_f) { }
Vector3f(const float _x, const float _y, const float _z) : mX(_x), mY(_y), mZ(_z) { }
explicit Vector3f(const Vector2f& _v) : mX(((Vector3f&)_v).mX), mY(((Vector3f&)_v).mY), mZ(0) { }
explicit Vector3f(const Vector2f& _v, const float _z) : mX(((Vector3f&)_v).mX), mY(((Vector3f&)_v).mY), mZ(_z) { }
explicit Vector3f(const Vector4f& _v) : mX(((Vector3f&)_v).mX), mY(((Vector3f&)_v).mY), mZ(((Vector3f&)_v).mZ) { }
const bool operator==(const Vector3f& other) const { return ((mX == other.mX) && (mY == other.mY) && (mZ == other.mZ)); }
const bool operator!=(const Vector3f& other) const { return ((mX != other.mX) || (mY != other.mY) || (mZ != other.mZ)); }
const bool operator==(const Vector3f& _other) const { return ((mX == _other.mX) && (mY == _other.mY) && (mZ == _other.mZ)); }
const bool operator!=(const Vector3f& _other) const { return ((mX != _other.mX) || (mY != _other.mY) || (mZ != _other.mZ)); }
const Vector3f operator+(const Vector3f& other) const { return { mX + other.mX, mY + other.mY, mZ + other.mZ }; }
const Vector3f operator-(const Vector3f& other) const { return { mX - other.mX, mY - other.mY, mZ - other.mZ }; }
const Vector3f operator*(const Vector3f& other) const { return { mX * other.mX, mY * other.mY, mZ * other.mZ }; }
const Vector3f operator/(const Vector3f& other) const { return { mX / other.mX, mY / other.mY, mZ / other.mZ }; }
const Vector3f operator+(const Vector3f& _other) const { return { mX + _other.mX, mY + _other.mY, mZ + _other.mZ }; }
const Vector3f operator-(const Vector3f& _other) const { return { mX - _other.mX, mY - _other.mY, mZ - _other.mZ }; }
const Vector3f operator*(const Vector3f& _other) const { return { mX * _other.mX, mY * _other.mY, mZ * _other.mZ }; }
const Vector3f operator/(const Vector3f& _other) const { return { mX / _other.mX, mY / _other.mY, mZ / _other.mZ }; }
const Vector3f operator+(const float& other) const { return { mX + other, mY + other, mZ + other }; }
const Vector3f operator-(const float& other) const { return { mX - other, mY - other, mZ - other }; }
const Vector3f operator*(const float& other) const { return { mX * other, mY * other, mZ * other }; }
const Vector3f operator/(const float& other) const { return { mX / other, mY / other, mZ / other }; }
const Vector3f operator+(const float& _other) const { return { mX + _other, mY + _other, mZ + _other }; }
const Vector3f operator-(const float& _other) const { return { mX - _other, mY - _other, mZ - _other }; }
const Vector3f operator*(const float& _other) const { return { mX * _other, mY * _other, mZ * _other }; }
const Vector3f operator/(const float& _other) const { return { mX / _other, mY / _other, mZ / _other }; }
const Vector3f operator-() const { return { -mX , -mY, -mZ }; }
Vector3f& operator+=(const Vector3f& other) { *this = *this + other; return *this; }
Vector3f& operator-=(const Vector3f& other) { *this = *this - other; return *this; }
Vector3f& operator*=(const Vector3f& other) { *this = *this * other; return *this; }
Vector3f& operator/=(const Vector3f& other) { *this = *this / other; return *this; }
Vector3f& operator+=(const Vector3f& _other) { *this = *this + _other; return *this; }
Vector3f& operator-=(const Vector3f& _other) { *this = *this - _other; return *this; }
Vector3f& operator*=(const Vector3f& _other) { *this = *this * _other; return *this; }
Vector3f& operator/=(const Vector3f& _other) { *this = *this / _other; return *this; }
Vector3f& operator+=(const float& other) { *this = *this + other; return *this; }
Vector3f& operator-=(const float& other) { *this = *this - other; return *this; }
Vector3f& operator*=(const float& other) { *this = *this * other; return *this; }
Vector3f& operator/=(const float& other) { *this = *this / other; return *this; }
Vector3f& operator+=(const float& _other) { *this = *this + _other; return *this; }
Vector3f& operator-=(const float& _other) { *this = *this - _other; return *this; }
Vector3f& operator*=(const float& _other) { *this = *this * _other; return *this; }
Vector3f& operator/=(const float& _other) { *this = *this / _other; return *this; }
float& operator[](const int index) { assert(index < 3 && "index out of range"); return (&mX)[index]; }
const float& operator[](const int index) const { assert(index < 3 && "index out of range"); return (&mX)[index]; }
float& operator[](const int _index) { assert(_index < 3 && "index out of range"); return (&mX)[_index]; }
const float& operator[](const int _index) const { assert(_index < 3 && "index out of range"); return (&mX)[_index]; }
float& x() { return mX; }
float& y() { return mY; }
@ -56,7 +57,8 @@ public:
inline Vector2f& v2() { return *(Vector2f*)this; }
inline const Vector2f& v2() const { return *(Vector2f*)this; }
inline Vector3f& round() { mX = (int)(mX + 0.5f); mY = (int)(mY + 0.5f); mZ = (int)(mZ + 0.5f); return *this; }
Vector3f& round();
Vector3f& lerp(const Vector3f& _start, const Vector3f& _end, const float _fraction);
static const Vector3f Zero() { return { 0, 0, 0 }; }
static const Vector3f UnitX() { return { 1, 0, 0 }; }
@ -69,6 +71,6 @@ private:
float mY;
float mZ;
};
}; // Vector3f
#endif // ES_CORE_MATH_VECTOR3F_H

View file

@ -0,0 +1,23 @@
#include "math/Vector4f.h"
Vector4f& Vector4f::round()
{
mX = (int)(mX + 0.5f);
mY = (int)(mY + 0.5f);
mZ = (int)(mZ + 0.5f);
mW = (int)(mW + 0.5f);
return *this;
} // round
Vector4f& Vector4f::lerp(const Vector4f& _start, const Vector4f& _end, const float _fraction)
{
mX = Math::lerp(_start.x(), _end.x(), _fraction);
mY = Math::lerp(_start.y(), _end.y(), _fraction);
mZ = Math::lerp(_start.z(), _end.z(), _fraction);
mW = Math::lerp(_start.w(), _end.w(), _fraction);
return *this;
} // lerp

View file

@ -2,6 +2,7 @@
#ifndef ES_CORE_MATH_VECTOR4F_H
#define ES_CORE_MATH_VECTOR4F_H
#include "math/Misc.h"
#include <assert.h>
class Vector2f;
@ -11,42 +12,42 @@ class Vector4f
{
public:
Vector4f() { }
Vector4f(const float f) : mX(f), mY(f), mZ(f), mW(f) { }
Vector4f(const float x, const float y, const float z, const float w) : mX(x), mY(y), mZ(z), mW(w) { }
explicit Vector4f(const Vector2f& v) : mX(((Vector4f&)v).mX), mY(((Vector4f&)v).mY), mZ(0), mW(0) { }
explicit Vector4f(const Vector2f& v, const float z) : mX(((Vector4f&)v).mX), mY(((Vector4f&)v).mY), mZ(z), mW(0) { }
explicit Vector4f(const Vector2f& v, const float z, const float w) : mX(((Vector4f&)v).mX), mY(((Vector4f&)v).mY), mZ(z), mW(w) { }
explicit Vector4f(const Vector3f& v) : mX(((Vector4f&)v).mX), mY(((Vector4f&)v).mY), mZ(((Vector4f&)v).mZ), mW(0) { }
explicit Vector4f(const Vector3f& v, const float w) : mX(((Vector4f&)v).mX), mY(((Vector4f&)v).mY), mZ(((Vector4f&)v).mZ), mW(w) { }
Vector4f() { }
Vector4f(const float _f) : mX(_f), mY(_f), mZ(_f), mW(_f) { }
Vector4f(const float _x, const float _y, const float _z, const float _w) : mX(_x), mY(_y), mZ(_z), mW(_w) { }
explicit Vector4f(const Vector2f& _v) : mX(((Vector4f&)_v).mX), mY(((Vector4f&)_v).mY), mZ(0), mW(0) { }
explicit Vector4f(const Vector2f& _v, const float _z) : mX(((Vector4f&)_v).mX), mY(((Vector4f&)_v).mY), mZ(_z), mW(0) { }
explicit Vector4f(const Vector2f& _v, const float _z, const float _w) : mX(((Vector4f&)_v).mX), mY(((Vector4f&)_v).mY), mZ(_z), mW(_w) { }
explicit Vector4f(const Vector3f& _v) : mX(((Vector4f&)_v).mX), mY(((Vector4f&)_v).mY), mZ(((Vector4f&)_v).mZ), mW(0) { }
explicit Vector4f(const Vector3f& _v, const float _w) : mX(((Vector4f&)_v).mX), mY(((Vector4f&)_v).mY), mZ(((Vector4f&)_v).mZ), mW(_w) { }
const bool operator==(const Vector4f& other) const { return ((mX == other.mX) && (mY == other.mY) && (mZ == other.mZ) && (mW == other.mW)); }
const bool operator!=(const Vector4f& other) const { return ((mX != other.mX) || (mY != other.mY) || (mZ != other.mZ) || (mW != other.mW)); }
const bool operator==(const Vector4f& _other) const { return ((mX == _other.mX) && (mY == _other.mY) && (mZ == _other.mZ) && (mW == _other.mW)); }
const bool operator!=(const Vector4f& _other) const { return ((mX != _other.mX) || (mY != _other.mY) || (mZ != _other.mZ) || (mW != _other.mW)); }
const Vector4f operator+(const Vector4f& other) const { return { mX + other.mX, mY + other.mY, mZ + other.mZ, mW + other.mW }; }
const Vector4f operator-(const Vector4f& other) const { return { mX - other.mX, mY - other.mY, mZ - other.mZ, mW - other.mW }; }
const Vector4f operator*(const Vector4f& other) const { return { mX * other.mX, mY * other.mY, mZ * other.mZ, mW * other.mW }; }
const Vector4f operator/(const Vector4f& other) const { return { mX / other.mX, mY / other.mY, mZ / other.mZ, mW / other.mW }; }
const Vector4f operator+(const Vector4f& _other) const { return { mX + _other.mX, mY + _other.mY, mZ + _other.mZ, mW + _other.mW }; }
const Vector4f operator-(const Vector4f& _other) const { return { mX - _other.mX, mY - _other.mY, mZ - _other.mZ, mW - _other.mW }; }
const Vector4f operator*(const Vector4f& _other) const { return { mX * _other.mX, mY * _other.mY, mZ * _other.mZ, mW * _other.mW }; }
const Vector4f operator/(const Vector4f& _other) const { return { mX / _other.mX, mY / _other.mY, mZ / _other.mZ, mW / _other.mW }; }
const Vector4f operator+(const float& other) const { return { mX + other, mY + other, mZ + other, mW + other }; }
const Vector4f operator-(const float& other) const { return { mX - other, mY - other, mZ - other, mW - other }; }
const Vector4f operator*(const float& other) const { return { mX * other, mY * other, mZ * other, mW * other }; }
const Vector4f operator/(const float& other) const { return { mX / other, mY / other, mZ / other, mW / other }; }
const Vector4f operator+(const float& _other) const { return { mX + _other, mY + _other, mZ + _other, mW + _other }; }
const Vector4f operator-(const float& _other) const { return { mX - _other, mY - _other, mZ - _other, mW - _other }; }
const Vector4f operator*(const float& _other) const { return { mX * _other, mY * _other, mZ * _other, mW * _other }; }
const Vector4f operator/(const float& _other) const { return { mX / _other, mY / _other, mZ / _other, mW / _other }; }
const Vector4f operator-() const { return {-mX , -mY, -mZ, -mW }; }
Vector4f& operator+=(const Vector4f& other) { *this = *this + other; return *this; }
Vector4f& operator-=(const Vector4f& other) { *this = *this - other; return *this; }
Vector4f& operator*=(const Vector4f& other) { *this = *this * other; return *this; }
Vector4f& operator/=(const Vector4f& other) { *this = *this / other; return *this; }
Vector4f& operator+=(const Vector4f& _other) { *this = *this + _other; return *this; }
Vector4f& operator-=(const Vector4f& _other) { *this = *this - _other; return *this; }
Vector4f& operator*=(const Vector4f& _other) { *this = *this * _other; return *this; }
Vector4f& operator/=(const Vector4f& _other) { *this = *this / _other; return *this; }
Vector4f& operator+=(const float& other) { *this = *this + other; return *this; }
Vector4f& operator-=(const float& other) { *this = *this - other; return *this; }
Vector4f& operator*=(const float& other) { *this = *this * other; return *this; }
Vector4f& operator/=(const float& other) { *this = *this / other; return *this; }
Vector4f& operator+=(const float& _other) { *this = *this + _other; return *this; }
Vector4f& operator-=(const float& _other) { *this = *this - _other; return *this; }
Vector4f& operator*=(const float& _other) { *this = *this * _other; return *this; }
Vector4f& operator/=(const float& _other) { *this = *this / _other; return *this; }
float& operator[](const int index) { assert(index < 4 && "index out of range"); return (&mX)[index]; }
const float& operator[](const int index) const { assert(index < 4 && "index out of range"); return (&mX)[index]; }
float& operator[](const int _index) { assert(_index < 4 && "index out of range"); return (&mX)[_index]; }
const float& operator[](const int _index) const { assert(_index < 4 && "index out of range"); return (&mX)[_index]; }
float& x() { return mX; }
float& y() { return mY; }
@ -63,7 +64,8 @@ public:
inline Vector3f& v3() { return *(Vector3f*)this; }
inline const Vector3f& v3() const { return *(Vector3f*)this; }
inline Vector4f& round() { mX = (int)(mX + 0.5f); mY = (int)(mY + 0.5f); mZ = (int)(mZ + 0.5f); mW = (int)(mW + 0.5f); return *this; }
Vector4f& round();
Vector4f& lerp(const Vector4f& _start, const Vector4f& _end, const float _fraction);
static const Vector4f Zero() { return { 0, 0, 0, 0 }; }
static const Vector4f UnitX() { return { 1, 0, 0, 0 }; }
@ -78,6 +80,6 @@ private:
float mZ;
float mW;
};
}; // Vector4f
#endif // ES_CORE_MATH_VECTOR4F_H

View file

@ -595,11 +595,6 @@ float Font::getNewlineStartOffset(const std::string& text, const unsigned int& c
}
}
inline float font_round(float v)
{
return round(v);
}
TextCache* Font::buildTextCache(const std::string& text, Vector2f offset, unsigned int color, float xLen, Alignment alignment, float lineSpacing)
{
float x = offset[0] + (xLen != 0 ? getNewlineStartOffset(text, 0, xLen, alignment) : 0);
@ -643,8 +638,8 @@ TextCache* Font::buildTextCache(const std::string& text, Vector2f offset, unsign
// triangle 1
// round to fix some weird "cut off" text bugs
tri[0].pos = Vector2f(font_round(glyphStartX), font_round(y + (glyph->texSize.y() * textureSize.y() - glyph->bearing.y())));
tri[1].pos = Vector2f(font_round(glyphStartX + glyph->texSize.x() * textureSize.x()), font_round(y - glyph->bearing.y()));
tri[0].pos = Vector2f(Math::round(glyphStartX), Math::round(y + (glyph->texSize.y() * textureSize.y() - glyph->bearing.y())));
tri[1].pos = Vector2f(Math::round(glyphStartX + glyph->texSize.x() * textureSize.x()), Math::round(y - glyph->bearing.y()));
tri[2].pos = Vector2f(tri[0].pos.x(), tri[1].pos.y());
//tri[0].tex = Vector2f(0, 0);

View file

@ -13,10 +13,10 @@
class TextCache;
#define FONT_SIZE_MINI ((unsigned int)(0.030f * std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth())))
#define FONT_SIZE_SMALL ((unsigned int)(0.035f * std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth())))
#define FONT_SIZE_MEDIUM ((unsigned int)(0.045f * std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth())))
#define FONT_SIZE_LARGE ((unsigned int)(0.085f * std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth())))
#define FONT_SIZE_MINI ((unsigned int)(0.030f * Math::min(Renderer::getScreenHeight(), Renderer::getScreenWidth())))
#define FONT_SIZE_SMALL ((unsigned int)(0.035f * Math::min(Renderer::getScreenHeight(), Renderer::getScreenWidth())))
#define FONT_SIZE_MEDIUM ((unsigned int)(0.045f * Math::min(Renderer::getScreenHeight(), Renderer::getScreenWidth())))
#define FONT_SIZE_LARGE ((unsigned int)(0.085f * Math::min(Renderer::getScreenHeight(), Renderer::getScreenWidth())))
#define FONT_PATH_LIGHT ":/opensans_hebrew_condensed_light.ttf"
#define FONT_PATH_REGULAR ":/opensans_hebrew_condensed_regular.ttf"

View file

@ -1,5 +1,6 @@
#include "resources/TextureData.h"
#include "math/Misc.h"
#include "resources/ResourceManager.h"
#include "ImageIO.h"
#include "Log.h"
@ -8,7 +9,6 @@
#include <nanosvg/nanosvg.h>
#include <nanosvg/nanosvgrast.h>
#include <assert.h>
#include <math.h>
#include <string.h>
#define DPI 96
@ -62,18 +62,18 @@ bool TextureData::initSVGFromMemory(const unsigned char* fileData, size_t length
mSourceWidth = svgImage->width;
mSourceHeight = svgImage->height;
}
mWidth = (size_t)round(mSourceWidth);
mHeight = (size_t)round(mSourceHeight);
mWidth = (size_t)Math::round(mSourceWidth);
mHeight = (size_t)Math::round(mSourceHeight);
if (mWidth == 0)
{
// auto scale width to keep aspect
mWidth = (size_t)round(((float)mHeight / svgImage->height) * svgImage->width);
mWidth = (size_t)Math::round(((float)mHeight / svgImage->height) * svgImage->width);
}
else if (mHeight == 0)
{
// auto scale height to keep aspect
mHeight = (size_t)round(((float)mWidth / svgImage->width) * svgImage->height);
mHeight = (size_t)Math::round(((float)mWidth / svgImage->width) * svgImage->height);
}
unsigned char* dataRGBA = new unsigned char[mWidth * mHeight * 4];