summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2020-11-13 22:07:18 +0800
committerchai <chaifix@163.com>2020-11-13 22:07:18 +0800
commit0edde8a08c6a9a55135dadcff6cd21988d523041 (patch)
tree696f72ba8e82e7aaa8b41bb277557eb34e4ebaaf
parent2fae5dab12e9b7e3d70e21707c8b358834808451 (diff)
parent6f326b50d86fab5955a37fe317f14888662b055a (diff)
Merge branch 'master' of warmcat.org:/home/git-repo/GameLab
# Conflicts: # Projects/VisualStudio/Editor/Editor.vcxproj # Projects/VisualStudio/Editor/Editor.vcxproj.filters
-rw-r--r--Editor/EditorMain.cpp45
-rw-r--r--Editor/GUI/EditorWindows.cpp170
-rw-r--r--Editor/GUI/EditorWindows.h32
-rw-r--r--Editor/GUI/WinUtils.cpp43
-rw-r--r--Editor/GUI/WinUtils.h17
-rw-r--r--Editor/main.cpp43
-rw-r--r--Editor/wog.c746
-rw-r--r--Editor/wog.h219
-rw-r--r--Runtime/Math/FloatConversion.h697
-rw-r--r--Runtime/Math/Rect.h150
-rw-r--r--Runtime/Math/Vector2.cpp11
-rw-r--r--Runtime/Math/Vector2.h111
-rw-r--r--Runtime/main.cpp6
13 files changed, 1266 insertions, 1024 deletions
diff --git a/Editor/EditorMain.cpp b/Editor/EditorMain.cpp
new file mode 100644
index 0000000..d45d08b
--- /dev/null
+++ b/Editor/EditorMain.cpp
@@ -0,0 +1,45 @@
+#include <windows.h>
+#include <vector>
+#include "GUI/EditorWindows.h"
+
+static int MainMessageLoop()
+{
+ BOOL returnValue;
+ MSG msg, lastMsg;
+ msg.message = WM_NULL;
+ std::vector<MSG> messages;
+ PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);
+ bool isQuitSignaled = msg.message == WM_QUIT;
+
+ while (!isQuitSignaled)
+ {
+ MSG msg;
+ while (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE) != 0)
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+
+ if (msg.message == WM_QUIT)
+ isQuitSignaled = true;
+
+ }
+
+ }
+
+ return (INT)msg.wParam;
+}
+
+int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
+{
+ RegisterWindowClasses();
+
+ ContainnerWindow* wnd = new ContainnerWindow();
+
+ Vector2f min = Vector2f(100, 100);
+ Vector2f max = Vector2f(700, 700);
+ wnd->Init(Rectf(400, 400, 500, 500), ContainnerWindow::kShowMainWindow, min, max);
+
+ MainMessageLoop();
+
+ return 0;
+}
diff --git a/Editor/GUI/EditorWindows.cpp b/Editor/GUI/EditorWindows.cpp
index e69de29..00c573a 100644
--- a/Editor/GUI/EditorWindows.cpp
+++ b/Editor/GUI/EditorWindows.cpp
@@ -0,0 +1,170 @@
+#include "EditorWindows.h"
+#include "WinUtils.h"
+
+static const wchar_t* kContainerWindowClassName = L"GameLabContainerWndClass";
+static const wchar_t* kPopupWindowClassName = L"GameLabPopupWndClass";
+static const wchar_t* kViewportClassName = L"GameLabViewportWndClass";
+static const char* kIsMainWindowMaximized = "IsMainWindowMaximized";
+
+static ATOM s_ContainerWindowClassAtom;
+static ATOM s_PopupWindowClassAtom;
+static ATOM s_GUIViewClassAtom;
+
+void RegisterWindowClasses()
+{
+ s_ContainerWindowClassAtom = winutils::RegisterWindowClass(kContainerWindowClassName, ContainnerWindow::ContainerWndProc, CS_HREDRAW | CS_VREDRAW);
+ s_PopupWindowClassAtom = winutils::RegisterWindowClass(kPopupWindowClassName, ContainnerWindow::ContainerWndProc, CS_HREDRAW | CS_VREDRAW | CS_DROPSHADOW);//CS_HREDRAW宽度(水平)变化时重绘、CS_VREDRAW高度(垂直)变化时重绘
+ s_GUIViewClassAtom = winutils::RegisterWindowClass(kViewportClassName, GUIView::GUIViewWndProc, CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS);
+}
+
+LRESULT CALLBACK ContainnerWindow::ContainerWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ long flag = DefWindowProcW(hWnd, message, wParam, lParam);
+ return flag;
+}
+
+ContainnerWindow::ContainnerWindow()
+{
+}
+
+
+ContainnerWindow::~ContainnerWindow()
+{
+
+}
+
+void ContainnerWindow::Init(Rectf pixelRect, int showMode, const Vector2f& minSize, const Vector2f& maxSize)
+{
+ // Aux windows are mac only. on windows they look just like normal utility windows.
+ if (showMode == kShowAuxWindow)
+ showMode = kShowUtility;
+
+ m_ShowMode = static_cast<ShowMode>(showMode);
+ m_IsClosing = false;
+ m_InMenuLoop = false;
+ m_CloseFromScriptDontShutdown = false;
+
+ bool shouldMaximize = false;
+ if (showMode == kShowMainWindow)
+ {
+ //shouldMaximize = s_IsMainWindowMaximized = EditorPrefs::GetBool(kIsMainWindowMaximized, false);
+ //GetRestoredMainWindowDimensions();
+ }
+
+ RECT rect = { 120, 120, 220, 220 };
+ m_InternalRect.x = m_InternalRect.y = m_InternalRect.width = m_InternalRect.height = 0.0f;
+
+ DWORD windowStyle = 0;
+ DWORD extendedStyle = 0;
+ LPCWSTR windowClass = kContainerWindowClassName;
+
+ switch (showMode) {
+ // 容纳GUIPanel的非主窗口
+ case kShowNormalWindow:
+ windowStyle = WS_POPUP | WS_CLIPCHILDREN | WS_THICKFRAME;
+ extendedStyle = WS_EX_TOOLWINDOW;
+ break;
+ // 主窗口,含菜单
+ case kShowMainWindow:
+ windowStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_CLIPCHILDREN | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
+ extendedStyle = 0;
+ break;
+ case kShowPopupMenu:
+ windowStyle = WS_POPUP | WS_CLIPCHILDREN;
+ extendedStyle = WS_EX_TOOLWINDOW;
+ windowClass = kPopupWindowClassName;
+ break;
+ case kShowNoShadow:
+ windowStyle = WS_POPUP | WS_CLIPCHILDREN;
+ extendedStyle = WS_EX_TOOLWINDOW;
+ break;
+ case kShowUtility:
+ windowStyle = WS_POPUP | WS_CAPTION | WS_THICKFRAME | WS_SYSMENU;
+ extendedStyle = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW;
+ break;
+ default:
+ // ErrorString("Unknown container show mode");
+ break;
+ }
+
+ HWND parentWindow = NULL;
+ if (showMode == kShowMainWindow)
+ {
+ parentWindow = NULL;
+ }
+ else
+ {
+ // parentWindow = GetMainEditorWindow();
+ }
+
+ bool notSizeable = (minSize == maxSize) && (minSize != Vector2f::zero);
+ if (notSizeable)
+ windowStyle &= ~(WS_THICKFRAME);
+
+ AdjustWindowRectEx(&rect, windowStyle, showMode == kShowMainWindow, extendedStyle);
+ int extraX = rect.right - rect.left - 200;
+ int extraY = rect.bottom - rect.top - 200;
+
+ m_MinSize.x = minSize.x + extraX;
+ m_MinSize.y = minSize.y + extraY;
+ m_MaxSize.x = maxSize.x + extraX;
+ m_MaxSize.y = maxSize.y + extraY;
+
+
+ //if (showMode == kShowUtility)
+ // s_ZUtilityWindows.push_back(m_ContainerListNode);
+ // Create window
+ m_Window = CreateWindowExW(
+ extendedStyle,
+ windowClass,
+ L"",
+ windowStyle,
+ rect.left,
+ rect.top,
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ parentWindow,
+ NULL,
+ winutils::GetInstanceHandle(),
+ NULL
+ );
+ SetWindowLongPtr(m_Window, GWLP_USERDATA, (LONG_PTR)this);
+ //UpdateMaxMaximizedRect();
+
+ if (pixelRect.width > 10 || pixelRect.height > 10)
+ {
+ //SetRect(pixelRect);
+ if (shouldMaximize)
+ SetWindowLong(m_Window, GWL_STYLE, windowStyle | WS_MAXIMIZE);
+ }
+
+
+ if (showMode == kShowMainWindow)
+ {
+ //SetMainEditorWindow(m_Window);
+ //HMENU menu = GetMainMenuHandle();
+ //if (menu)
+ // SetMenu(m_Window, menu);
+ //GetApplication().UpdateMainWindowTitle();
+ //GetApplication().UpdateDocumentEdited();
+ }
+ ShowWindow(m_Window, SW_SHOW);
+
+ //s_ContainerWindows.insert(this);
+
+ //ShowInTaskbarIfNoMainWindow(m_Window);
+
+}
+
+//------------------------------------------------------------------------------------------------------------------
+
+LRESULT CALLBACK GUIView::GUIViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ long flag = DefWindowProcW(hWnd, message, wParam, lParam);
+ return flag;
+}
+
+void GUIView::DoPaint()
+{
+
+} \ No newline at end of file
diff --git a/Editor/GUI/EditorWindows.h b/Editor/GUI/EditorWindows.h
index 90e71a4..a78e163 100644
--- a/Editor/GUI/EditorWindows.h
+++ b/Editor/GUI/EditorWindows.h
@@ -2,23 +2,51 @@
#define EDITOR_WINDOW_H
#include <windows.h>
+#include "Runtime/Math/Rect.h"
+
+void RegisterWindowClasses();
// 一个containner window中有多个viewport
class ContainnerWindow
{
public:
+ enum ShowMode {
+ kShowNormalWindow = 0, // normal window with max/min/close buttons
+ kShowPopupMenu = 1, // popup menu - no title bar
+ kShowUtility = 2, // tool window - floats in the app, and hides when the app deactivates
+ kShowNoShadow = 3, // no shadow/decorations
+ kShowMainWindow = 4, // main Unity window. On Mac does not have close button; on Windows has menu bar etc.
+ kShowAuxWindow = 5, // Popup windows like the color picker, gradient editor, etc. Drawn with black background on Mac
+ };
+
+ ContainnerWindow();
+ ~ContainnerWindow();
+
+ static LRESULT CALLBACK ContainerWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+
+ void Init(Rectf size, int showMode, const Vector2f& minSize, const Vector2f& maxSize);
private:
HWND m_Window;
POINT m_Size;
+ ShowMode m_ShowMode; // 窗口类型
+ bool m_IsClosing;
+ bool m_InMenuLoop;
+ bool m_CloseFromScriptDontShutdown;
+ Rectf m_InternalRect;
+ POINT m_MinSize;
+ POINT m_MaxSize;
};
-// 窗口内的单个viewport
-class Viewport
+// 窗口内的单个子窗口,是事件相应、绘制、布局的单元
+class GUIView
{
public:
+ static LRESULT CALLBACK GUIViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+
+ void DoPaint();
private:
HWND m_View;
diff --git a/Editor/GUI/WinUtils.cpp b/Editor/GUI/WinUtils.cpp
new file mode 100644
index 0000000..e7b2d5b
--- /dev/null
+++ b/Editor/GUI/WinUtils.cpp
@@ -0,0 +1,43 @@
+#include "winutils.h"
+
+namespace winutils
+{
+
+ static HINSTANCE gInstanceHandle = NULL;
+
+ HINSTANCE GetInstanceHandle()
+ {
+ return gInstanceHandle;
+ }
+
+ ATOM RegisterWindowClass(const wchar_t* className, WNDPROC windowProc, unsigned int style)
+ {
+#if DEBUG_WIN_UTILS
+ printf_console("Debug winutils: register class %s\n", className);
+#endif
+
+ WNDCLASSEXW wcex;
+ memset(&wcex, 0, sizeof(wcex));
+ wcex.cbSize = sizeof(wcex);
+ wcex.style = style;
+ wcex.lpfnWndProc = windowProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = winutils::GetInstanceHandle();
+ //wcex.hIcon = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_APP_ICON);
+ wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wcex.hbrBackground = NULL;
+ wcex.lpszMenuName = NULL;
+ wcex.lpszClassName = className;
+ ATOM classAtom = RegisterClassExW(&wcex);
+ //if (!classAtom)
+ // printf("Failed to register window class %s: %s\n", className, WIN_LAST_ERROR_TEXT);
+ return classAtom;
+ }
+
+ void UnregisterWindowClass(const wchar_t* className)
+ {
+
+ }
+
+}
diff --git a/Editor/GUI/WinUtils.h b/Editor/GUI/WinUtils.h
new file mode 100644
index 0000000..9257d77
--- /dev/null
+++ b/Editor/GUI/WinUtils.h
@@ -0,0 +1,17 @@
+#ifndef WINUTILS_H
+#define WINUTILS_H
+
+#include <windows.h>
+
+namespace winutils
+{
+ HINSTANCE GetInstanceHandle();
+
+ // 注册windows窗口类
+ ATOM RegisterWindowClass(const wchar_t* className, WNDPROC windowProc, unsigned int style);
+ void UnregisterWindowClass(const wchar_t* className);
+
+
+}
+
+#endif \ No newline at end of file
diff --git a/Editor/main.cpp b/Editor/main.cpp
deleted file mode 100644
index 58e5f04..0000000
--- a/Editor/main.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-extern "C" {
-#include "wog.h"
-}
-
-#include <glad/glad.h>
-#include <windows.h>
-
-wog_Window * wnd ;
-
-void* proc(const char *name) {
- return wglGetProcAddress(name);
-}
-
-int main(int argc, char* argv[]) {
- wnd = wog_createWindow("GameLab" , 800, 600, 500, 500, 0);
- wog_show(wnd);
-
- wog_GLContext* ctx = wog_createGLContext(wnd);
- wog_makeCurrent(wnd, ctx);
-
- //gladLoadGLLoader(proc);
- int load = gladLoadGL();
-
-// wog_makeCurrent(wnd, ctx);
-
- while (true) {
- wog_Event e;
- while (wog_pollEvent(wnd, &e)) {
- if (e.type == WOG_ECLOSE)
- goto quit;
- }
- //glViewport(0, 0, 500, 500);
- glClearColor(0.16, 0.16, 0.16, 1);
- glClear(GL_COLOR_BUFFER_BIT);
- glFlush();
-
- wog_swapBuffers(wnd);
- }
-
-quit:
-
- return 0;
-}
diff --git a/Editor/wog.c b/Editor/wog.c
deleted file mode 100644
index 6cfbf64..0000000
--- a/Editor/wog.c
+++ /dev/null
@@ -1,746 +0,0 @@
-/**
-* Copyright (c) 2015~2017 chai(neonum)
-*
-* This library is free software; you can redistribute it and/or modify it
-* under the terms of the MIT license. See LICENSE for details.
-*/
-
-#include "wog.h"
-#include <windows.h>
-#include <malloc.h>
-#include <stdio.h>
-#include <memory.h>
-#include <assert.h>
-
-#if WOG_API == WOG_GL
-#include <gl/GL.h>
-#include <gl/GLU.h>
-#endif
-
-
-#if WOG_API == WOG_GL
-/**
-* We need opengl32.lib and glu32.lib for using opengl functions on
-* windows platform.
-*/
-#pragma comment( lib, "opengl32.lib" )
-//#pragma comment( lib, "glu32.lib" )
-#endif
-
-#define WINDOW_CLASS "WOG_WND"
-
-#define heap_alloc(T, C) (T*)malloc(sizeof(T)*(C))
-#define stack_alloc(T, C) (T*)alloca(sizeof(T)*(C))
-#define zero_mem(I, L) memset(I, 0, L)
-
-#define max(a, b) (a < b ? b : a)
-#define min(a, b) (a < b ? a : b)
-#define clamp(x, minv, maxv) (max(minv, min(x, maxv)))
-
-static HINSTANCE g_hinstance = NULL;
-
-typedef struct wog_Window
-{
- HWND hwnd; // Window handler
- HINSTANCE hInstance;
- HDC hdc; // Device Context
- HDC mdc; // Memory Device Contexts
-#if WOG_API == WOG_GDI
- wog_Surface* surface; // render buffer
-#endif
- int mouse_capture; // mouse capture count
-}wog_Window;
-
-#if WOG_API == WOG_GL
-typedef struct wog_GLContext
-{
- HGLRC hrc; // Rendering Context
-}wog_GLContext;
-#endif
-
-// A mouse capture count is used
-void wog_setMouseCapture(wog_Window* wnd)
-{
- if (wnd->mouse_capture <= 0)
- {
- SetCapture(wnd->hwnd);
- wnd->mouse_capture = 0;
- }
- ++wnd->mouse_capture;
-}
-
-void wog_releaseMouseCapture(wog_Window* wnd)
-{
- --wnd->mouse_capture;
- if (wnd->mouse_capture <= 0)
- ReleaseCapture();
-}
-
-void wog_handleEvent(wog_Window* window, MSG* msg, wog_Event* e)
-{
- UINT uMsg;
- WPARAM wParam;
- LPARAM lParam;
- uMsg = msg->message;
- wParam = msg->wParam;
- lParam = msg->lParam;
- HWND hWnd = window->hwnd;
-
- switch (uMsg)
- {
- case WM_SYSCOMMAND:
- {
- switch (wParam)
- {
- case SC_SCREENSAVE:
- case SC_MONITORPOWER:
- return ;
- }
- break;
- }
- return ;
-
- case WM_CLOSE:
- {
- zero_mem(e, sizeof(wog_Event));
- e->type = WOG_ECLOSE;
- return ;
- }
-
- case WM_KEYDOWN:
- case WM_SYSKEYDOWN:
- if ((wParam >= 0) && (wParam <= 255))
- {
- zero_mem(e, sizeof(wog_Event));
- e->type = WOG_EKEYDOWN;
- e->key = wParam;
-
- return ;
- }
- break;
-
- case WM_KEYUP:
- case WM_SYSKEYUP:
- if ((wParam >= 0) && (wParam <= 255))
- {
- zero_mem(e, sizeof(wog_Event));
- e->type = WOG_EKEYUP;
- e->key = wParam;
-
- return ;
- }
- break;
-
- case WM_MOUSEMOVE:
- {
- zero_mem(e, sizeof(wog_Event));
- e->type = WOG_EMOUSEMOTION;
- wog_getMouse(window, &e->pos.x, &e->pos.y);
- return ;
- }
-
- case WM_MOUSEWHEEL: // mousewheel scroll
- {
- int zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
- zero_mem(e, sizeof(wog_Event));
- e->type = WOG_EMOUSEWHEEL;
- e->wheel = zDelta > 0 ? 1 : -1;
- return ;
- }
-
- case WM_LBUTTONDOWN:
- {
- zero_mem(e, sizeof(wog_Event));
- e->type = WOG_EMOUSEBUTTONDOWN;
- e->button = WOG_MOUSE_LBUTTON;
- wog_getMouse(window, &e->pos.x, &e->pos.y);
- wog_setMouseCapture(window);
- return ;
- }
-
- case WM_RBUTTONDOWN:
- {
- zero_mem(e, sizeof(wog_Event));
- e->type = WOG_EMOUSEBUTTONDOWN;
- e->button = WOG_MOUSE_RBUTTON;
- wog_getMouse(window, &e->pos.x, &e->pos.y);
- wog_setMouseCapture(window);
- return ;
- }
-
- case WM_MBUTTONDOWN:
- {
- zero_mem(e, sizeof(wog_Event));
- e->type = WOG_EMOUSEBUTTONDOWN;
- e->button = WOG_MOUSE_MIDDLE;
- wog_getMouse(window, &e->pos.x, &e->pos.y);
- wog_setMouseCapture(window);
- return ;
- }
-
- case WM_LBUTTONUP:
- {
- zero_mem(e, sizeof(wog_Event));
- e->type = WOG_EMOUSEBUTTONUP;
- e->button = WOG_MOUSE_LBUTTON;
- wog_getMouse(window, &e->pos.x, &e->pos.y);
- wog_releaseMouseCapture(window);
- return ;
- }
-
- case WM_RBUTTONUP:
- {
- zero_mem(e, sizeof(wog_Event));
- e->type = WOG_EMOUSEBUTTONUP;
- e->button = WOG_MOUSE_RBUTTON;
- wog_getMouse(window, &e->pos.x, &e->pos.y);
- wog_releaseMouseCapture(window);
- return ;
- }
-
- case WM_MBUTTONUP:
- {
- zero_mem(e, sizeof(wog_Event));
- e->type = WOG_EMOUSEBUTTONUP;
- e->button = WOG_MOUSE_MIDDLE;
- wog_getMouse(window, &e->pos.x, &e->pos.y);
- wog_releaseMouseCapture(window);
- return ;
- }
-
- case WM_PAINT:
-
- UpdateWindow(window->hwnd);
-
- return 0;
-
- break;
-
- default:
- e->type = WOG_EUNKNOWN;
- break;
- }
- DefWindowProc(hWnd, uMsg, wParam, lParam);
- return ;
-}
-
-
-int wog_pollEvent(wog_Window* wnd, wog_Event* e)
-{
- MSG msg;
- if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
- {
- if (msg.message == WM_QUIT) return 0;
- TranslateMessage(&msg);
- wog_handleEvent(wnd, &msg, e);
- return 1;
- }
- return 0;
-}
-
-
-// on size changed callback;
-static wog_Callback onSizeChanged = 0;
-static wog_Callback onQuit = 0;
-
-
-static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- // Get The Window Context
- wog_Window* window = (wog_Window*)(GetWindowLong(hWnd, GWL_USERDATA));
-
- // call callback functions
-#define call(callback)\
- if (callback) \
- callback(window)
-
- switch (uMsg)
- {
- case WM_CREATE:
- {
- CREATESTRUCT* creation = (CREATESTRUCT*)(lParam); // Store Window Structure Pointer
- window = (wog_Window*)(creation->lpCreateParams); // Get wog_Window
- SetWindowLong(hWnd, GWL_USERDATA, (LONG)(window)); // Save it
- }
- return 0;
-
- case WM_CLOSE: // Post WM_CLOSE to message queue.
- PostMessage(hWnd, WM_CLOSE, wParam, lParam);
- return 0;
-
- case WM_SIZE:
- call(onSizeChanged);
- return 0;
-
- case WM_QUIT:
- call(onQuit);
- return 0;
-
- }
-
- return DefWindowProc(hWnd, uMsg, wParam, lParam);
-#undef call
-}
-
-
-void wog_registerResizeCallback(wog_Callback cal)
-{
- onSizeChanged = cal;
-}
-
-
-void wog_registerQuitCallback(wog_Callback cal)
-{
- onQuit = cal;
-}
-
-#if WOG_API == WOG_GDI
-wog_Surface* wog_getsurface(wog_Window* wnd) {
- return wnd->surface;
-}
-#endif
-
-static int registerWindowClass()
-{
- // Register A Window Class
- WNDCLASSEX windowClass; // Window Class
- zero_mem(&windowClass, sizeof(WNDCLASSEX)); // Make Sure Memory Is Cleared
-
- windowClass.cbSize = sizeof(WNDCLASSEX); // Size Of The windowClass Structure
- windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraws The Window For Any Movement / Resizing
- windowClass.lpfnWndProc = (WNDPROC)(WindowProc); // WindowProc Handles Messages
- windowClass.hInstance = g_hinstance; // Set The Instance
- windowClass.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE); // Class Background Brush Color
- windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointer
- windowClass.lpszClassName = WINDOW_CLASS; // Sets The Applications Classname
- //windowClass.hIcon = (HICON)LoadIcon(g_hinstance, "icon.ico");
-
- if (RegisterClassEx(&windowClass) == 0) // Did Registering The Class Fail?
- {
- // NOTE: Failure, Should Never Happen
- MessageBox(HWND_DESKTOP, "RegisterClassEx Failed!", "Error", MB_OK | MB_ICONEXCLAMATION);
- return FALSE; // Return False (Failure)
- }
- return TRUE;
-}
-
-/*
- * for memory device context, see
- * https://docs.microsoft.com/en-us/windows/desktop/gdi/memory-device-contexts
- * also
- * SDL_windowsframebuffer.c WIN_CreateWindowFramebuffer
- */
-static void create_surface(wog_Window* wnd, int width, int height) {
- BITMAPINFOHEADER bi_header;
- HDC memory_dc;
- HBITMAP dib_bitmap;
- HBITMAP old_bitmap;
- unsigned char *buffer; // color buffer
- wog_Surface *surface;
-
- memory_dc = CreateCompatibleDC(wnd->hdc); /*memory device contexts*/
-
- memset(&bi_header, 0, sizeof(BITMAPINFOHEADER));
- bi_header.biSize = sizeof(BITMAPINFOHEADER);
- bi_header.biWidth = width;
- bi_header.biHeight = -height; /* top-down */
- bi_header.biPlanes = 1;
- bi_header.biBitCount = 32;
- bi_header.biCompression = BI_RGB;
- /*create bitmap*/
- dib_bitmap = CreateDIBSection(memory_dc, (BITMAPINFO*)&bi_header, DIB_RGB_COLORS, (void**)&buffer, NULL, 0);
- assert(dib_bitmap != NULL);
- old_bitmap = (HBITMAP)SelectObject(memory_dc, dib_bitmap);
- DeleteObject(old_bitmap);
-
- surface = (wog_Surface*)malloc(sizeof(wog_Surface));
- surface->width = width;
- surface->height = height;
- surface->channels = 4;
- surface->buffer = buffer;
-
-#if WOG_API == WOG_GDI
- wnd->surface = surface;
-#endif
- wnd->mdc = memory_dc;
-}
-
-
-wog_Window* wog_createWindow(const char* title, int width, int height, int x, int y, uint32 flags)
-{
- int client_w = width, client_h = height;
-
- if (g_hinstance == NULL)
- {
- g_hinstance = GetModuleHandle(NULL);
- }
-
- if (! registerWindowClass())
- {
- printf("Register window class failed.\n");
- return 0;
- }
-
- wog_Window* wnd = heap_alloc(wog_Window, 1);
- zero_mem(wnd, sizeof(wog_Window));
-
- DWORD windowStyle = 0; // Define Our Window Style
- windowStyle |= WS_POPUP;
- windowStyle |= WS_OVERLAPPED;
- windowStyle |= WS_CAPTION;
- windowStyle |= WS_SYSMENU;
- windowStyle |= WS_MINIMIZEBOX;
- windowStyle |= WS_MAXIMIZEBOX;
- //windowStyle |= WS_VISIBLE;
-#define hasbit(fs, f) ((fs & f) == f)
- /*if (hasbit(flags, WOG_RESIZABLE)) */windowStyle |= WS_SIZEBOX;
- if (hasbit(flags, WOG_DISABLE)) windowStyle |= WS_DISABLED;
-
- DWORD windowExtendedStyle = WS_EX_APPWINDOW; // Define The Window's Extended Style
- RECT windowRect = { 0, 0, width, height };
- AdjustWindowRectEx(&windowRect, windowStyle, 0, windowExtendedStyle);
- width = windowRect.right - windowRect.left;
- height = windowRect.bottom - windowRect.top;
- wnd->hwnd = CreateWindowEx(
- windowExtendedStyle,
- WINDOW_CLASS,
- title,
- windowStyle,
- x, y,
- width, height,
- HWND_DESKTOP,
- 0,
- GetModuleHandle(NULL),
- wnd
- );
-
- wnd->hInstance = g_hinstance;
-
- if (wnd->hwnd == 0)
- return 0;
-
- if (hasbit(flags, WOG_HIDDEN)) wog_hide(wnd);
-
- // init device context
- wnd->hdc = GetDC(wnd->hwnd);
- if (wnd->hdc== 0)
- {
- DestroyWindow(wnd->hwnd);
- wnd->hwnd = 0;
- return 0;
- }
-
- wnd->mouse_capture = 0;
-
-#if WOG_API == WOG_GDI
- create_surface(wnd, client_w, client_h);
-#endif
-
-#if WOG_API == WOG_GL
- PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be
- {
- sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
- 1, // Version Number
- PFD_DRAW_TO_WINDOW | // Format Must Support Window
- PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
- PFD_DOUBLEBUFFER, // Must Support Double Buffering
- PFD_TYPE_RGBA, // Request An RGBA Format
- 32, // Select Our Color Depth
- 0, 0, 0, 0, 0, 0, // Color Bits Ignored
- 0, // No Alpha Buffer
- 0, // Shift Bit Ignored
- 0, // No Accumulation Buffer
- 0, 0, 0, 0, // Accumulation Bits Ignored
- 16, // 16Bit Z-Buffer (Depth Buffer)
- 0, // No Stencil Buffer
- 0, // No Auxiliary Buffer
- PFD_MAIN_PLANE, // Main Drawing Layer
- 0, // Reserved
- 0, 0, 0 // Layer Masks Ignored
- };
- // set pixel format
- unsigned int pixelformat;
- pixelformat = ChoosePixelFormat(wnd->hdc, &pfd);
- if (pixelformat == 0)
- {
- wog_destroyWindow(wnd);
- return 0;
- }
-
- // set pixel format
- if (SetPixelFormat(wnd->hdc, pixelformat, &pfd) == 0 )
- {
- wog_destroyWindow(wnd);
- return 0;
- }
-#endif
-
- return wnd;
-}
-
-#if WOG_API == WOG_GL
-wog_GLContext* wog_createGLContext(wog_Window* wnd)
-{
- wog_GLContext* cxt = heap_alloc(wog_GLContext, 1);
- zero_mem(cxt, sizeof(wog_GLContext));
- cxt->hrc = wglCreateContext(wnd->hdc); // create opengl context base on device context
- if (cxt->hrc == 0)
- {
- free(cxt);
- return 0;
- }
- return cxt;
-}
-#endif
-
-#if WOG_API == WOG_GL
-int wog_makeCurrent(wog_Window* wnd, wog_GLContext* cxt)
-{
- if (wnd && cxt)
- {
- if (wglMakeCurrent(wnd->hdc, cxt->hrc) == 0)
- {
- return 0;
- }
- return 1;
- }
-
- return 0;
-}
-#endif
-
-#if WOG_API == WOG_GL
-void wog_destroyGLContext(wog_GLContext* cxt)
-{
- if (cxt && cxt->hrc)
- {
- wglDeleteContext(cxt->hrc);
- free(cxt);
- }
-}
-#endif
-
-#if WOG_API == WOG_GDI
-void wog_updateSurface(wog_Window* wnd) {
- if(wnd->surface == NULL) return ;
- int width = wnd->surface->width, height = wnd->surface->height;
- BitBlt(wnd->hdc, 0, 0, wnd->surface, height, wnd->mdc, 0, 0, SRCCOPY);
-}
-#endif
-
-void wog_destroyWindow(wog_Window* wnd)
-{
- if (wnd)
- {
- ReleaseDC(wnd->hwnd, wnd->hdc);
- DestroyWindow(wnd->hwnd);
- free(wnd);
- }
-}
-
-
-static void UnEscapeQuotes(char *arg)
-{
- char *last = NULL;
-
- while (*arg) {
- if (*arg == '"' && *last == '\\') {
- char *c_curr = arg;
- char *c_last = last;
-
- while (*c_curr) {
- *c_last = *c_curr;
- c_last = c_curr;
- c_curr++;
- }
- *c_last = '\0';
- }
- last = arg;
- arg++;
- }
-}
-
-
-/* Parse a command line buffer into arguments */
-static int ParseCommandLine(char *cmdline, char **argv)
-{
- char *bufp;
- char *lastp = NULL;
- int argc, last_argc;
-
- argc = last_argc = 0;
- for (bufp = cmdline; *bufp; ) {
- /* Skip leading whitespace */
- while (isspace(*bufp)) {
- ++bufp;
- }
- /* Skip over argument */
- if (*bufp == '"') {
- ++bufp;
- if (*bufp) {
- if (argv) {
- argv[argc] = bufp;
- }
- ++argc;
- }
- /* Skip over word */
- while (*bufp && (*bufp != '"' || (lastp && *lastp == '\\'))) {
- lastp = bufp;
- ++bufp;
- }
- }
- else {
- if (*bufp) {
- if (argv) {
- argv[argc] = bufp;
- }
- ++argc;
- }
- /* Skip over word */
- while (*bufp && !isspace(*bufp)) {
- ++bufp;
- }
- }
- if (*bufp) {
- if (argv) {
- *bufp = '\0';
- }
- ++bufp;
- }
-
- /* Strip out \ from \" sequences */
- if (argv && last_argc != argc) {
- UnEscapeQuotes(argv[last_argc]);
- }
- last_argc = argc;
- }
- if (argv) {
- argv[argc] = NULL;
- }
- return(argc);
-}
-
-
-#ifdef main
-#undef main
-#endif
-
-
-#if defined(_MSC_VER) && !defined(_WIN32_WCE)
-/* The VC++ compiler needs main defined */
-#define console_main main
-#endif
-
-extern int wog_main(int argc, char* argv[]);
-
-/**
-* Entry of console application.
-*/
-int console_main(int argc, char* argv[])
-{
- int status = wog_main(argc, argv);
- return status;
-}
-
-
-/**
-* Entry of windows application.
-*/
-int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
-{
- g_hinstance = hInst;
-
- char* temp = GetCommandLine();
- int len = strlen(temp) + 1;
- char* cmd = stack_alloc(char, len);
- strcpy(cmd, temp);
- cmd[len - 1] = '\0';
-
- int argc = 0;
- char** argv = 0;
- argc = ParseCommandLine(cmd, 0);
- ParseCommandLine(cmd, 0);
- argv = stack_alloc(char*, argc + 1);
- ParseCommandLine(cmd, argv);
-
- int status = console_main(argc, argv);
-
- return status;
-}
-
-
-void wog_swapBuffers(wog_Window* wnd)
-{
- if (wnd)
- {
- SwapBuffers(wnd->hdc);
- }
-}
-
-
-void wog_getMouse(wog_Window* wnd, int *x, int *y)
-{
- POINT p;
- GetCursorPos(&p);
- ScreenToClient(wnd->hwnd, &p);
- int w, h;
- wog_getwindowsize(wnd, &w, &h);
- //*x = clamp(p.x, 0, w);
- //*y = clamp(p.y, 0, h);
- *x = p.x;
- *y = p.y;
-}
-
-
-void wog_getwindowsize(wog_Window* wnd, int* width, int* height)
-{
- RECT r;
- GetClientRect(wnd->hwnd, &r);
- *width = r.right;
- *height = r.bottom;
-}
-
-
-void wog_show(wog_Window* wnd)
-{
- ShowWindow(wnd->hwnd, SW_SHOW);
-}
-
-
-void wog_hide(wog_Window* wnd)
-{
- ShowWindow(wnd->hwnd, SW_HIDE);
-}
-
-
-void wog_sleep(int ms)
-{
- Sleep(ms);
-}
-
-int wog_tick()
-{
- return GetTickCount();
-}
-
-
-void wog_setcursor(wog_Window* wnd, unsigned int cursor)
-{
- SetCursor(LoadCursor(NULL, cursor));
-}
-
-//void wog_setcursorImage(wog_Window* wnd, const char* path)
-//{
-// SetCursor(LoadImageA(NULL, path, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_LOADFROMFILE));
-// printf("wog_setcursorImage\n");
-//}
-
-void wog_setcursorImage(wog_Window* wnd, Wog_Cursor icon)
-{
- SetCursor(icon);
-}
-
-HINSTANCE wog_get_instance()
-{
- return g_hinstance;
-}
diff --git a/Editor/wog.h b/Editor/wog.h
deleted file mode 100644
index f5661db..0000000
--- a/Editor/wog.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
-* Copyright (c) 2015~2020 chai
-*/
-
-#ifndef _WOG_H
-#define _WOG_H
-#include <Windows.h> // for virtual key value
-
-#define WOG_GL 1
-#define WOG_GDI 2
-
-#define WOG_API WOG_GL
-
-typedef unsigned int uint32;
-typedef unsigned short uint16;
-
-enum // event type
-{
- WOG_EUNKNOWN = 0, // unknown event
-
- WOG_EKEYDOWN, // key pressed
- WOG_EKEYUP, // key released
-
- WOG_EMOUSEMOTION, // mouse motion
- WOG_EMOUSEWHEEL, // mouse wheel scrolling
- WOG_EMOUSEBUTTONDOWN, // mosue button down
- WOG_EMOUSEBUTTONUP, // mosue button down
-
- WOG_ECLOSE, // close window
-};
-
-enum // mouse button event, e.button value
-{
- WOG_MOUSE_LBUTTON, // left mouse button
- WOG_MOUSE_RBUTTON, // right mouse button
- WOG_MOUSE_MIDDLE, // middle button
-};
-
-typedef struct wog_Event
-{
- int type;
- //union // event value
- //{
- int key; // for key, simply use windows virtual key value
- // see https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
- struct // for mouse motion
- {
- int x, y; // mouse position
- }pos;
- int wheel; // 1 indicate scroll up and -1 indicate scrool down
- int button; // mouse button
- //};
-}wog_Event;
-
-//* VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39)
- //* 0x40 : unassigned
- //* VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A)
-
-//定义数据字符0~9
-#define VK_0 0x30
-#define VK_1 0x31
-#define VK_2 0x32
-#define VK_3 0x33
-#define VK_4 0x34
-#define VK_5 0x35
-#define VK_6 0x36
-#define VK_7 0x37
-#define VK_8 0x38
-#define VK_9 0x39
-
-//定义数据字符A~Z
-#define VK_A 0x41
-#define VK_B 0x42
-#define VK_C 0x43
-#define VK_D 0x44
-#define VK_E 0x45
-#define VK_F 0x46
-#define VK_G 0x47
-#define VK_H 0x48
-#define VK_I 0x49
-#define VK_J 0x4A
-#define VK_K 0x4B
-#define VK_L 0x4C
-#define VK_M 0x4D
-#define VK_N 0x4E
-#define VK_O 0x4F
-#define VK_P 0x50
-#define VK_Q 0x51
-#define VK_R 0x52
-#define VK_S 0x53
-#define VK_T 0x54
-#define VK_U 0x55
-#define VK_V 0x56
-#define VK_W 0x57
-#define VK_X 0x58
-#define VK_Y 0x59
-#define VK_Z 0x5A
-
-//定义数据字符a~z
-#define VK_a 0x61
-#define VK_b 0x62
-#define VK_c 0x63
-#define VK_d 0x64
-#define VK_e 0x65
-#define VK_f 0x66
-#define VK_g 0x67
-#define VK_h 0x68
-#define VK_i 0x69
-#define VK_j 0x6A
-#define VK_k 0x6B
-#define VK_l 0x6C
-#define VK_m 0x6D
-#define VK_n 0x6E
-#define VK_o 0x6F
-#define VK_p 0x70
-#define VK_q 0x71
-#define VK_r 0x72
-#define VK_s 0x73
-#define VK_t 0x74
-#define VK_u 0x75
-#define VK_v 0x76
-#define VK_w 0x77
-#define VK_x 0x78
-#define VK_y 0x79
-#define VK_z 0x7A
-
-typedef struct {
- int width, height, channels;
- unsigned char* buffer;
-} wog_Surface;
-
-/**
-* Entry of user program which defined in user project. You need provide
-* this function's defination.
-*/
-#define main wog_main
-extern int wog_main(int argc, char* argv[]);
-
-typedef struct wog_Window wog_Window;
-
-#if WOG_API == WOG_GL
-/**
-* Struct that hold opengl context generated by wglCreateContext() which
-* defined in opengl32.lib
-*/
-typedef struct wog_GLContext wog_GLContext;
-#endif
-
-enum // window style flag
-{
- WOG_HIDDEN = 4,
- WOG_RESIZABLE = 8,
- WOG_DISABLE = 16,
-};
-
-/**
-* Create window with given configures.
-* flag would be:
-* WOG_HIDDEN
-* WOG_RESIZABLE
-* WOG_DISABLE
-* or just 0;
-*/
-wog_Window* wog_createWindow(const char* title, int width, int height, int x, int y, uint32 flags);
-
-#if WOG_API == WOG_GL
-wog_GLContext* wog_createGLContext(wog_Window* wnd);
-
-int wog_makeCurrent(wog_Window* wnd, wog_GLContext* cxt);
-
-void wog_destroyGLContext(wog_GLContext* cxt);
-#endif
-
-void wog_destroyWindow(wog_Window* wnd);
-
-#if WOG_API == WOG_GL
-void wog_swapBuffers(wog_Window* wnd);
-#endif
-
-#if WOG_API == WOG_GDI
-void wog_updateSurface(wog_Window* wnd);
-#endif
-
-int wog_pollEvent(wog_Window* wnd, wog_Event* e);
-
-void wog_getMouse(wog_Window* wnd, int *x, int *y);
-
-// get current ticks
-int wog_tick();
-
-void wog_sleep(int ms);
-
-void wog_getwindowsize(wog_Window* wnd, int* width, int* height);
-
-void wog_show(wog_Window* wnd);
-
-void wog_hide(wog_Window* wnd);
-
-typedef void(*wog_Callback)(wog_Window* wnd) ;
-
-/**
-* Register callback functions.
-*/
-void wog_registerResizeCallback(wog_Callback cal);
-void wog_registerQuitCallback(wog_Callback cal);
-
-wog_Surface* wog_getsurface(wog_Window* wnd);
-
-void wog_setcursor(wog_Window* wnd, unsigned int cursor);
-//void wog_setcursorImage(wog_Window* wnd, const char* path);
-typedef HANDLE Wog_Cursor;
-void wog_setcursorImage(wog_Window* wnd, Wog_Cursor icon);
-
-void wog_setMouseCapture(wog_Window* wnd);
-void wog_releaseMouseCapture(wog_Window* wnd);
-
-HINSTANCE wog_get_instance();
-
-#endif \ No newline at end of file
diff --git a/Runtime/Math/FloatConversion.h b/Runtime/Math/FloatConversion.h
new file mode 100644
index 0000000..e5c0f23
--- /dev/null
+++ b/Runtime/Math/FloatConversion.h
@@ -0,0 +1,697 @@
+#ifndef FLOATCONVERSION_H
+#define FLOATCONVERSION_H
+
+#include <algorithm>
+#include <cmath>
+#include <limits>
+#include <math.h>
+
+#include "Runtime/Utilities/Type.h"
+#include "Runtime/Utilities/Assert.h"
+
+#if defined(SN_TARGET_PS3)
+# include <ppu_intrinsics.h>
+#elif defined(__GNUC__) && defined(__ppc__)
+# include <ppc_intrinsics.h>
+#endif
+
+#ifndef kPI
+#define kPI 3.14159265358979323846264338327950288419716939937510F
+#endif
+
+const float kBiggestFloatSmallerThanOne = 0.99999994f;
+const double kBiggestDoubleSmallerThanOne = 0.99999999999999989;
+
+#if defined(_XBOX)
+#define __FSELF __fself
+#elif defined(SN_TARGET_PS3)
+#define __FSELF __fsels
+#endif
+
+inline float FloatMin(float a, float b)
+{
+#if defined(_XBOX) || defined(SN_TARGET_PS3)
+ return __FSELF((a)-(b), b, a);
+#else
+ // return std::min(a, b);
+ return a < b ? a : b;
+#endif
+}
+
+inline float FloatMax(float a, float b)
+{
+#if defined(_XBOX) || defined(SN_TARGET_PS3)
+ return __FSELF((a)-(b), a, b);
+#else
+ //return std::max(a, b);
+ return a > b ? a : b;
+#endif
+}
+
+inline float Abs(float v)
+{
+#if defined(__ppc__) && (defined(__MWERKS__) || defined(SN_TARGET_PS3))
+ return __fabsf(v);
+#elif defined(_XBOX)
+ return __fabs(v);
+#else
+ return v < 0.0F ? -v : v;
+#endif
+}
+
+inline double Abs(double v)
+{
+ return v < 0.0 ? -v : v;
+}
+
+inline int Abs(int v)
+{
+ return v < 0 ? -v : v;
+}
+
+// Floor, ceil and round functions.
+//
+// When changing or implementing these functions, make sure the tests in MathTest.cpp
+// still pass.
+//
+// Floor: rounds to the largest integer smaller than or equal to the input parameter.
+// Ceil: rounds to the smallest integer larger than or equal to the input parameter.
+// Round: rounds to the nearest integer. Ties (0.5) are rounded up to the smallest integer
+// larger than or equal to the input parameter.
+// Chop/truncate: use a normal integer cast.
+//
+// Windows:
+// Casts are as fast as a straight fistp on an SSE equipped CPU. This is by far the most common
+// scenario and will result in the best code for most users. fistp will use the rounding mode set
+// in the control register (round to nearest by default), and needs fiddling to work properly.
+// This actually makes code that attempt to use fistp slower than a cast.
+// Unless we want round to nearest, in which case fistp should be the best choice, right? But
+// it is not. The default rounding mode is round to nearest, but in case of a tie (0.5), round to
+// nearest even is used. Thus 0.5 is rounded down to 0, 1.5 is rounded up to 2.
+// Conclusion - fistp is useless without stupid fiddling around that actually makes is slower than
+// an SSE cast.
+//
+// OS X Intel:
+// Needs investigating
+//
+// OS X PowerPC:
+// Needs investigating
+//
+// Xbox 360:
+// Needs investigating
+//
+// PS3:
+// Needs investigating
+//
+// iPhone:
+// Needs investigating
+//
+// Android:
+// Needs investigating
+
+
+inline int FloorfToInt(float f)
+{
+ DebugAssertIf(f < INT_MIN || f > INT_MAX);
+ return f >= 0 ? (int)f : (int)(f - kBiggestFloatSmallerThanOne);
+}
+
+inline UInt32 FloorfToIntPos(float f)
+{
+ DebugAssertIf(f < 0 || f > UINT_MAX);
+ return (UInt32)f;
+}
+
+inline float Floorf(float f)
+{
+ // Use std::floor().
+ // We are interested in reliable functions that do not lose precision.
+ // Casting to int and back to float would not be helpful.
+ return floor(f);
+}
+
+inline double Floord(double f)
+{
+ // Use std::floor().
+ // We are interested in reliable functions that do not lose precision.
+ // Casting to int and back to float would not be helpful.
+ return floor(f);
+}
+
+
+inline int CeilfToInt(float f)
+{
+ DebugAssertIf(f < INT_MIN || f > INT_MAX);
+ return f >= 0 ? (int)(f + kBiggestFloatSmallerThanOne) : (int)(f);
+}
+
+inline UInt32 CeilfToIntPos(float f)
+{
+ DebugAssertIf(f < 0 || f > UINT_MAX);
+ return (UInt32)(f + kBiggestFloatSmallerThanOne);
+}
+
+inline float Ceilf(float f)
+{
+ // Use std::ceil().
+ // We are interested in reliable functions that do not lose precision.
+ // Casting to int and back to float would not be helpful.
+ return ceil(f);
+}
+
+inline double Ceild(double f)
+{
+ // Use std::ceil().
+ // We are interested in reliable functions that do not lose precision.
+ // Casting to int and back to float would not be helpful.
+ return ceil(f);
+}
+
+
+inline int RoundfToInt(float f)
+{
+ return FloorfToInt(f + 0.5F);
+}
+
+inline UInt32 RoundfToIntPos(float f)
+{
+ return FloorfToIntPos(f + 0.5F);
+}
+
+inline float Roundf(float f)
+{
+ return Floorf(f + 0.5F);
+}
+
+inline double Roundf(double f)
+{
+ return Floord(f + 0.5);
+}
+
+
+/// Fast conversion of float [0...1] to 0 ... 65535
+inline int NormalizedToWord(float f)
+{
+ f = FloatMax(f, 0.0F);
+ f = FloatMin(f, 1.0F);
+ return RoundfToIntPos(f * 65535.0f);
+}
+
+/// Fast conversion of float [0...1] to 0 ... 65535
+inline float WordToNormalized(int p)
+{
+ AssertIf(p < 0 || p > 65535);
+ return (float)p / 65535.0F;
+}
+
+/// Fast conversion of float [0...1] to 0 ... 255
+inline int NormalizedToByte(float f)
+{
+ f = FloatMax(f, 0.0F);
+ f = FloatMin(f, 1.0F);
+ return RoundfToIntPos(f * 255.0f);
+}
+
+/// Fast conversion of float [0...1] to 0 ... 255
+inline float ByteToNormalized(int p)
+{
+ AssertIf(p < 0 || p > 255);
+ return (float)p / 255.0F;
+}
+
+
+// Returns float remainder for t / length
+inline float Repeat(float t, float length)
+{
+ return t - Floorf(t / length) * length;
+}
+
+// Returns double remainder for t / length
+inline double RepeatD(double t, double length)
+{
+ return t - floor(t / length) * length;
+}
+
+// Returns relative angle on the interval (-pi, pi]
+inline float DeltaAngleRad(float current, float target)
+{
+ float delta = Repeat((target - current), 2 * kPI);
+ if (delta > kPI)
+ delta -= 2 * kPI;
+ return delta;
+}
+
+// Returns true if the distance between f0 and f1 is smaller than epsilon
+inline bool CompareApproximately(float f0, float f1, float epsilon = 0.000001F)
+{
+ float dist = (f0 - f1);
+ dist = Abs(dist);
+ return dist < epsilon;
+}
+
+/// CopySignf () returns x with its sign changed to y's.
+inline float CopySignf(float x, float y)
+{
+ union
+ {
+ float f;
+ UInt32 i;
+ } u, u0, u1;
+ u0.f = x; u1.f = y;
+ UInt32 a = u0.i;
+ UInt32 b = u1.i;
+ SInt32 mask = 1 << 31;
+ UInt32 sign = b & mask;
+ a &= ~mask;
+ a |= sign;
+
+ u.i = a;
+ return u.f;
+}
+
+inline int CompareFloatRobustSignUtility(float A)
+{
+ // The sign bit of a number is the high bit.
+ union
+ {
+ float f;
+ int i;
+ } u;
+ u.f = A;
+ return (u.i) & 0x80000000;
+}
+
+inline bool CompareFloatRobust(float f0, float f1, int maxUlps = 10)
+{
+ // After adjusting floats so their representations are lexicographically
+ // ordered as twos-complement integers a very small positive number
+ // will compare as 'close' to a very small negative number. If this is
+ // not desireable, and if you are on a platform that supports
+ // subnormals (which is the only place the problem can show up) then
+ // you need this check.
+ // The check for A == B is because zero and negative zero have different
+ // signs but are equal to each other.
+ if (CompareFloatRobustSignUtility(f0) != CompareFloatRobustSignUtility(f1))
+ return f0 == f1;
+
+ union
+ {
+ float f;
+ int i;
+ } u0, u1;
+ u0.f = f0;
+ u1.f = f1;
+ int aInt = u0.i;
+ // Make aInt lexicographically ordered as a twos-complement int
+ if (aInt < 0)
+ aInt = 0x80000000 - aInt;
+ // Make bInt lexicographically ordered as a twos-complement int
+ int bInt = u1.i;
+ if (bInt < 0)
+ bInt = 0x80000000 - bInt;
+
+ // Now we can compare aInt and bInt to find out how far apart A and B
+ // are.
+ int intDiff = Abs(aInt - bInt);
+ if (intDiff <= maxUlps)
+ return true;
+ return false;
+}
+
+// Returns the t^2
+template<class T>
+T Sqr(const T& t)
+{
+ return t * t;
+}
+
+#define kDeg2Rad (2.0F * kPI / 360.0F)
+#define kRad2Deg (1.F / kDeg2Rad)
+
+inline float Deg2Rad(float deg)
+{
+ // TODO : should be deg * kDeg2Rad, but can't be changed,
+ // because it changes the order of operations and that affects a replay in some RegressionTests
+ return deg / 360.0F * 2.0F * kPI;
+}
+
+inline float Rad2Deg(float rad)
+{
+ // TODO : should be rad * kRad2Deg, but can't be changed,
+ // because it changes the order of operations and that affects a replay in some RegressionTests
+ return rad / 2.0F / kPI * 360.0F;
+}
+
+inline float Lerp(float from, float to, float t)
+{
+ return to * t + from * (1.0F - t);
+}
+
+inline bool IsNAN(float value)
+{
+#if defined __APPLE_CC__
+ return value != value;
+#elif _MSC_VER
+ return _isnan(value) != 0;
+#else
+ return isnan(value);
+#endif
+}
+
+inline bool IsNAN(double value)
+{
+#if defined __APPLE_CC__
+ return value != value;
+#elif _MSC_VER
+ return _isnan(value) != 0;
+#else
+ return isnan(value);
+#endif
+}
+
+inline bool IsPlusInf(float value) { return value == std::numeric_limits<float>::infinity(); }
+inline bool IsMinusInf(float value) { return value == -std::numeric_limits<float>::infinity(); }
+
+inline bool IsFinite(const float& value)
+{
+ // Returns false if value is NaN or +/- infinity
+ UInt32 intval = *reinterpret_cast<const UInt32*>(&value);
+ return (intval & 0x7f800000) != 0x7f800000;
+}
+
+inline bool IsFinite(const double& value)
+{
+ // Returns false if value is NaN or +/- infinity
+ UInt64 intval = *reinterpret_cast<const UInt64*>(&value);
+ return (intval & 0x7ff0000000000000LL) != 0x7ff0000000000000LL;
+}
+
+inline float InvSqrt(float p) { return 1.0F / sqrt(p); }
+inline float Sqrt(float p) { return sqrt(p); }
+
+/// - Almost highest precision sqrt
+/// - Returns 0 if value is 0 or -1
+/// inline float FastSqrt (float value)
+
+/// - Almost highest precision inv sqrt
+/// - if value == 0 or -0 it returns 0.
+/// inline float FastInvSqrt (float value)
+
+/// - Low precision inv sqrt approximately
+/// - if value == 0 or -0 it returns nan or undefined
+/// inline float FastestInvSqrt (float value)
+
+#if defined(__ppc__) || defined(SN_TARGET_PS3)
+
+#if UNITY_WII
+// Copied from <CodeWarrior>\PowerPC_EABI_Support\MSL\MSL_C\PPC_EABI\Include\math_ppc_inlines.h
+// Requires hardware floating to be enabled
+// P.S I've also profiled with function below which uses fabs(x) == 0.0F, it's two times slower than this one
+inline float FastSqrt(float x)
+{
+ static const double _half = .5f;
+ static const double _three = 3.0f;
+
+ if (x > 0.0f)
+ {
+ double xd = (double)x;
+ double guess = __frsqrte(xd); /* returns an approximation to */
+ guess = _half * guess*(_three - guess * guess*xd); /* now have 12 sig bits */
+ guess = _half * guess*(_three - guess * guess*xd); /* now have 24 sig bits */
+ return (float)(xd * guess);
+ }
+ else if (x < 0.0)
+ return NAN;
+ else
+ return x;
+}
+#else
+/// - Accurate to 1 bit precision
+/// - returns zero if x is zero
+inline float FastSqrt(float x)
+{
+ const float half = 0.5;
+ const float one = 1.0;
+ float B, y0, y1;
+
+ // This'll NaN if it hits frsqrte. Handle both +0.0 and -0.0
+ if (fabs(x) == 0.0F)
+ return x;
+
+ B = x;
+
+#if defined(__GNUC__) && !defined(SN_TARGET_PS3)
+ y0 = __frsqrtes(B);
+#else
+ y0 = __frsqrte(B);
+#endif
+ // First refinement step
+
+ y1 = y0 + half * y0*(one - B * y0*y0);
+
+ // Second refinement step -- copy the output of the last step to the input of this step
+
+ y0 = y1;
+ y1 = y0 + half * y0*(one - B * y0*y0);
+
+ // Get sqrt(x) from x * 1/sqrt(x)
+ return x * y1;
+}
+#endif
+
+/// - Accurate to 1 bit precision
+/// - returns zero if f is zero
+inline float FastInvSqrt(float f)
+{
+ float result;
+ float estimate, estimate2;
+ float oneHalf = 0.5f;
+ float one = oneHalf + oneHalf;
+ //Calculate a 5 bit starting estimate for the reciprocal sqrt
+#if defined(__GNUC__) && !defined(SN_TARGET_PS3)
+ estimate = estimate2 = __frsqrtes(f);
+#else
+ estimate = estimate2 = __frsqrte(f);
+#endif
+
+ //if you require less precision, you may reduce the number of loop iterations
+ estimate = estimate + oneHalf * estimate * (one - f * estimate * estimate);
+ estimate = estimate + oneHalf * estimate * (one - f * estimate * estimate);
+
+#if defined(__GNUC__) && !defined(SN_TARGET_PS3)
+ result = __fsels(-f, estimate2, estimate);
+#else
+ result = __fsel(-f, estimate2, estimate);
+#endif
+ return result;
+}
+
+/// Fast inverse sqrt function
+inline float FastestInvSqrt(float value)
+{
+#if defined (__ppc__) && (defined (__MWERKS__) || defined(SN_TARGET_PS3))
+ return (float)__frsqrte(value);
+#elif defined (__ppc__)
+ return (float)__frsqrtes(value);
+#else
+ return 1.0F / sqrtf(value);
+#endif
+}
+
+#else
+
+inline float FastSqrt(float value)
+{
+ return sqrtf(value);
+}
+
+inline float FastInvSqrt(float f)
+{
+ // The Newton iteration trick used in FastestInvSqrt is a bit faster on
+ // Pentium4 / Windows, but lower precision. Doing two iterations is precise enough,
+ // but actually a bit slower.
+ if (fabs(f) == 0.0F)
+ return f;
+ return 1.0F / sqrtf(f);
+}
+
+inline float FastestInvSqrt(float f)
+{
+ union
+ {
+ float f;
+ int i;
+ } u;
+ float fhalf = 0.5f*f;
+ u.f = f;
+ int i = u.i;
+ i = 0x5f3759df - (i >> 1);
+ u.i = i;
+ f = u.f;
+ f = f * (1.5f - fhalf * f*f);
+ // f = f*(1.5f - fhalf*f*f); // uncommenting this would be two iterations
+ return f;
+}
+
+#endif
+
+inline float SqrtImpl(float f)
+{
+#if UNITY_WII || UNITY_FLASH
+ return FastSqrt(f);
+#else
+ return sqrt(f);
+#endif
+}
+inline float Sin(float f)
+{
+ return sinf(f);
+}
+
+inline float Pow(float f, float f2)
+{
+ return powf(f, f2);
+}
+
+inline float Cos(float f)
+{
+ return cosf(f);
+}
+
+inline float Sign(float f)
+{
+#if defined(_XBOX)
+ return __fsel(f, 1.0f, -1.0f);
+#else
+ if (f < 0.0F)
+ return -1.0F;
+ else
+ return 1.0;
+#endif
+}
+
+#if UNITY_EDITOR
+
+class FloatToHalfConverter
+{
+public:
+ FloatToHalfConverter();
+
+ void Convert(const float& src, UInt16& dest)
+ {
+ UInt32 bits = *reinterpret_cast<const UInt32*>(&src);
+ UInt8 index = UInt8(bits >> 23);
+ UInt32 sign = bits & 0x80000000;
+ UInt32 mantissa = bits & 0x007fffff;
+ dest = (sign >> 16) | m_ExponentTable[index] | (mantissa >> m_MantissaShift[index]);
+ }
+
+private:
+ UInt16 m_ExponentTable[256];
+ UInt8 m_MantissaShift[256];
+};
+
+extern FloatToHalfConverter g_FloatToHalf;
+
+#endif // UNITY_EDITOR
+
+#if UNITY_SUPPORTS_SSE
+#include "Runtime/Math/Simd/SimdMath.h"
+
+#define SSE_CONST4(name, val) static const ALIGN16 UInt32 name[4] = { (val), (val), (val), (val) }
+#define CONST_M128I(name) *(const __m128i *)&name
+
+static ALIGN16 UInt16 source[] = { 0,0,0,0,0,0,0,0 };
+static ALIGN16 float destination[] = { 0.0,0.0,0.0,0.0 };
+
+static void HalfToFloat(UInt16 src, float& dest)
+{
+ SSE_CONST4(mask_nosign, 0x7fff);
+ SSE_CONST4(smallest_normal, 0x0400);
+ SSE_CONST4(infinity, 0x7c00);
+ SSE_CONST4(expadjust_normal, (127 - 15) << 23);
+ SSE_CONST4(magic_denorm, 113 << 23);
+
+ source[0] = src;
+ __m128i in = _mm_loadu_si128(reinterpret_cast<const __m128i*>(source));
+ __m128i mnosign = CONST_M128I(mask_nosign);
+ __m128i eadjust = CONST_M128I(expadjust_normal);
+ __m128i smallest = CONST_M128I(smallest_normal);
+ __m128i infty = CONST_M128I(infinity);
+ __m128i expmant = _mm_and_si128(mnosign, in);
+ __m128i justsign = _mm_xor_si128(in, expmant);
+ __m128i b_notinfnan = _mm_cmpgt_epi32(infty, expmant);
+ __m128i b_isdenorm = _mm_cmpgt_epi32(smallest, expmant);
+ __m128i shifted = _mm_slli_epi32(expmant, 13);
+ __m128i adj_infnan = _mm_andnot_si128(b_notinfnan, eadjust);
+ __m128i adjusted = _mm_add_epi32(eadjust, shifted);
+ __m128i den1 = _mm_add_epi32(shifted, CONST_M128I(magic_denorm));
+ __m128i adjusted2 = _mm_add_epi32(adjusted, adj_infnan);
+ __m128 den2 = _mm_sub_ps(_mm_castsi128_ps(den1), *(const __m128 *)&magic_denorm);
+ __m128 adjusted3 = _mm_and_ps(den2, _mm_castsi128_ps(b_isdenorm));
+ __m128 adjusted4 = _mm_andnot_ps(_mm_castsi128_ps(b_isdenorm), _mm_castsi128_ps(adjusted2));
+ __m128 adjusted5 = _mm_or_ps(adjusted3, adjusted4);
+ __m128i sign = _mm_slli_epi32(justsign, 16);
+ __m128 out = _mm_or_ps(adjusted5, _mm_castsi128_ps(sign));
+ _mm_storeu_ps(destination, out);
+ dest = destination[0];
+#undef SSE_CONST4
+#undef CONST_M128I
+}
+
+#else
+
+static void HalfToFloat(UInt16 src, float& dest)
+{
+ // Integer alias
+ UInt32& bits = *reinterpret_cast<UInt32*>(&dest);
+
+ // Based on Fabian Giesen's public domain half_to_float_fast3
+ static const UInt32 magic = { 113 << 23 };
+ const float& magicFloat = *reinterpret_cast<const float*>(&magic);
+ static const UInt32 shiftedExp = 0x7c00 << 13; // exponent mask after shift
+
+ // Mask out sign bit
+ bits = src & 0x7fff;
+ if (bits)
+ {
+ // Move exponent + mantissa to correct bits
+ bits <<= 13;
+ UInt32 exponent = bits & shiftedExp;
+ if (exponent == 0)
+ {
+ // Handle denormal
+ bits += magic;
+ dest -= magicFloat;
+ }
+ else if (exponent == shiftedExp) // Inf/NaN
+ bits += (255 - 31) << 23;
+ else
+ bits += (127 - 15) << 23;
+ }
+
+ // Copy sign bit
+ bits |= (src & 0x8000) << 16;
+}
+
+#endif
+
+using std::cos;
+using std::pow;
+using std::atan2;
+using std::acos;
+using std::sin;
+using std::sqrt;
+using std::log;
+using std::exp;
+
+// On non-C99 platforms log2 is not available, so approximate it.
+#if UNITY_WIN || UNITY_XENON || UNITY_ANDROID || UNITY_FLASH || UNITY_WEBGL
+#define kNaturalLogarithm2 0.693147180559945309417
+#define Log2(x) (logf(x) / kNaturalLogarithm2)
+#else
+#define Log2(x) log2f(x)
+#endif
+
+
+#endif
diff --git a/Runtime/Math/Rect.h b/Runtime/Math/Rect.h
new file mode 100644
index 0000000..3b4f16c
--- /dev/null
+++ b/Runtime/Math/Rect.h
@@ -0,0 +1,150 @@
+#ifndef RECT_H
+#define RECT_H
+
+#include "Vector2.h"
+
+/// A rectangle.
+template <typename T>
+class RectT
+{
+public:
+ typedef RectT<T> RectType;
+ typedef float BaseType;
+
+ T x; ///< Rectangle x coordinate.
+ T y; ///< Rectangle y coordinate.
+ T width; ///< Rectangle width.
+ T height; ///< Rectangle height.
+
+ inline static const char* GetTypeString();
+ inline static bool IsAnimationChannel() { return false; }
+ inline static bool MightContainPPtr() { return false; }
+ /// Create a empty rectangle.
+ RectT()
+ {
+ Reset();
+ }
+
+ /// Create a new rectangle.
+ RectT(T inX, T inY, T iWidth, T iHeight)
+ {
+ x = inX; width = iWidth;
+ y = inY; height = iHeight;
+ }
+
+ T GetRight() const { return x + width; }
+ T GetBottom() const { return y + height; }
+ void SetLeft(T l) { T oldXMax = GetXMax(); x = l; width = oldXMax - x; }
+ void SetTop(T t) { T oldYMax = GetYMax(); y = t; height = oldYMax - y; }
+ void SetRight(T r) { width = r - x; }
+ void SetBottom(T b) { height = b - y; }
+
+
+ T GetXMax() const { return x + width; }
+ T GetYMax() const { return y + height; }
+
+ /// Return true if rectangle is empty.
+ inline bool IsEmpty() const { return width <= 0 || height <= 0; }
+
+ inline void SetPosition(const Vector2f& position) { x = position.x; y = position.y; }
+ inline Vector2f GetPosition() const { return Vector2f(x, y); }
+
+ inline void SetSize(const Vector2f& size) { width = size.x; height = size.y; }
+ inline Vector2f GetSize() const { return Vector2f(width, height); }
+ /// Resets the rectangle
+ inline void Reset() { x = y = width = height = 0; }
+
+ /// Sets the rectangle
+ inline void Set(T inX, T inY, T iWidth, T iHeight)
+ {
+ x = inX; width = iWidth;
+ y = inY; height = iHeight;
+ }
+
+ inline void Scale(T dx, T dy) { x *= dx; width *= dx; y *= dy; height *= dy; }
+
+ /// Set Center position of rectangle (size stays the same)
+ void SetCenterPos(T cx, T cy) { x = cx - width / 2; y = cy - height / 2; }
+ Vector2f GetCenterPos() const { return Vector2f(x + (BaseType)width / 2, y + (BaseType)height / 2); }
+
+ /// Ensure this is inside the rect r.
+ void Clamp(const RectType &r)
+ {
+ T x2 = x + width;
+ T y2 = y + height;
+ T rx2 = r.x + r.width;
+ T ry2 = r.y + r.height;
+
+ if (x < r.x) x = r.x;
+ if (x2 > rx2) x2 = rx2;
+ if (y < r.y) y = r.y;
+ if (y2 > ry2) y2 = ry2;
+
+ width = x2 - x;
+ if (width < 0) width = 0;
+
+ height = y2 - y;
+ if (height < 0) height = 0;
+ }
+
+ /// Move rectangle by deltaX, deltaY.
+ inline void Move(T dX, T dY) { x += dX; y += dY; }
+
+ /// Return the width of rectangle.
+ inline T Width() const { return width; }
+
+ /// Return the height of rectangle.
+ inline T Height() const { return height; }
+
+ /// Return true if a point lies within rectangle bounds.
+ inline bool Contains(T px, T py) const { return (px >= x) && (px < x + width) && (py >= y) && (py < y + height); }
+ inline bool Contains(const Vector2f& p) const { return Contains(p.x, p.y); }
+ /// Return true if a relative point lies within rectangle bounds.
+ inline bool ContainsRel(T x, T y) const
+ {
+ return (x >= 0) && (x < Width()) && (y >= 0) && (y < Height());
+ }
+
+ inline bool Intersects(const RectType& r) const
+ {
+ // Rects are disjoint if there's at least one separating axis
+ bool disjoint = x + width < r.x;
+ disjoint |= r.x + r.width < x;
+ disjoint |= y + height < r.y;
+ disjoint |= r.y + r.height < y;
+ return !disjoint;
+ }
+
+ /// Normalize a rectangle such that xmin <= xmax and ymin <= ymax.
+ inline void Normalize()
+ {
+ width = std::max<T>(width, 0);
+ height = std::max<T>(height, 0);
+ }
+
+ bool operator == (const RectType& r)const { return x == r.x && y == r.y && width == r.width && height == r.height; }
+ bool operator != (const RectType& r)const { return x != r.x || y != r.y || width != r.width || height != r.height; }
+};
+
+typedef RectT<float> Rectf;
+typedef RectT<int> RectInt;
+
+template<> inline const char* Rectf::GetTypeString() { return "Rectf"; }
+template<> inline const char* RectInt::GetTypeString() { return "RectInt"; }
+
+inline bool CompareApproximately(const Rectf& lhs, const Rectf& rhs)
+{
+ return CompareApproximately(lhs.x, rhs.x) && CompareApproximately(lhs.y, rhs.y) &&
+ CompareApproximately(lhs.width, rhs.width) && CompareApproximately(lhs.height, rhs.height);
+}
+
+/// Make a rect with width & height
+template<typename T>
+inline RectT<T> MinMaxRect(T minx, T miny, T maxx, T maxy) { return RectT<T>(minx, miny, maxx - minx, maxy - miny); }
+
+// RectT<float> specialization
+template<>
+inline bool Rectf::IsEmpty() const { return width <= 0.00001F || height <= 0.00001F; }
+
+
+#endif
diff --git a/Runtime/Math/Vector2.cpp b/Runtime/Math/Vector2.cpp
index e69de29..e636362 100644
--- a/Runtime/Math/Vector2.cpp
+++ b/Runtime/Math/Vector2.cpp
@@ -0,0 +1,11 @@
+#include "Vector2.h"
+
+using namespace std;
+
+const float Vector2f::epsilon = 0.00001F;
+const float Vector2f::infinity = numeric_limits<float>::infinity();
+const Vector2f Vector2f::infinityVec = Vector2f(numeric_limits<float>::infinity(), numeric_limits<float>::infinity());
+
+const Vector2f Vector2f::zero = Vector2f(0, 0);
+const Vector2f Vector2f::xAxis = Vector2f(1, 0);
+const Vector2f Vector2f::yAxis = Vector2f(0, 1);
diff --git a/Runtime/Math/Vector2.h b/Runtime/Math/Vector2.h
index 7bf3987..01fa015 100644
--- a/Runtime/Math/Vector2.h
+++ b/Runtime/Math/Vector2.h
@@ -1,17 +1,112 @@
#ifndef VECTOR2_H
#define VECTOR2_H
-class Vector2
+#include "FloatConversion.h"
+
+class Vector2f
{
-public:
- float x, y;
+public:
+ float x, y;
+
+
+ Vector2f() : x(0.f), y(0.f) {}
+ Vector2f(float inX, float inY) { x = inX; y = inY; }
+ explicit Vector2f(const float* p) { x = p[0]; y = p[1]; }
+
+ void Set(float inX, float inY) { x = inX; y = inY; }
+
+ float* GetPtr() { return &x; }
+ const float* GetPtr()const { return &x; }
+ float& operator[] (int i) { DebugAssertIf(i < 0 || i > 1); return (&x)[i]; }
+ const float& operator[] (int i)const { DebugAssertIf(i < 0 || i > 1); return (&x)[i]; }
- inline void Set(float x, float y)
- {
- this->x = x;
- this->y = y;
- }
+ Vector2f& operator += (const Vector2f& inV) { x += inV.x; y += inV.y; return *this; }
+ Vector2f& operator -= (const Vector2f& inV) { x -= inV.x; y -= inV.y; return *this; }
+ Vector2f& operator *= (const float s) { x *= s; y *= s; return *this; }
+ Vector2f& operator /= (const float s) { DebugAssertIf(CompareApproximately(s, 0.0F)); x /= s; y /= s; return *this; }
+ bool operator == (const Vector2f& v)const { return x == v.x && y == v.y; }
+ bool operator != (const Vector2f& v)const { return x != v.x || y != v.y; }
+
+ Vector2f operator - () const { return Vector2f(-x, -y); }
+
+ Vector2f& Scale(const Vector2f& inV) { x *= inV.x; y *= inV.y; return *this; }
+
+ static const float epsilon;
+ static const float infinity;
+ static const Vector2f infinityVec;
+ static const Vector2f zero;
+ static const Vector2f xAxis;
+ static const Vector2f yAxis;
};
+//inline Vector2f Scale(const Vector2f& lhs, const Vector2f& rhs) { return Vector2f(lhs.x * rhs.x, lhs.y * rhs.y); }
+//
+//inline Vector2f operator + (const Vector2f& lhs, const Vector2f& rhs) { return Vector2f(lhs.x + rhs.x, lhs.y + rhs.y); }
+//inline Vector2f operator - (const Vector2f& lhs, const Vector2f& rhs) { return Vector2f(lhs.x - rhs.x, lhs.y - rhs.y); }
+//inline float Dot(const Vector2f& lhs, const Vector2f& rhs) { return lhs.x * rhs.x + lhs.y * rhs.y; }
+//
+//inline float SqrMagnitude(const Vector2f& inV) { return Dot(inV, inV); }
+//inline float Magnitude(const Vector2f& inV) { return SqrtImpl(Dot(inV, inV)); }
+//
+//inline float Angle(const Vector2f& lhs, const Vector2f& rhs) { return acos(std::min(1.0f, std::max(-1.0f, Dot(lhs, rhs) / (Magnitude(lhs) * Magnitude(rhs))))); }
+//
+//inline Vector2f operator * (const Vector2f& inV, float s) { return Vector2f(inV.x * s, inV.y * s); }
+//inline Vector2f operator * (const float s, const Vector2f& inV) { return Vector2f(inV.x * s, inV.y * s); }
+//inline Vector2f operator / (const Vector2f& inV, float s) { Vector2f temp(inV); temp /= s; return temp; }
+//inline Vector2f Inverse(const Vector2f& inVec) { return Vector2f(1.0F / inVec.x, 1.0F / inVec.y); }
+//
+//// Normalizes a vector, asserts if the vector can be normalized
+//inline Vector2f Normalize(const Vector2f& inV) { return inV / Magnitude(inV); }
+//// Normalizes a vector, returns default vector if it can't be normalized
+//inline Vector2f NormalizeSafe(const Vector2f& inV, const Vector2f& defaultV = Vector2f::zero);
+//
+//inline Vector2f Lerp(const Vector2f& from, const Vector2f& to, float t) { return to * t + from * (1.0f - t); }
+//
+//// Returns a vector with the smaller of every component from v0 and v1
+//inline Vector2f min(const Vector2f& lhs, const Vector2f& rhs) { return Vector2f(std::min(lhs.x, rhs.x), std::min(lhs.y, rhs.y)); }
+//// Returns a vector with the larger of every component from v0 and v1
+//inline Vector2f max(const Vector2f& lhs, const Vector2f& rhs) { return Vector2f(std::max(lhs.x, rhs.x), std::max(lhs.y, rhs.y)); }
+//
+//bool CompareApproximately(const Vector2f& inV0, const Vector2f& inV1, float inMaxDist = Vector2f::epsilon);
+//
+//inline bool CompareApproximately(const Vector2f& inV0, const Vector2f& inV1, float inMaxDist)
+//{
+// return SqrMagnitude(inV1 - inV0) < inMaxDist * inMaxDist;
+//}
+//
+//inline bool IsNormalized(const Vector2f& vec, float epsilon = Vector2f::epsilon)
+//{
+// return CompareApproximately(SqrMagnitude(vec), 1.0F, epsilon);
+//}
+//
+///// Returns the abs of every component of the vector
+//inline Vector2f Abs(const Vector2f& v) { return Vector2f(Abs(v.x), Abs(v.y)); }
+//
+//inline bool IsFinite(const Vector2f& f)
+//{
+// return IsFinite(f.x) & IsFinite(f.y);
+//}
+//
+//inline Vector2f NormalizeFast(const Vector2f& inV)
+//{
+// float m = SqrMagnitude(inV);
+// // GCC version of __frsqrte:
+// // static inline double __frsqrte (double x) {
+// // double y;
+// // asm ( "frsqrte %0, %1" : /*OUT*/ "=f" (y) : /*IN*/ "f" (x) );
+// // return y;
+// // }
+// return inV * FastInvSqrt(m);
+//}
+//
+//inline Vector2f NormalizeSafe(const Vector2f& inV, const Vector2f& defaultV)
+//{
+// float mag = Magnitude(inV);
+// if (mag > Vector2f::epsilon)
+// return inV / Magnitude(inV);
+// else
+// return defaultV;
+//}
+
#endif \ No newline at end of file
diff --git a/Runtime/main.cpp b/Runtime/main.cpp
deleted file mode 100644
index 8e8dba0..0000000
--- a/Runtime/main.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "SDL2/SDL.h"
-
-int main(int argn, char* args[])
-{
- return 0;
-}