void RegisterCVar(std::string name, int* variableAddr) {
this->cVarBook.insert({ name, variableAddr });
- std::cout << "Registered CVAR: " << name << " at address: 0x" <<std::hex << variableAddr << std::endl;
+ //std::cout << "Registered CVAR: " << name << " at address: 0x" <<std::hex << variableAddr << std::endl;
}
void RegisterCmd(std::string name, void* addr) {
this->cCmdBook.insert({ name, addr });
- std::cout << "Registered CCMD: " << name << " at address: 0x" << std::hex << addr << std::endl;
+ //std::cout << "Registered CCMD: " << name << " at address: 0x" << std::hex << addr << std::endl;
}
void CallCmd(std::string name) {
<None Include="depth.vs" />
<None Include="lit.fs" />
<None Include="lit.vs" />
+ <None Include="main.cpp.backup.temp" />
+ <None Include="shaders\worldgrid.fs" />
+ <None Include="shaders\worldgrid.vs" />
<None Include="textfont.fs" />
<None Include="textfont.vs" />
<None Include="unlit.fs" />
<None Include="textfont.fs">
<Filter>OpenGL\Shader Files</Filter>
</None>
+ <None Include="shaders\worldgrid.fs">
+ <Filter>OpenGL\Shader Files</Filter>
+ </None>
+ <None Include="shaders\worldgrid.vs">
+ <Filter>OpenGL\Shader Files</Filter>
+ </None>
+ <None Include="main.cpp.backup.temp">
+ <Filter>Source Files</Filter>
+ </None>
</ItemGroup>
<ItemGroup>
<Image Include="dina-r.png">
#include <glm\gtc\matrix_transform.hpp>
#include <glm\gtc\type_ptr.hpp>
+enum MeshMode {
+ POS_XYZ_TEXCOORD_UV
+};
+
class Mesh {
int elementCount;
glBindBuffer(GL_ARRAY_BUFFER, this->VBO);
}
+ Mesh(std::vector<float> vertices, MeshMode mode) {
+ if (vertices.size() <= 0)
+ return;
+
+ if (mode == MeshMode::POS_XYZ_TEXCOORD_UV) {
+ this->vertices = vertices;
+ this->elementCount = vertices.size() / 5;
+
+ // first, configure the cube's VAO (and VBO)
+ glGenVertexArrays(1, &this->VAO);
+ glGenBuffers(1, &this->VBO);
+
+ glBindBuffer(GL_ARRAY_BUFFER, this->VBO);
+ glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], GL_STATIC_DRAW);
+
+ glBindVertexArray(this->VAO);
+
+ // position attribute
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
+ glEnableVertexAttribArray(0);
+
+ //UV Coords
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
+ glEnableVertexAttribArray(1);
+ }
+ }
+
Mesh(std::vector<float> vertices) {
if (vertices.size() <= 0)
return;
glDeleteBuffers(1, &this->VBO);
}
+
std::vector<float> verts;
float current_x = 0;
{
float height = (Depth - HEIGHT_MIN) / HEIGHT_MAX;
- FragColor = vec4(height, height, height, Alpha);
+ FragColor = vec4(height, height, height, 1.0);
}
\ No newline at end of file
+const char* MCDV_VERSION = "1.5.3";
+
#include <glad\glad.h>
#include <GLFW\glfw3.h>
#include <iostream>
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
+inline void opengl_render_opaque() {
+ glDisable(GL_BLEND);
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_TRUE);
+}
+inline void opengl_render_additive() {
+ glDepthMask(GL_TRUE);
+ glEnable(GL_BLEND);
+
+ // I still do not fully understand OPENGL blend modes. However these equations looks nice for the grid floor.
+ glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
+ glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ZERO, GL_ONE);
+}
+
+#define SOURCE_OGL_SCALEFACTOR 0.01f
+
int window_width = 1024;
int window_height = 1024;
// Some windows stuff
#ifdef WIN32
+void _ccmd_open_generic_win() {
+ OPENFILENAME ofn; // common dialog box structure
+ char szFile[260]; // buffer for file name
+ //HWND hwnd; // owner window
+ HANDLE hf; // file handle
+ // Initialize OPENFILENAME
+ ZeroMemory(&ofn, sizeof(ofn));
+ ofn.lStructSize = sizeof(ofn);
+ //ofn.hwndOwner = hwnd;
+ ofn.lpstrFile = szFile;
+ // Set lpstrFile[0] to '\0' so that GetOpenFileName does not
+ // use the contents of szFile to initialize itself.
+ ofn.lpstrFile[0] = '\0';
+ ofn.nMaxFile = sizeof(szFile);
+ ofn.lpstrFilter = "Map Files (*.nav;*.bsp)\0*.NAV;*.BSP\0Nav Mesh\0*.NAV\0BSP file\0*.BSP\0";
+ ofn.nFilterIndex = 1;
+ ofn.lpstrFileTitle = NULL;
+ ofn.nMaxFileTitle = 0;
+ ofn.lpstrInitialDir = NULL;
+ ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
+
+ // Display the Open dialog box.
+
+ if (GetOpenFileName(&ofn) == TRUE) {
+
+ if (split(ofn.lpstrFile, '.').back() == "bsp") {
+ vbsp_level bsp_map(ofn.lpstrFile, true);
+ mesh_map_bsp = new Mesh(bsp_map.generate_bigmesh());
+ std::cout << "Opening BSP file" << std::endl;
+ }
+
+ if (split(ofn.lpstrFile, '.').back() == "nav") {
+ Nav::Mesh bob(ofn.lpstrFile);
+ mesh_map_nav = new Mesh(bob.generateGLMesh());
+ std::cout << "Opening NAV mesh file" << std::endl;
+ }
+ }
+ else {
+ console.FeedBack("Couldn't read file. (getopenfilename)", MSG_STATUS::ERR);
+ mesh_map_nav = NULL;
+ }
+}
+
void _ccmd_open_nav_win() {
OPENFILENAME ofn; // common dialog box structure
char szFile[260]; // buffer for file name
Nav::Mesh bob(ofn.lpstrFile);
//mesh_map_nav->~Mesh(); //Destroy old mesh
mesh_map_nav = new Mesh(bob.generateGLMesh());
-
+
}
else {
console.FeedBack("Couldn't read file. (getopenfilename)");
//Mesh handling -----------------------------------------------------------------------------
- if (_filesrc_bsp != "none"){
+ if (_filesrc_bsp != "none") {
vbsp_level bsp_map(_filesrc_bsp, true);
mesh_map_bsp = new Mesh(bsp_map.generate_bigmesh());
}
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
+ float _gs = 4096.0f;
+ float _uvs = 8.0f;
+
+ // World Grid
+ Mesh* world_grid_mesh = new Mesh(std::vector<float>{
+ -(_gs * SOURCE_OGL_SCALEFACTOR), -0.0025f, -(_gs * SOURCE_OGL_SCALEFACTOR), -_uvs, -_uvs,
+ -(_gs * SOURCE_OGL_SCALEFACTOR), -0.0025f, _gs * SOURCE_OGL_SCALEFACTOR, -_uvs, _uvs,
+ _gs * SOURCE_OGL_SCALEFACTOR, -0.0025f, -(_gs * SOURCE_OGL_SCALEFACTOR), _uvs, -_uvs,
+ -(_gs * SOURCE_OGL_SCALEFACTOR), -0.0025f, _gs * SOURCE_OGL_SCALEFACTOR, -_uvs, _uvs,
+ _gs * SOURCE_OGL_SCALEFACTOR, -0.0025f, _gs * SOURCE_OGL_SCALEFACTOR, _uvs, _uvs,
+ _gs * SOURCE_OGL_SCALEFACTOR, -0.0025f, -(_gs * SOURCE_OGL_SCALEFACTOR), _uvs, -_uvs
+ }, MeshMode::POS_XYZ_TEXCOORD_UV);
+
+ Mesh* world_grid_mesh_t = new Mesh(std::vector<float>{
+ -2.560f, -2.560f, 0.0f, -1.0f, -1.0f, 0.0f,
+ -2.560f, 2.560f, 0.0f, -1.0f, 1.0f, 0.0f,
+ 2.560f, -2.560f, 0.0f, 1.0f, -1.0f, 0.0f,
+ -2.560f, 2.560f, 0.0f, -1.0f, 1.0f, 0.0f,
+ 2.560f, 2.560f, 0.0f, 1.0f, 1.0f, 0.0f,
+ 2.560f, -2.560f, 0.0f, 1.0f, -1.0f, 0.0f
+ });
+
+ Texture world_grid_mesh_texture("textures/grid.png");
+
+ Shader world_grid_shader("shaders/worldgrid.vs", "shaders/worldgrid.fs");
+
TextFont::init(); //Setup textfonts before we use it
/*
- ui_text_info = new TextFont("Hello World!");
- ui_text_info->size = glm::vec2(1.0f / window_width, 1.0f / window_height) * 2.0f;
- ui_text_info->alpha = 1.0f;
- ui_text_info->color = glm::vec3(0.75f, 0.75f, 0.75f);
- ui_text_info->screenPosition = glm::vec2(0, (1.0f / window_height) * 15.0f); */
-
-
+ ui_text_info = new TextFont("Hello World!");
+ ui_text_info->size = glm::vec2(1.0f / window_width, 1.0f / window_height) * 2.0f;
+ ui_text_info->alpha = 1.0f;
+ ui_text_info->color = glm::vec3(0.75f, 0.75f, 0.75f);
+ ui_text_info->screenPosition = glm::vec2(0, (1.0f / window_height) * 15.0f); */
+
+
ui_text_loaded = new TextFont("Currently Loaded:\n " + std::string(_filesrc_bsp) + "\n " + std::string(_filesrc_nav));
ui_text_loaded->size = glm::vec2(1.0f / window_width, 1.0f / window_height) * 2.0f;
ui_text_loaded->alpha = 1.0f;
#ifdef WIN32
console.RegisterCmd("OPENNAV", &_ccmd_open_nav_win);
console.RegisterCmd("OPENBSP", &_ccmd_open_bsp_win);
+ console.RegisterCmd("OPEN", &_ccmd_open_generic_win);
#endif
//Help
//Thanks
console.RegisterCmd("THANKS", &_ccmd_thanks);
+ console.FeedBack(std::string("CSGO Heightmap - Version : ") + MCDV_VERSION, MSG_STATUS::THANKS);
//FrameBuffer t_frame_buffer = FrameBuffer();
//Input
processInput(window, keys);
- if(!console.isEnabled)
+ if (!console.isEnabled)
camera.handleInput(deltaTime);
console.handleKeysTick();
}
//Rendering commands
- glClearColor(0.05f, 0.05f, 0.2f, 1.0f);
+ glClearColor(0.05f, 0.05f, 0.05f, 1.0f);
- if(T_ARM_FOR_FB_RENDER) glClearColor(0.0f, 1.0f, 0.00f, 1.0f);
+ if (T_ARM_FOR_FB_RENDER) glClearColor(0.0f, 1.0f, 0.00f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPolygonMode(GL_FRONT, GL_FILL);
- glDisable(GL_BLEND);
- glEnable(GL_DEPTH_TEST);
- glDepthMask(1);
+
+ opengl_render_opaque();
shader_lit.use();
- if(SV_PERSPECTIVE == 0)
+ if (SV_PERSPECTIVE == 0)
shader_lit.setMatrix("projection", glm::perspective(glm::radians(90.0f / 2), (float)window_width / (float)window_height, (float)M_CLIP_NEAR * 0.01f, (float)M_CLIP_FAR * 0.01f));
else
shader_lit.setMatrix("projection", glm::ortho(-(float)M_ORTHO_SIZE, (float)M_ORTHO_SIZE, -(float)M_ORTHO_SIZE, (float)M_ORTHO_SIZE, (float)M_CLIP_NEAR * 0.01f, (float)M_CLIP_FAR * 0.01f));
shader_lit.setFloat("HEIGHT_MIN", (float)M_HEIGHT_MIN * 0.01f);
shader_lit.setFloat("HEIGHT_MAX", (float)M_HEIGHT_MAX * 0.01f);
-
+
if (SV_RENDERMODE == 0) {
glEnable(GL_CULL_FACE);
if (mesh_map_bsp != NULL)
mesh_map_bsp->Draw();
}
-
+
if (SV_RENDERMODE == 1) {
glDisable(GL_CULL_FACE);
if (mesh_map_nav != NULL)
mesh_map_nav->Draw();
}
+ //GRID
+
+ opengl_render_additive();
+
+ model = glm::mat4();
+ world_grid_shader.use();
+ if (SV_PERSPECTIVE == 0)
+ world_grid_shader.setMatrix("projection", glm::perspective(glm::radians(90.0f / 2), (float)window_width / (float)window_height, (float)M_CLIP_NEAR * 0.01f, (float)M_CLIP_FAR * 0.01f));
+ else
+ world_grid_shader.setMatrix("projection", glm::ortho(-(float)M_ORTHO_SIZE, (float)M_ORTHO_SIZE, -(float)M_ORTHO_SIZE, (float)M_ORTHO_SIZE, (float)M_CLIP_NEAR * 0.01f, (float)M_CLIP_FAR * 0.01f));
+ world_grid_shader.setMatrix("view", camera.getViewMatrix());
+ world_grid_shader.setMatrix("model", model);
+ world_grid_shader.setFloat("alpha", 0.44f);
+ world_grid_shader.setInt("text", 0);
+
+ world_grid_mesh_texture.bind();
+ glDisable(GL_CULL_FACE);
+ world_grid_mesh->Draw();
+
+ opengl_render_opaque();
if (!T_ARM_FOR_FB_RENDER) { // UI
update_globals_ui_text(ui_text_info); //Update globals
}
if (keys.getKeyDown(GLFW_KEY_2)) {
- SV_EDITMODE = 1;
+ SV_EDITMODE = 1;
update_globals_ui_text(ui_text_info); //Update globals
}
if (keys.getKeyDown(GLFW_KEY_3)) {
}
if (keys.getKeyDown(GLFW_KEY_5)) {
- SV_PERSPECTIVE = 0;
+ SV_PERSPECTIVE = 0;
update_globals_ui_text(ui_text_info); //Update globals
}
if (keys.getKeyDown(GLFW_KEY_6)) {
- SV_PERSPECTIVE = 1;
+ SV_PERSPECTIVE = 1;
update_globals_ui_text(ui_text_info); //Update globals
}
if (keys.getKeyDown(GLFW_KEY_7)) {
SV_RENDERMODE = 0;
update_globals_ui_text(ui_text_info); //Update globals
-
+
}
if (keys.getKeyDown(GLFW_KEY_8)) {
- SV_RENDERMODE = 1;
+ SV_RENDERMODE = 1;
update_globals_ui_text(ui_text_info); //Update globals
}
{
//camera.fov = glm::clamp(camera.fov + (float)yoffset, 2.0f, 90.0f);
- if(SV_EDITMODE == 0)
+ if (SV_EDITMODE == 0)
M_HEIGHT_MIN += (float)yoffset * 0.1f;
if (SV_EDITMODE == 1)
--- /dev/null
+#include <glad\glad.h>
+#include <GLFW\glfw3.h>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <vector>
+#include <direct.h>
+
+#include <regex>
+
+#include "GLFWUtil.hpp"
+
+#include "vbsp.hpp"
+#include "nav.hpp"
+#include "radar.hpp"
+#include "util.h"
+
+#include "Shader.hpp"
+#include "Texture.hpp"
+#include "Camera.hpp"
+#include "Mesh.hpp"
+#include "GameObject.hpp"
+#include "TextFont.hpp"
+#include "Console.hpp"
+#include "FrameBuffer.hpp"
+
+#include <glm\glm.hpp>
+#include <glm\gtc\matrix_transform.hpp>
+#include <glm\gtc\type_ptr.hpp>
+
+#ifdef WIN32
+#include <windows.h>
+#include <Commdlg.h>
+#endif
+
+void framebuffer_size_callback(GLFWwindow* window, int width, int height);
+void processInput(GLFWwindow* window, util_keyHandler keys);
+void mouse_callback(GLFWwindow* window, double xpos, double ypos);
+void mouse_button_callback(GLFWwindow* window, int button, int action, int mods);
+void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
+
+inline void opengl_render_opaque() {
+ glDisable(GL_BLEND);
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_TRUE);
+}
+inline void opengl_render_additive() {
+ //glDepthMask(GL_FALSE);
+ glDepthMask(true);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_COLOR, GL_DST_ALPHA);
+ glBlendEquation(GL_FUNC_ADD);
+}
+
+#define SOURCE_OGL_SCALEFACTOR 0.01f
+
+int window_width = 1024;
+int window_height = 1024;
+
+float deltaTime = 0.0f;
+float lastFrame = 0.0f;
+
+bool isClicking = false;
+
+double mousex = 0.0;
+double mousey = 0.0;
+
+Camera camera;
+Console console;
+
+int SV_WIREFRAME = 0; //0: off 1: overlay 2: only
+int SV_RENDERMODE = 0;
+int SV_PERSPECTIVE = 0;
+
+int M_HEIGHT_MIN = 0.0f;
+int M_HEIGHT_MAX = 10.0f * 100.0f;
+
+int M_CLIP_NEAR = 0.1f * 100.0f;
+int M_CLIP_FAR = 100.0f * 100.0f;
+
+int T_RENDER_RESOLUTION_X = 1024;
+int T_RENDER_RESOLUTION_Y = 1024;
+bool T_ARM_FOR_FB_RENDER = false;
+
+bool SV_DRAW_BSP = true;
+bool SV_DRAW_NAV = false;
+
+bool V_DO_QUIT = false;
+
+std::string _filesrc_bsp;
+std::string _filesrc_nav;
+
+Radar* _radar;
+
+Mesh* mesh_map_bsp = NULL;
+Mesh* mesh_map_nav = NULL;
+
+int M_ORTHO_SIZE = 20;
+
+// Runtime UI stuffz
+void update_globals_ui_text(TextFont* target); //Auto update the ui text
+TextFont* ui_text_info;
+TextFont* ui_text_loaded;
+
+//CCMDS
+void _ccmd_renderbsp() { SV_RENDERMODE = 0; }
+void _ccmd_rendernav() { SV_RENDERMODE = 1; }
+void _ccmd_exit() { V_DO_QUIT = true; }
+void _ccmd_perspective() { SV_PERSPECTIVE = 0; }
+void _ccmd_orthographic() { SV_PERSPECTIVE = 1; }
+void _ccmd_render_image() { T_ARM_FOR_FB_RENDER = true; }
+void _ccmd_reset_ang() { camera.pitch = -90; camera.yaw = 0; camera.mouseUpdate(0, 0, true); }
+
+// Some windows stuff
+#ifdef WIN32
+void _ccmd_open_nav_win() {
+ OPENFILENAME ofn; // common dialog box structure
+ char szFile[260]; // buffer for file name
+ //HWND hwnd; // owner window
+ HANDLE hf; // file handle
+ // Initialize OPENFILENAME
+ ZeroMemory(&ofn, sizeof(ofn));
+ ofn.lStructSize = sizeof(ofn);
+ //ofn.hwndOwner = hwnd;
+ ofn.lpstrFile = szFile;
+ // Set lpstrFile[0] to '\0' so that GetOpenFileName does not
+ // use the contents of szFile to initialize itself.
+ ofn.lpstrFile[0] = '\0';
+ ofn.nMaxFile = sizeof(szFile);
+ ofn.lpstrFilter = "Nav Mesh\0*.NAV\0";
+ ofn.nFilterIndex = 1;
+ ofn.lpstrFileTitle = NULL;
+ ofn.nMaxFileTitle = 0;
+ ofn.lpstrInitialDir = NULL;
+ ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
+
+ // Display the Open dialog box.
+
+ if (GetOpenFileName(&ofn) == TRUE) {
+
+ Nav::Mesh bob(ofn.lpstrFile);
+ //mesh_map_nav->~Mesh(); //Destroy old mesh
+ mesh_map_nav = new Mesh(bob.generateGLMesh());
+
+ }
+ else {
+ console.FeedBack("Couldn't read file. (getopenfilename)");
+ mesh_map_nav = NULL;
+ }
+}
+
+void _ccmd_open_bsp_win() {
+ OPENFILENAME ofn; // common dialog box structure
+ char szFile[260]; // buffer for file name
+ //HWND hwnd; // owner window
+ HANDLE hf; // file handle
+ // Initialize OPENFILENAME
+ ZeroMemory(&ofn, sizeof(ofn));
+ ofn.lStructSize = sizeof(ofn);
+ //ofn.hwndOwner = hwnd;
+ ofn.lpstrFile = szFile;
+ // Set lpstrFile[0] to '\0' so that GetOpenFileName does not
+ // use the contents of szFile to initialize itself.
+ ofn.lpstrFile[0] = '\0';
+ ofn.nMaxFile = sizeof(szFile);
+ ofn.lpstrFilter = "BSP file\0*.BSP\0";
+ ofn.nFilterIndex = 1;
+ ofn.lpstrFileTitle = NULL;
+ ofn.nMaxFileTitle = 0;
+ ofn.lpstrInitialDir = NULL;
+ ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
+
+ // Display the Open dialog box.
+
+ if (GetOpenFileName(&ofn) == TRUE) {
+
+ vbsp_level bsp_map(ofn.lpstrFile, true);
+ mesh_map_bsp = new Mesh(bsp_map.generate_bigmesh());
+
+ }
+ else {
+ console.FeedBack("Couldn't read file. (getopenfilename)");
+ mesh_map_bsp = NULL;
+ }
+}
+#endif
+
+void _ccmd_help() {
+ console.FeedBack(R"TERRI00(
+
+Controls:
+ WASD Fly
+ Click and drag Look around
+ ` or ~ key Open console
+
+Commands:
+ General:
+ QUIT / EXIT Closes (wow!)
+ NAV View nav mesh
+ BSP View bsp file
+ HELP Helps you out
+
+ Camera:
+ PERSPECTIVE / PERSP Switches to perspective view
+ ORTHOGRAPHIC / ORTHO Switches to orthographic view
+ OSIZE / SIZE <int> Changes the orthographic scale
+ LOOKDOWN Sets yaw to 0, pitch to -90
+
+ RENDER Renders the view to render.png
+
+ Variables:
+ RENDERMODE <int> Same as nav/bsp switch
+ PROJMATRIX <int> Same as persp/ortho
+
+ Variables (the actual height stuff):
+ MIN <int> Minimum levels of height (units)
+ MAX <int> Maximum levels of height (units)
+
+ FARZ <int> Far clip plane of the camera
+ NEARZ <int> Near clip plane of the camera
+)TERRI00", MSG_STATUS::SUCCESS);
+}
+
+void _ccmd_thanks() {
+ console.FeedBack(R"TERRI00(
+
+Thank you:
+ JamDoggie
+ CrTech
+ JimWood)TERRI00", MSG_STATUS::THANKS);
+}
+
+int main(int argc, char* argv[]) {
+ _filesrc_bsp = "none";
+ _filesrc_nav = "none";
+
+ _chdir(argv[0]); //Reset working directory
+
+ std::cout << argv[0] << std::endl;
+
+ for (int i = 1; i < argc; ++i) {
+ char* _arg = argv[i];
+ std::string arg = _arg;
+
+ if (split(arg, '.').back() == "bsp") {
+ _filesrc_bsp = arg;
+ }
+
+ if (split(arg, '.').back() == "nav") {
+ _filesrc_nav = arg;
+ }
+ }
+
+#pragma region Initialisation
+
+ std::cout << "CS:GO Heightmap generator" << std::endl;
+
+ //Initialize OpenGL
+ glfwInit();
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); //We are using version 3.3 of openGL
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
+ glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+ glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
+ //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
+
+ //Creating the window
+ GLFWwindow* window = glfwCreateWindow(window_width, window_height, "CS:GO Heightmap generator", NULL, NULL);
+
+ //Check if window open
+ if (window == NULL)
+ {
+ std::cout << "Failed to create GLFW window" << std::endl;
+ glfwTerminate(); return -1;
+ }
+ glfwMakeContextCurrent(window);
+
+ //Settingn up glad
+ if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
+ {
+ std::cout << "Failed to initialize GLAD" << std::endl; return -1;
+ }
+
+ //Viewport
+ glViewport(0, 0, 1024, 1024);
+ glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
+
+ //Mouse
+ glfwSetCursorPosCallback(window, mouse_callback);
+ glfwSetScrollCallback(window, scroll_callback);
+ glfwSetMouseButtonCallback(window, mouse_button_callback);
+
+#pragma endregion
+
+ // configure global opengl state
+ // -----------------------------
+ glEnable(GL_DEPTH_TEST);
+
+ //The unlit shader thing
+ Shader shader_unlit("shaders/unlit.vs", "shaders/unlit.fs");
+ Shader shader_lit("shaders/depth.vs", "shaders/depth.fs");
+
+ //Mesh handling -----------------------------------------------------------------------------
+
+ if (_filesrc_bsp != "none"){
+ vbsp_level bsp_map(_filesrc_bsp, true);
+ mesh_map_bsp = new Mesh(bsp_map.generate_bigmesh());
+ }
+
+ if (_filesrc_nav != "none") {
+ Nav::Mesh bob(_filesrc_nav);
+ mesh_map_nav = new Mesh(bob.generateGLMesh());
+ }
+
+ //Radar rtest("de_overpass.txt");
+ //_radar = &rtest;
+
+ //VertAlphaMesh t300(vbsp_level::genVertAlpha(t200.vertices, t201.vertices));
+
+ util_keyHandler keys(window);
+ //Create camera (test)
+ camera = Camera(&keys);
+
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_FRONT);
+
+ float _gs = 4096.0f;
+ float _uvs = 8.0f;
+
+ // World Grid
+ Mesh* world_grid_mesh = new Mesh(std::vector<float>{
+ -(_gs * SOURCE_OGL_SCALEFACTOR), 0.0f, -(_gs * SOURCE_OGL_SCALEFACTOR), -_uvs, -_uvs,
+ -(_gs * SOURCE_OGL_SCALEFACTOR), 0.0f, _gs * SOURCE_OGL_SCALEFACTOR, -_uvs, _uvs,
+ _gs * SOURCE_OGL_SCALEFACTOR, 0.0f, -(_gs * SOURCE_OGL_SCALEFACTOR), _uvs, -_uvs,
+ -(_gs * SOURCE_OGL_SCALEFACTOR), 0.0f, _gs * SOURCE_OGL_SCALEFACTOR, -_uvs, _uvs,
+ _gs * SOURCE_OGL_SCALEFACTOR, 0.0f, _gs * SOURCE_OGL_SCALEFACTOR, _uvs, _uvs,
+ _gs * SOURCE_OGL_SCALEFACTOR, 0.0f, -(_gs * SOURCE_OGL_SCALEFACTOR), _uvs, -_uvs
+ }, MeshMode::POS_XYZ_TEXCOORD_UV);
+
+ Mesh* world_grid_mesh_t = new Mesh(std::vector<float>{
+ -2.560f, -2.560f, 0.0f, -1.0f, -1.0f, 0.0f,
+ -2.560f, 2.560f, 0.0f, -1.0f, 1.0f, 0.0f,
+ 2.560f, -2.560f, 0.0f, 1.0f, -1.0f, 0.0f,
+ -2.560f, 2.560f, 0.0f, -1.0f, 1.0f, 0.0f,
+ 2.560f, 2.560f, 0.0f, 1.0f, 1.0f, 0.0f,
+ 2.560f, -2.560f, 0.0f, 1.0f, -1.0f, 0.0f
+ });
+
+ Texture world_grid_mesh_texture("textures/grid.png");
+
+ Shader world_grid_shader("shaders/worldgrid.vs", "shaders/worldgrid.fs");
+
+ TextFont::init(); //Setup textfonts before we use it
+
+ /*
+ ui_text_info = new TextFont("Hello World!");
+ ui_text_info->size = glm::vec2(1.0f / window_width, 1.0f / window_height) * 2.0f;
+ ui_text_info->alpha = 1.0f;
+ ui_text_info->color = glm::vec3(0.75f, 0.75f, 0.75f);
+ ui_text_info->screenPosition = glm::vec2(0, (1.0f / window_height) * 15.0f); */
+
+
+ ui_text_loaded = new TextFont("Currently Loaded:\n " + std::string(_filesrc_bsp) + "\n " + std::string(_filesrc_nav));
+ ui_text_loaded->size = glm::vec2(1.0f / window_width, 1.0f / window_height) * 2.0f;
+ ui_text_loaded->alpha = 1.0f;
+ ui_text_loaded->color = glm::vec3(0.88f, 0.75f, 0.1f);
+ ui_text_loaded->screenPosition = glm::vec2(0, 1.0f - ((1.0f / window_height) * 45.0f));
+
+ //update_globals_ui_text(ui_text_info); //Update globals
+
+ //Generate console
+ console = Console(&keys, &window_width, &window_height);
+ console.RegisterCVar("RENDERMODE", &SV_RENDERMODE);
+
+ //Experimental
+#ifdef WIN32
+ console.RegisterCmd("OPENNAV", &_ccmd_open_nav_win);
+ console.RegisterCmd("OPENBSP", &_ccmd_open_bsp_win);
+#endif
+
+ //Help
+ console.RegisterCmd("HELP", &_ccmd_help);
+
+ //Quit ccmds
+ console.RegisterCmd("QUIT", &_ccmd_exit);
+ console.RegisterCmd("EXIT", &_ccmd_exit);
+
+ //Render modes
+ console.RegisterCmd("NAV", &_ccmd_rendernav);
+ console.RegisterCmd("BSP", &_ccmd_renderbsp);
+
+ console.RegisterCmd("PERSPECTIVE", &_ccmd_perspective);
+ console.RegisterCmd("PERSP", &_ccmd_perspective);
+ console.RegisterCmd("ORTHOGRAPHIC", &_ccmd_orthographic);
+ console.RegisterCmd("ORTHO", &_ccmd_orthographic);
+ console.RegisterCmd("LOOKDOWN", &_ccmd_reset_ang);
+
+ //console.RegisterCVar("SX", &T_RENDER_RESOLUTION_X);
+ //console.RegisterCVar("SY", &T_RENDER_RESOLUTION_Y);
+ console.RegisterCmd("RENDER", &_ccmd_render_image);
+
+ //Register CVARS
+ console.RegisterCVar("RENDERMODE", &SV_RENDERMODE);
+ console.RegisterCVar("PROJMATRIX", &SV_PERSPECTIVE);
+ console.RegisterCVar("MIN", &M_HEIGHT_MIN);
+ console.RegisterCVar("MAX", &M_HEIGHT_MAX);
+ console.RegisterCVar("OSIZE", &M_ORTHO_SIZE);
+ console.RegisterCVar("SIZE", &M_ORTHO_SIZE);
+
+ //Far/near
+ console.RegisterCVar("FARZ", &M_CLIP_FAR);
+ console.RegisterCVar("NEARZ", &M_CLIP_NEAR);
+
+ //Thanks
+ console.RegisterCmd("THANKS", &_ccmd_thanks);
+
+ //FrameBuffer t_frame_buffer = FrameBuffer();
+
+ //The main loop
+ while (!glfwWindowShouldClose(window))
+ {
+ float currentFrame = glfwGetTime();
+ deltaTime = currentFrame - lastFrame;
+ lastFrame = currentFrame;
+
+ //Input
+ processInput(window, keys);
+ if(!console.isEnabled)
+ camera.handleInput(deltaTime);
+
+ console.handleKeysTick();
+
+ if (T_ARM_FOR_FB_RENDER) {
+ //t_frame_buffer.Bind();
+ glViewport(0, 0, T_RENDER_RESOLUTION_X, T_RENDER_RESOLUTION_Y);
+ }
+
+ //Rendering commands
+ glClearColor(0.05f, 0.05f, 0.2f, 1.0f);
+
+
+ if(T_ARM_FOR_FB_RENDER) glClearColor(0.0f, 1.0f, 0.00f, 1.0f);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glPolygonMode(GL_FRONT, GL_FILL);
+
+
+
+ opengl_render_opaque();
+
+
+ shader_lit.use();
+ if(SV_PERSPECTIVE == 0)
+ shader_lit.setMatrix("projection", glm::perspective(glm::radians(90.0f / 2), (float)window_width / (float)window_height, (float)M_CLIP_NEAR * 0.01f, (float)M_CLIP_FAR * 0.01f));
+ else
+ shader_lit.setMatrix("projection", glm::ortho(-(float)M_ORTHO_SIZE, (float)M_ORTHO_SIZE, -(float)M_ORTHO_SIZE, (float)M_ORTHO_SIZE, (float)M_CLIP_NEAR * 0.01f, (float)M_CLIP_FAR * 0.01f));
+
+ shader_lit.setMatrix("view", camera.getViewMatrix());
+
+ glm::mat4 model = glm::mat4();
+ shader_lit.setMatrix("model", model);
+
+ shader_lit.setVec3("color", 0.0f, 0.0f, 1.0f);
+ shader_lit.setFloat("HEIGHT_MIN", (float)M_HEIGHT_MIN * 0.01f);
+ shader_lit.setFloat("HEIGHT_MAX", (float)M_HEIGHT_MAX * 0.01f);
+
+
+ if (SV_RENDERMODE == 0) {
+ glEnable(GL_CULL_FACE);
+ if (mesh_map_bsp != NULL)
+ mesh_map_bsp->Draw();
+ }
+
+ if (SV_RENDERMODE == 1) {
+ glDisable(GL_CULL_FACE);
+ if (mesh_map_nav != NULL)
+ mesh_map_nav->Draw();
+ }
+
+ //GRID
+
+ opengl_render_additive();
+
+ model = glm::mat4();
+ world_grid_shader.use();
+ if (SV_PERSPECTIVE == 0)
+ world_grid_shader.setMatrix("projection", glm::perspective(glm::radians(90.0f / 2), (float)window_width / (float)window_height, (float)M_CLIP_NEAR * 0.01f, (float)M_CLIP_FAR * 0.01f));
+ else
+ world_grid_shader.setMatrix("projection", glm::ortho(-(float)M_ORTHO_SIZE, (float)M_ORTHO_SIZE, -(float)M_ORTHO_SIZE, (float)M_ORTHO_SIZE, (float)M_CLIP_NEAR * 0.01f, (float)M_CLIP_FAR * 0.01f));
+
+ world_grid_shader.setMatrix("view", camera.getViewMatrix());
+ world_grid_shader.setMatrix("model", model);
+ world_grid_shader.setFloat("alpha", 0.44f);
+ world_grid_shader.setInt("text", 0);
+
+ world_grid_mesh_texture.bind();
+ glDisable(GL_CULL_FACE);
+ world_grid_mesh->Draw();
+
+ opengl_render_opaque();
+
+
+ if (!T_ARM_FOR_FB_RENDER) { // UI
+ console.draw();
+
+ //ui_text_info->DrawWithBackground();
+ //ui_text_loaded->DrawWithBackground();
+ }
+
+ //Sort out render buffer stuff
+ if (T_ARM_FOR_FB_RENDER) {
+ std::cout << "Done" << std::endl;
+
+ void* data = malloc(3 * T_RENDER_RESOLUTION_X * T_RENDER_RESOLUTION_Y);
+ glReadPixels(0, 0, T_RENDER_RESOLUTION_X, T_RENDER_RESOLUTION_Y, GL_RGB, GL_UNSIGNED_BYTE, data);
+
+ if (data != 0) {
+ stbi_flip_vertically_on_write(true);
+ stbi_write_png("render.png", T_RENDER_RESOLUTION_X, T_RENDER_RESOLUTION_Y, 3, data, T_RENDER_RESOLUTION_X * 3);
+ console.FeedBack("Done! Saved to: render.png", MSG_STATUS::SUCCESS);
+ }
+ else
+ console.FeedBack("Something went wrong making render", MSG_STATUS::ERR);
+
+ //t_frame_buffer.Unbind();
+ glViewport(0, 0, window_width, window_height);
+ T_ARM_FOR_FB_RENDER = false;
+ }
+
+
+ //Check and call events, swap buffers
+ glfwSwapBuffers(window);
+ glfwPollEvents();
+
+ if (V_DO_QUIT)
+ break;
+ }
+
+ //Exit safely
+ glfwTerminate();
+ return 0;
+}
+
+//Automatically readjust to the new size we just received
+void framebuffer_size_callback(GLFWwindow* window, int width, int height)
+{
+ glViewport(0, 0, width, height);
+ window_width = width;
+ window_height = height;
+}
+
+bool K_CONTROL_MIN = false;
+bool K_CONTROL_MAX = false;
+int SV_EDITMODE = 0;
+
+void setWindowTitle() {
+ std::string title = "BigmanEngine | ";
+
+}
+
+void processInput(GLFWwindow* window, util_keyHandler keys)
+{
+ if (keys.getKeyDown(GLFW_KEY_ESCAPE))
+ glfwSetWindowShouldClose(window, true);
+
+ if (keys.getKeyDown(GLFW_KEY_GRAVE_ACCENT))
+ console.isEnabled = !console.isEnabled;
+
+
+ return;
+ if (keys.getKeyDown(GLFW_KEY_1)) {
+ SV_EDITMODE = 0;
+ update_globals_ui_text(ui_text_info); //Update globals
+ }
+ if (keys.getKeyDown(GLFW_KEY_2)) {
+ SV_EDITMODE = 1;
+ update_globals_ui_text(ui_text_info); //Update globals
+ }
+ if (keys.getKeyDown(GLFW_KEY_3)) {
+ SV_EDITMODE = 2; //glfwSetWindowTitle(window, "Bigman Engine :: de_overpass.bsp - EDITING NEAR");
+ update_globals_ui_text(ui_text_info); //Update globals
+ }
+ if (keys.getKeyDown(GLFW_KEY_4)) {
+ SV_EDITMODE = 3; //glfwSetWindowTitle(window, "Bigman Engine :: de_overpass.bsp - EDITING FAR");
+ update_globals_ui_text(ui_text_info); //Update globals
+ }
+
+ if (keys.getKeyDown(GLFW_KEY_5)) {
+ SV_PERSPECTIVE = 0;
+ update_globals_ui_text(ui_text_info); //Update globals
+ }
+
+ if (keys.getKeyDown(GLFW_KEY_6)) {
+ SV_PERSPECTIVE = 1;
+ update_globals_ui_text(ui_text_info); //Update globals
+ }
+
+
+ if (keys.getKeyDown(GLFW_KEY_7)) {
+ SV_RENDERMODE = 0;
+ update_globals_ui_text(ui_text_info); //Update globals
+
+ }
+
+ if (keys.getKeyDown(GLFW_KEY_8)) {
+ SV_RENDERMODE = 1;
+ update_globals_ui_text(ui_text_info); //Update globals
+ }
+
+ if (keys.getKeyDown(GLFW_KEY_9)) {
+ SV_EDITMODE = 4;
+ //M_ORTHO_SIZE = (_radar->scale / 0.1f) / 2.0f;
+ //camera.cameraPos.x = (-_radar->pos_x ) * 0.01f;
+ //camera.cameraPos.z = (_radar->pos_y - 1024) * 0.01f;
+ update_globals_ui_text(ui_text_info); //Update globals
+
+ }
+
+ if (keys.getKeyDown(GLFW_KEY_0)) {
+ camera.yaw = 0;
+ camera.pitch = -90;
+ camera.mouseUpdate(0, 0, true);
+ //camera.cameraFront = glm::vec3(0, 0, -1);
+ //camera.cameraUp = glm::vec3(0, 1, 0);
+ }
+}
+
+std::string _globals_editmode_lookups[] = {
+ "Minimum Z",
+ "Maximum Z",
+ "Far Clip plane",
+ "Near Clip plane",
+ "Orthographic Size"
+};
+
+void update_globals_ui_text(TextFont* target) {
+
+ std::ostringstream ss;
+
+ ss << "Perspective: " << (SV_PERSPECTIVE == 0 ? "Perspective" : "Orthographic") << "\n";
+ if (SV_PERSPECTIVE == 1) ss << "Ortho scale: " << M_ORTHO_SIZE << "\n";
+ ss << "Viewing: " << (SV_RENDERMODE == 0 ? "BSP" : "NAV") << "\n";
+ ss << "Editing: " << _globals_editmode_lookups[SV_EDITMODE] << "\n";
+
+
+ target->SetText(ss.str());
+}
+
+void mouse_callback(GLFWwindow* window, double xpos, double ypos)
+{
+ camera.mouseUpdate(xpos, ypos, isClicking);
+ mousex = xpos; mousey = ypos;
+}
+
+void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
+{
+ //camera.fov = glm::clamp(camera.fov + (float)yoffset, 2.0f, 90.0f);
+
+ if(SV_EDITMODE == 0)
+ M_HEIGHT_MIN += (float)yoffset * 0.1f;
+
+ if (SV_EDITMODE == 1)
+ M_HEIGHT_MAX += (float)yoffset * 0.1f;
+
+ if (SV_EDITMODE == 4)
+ M_ORTHO_SIZE += (float)yoffset * 0.1f;
+
+ //if (SV_EDITMODE == 2) M_CLIP_NEAR += (float)yoffset * 0.1f;
+
+ //if (SV_EDITMODE == 3) M_CLIP_FAR += (float)yoffset * 0.1f;
+}
+
+void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
+{
+ if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
+ {
+ glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
+ isClicking = true;
+ }
+ else
+ {
+ glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
+ isClicking = false;
+ }
+}
\ No newline at end of file
--- /dev/null
+#version 330 core
+in vec2 TexCoords;
+out vec4 FragColor;
+
+uniform vec3 color;
+uniform float alpha;
+uniform sampler2D text;
+
+void main()
+{
+ vec4 sample = texture(text, TexCoords);
+
+ FragColor = vec4(sample.r, sample.g, sample.b, sample.a * alpha);
+ //FragColor = vec4(texture(text, TexCoords).r, 0.0, 0.0, 1.0);
+}
\ No newline at end of file
--- /dev/null
+#version 330 core
+layout (location = 0) in vec3 aPos;
+layout (location = 1) in vec2 texCoords;
+
+out vec2 TexCoords;
+
+uniform mat4 model;
+uniform mat4 view;
+uniform mat4 projection;
+
+void main()
+{
+ TexCoords = texCoords;
+ gl_Position = projection * view * model * vec4(aPos, 1.0);
+}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="main.cpp" />
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <VCProjectVersion>15.0</VCProjectVersion>
- <ProjectGuid>{21F22CE8-5445-44FA-8561-D3B8E94D55C5}</ProjectGuid>
- <Keyword>Win32Proj</Keyword>
- <RootNamespace>MCDVLib</RootNamespace>
- <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v141</PlatformToolset>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>StaticLibrary</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v141</PlatformToolset>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>StaticLibrary</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <PlatformToolset>v141</PlatformToolset>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>StaticLibrary</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <PlatformToolset>v141</PlatformToolset>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Label="Shared">
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LinkIncremental>true</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <LinkIncremental>true</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <LinkIncremental>false</LinkIncremental>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <LinkIncremental>false</LinkIncremental>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <Optimization>Disabled</Optimization>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- </ClCompile>
- <Link>
- <SubSystem>Windows</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <Optimization>Disabled</Optimization>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- </ClCompile>
- <Link>
- <SubSystem>Windows</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <Optimization>MaxSpeed</Optimization>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- </ClCompile>
- <Link>
- <SubSystem>Windows</SubSystem>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <WarningLevel>Level3</WarningLevel>
- <Optimization>MaxSpeed</Optimization>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <SDLCheck>true</SDLCheck>
- <PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- </ClCompile>
- <Link>
- <SubSystem>Windows</SubSystem>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- </ItemDefinitionGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup>
- <Filter Include="Source Files">
- <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
- <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
- </Filter>
- <Filter Include="Header Files">
- <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
- <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
- </Filter>
- <Filter Include="Resource Files">
- <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
- <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
- </Filter>
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="main.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- </ItemGroup>
-</Project>
\ No newline at end of file
+++ /dev/null
-#include <Windows.h>
-/*
-#include "../MCDV/vector.h"
-#include "../MCDV/interpolation.h"
-#include "../MCDV/interpolation.cpp"
-#include "../MCDV/structures.h"
-#include "../MCDV/structures.cpp"
-#include "../MCDV/vbsp_level.h"
-#include "../MCDV/vbsp_level.cpp"
-#include "../MCDV/vtx_mesh.h"
-#include "../MCDV/vtx_mesh.cpp"
-#include "../MCDV/vvd_data.h"
-#include "../MCDV/vvd_data.cpp"
-
-extern "C"
-{
- /* Converts BSP level into a TBSP filetype
- __declspec(dllexport) int BSPtoTBSP(const char* path, const char* out)
- {
- try
- {
- vbsp_level level(path);
- level.convertToTBSP(out);
- }
- catch (std::exception e)
- {
- std::cout << e.what() << std::endl;
- return -1;
- }
-
- return 0;
- }
-
- /* Converts a .mdl's vtex and vvd formats into TMDL filetype
- __declspec(dllexport) int MDLDatatoTMDL(const char* path_vtex, const char* path_vvd, const char* out)
- {
- try
- {
- vtx_mesh vtx(path_vtex);
-
- vvd_data vvd(path_vvd);
-
- mesh m(vvd, vtx);
-
- m.test_save_tmdl(out);
- }
- catch (std::exception e)
- {
- std::cout << e.what() << std::endl;
- return -1;
- }
-
- return 0;
- }
-}
-*/
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="utf-8" ?>
-<configuration>
- <startup>
- <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
- </startup>
-</configuration>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProjectGuid>{71666EC8-527E-4C98-BD6F-2FC0AA104350}</ProjectGuid>
- <OutputType>Library</OutputType>
- <RootNamespace>MCDV_Lib_Sharp</RootNamespace>
- <AssemblyName>MCDV_Lib_Sharp</AssemblyName>
- <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup>
- <StartupObject />
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="System.Xml.Linq" />
- <Reference Include="System.Data.DataSetExtensions" />
- <Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Data" />
- <Reference Include="System.Net.Http" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="dllimports.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- </ItemGroup>
- <ItemGroup>
- <None Include="App.config" />
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-</Project>
\ No newline at end of file
+++ /dev/null
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("MCDV_Lib_Sharp")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("MCDV_Lib_Sharp")]
-[assembly: AssemblyCopyright("Copyright © 2017")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("71666ec8-527e-4c98-bd6f-2fc0aa104350")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+++ /dev/null
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace MCDV_Lib_Sharp
-{
- public class MCDV
- {
- [DllImport("MCDV_Lib.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern int BSPtoTBSP(string path, string output);
-
- [DllImport("MCDV_Lib.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern int MDLDatatoTMDL(string path_vtex, string path_vvd, string output);
- }
-}
+++ /dev/null
-<?xml version="1.0" encoding="utf-8" ?>
-<configuration>
- <startup>
- <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
- </startup>
-</configuration>
\ No newline at end of file
+++ /dev/null
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace MCDV_Processor
-{
- class Debug
- {
-
- private static bool isProgressBar = false;
- private static string headerRef = "";
- private static string currmessage = "";
-
- enum DebugLevel
- {
- low,
- normal,
- high
- }
-
- public static void Log(string msg, params object[] args) { printMsg(string.Format(msg, args), ConsoleColor.Gray, DebugLevel.high, "log"); }
- public static void Info(string msg, params object[] args) { printMsg(string.Format(msg, args), ConsoleColor.White, DebugLevel.normal, "INFO"); }
- public static void Success(string msg, params object[] args) { printMsg(string.Format(msg, args), ConsoleColor.Cyan, DebugLevel.low, "Success"); }
- public static void Error(string msg, params object[] args) { printMsg(string.Format(msg, args), ConsoleColor.Red, DebugLevel.low, "Error"); }
- public static void Warn(string msg, params object[] args) { printMsg(string.Format(msg, args), ConsoleColor.DarkCyan, DebugLevel.normal, "Warn"); }
- public static void Headings(string msg, params object[] args) { printMsg(string.Format(msg, args), ConsoleColor.White, DebugLevel.normal, "", false); }
-
- public static void Blue(string msg, params object[] args) { printMsg(string.Format(msg, args), ConsoleColor.DarkGray, DebugLevel.normal, "", false, true); }
- public static void White(string msg, params object[] args) { printMsg(string.Format(msg, args), ConsoleColor.White, DebugLevel.normal, "", false, true); }
-
- public static void progressBar(string header, int percent)
- {
- isProgressBar = true;
- headerRef = header;
- Console.Write("\n");
-
- updateProgressBar(percent);
- }
-
- public static void updateProgressBar(int percent)
- {
- if (isProgressBar)
- {
- Console.Write("\r");
- for (int i = 0; i < 100; i++) //Clears everything so stuff doesnt hang around
- Console.Write(" ");
-
-
- Console.ForegroundColor = ConsoleColor.White;
- Console.Write("\r{0} [", headerRef);
-
- int bars = Math.Max(0, Math.Min(percent / 4, 100)); //hacky clamp
-
- Console.ForegroundColor = ConsoleColor.Cyan;
-
- for (int i = 0; i < bars; i++)
- Console.Write("#");
- for (int i = 0; i < 25 - bars; i++)
- Console.Write(" ");
-
- Console.ForegroundColor = ConsoleColor.White;
- Console.Write("] {0}%", percent);
-
- Console.Write(" -> {0}", currmessage);
- }
- }
-
- public static void exitProgressBar()
- {
- updateProgressBar(100);
-
- isProgressBar = false;
- Console.WriteLine(" COMPLETE");
- }
-
- private static void printMsg(string message, ConsoleColor c, DebugLevel lvl = DebugLevel.low, string prefix = "", bool usedate = true, bool bluepost = false)
- {
-
- if (bluepost)
- {
- Console.ForegroundColor = c;
- Console.Write(message);
- Console.ForegroundColor = ConsoleColor.Gray;
- return;
- }
-
- if (!isProgressBar)
- {
- if (lvl <= DebugLevel.high)
- {
- Console.ForegroundColor = c;
- if (usedate)
- Console.Write("[" + DateTime.Now.ToShortTimeString() + " | " + prefix + "] ");
- Console.Write(message + "\n");
- Console.ForegroundColor = ConsoleColor.Gray;
- }
- }
- else
- {
- currmessage = message;
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProjectGuid>{B9C44160-6699-4DFF-AD66-AD39D83E8A21}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <RootNamespace>MCDV_Processor</RootNamespace>
- <AssemblyName>MCDV_Processor</AssemblyName>
- <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="System.Xml.Linq" />
- <Reference Include="System.Data.DataSetExtensions" />
- <Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Data" />
- <Reference Include="System.Net.Http" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Debug.cs" />
- <Compile Include="dllimports.cs" />
- <Compile Include="Program.cs" />
- <Compile Include="ProgressViewer.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- </ItemGroup>
- <ItemGroup>
- <None Include="App.config" />
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-</Project>
\ No newline at end of file
+++ /dev/null
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace MCDV_Processor
-{
- class Program
- {
- public static string dbFolder = @"D:\MCDV-MODEL-DATABASE\CONVERTED";
-
- static void Main(string[] args)
- {
- //runDatabaseConversion(@"D:\MCDV-MODEL-DATABASE\SOURCE", @"D:\MCDV-MODEL-DATABASE\CONVERTED");
-
- //Console.ReadLine();
- //return;
-
- //MCDV.BSPtoTBSP(@"testmaterial\ar_baggage.bsp", "test.tbsp");
- List<string> test_models = getModelList("de_mirage.tbsp");
-
- foreach(string mdl in test_models)
- {
- copyDBFileToFolder(mdl, "de_mirage.resources");
- }
-
- Console.ReadLine();
- }
-
- //Check if model in database
- public static bool checkModelInDatabase(string modelName)
- {
- if (File.Exists(Path.ChangeExtension(dbFolder + "/" + modelName, "tmdl")))
- return true;
- return false;
- }
-
- //Copys model from database to target dir
- public static void copyDBFileToFolder(string modelName, string targetFolder)
- {
- if(checkModelInDatabase(modelName))
- {
- string targetDirRel = Path.GetDirectoryName(modelName);
- if (!Directory.Exists(targetFolder + "/" + targetDirRel))
- Directory.CreateDirectory(targetFolder + "/" + targetDirRel);
-
- File.Copy(Path.ChangeExtension(dbFolder + "/" + modelName, "tmdl"), Path.ChangeExtension(targetFolder + "/" + modelName, "tmdl"));
- }
- }
-
- public static void runDatabaseConversion(string sourceFolder)
- {
- //Find all .mdl files
- string[] files = Directory.GetFiles(sourceFolder, "*.mdl", SearchOption.AllDirectories);
-
- ProgressViewer viewer = new ProgressViewer("Converted model 0 of " + files.Length);
-
- int c = 0;
-
- foreach (string file in files)
- {
- string dir = Path.GetDirectoryName(file);
- string modelName = Path.GetFileNameWithoutExtension(file);
-
- string relativeFileDir = (dir + "/" + modelName).Substring(sourceFolder.Length);
-
- //Search for vtx file
- string[] suffixes = new string[] { ".dx90.vtx" };
-
- string vtx_path = "";
- string vvd_path = "";
- foreach (string suffix in suffixes)
- {
- if (File.Exists(dir + "/" + modelName + suffix))
- vtx_path = dir + "/" + modelName + suffix;
- }
-
- if (File.Exists(dir + "/" + modelName + ".vvd"))
- vvd_path = dir + "/" + modelName + ".vvd";
-
- if (vtx_path != "" && vvd_path != "")
- {
- //Console.WriteLine("Converting {0} to .TMDL", modelName);
-
- string targetFile = dbFolder + "/" + relativeFileDir + ".tmdl";
-
- //Create file if it does not exist
- if (!Directory.Exists(Path.GetDirectoryName(targetFile)))
- Directory.CreateDirectory(Path.GetDirectoryName(targetFile));
-
- //Check / skip if file exits already
- if (File.Exists(targetFile))
- continue;
-
-
- int status = MCDV.MDLDatatoTMDL(vtx_path, vvd_path, targetFile);
-
-
- }
- else
- {
- //Console.WriteLine("Error searching for model vtx/vvd: {0}", file);
- }
-
- c++;
-
- viewer.title = "Converted model " + c + " of " + files.Length;
-
- viewer.percent = (float)c / (float)files.Length;
- viewer.Draw();
- }
-
- viewer.End();
- }
-
- //Grabs the model list out of the .tbsp file
- public static List<string> getModelList(string tbsp_path)
- {
- List<string> modelList = new List<string>();
-
- if (File.Exists(tbsp_path))
- {
- using (BinaryReader reader = new BinaryReader(File.Open(tbsp_path, FileMode.Open)))
- {
- //Read through
- int magicNum = reader.ReadInt32();
- int version = reader.ReadInt32();
-
- int meshCount = reader.ReadInt32();
- int meshLocation = reader.ReadInt32();
-
- int modelCount = reader.ReadInt32();
- int modelLocation = reader.ReadInt32();
-
- int modelDictCount = reader.ReadInt32();
- int modelDictLocation = reader.ReadInt32();
-
- int entityCount = reader.ReadInt32();
- int entityLocation = reader.ReadInt32();
-
- //Jump to modelDict location
- reader.BaseStream.Seek(modelDictLocation, SeekOrigin.Begin);
-
- for(int i = 0; i < modelDictCount; i++)
- {
- string build = "";
- byte c;
- while ((c = reader.ReadByte()) != '\0')
- build += (char)c;
-
- modelList.Add(build);
- }
- }
- }
-
- return modelList;
- }
- }
-}
+++ /dev/null
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace MCDV_Processor
-{
- public class ProgressViewer
- {
- public float percent = 0.0f;
- public string title = "";
-
- private int console_y = 0;
-
-
- public void Draw(bool end = false, bool error = false)
- {
- int prev_y = Console.CursorTop;
-
- Console.ForegroundColor = ConsoleColor.Black;
- Console.SetCursorPosition(0, console_y);
-
- //Get the amount of characters needed to fill region
-
- string new_title = title + " - " + (int)(percent * 100.0f) + "%";
-
- int cwidth = Console.BufferWidth;
-
- int textWidth = new_title.Count();
-
- int padWidth = (cwidth - textWidth) / 2;
-
- string newt = "";
-
- for (int i = 0; i < padWidth; i++)
- newt += " ";
-
- newt += new_title;
-
- for (int i = 0; i < cwidth - (padWidth + textWidth); i++)
- newt += " ";
-
- int percentBuffer = (int)(percent * (float)cwidth);
- percentBuffer = percentBuffer > cwidth ? cwidth : percentBuffer;
-
- for (int i = 0; i < newt.Length; i++)
- {
-
- Console.BackgroundColor = ConsoleColor.Green;
-
- if (i > percentBuffer)
- Console.BackgroundColor = ConsoleColor.DarkGreen;
-
- if (end)
- Console.BackgroundColor = ConsoleColor.DarkGray;
-
- if (error)
- Console.BackgroundColor = ConsoleColor.DarkRed;
-
- Console.Write(newt[i]);
- }
-
- Console.SetCursorPosition(0, prev_y);
- Console.ForegroundColor = ConsoleColor.Gray;
- Console.BackgroundColor = ConsoleColor.Black;
- }
-
- public void End()
- {
- this.percent = 1.0f;
- this.title += " COMPLETED";
- this.Draw(true);
- Console.Write("\n");
- }
-
- public void Error()
- {
- this.title += " FAILED";
- this.Draw(true, true);
- Console.Write("\n");
- }
-
- public ProgressViewer(string title)
- {
- this.title = title;
-
- this.console_y = Console.CursorTop;
-
- this.Draw();
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("MCDV_Processor")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("MCDV_Processor")]
-[assembly: AssemblyCopyright("Copyright © 2017")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("b9c44160-6699-4dff-ad66-ad39d83e8a21")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+++ /dev/null
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace MCDV_Processor
-{
- public class MCDV
- {
- [DllImport("../../../Debug/MCDV_Lib.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern int BSPtoTBSP(string path, string output);
-
- [DllImport("../../../Debug/MCDV_Lib.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern int MDLDatatoTMDL(string path_vtex, string path_vvd, string output);
- }
-}
+++ /dev/null
-<head>
- <script type="text/javascript" src="gl-matrix-min.js"></script>
- <script type="text/javascript" src="webgl-utils.js"></script>
-
- <script id="shader-fs" type="x-shader/x-fragment">
- precision mediump float;
- varying vec2 vTextureCoord;
- varying vec3 vLightWeighting;
- uniform sampler2D uSampler;
- void main(void) {
- vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
-
- float z = (gl_FragCoord.z / gl_FragCoord.w) * 0.003;
- //gl_FragColor = vec4(z, z, z, 255);
- gl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a) + z;
- }
- </script>
-
- <script id="shader-vs" type="x-shader/x-vertex">
- attribute vec3 aVertexPosition;
- attribute vec3 aVertexNormal;
- attribute vec2 aTextureCoord;
- uniform mat4 uMVMatrix;
- uniform mat4 uPMatrix;
- uniform mat4 viewMatrix;
- uniform mat3 uNMatrix;
- uniform vec3 uAmbientColor;
- uniform vec3 uLightingDirection;
- uniform vec3 uDirectionalColor;
- varying vec2 vTextureCoord;
- varying vec3 vLightWeighting;
- void main(void) {
- gl_Position = uPMatrix * viewMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
- vTextureCoord = aTextureCoord;
-
- vec3 transformedNormal = uNMatrix * aVertexNormal;
- float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);
- vLightWeighting = uAmbientColor + uDirectionalColor * directionalLightWeighting;
- }
- </script>
-
- <script src="tbsp-min.js"></script>
- <script src="level-viewer-min.js"></script>
-
-</head>
-
-<body onload="webGLStart();">
-
- <canvas id="glCanvas" width="640" height="480"></canvas>
-
- <p style="position:fixed;top:0px;right:60px;color:#FFF;">Click and drag to move around<br>WASD to move<br><br>:))</p>
-
- <p id="fps">0fps</p>
-</body>
+++ /dev/null
-<head>
- <script type="text/javascript" src="gl-matrix.js"></script>
- <script type="text/javascript" src="webgl-utils.js"></script>
-
- <script id="shader-fs" type="x-shader/x-fragment">
- precision mediump float;
- varying vec2 vTextureCoord;
- varying vec3 vLightWeighting;
- uniform sampler2D uSampler;
- void main(void) {
- vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
-
- float z = (gl_FragCoord.z / gl_FragCoord.w) * 0.003;
- //gl_FragColor = vec4(z, z, z, 255);
- gl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a) + z;
- }
- </script>
-
- <script id="shader-vs" type="x-shader/x-vertex">
- attribute vec3 aVertexPosition;
- attribute vec3 aVertexNormal;
- attribute vec2 aTextureCoord;
- uniform mat4 uMVMatrix;
- uniform mat4 uPMatrix;
- uniform mat4 viewMatrix;
- uniform mat3 uNMatrix;
- uniform vec3 uAmbientColor;
- uniform vec3 uLightingDirection;
- uniform vec3 uDirectionalColor;
- varying vec2 vTextureCoord;
- varying vec3 vLightWeighting;
- void main(void) {
- gl_Position = uPMatrix * viewMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
- vTextureCoord = aTextureCoord;
-
- vec3 transformedNormal = uNMatrix * aVertexNormal;
- float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);
- vLightWeighting = uAmbientColor + uDirectionalColor * directionalLightWeighting;
- }
- </script>
-
- <script src="dynview.js"></script>
-
-</head>
-
-<body>
-
-<script>
-var data = load_binary_resource("output.terri");
-var reader = new binaryReader(data);
-
-
-var kills_ct = [];
-var kills_t = [];
-
-var count = reader.readUint32();
-
-for(var x = 0; x < count; x++){
- var team = reader.readUint32();
- console.log(team);
- for(var i = 0; i < 6; i++){
- kills_t.push(reader.readFloat());
- }
-}
-
-console.log(kills_t);
-
-
-//var level = new tbsp_level(map_data);
-</script>
-
-</body>
+++ /dev/null
-//====================================================================
-// RESOURCE TO BYTE ARRAY LOADER
-//Deprecated
-function load_binary_resource(url) {
- var byteArray = [];
- var req = new XMLHttpRequest();
- req.open('GET', url, false);
- req.overrideMimeType('text\/plain; charset=x-user-defined');
- req.send(null);
- if (req.status != 200) return byteArray;
- for (var i = 0; i < req.responseText.length; ++i) {
- byteArray.push(req.responseText.charCodeAt(i) & 0xff)
- }
- return byteArray;
-}
-
-
-//=========================================================
-// BINARY READER class
-
-//Takes in a byte array as source data
-//Works like fstream from c++
-function binaryReader(bytes)
-{
- this.pos = 0;
- this.data = bytes;
-
- this.readUint32 = function()
- {
- var val = (this.data[this.pos + 3] << 24) +
- (this.data[this.pos + 2] << 16) +
- (this.data[this.pos + 1] << 8) +
- this.data[this.pos + 0];
- this.pos += 4;
- return val;
- }
-
- this.readString = function()
- {
- var val = "";
- while(true)
- {
- if(this.data[this.pos] != 0x0)
- {
- val += String.fromCharCode(this.data[this.pos]);
- this.pos++;
- }
- else
- {
- this.pos++;
- break;
- }
- }
-
- return val;
- }
-
- this.readFloat = function()
- {
- var dat = [this.data[this.pos+3],
- this.data[this.pos+2],
- this.data[this.pos+1],
- this.data[this.pos+0]];
- var buf = new ArrayBuffer(4);
- var view = new DataView(buf);
-
- dat.forEach(function (b, i) {
- view.setUint8(i, b);
- });
-
- var val = view.getFloat32(0);
-
- this.pos += 4;
- return val;
- }
-}
+++ /dev/null
-!function(t,r){"object"==typeof exports?module.exports=r(global):"function"==typeof define&&define.amd?define([],function(){return r(t)}):r(t)}(this,function(t){"use strict";function r(t){return a=t}function n(){return a="undefined"!=typeof Float32Array?Float32Array:Array}var e={};!function(){if("undefined"!=typeof Float32Array){var t=new Float32Array(1),r=new Int32Array(t.buffer);e.invsqrt=function(n){var e=.5*n;t[0]=n;r[0]=1597463007-(r[0]>>1);var a=t[0];return a*(1.5-e*a*a)}}else e.invsqrt=function(t){return 1/Math.sqrt(t)}}();var a=null;n();var u={};u.create=function(t){var r=new a(3);return t?(r[0]=t[0],r[1]=t[1],r[2]=t[2]):r[0]=r[1]=r[2]=0,r},u.createFrom=function(t,r,n){var e=new a(3);return e[0]=t,e[1]=r,e[2]=n,e},u.set=function(t,r){return r[0]=t[0],r[1]=t[1],r[2]=t[2],r},u.equal=function(t,r){return t===r||Math.abs(t[0]-r[0])<1e-6&&Math.abs(t[1]-r[1])<1e-6&&Math.abs(t[2]-r[2])<1e-6},u.add=function(t,r,n){return n&&t!==n?(n[0]=t[0]+r[0],n[1]=t[1]+r[1],n[2]=t[2]+r[2],n):(t[0]+=r[0],t[1]+=r[1],t[2]+=r[2],t)},u.subtract=function(t,r,n){return n&&t!==n?(n[0]=t[0]-r[0],n[1]=t[1]-r[1],n[2]=t[2]-r[2],n):(t[0]-=r[0],t[1]-=r[1],t[2]-=r[2],t)},u.multiply=function(t,r,n){return n&&t!==n?(n[0]=t[0]*r[0],n[1]=t[1]*r[1],n[2]=t[2]*r[2],n):(t[0]*=r[0],t[1]*=r[1],t[2]*=r[2],t)},u.negate=function(t,r){return r||(r=t),r[0]=-t[0],r[1]=-t[1],r[2]=-t[2],r},u.scale=function(t,r,n){return n&&t!==n?(n[0]=t[0]*r,n[1]=t[1]*r,n[2]=t[2]*r,n):(t[0]*=r,t[1]*=r,t[2]*=r,t)},u.normalize=function(t,r){r||(r=t);var n=t[0],e=t[1],a=t[2],u=Math.sqrt(n*n+e*e+a*a);return u?1===u?(r[0]=n,r[1]=e,r[2]=a,r):(u=1/u,r[0]=n*u,r[1]=e*u,r[2]=a*u,r):(r[0]=0,r[1]=0,r[2]=0,r)},u.cross=function(t,r,n){n||(n=t);var e=t[0],a=t[1],u=t[2],i=r[0],o=r[1],c=r[2];return n[0]=a*c-u*o,n[1]=u*i-e*c,n[2]=e*o-a*i,n},u.length=function(t){var r=t[0],n=t[1],e=t[2];return Math.sqrt(r*r+n*n+e*e)},u.squaredLength=function(t){var r=t[0],n=t[1],e=t[2];return r*r+n*n+e*e},u.dot=function(t,r){return t[0]*r[0]+t[1]*r[1]+t[2]*r[2]},u.direction=function(t,r,n){n||(n=t);var e=t[0]-r[0],a=t[1]-r[1],u=t[2]-r[2],i=Math.sqrt(e*e+a*a+u*u);return i?(i=1/i,n[0]=e*i,n[1]=a*i,n[2]=u*i,n):(n[0]=0,n[1]=0,n[2]=0,n)},u.lerp=function(t,r,n,e){return e||(e=t),e[0]=t[0]+n*(r[0]-t[0]),e[1]=t[1]+n*(r[1]-t[1]),e[2]=t[2]+n*(r[2]-t[2]),e},u.dist=function(t,r){var n=r[0]-t[0],e=r[1]-t[1],a=r[2]-t[2];return Math.sqrt(n*n+e*e+a*a)};var i=null,o=new a(4);u.unproject=function(t,r,n,e,a){a||(a=t),i||(i=h.create());var u=i,c=o;return c[0]=2*(t[0]-e[0])/e[2]-1,c[1]=2*(t[1]-e[1])/e[3]-1,c[2]=2*t[2]-1,c[3]=1,h.multiply(n,r,u),h.inverse(u)?(h.multiplyVec4(u,c),0===c[3]?null:(a[0]=c[0]/c[3],a[1]=c[1]/c[3],a[2]=c[2]/c[3],a)):null};var c=u.createFrom(1,0,0),f=u.createFrom(0,1,0),s=u.createFrom(0,0,1),v=u.create();u.rotationTo=function(t,r,n){n||(n=l.create());var e=u.dot(t,r),a=v;if(e>=1)l.set(m,n);else if(e<1e-6-1)u.cross(c,t,a),u.length(a)<1e-6&&u.cross(f,t,a),u.length(a)<1e-6&&u.cross(s,t,a),u.normalize(a),l.fromAngleAxis(Math.PI,a,n);else{var i=Math.sqrt(2*(1+e)),o=1/i;u.cross(t,r,a),n[0]=a[0]*o,n[1]=a[1]*o,n[2]=a[2]*o,n[3]=.5*i,l.normalize(n)}return n[3]>1?n[3]=1:n[3]<-1&&(n[3]=-1),n},u.str=function(t){return"["+t[0]+", "+t[1]+", "+t[2]+"]"};var M={};M.create=function(t){var r=new a(9);return t?(r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[3],r[4]=t[4],r[5]=t[5],r[6]=t[6],r[7]=t[7],r[8]=t[8]):r[0]=r[1]=r[2]=r[3]=r[4]=r[5]=r[6]=r[7]=r[8]=0,r},M.createFrom=function(t,r,n,e,u,i,o,c,f){var s=new a(9);return s[0]=t,s[1]=r,s[2]=n,s[3]=e,s[4]=u,s[5]=i,s[6]=o,s[7]=c,s[8]=f,s},M.determinant=function(t){var r=t[0],n=t[1],e=t[2],a=t[3],u=t[4],i=t[5],o=t[6],c=t[7],f=t[8];return r*(f*u-i*c)+n*(-f*a+i*o)+e*(c*a-u*o)},M.inverse=function(t,r){var n,e=t[0],a=t[1],u=t[2],i=t[3],o=t[4],c=t[5],f=t[6],s=t[7],v=t[8],h=v*o-c*s,l=-v*i+c*f,m=s*i-o*f,b=e*h+a*l+u*m;return b?(n=1/b,r||(r=M.create()),r[0]=h*n,r[1]=(-v*a+u*s)*n,r[2]=(c*a-u*o)*n,r[3]=l*n,r[4]=(v*e-u*f)*n,r[5]=(-c*e+u*i)*n,r[6]=m*n,r[7]=(-s*e+a*f)*n,r[8]=(o*e-a*i)*n,r):null},M.multiply=function(t,r,n){n||(n=t);var e=t[0],a=t[1],u=t[2],i=t[3],o=t[4],c=t[5],f=t[6],s=t[7],v=t[8],M=r[0],h=r[1],l=r[2],m=r[3],b=r[4],y=r[5],d=r[6],p=r[7],q=r[8];return n[0]=M*e+h*i+l*f,n[1]=M*a+h*o+l*s,n[2]=M*u+h*c+l*v,n[3]=m*e+b*i+y*f,n[4]=m*a+b*o+y*s,n[5]=m*u+b*c+y*v,n[6]=d*e+p*i+q*f,n[7]=d*a+p*o+q*s,n[8]=d*u+p*c+q*v,n},M.multiplyVec2=function(t,r,n){n||(n=r);var e=r[0],a=r[1];return n[0]=e*t[0]+a*t[3]+t[6],n[1]=e*t[1]+a*t[4]+t[7],n},M.multiplyVec3=function(t,r,n){n||(n=r);var e=r[0],a=r[1],u=r[2];return n[0]=e*t[0]+a*t[3]+u*t[6],n[1]=e*t[1]+a*t[4]+u*t[7],n[2]=e*t[2]+a*t[5]+u*t[8],n},M.set=function(t,r){return r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[3],r[4]=t[4],r[5]=t[5],r[6]=t[6],r[7]=t[7],r[8]=t[8],r},M.equal=function(t,r){return t===r||Math.abs(t[0]-r[0])<1e-6&&Math.abs(t[1]-r[1])<1e-6&&Math.abs(t[2]-r[2])<1e-6&&Math.abs(t[3]-r[3])<1e-6&&Math.abs(t[4]-r[4])<1e-6&&Math.abs(t[5]-r[5])<1e-6&&Math.abs(t[6]-r[6])<1e-6&&Math.abs(t[7]-r[7])<1e-6&&Math.abs(t[8]-r[8])<1e-6},M.identity=function(t){return t||(t=M.create()),t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},M.transpose=function(t,r){if(!r||t===r){var n=t[1],e=t[2],a=t[5];return t[1]=t[3],t[2]=t[6],t[3]=n,t[5]=t[7],t[6]=e,t[7]=a,t}return r[0]=t[0],r[1]=t[3],r[2]=t[6],r[3]=t[1],r[4]=t[4],r[5]=t[7],r[6]=t[2],r[7]=t[5],r[8]=t[8],r},M.toMat4=function(t,r){return r||(r=h.create()),r[15]=1,r[14]=0,r[13]=0,r[12]=0,r[11]=0,r[10]=t[8],r[9]=t[7],r[8]=t[6],r[7]=0,r[6]=t[5],r[5]=t[4],r[4]=t[3],r[3]=0,r[2]=t[2],r[1]=t[1],r[0]=t[0],r},M.str=function(t){return"["+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+"]"};var h={};h.create=function(t){var r=new a(16);return t&&(r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[3],r[4]=t[4],r[5]=t[5],r[6]=t[6],r[7]=t[7],r[8]=t[8],r[9]=t[9],r[10]=t[10],r[11]=t[11],r[12]=t[12],r[13]=t[13],r[14]=t[14],r[15]=t[15]),r},h.createFrom=function(t,r,n,e,u,i,o,c,f,s,v,M,h,l,m,b){var y=new a(16);return y[0]=t,y[1]=r,y[2]=n,y[3]=e,y[4]=u,y[5]=i,y[6]=o,y[7]=c,y[8]=f,y[9]=s,y[10]=v,y[11]=M,y[12]=h,y[13]=l,y[14]=m,y[15]=b,y},h.set=function(t,r){return r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[3],r[4]=t[4],r[5]=t[5],r[6]=t[6],r[7]=t[7],r[8]=t[8],r[9]=t[9],r[10]=t[10],r[11]=t[11],r[12]=t[12],r[13]=t[13],r[14]=t[14],r[15]=t[15],r},h.equal=function(t,r){return t===r||Math.abs(t[0]-r[0])<1e-6&&Math.abs(t[1]-r[1])<1e-6&&Math.abs(t[2]-r[2])<1e-6&&Math.abs(t[3]-r[3])<1e-6&&Math.abs(t[4]-r[4])<1e-6&&Math.abs(t[5]-r[5])<1e-6&&Math.abs(t[6]-r[6])<1e-6&&Math.abs(t[7]-r[7])<1e-6&&Math.abs(t[8]-r[8])<1e-6&&Math.abs(t[9]-r[9])<1e-6&&Math.abs(t[10]-r[10])<1e-6&&Math.abs(t[11]-r[11])<1e-6&&Math.abs(t[12]-r[12])<1e-6&&Math.abs(t[13]-r[13])<1e-6&&Math.abs(t[14]-r[14])<1e-6&&Math.abs(t[15]-r[15])<1e-6},h.identity=function(t){return t||(t=h.create()),t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},h.transpose=function(t,r){if(!r||t===r){var n=t[1],e=t[2],a=t[3],u=t[6],i=t[7],o=t[11];return t[1]=t[4],t[2]=t[8],t[3]=t[12],t[4]=n,t[6]=t[9],t[7]=t[13],t[8]=e,t[9]=u,t[11]=t[14],t[12]=a,t[13]=i,t[14]=o,t}return r[0]=t[0],r[1]=t[4],r[2]=t[8],r[3]=t[12],r[4]=t[1],r[5]=t[5],r[6]=t[9],r[7]=t[13],r[8]=t[2],r[9]=t[6],r[10]=t[10],r[11]=t[14],r[12]=t[3],r[13]=t[7],r[14]=t[11],r[15]=t[15],r},h.determinant=function(t){var r=t[0],n=t[1],e=t[2],a=t[3],u=t[4],i=t[5],o=t[6],c=t[7],f=t[8],s=t[9],v=t[10],M=t[11],h=t[12],l=t[13],m=t[14],b=t[15];return h*s*o*a-f*l*o*a-h*i*v*a+u*l*v*a+f*i*m*a-u*s*m*a-h*s*e*c+f*l*e*c+h*n*v*c-r*l*v*c-f*n*m*c+r*s*m*c+h*i*e*M-u*l*e*M-h*n*o*M+r*l*o*M+u*n*m*M-r*i*m*M-f*i*e*b+u*s*e*b+f*n*o*b-r*s*o*b-u*n*v*b+r*i*v*b},h.inverse=function(t,r){r||(r=t);var n,e=t[0],a=t[1],u=t[2],i=t[3],o=t[4],c=t[5],f=t[6],s=t[7],v=t[8],M=t[9],h=t[10],l=t[11],m=t[12],b=t[13],y=t[14],d=t[15],p=e*c-a*o,q=e*f-u*o,A=e*s-i*o,g=a*f-u*c,x=a*s-i*c,w=u*s-i*f,F=v*b-M*m,T=v*y-h*m,R=v*d-l*m,V=M*y-h*b,z=M*d-l*b,I=h*d-l*y,j=p*I-q*z+A*V+g*R-x*T+w*F;return j?(n=1/j,r[0]=(c*I-f*z+s*V)*n,r[1]=(-a*I+u*z-i*V)*n,r[2]=(b*w-y*x+d*g)*n,r[3]=(-M*w+h*x-l*g)*n,r[4]=(-o*I+f*R-s*T)*n,r[5]=(e*I-u*R+i*T)*n,r[6]=(-m*w+y*A-d*q)*n,r[7]=(v*w-h*A+l*q)*n,r[8]=(o*z-c*R+s*F)*n,r[9]=(-e*z+a*R-i*F)*n,r[10]=(m*x-b*A+d*p)*n,r[11]=(-v*x+M*A-l*p)*n,r[12]=(-o*V+c*T-f*F)*n,r[13]=(e*V-a*T+u*F)*n,r[14]=(-m*g+b*q-y*p)*n,r[15]=(v*g-M*q+h*p)*n,r):null},h.toRotationMat=function(t,r){return r||(r=h.create()),r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[3],r[4]=t[4],r[5]=t[5],r[6]=t[6],r[7]=t[7],r[8]=t[8],r[9]=t[9],r[10]=t[10],r[11]=t[11],r[12]=0,r[13]=0,r[14]=0,r[15]=1,r},h.toMat3=function(t,r){return r||(r=M.create()),r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[4],r[4]=t[5],r[5]=t[6],r[6]=t[8],r[7]=t[9],r[8]=t[10],r},h.toInverseMat3=function(t,r){var n,e=t[0],a=t[1],u=t[2],i=t[4],o=t[5],c=t[6],f=t[8],s=t[9],v=t[10],h=v*o-c*s,l=-v*i+c*f,m=s*i-o*f,b=e*h+a*l+u*m;return b?(n=1/b,r||(r=M.create()),r[0]=h*n,r[1]=(-v*a+u*s)*n,r[2]=(c*a-u*o)*n,r[3]=l*n,r[4]=(v*e-u*f)*n,r[5]=(-c*e+u*i)*n,r[6]=m*n,r[7]=(-s*e+a*f)*n,r[8]=(o*e-a*i)*n,r):null},h.multiply=function(t,r,n){n||(n=t);var e=t[0],a=t[1],u=t[2],i=t[3],o=t[4],c=t[5],f=t[6],s=t[7],v=t[8],M=t[9],h=t[10],l=t[11],m=t[12],b=t[13],y=t[14],d=t[15],p=r[0],q=r[1],A=r[2],g=r[3];return n[0]=p*e+q*o+A*v+g*m,n[1]=p*a+q*c+A*M+g*b,n[2]=p*u+q*f+A*h+g*y,n[3]=p*i+q*s+A*l+g*d,p=r[4],q=r[5],A=r[6],g=r[7],n[4]=p*e+q*o+A*v+g*m,n[5]=p*a+q*c+A*M+g*b,n[6]=p*u+q*f+A*h+g*y,n[7]=p*i+q*s+A*l+g*d,p=r[8],q=r[9],A=r[10],g=r[11],n[8]=p*e+q*o+A*v+g*m,n[9]=p*a+q*c+A*M+g*b,n[10]=p*u+q*f+A*h+g*y,n[11]=p*i+q*s+A*l+g*d,p=r[12],q=r[13],A=r[14],g=r[15],n[12]=p*e+q*o+A*v+g*m,n[13]=p*a+q*c+A*M+g*b,n[14]=p*u+q*f+A*h+g*y,n[15]=p*i+q*s+A*l+g*d,n},h.multiplyVec3=function(t,r,n){n||(n=r);var e=r[0],a=r[1],u=r[2];return n[0]=t[0]*e+t[4]*a+t[8]*u+t[12],n[1]=t[1]*e+t[5]*a+t[9]*u+t[13],n[2]=t[2]*e+t[6]*a+t[10]*u+t[14],n},h.multiplyVec4=function(t,r,n){n||(n=r);var e=r[0],a=r[1],u=r[2],i=r[3];return n[0]=t[0]*e+t[4]*a+t[8]*u+t[12]*i,n[1]=t[1]*e+t[5]*a+t[9]*u+t[13]*i,n[2]=t[2]*e+t[6]*a+t[10]*u+t[14]*i,n[3]=t[3]*e+t[7]*a+t[11]*u+t[15]*i,n},h.translate=function(t,r,n){var e,a,u,i,o,c,f,s,v,M,h,l,m=r[0],b=r[1],y=r[2];return n&&t!==n?(e=t[0],a=t[1],u=t[2],i=t[3],o=t[4],c=t[5],f=t[6],s=t[7],v=t[8],M=t[9],h=t[10],l=t[11],n[0]=e,n[1]=a,n[2]=u,n[3]=i,n[4]=o,n[5]=c,n[6]=f,n[7]=s,n[8]=v,n[9]=M,n[10]=h,n[11]=l,n[12]=e*m+o*b+v*y+t[12],n[13]=a*m+c*b+M*y+t[13],n[14]=u*m+f*b+h*y+t[14],n[15]=i*m+s*b+l*y+t[15],n):(t[12]=t[0]*m+t[4]*b+t[8]*y+t[12],t[13]=t[1]*m+t[5]*b+t[9]*y+t[13],t[14]=t[2]*m+t[6]*b+t[10]*y+t[14],t[15]=t[3]*m+t[7]*b+t[11]*y+t[15],t)},h.scale=function(t,r,n){var e=r[0],a=r[1],u=r[2];return n&&t!==n?(n[0]=t[0]*e,n[1]=t[1]*e,n[2]=t[2]*e,n[3]=t[3]*e,n[4]=t[4]*a,n[5]=t[5]*a,n[6]=t[6]*a,n[7]=t[7]*a,n[8]=t[8]*u,n[9]=t[9]*u,n[10]=t[10]*u,n[11]=t[11]*u,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n):(t[0]*=e,t[1]*=e,t[2]*=e,t[3]*=e,t[4]*=a,t[5]*=a,t[6]*=a,t[7]*=a,t[8]*=u,t[9]*=u,t[10]*=u,t[11]*=u,t)},h.rotate=function(t,r,n,e){var a,u,i,o,c,f,s,v,M,h,l,m,b,y,d,p,q,A,g,x,w,F,T,R,V=n[0],z=n[1],I=n[2],j=Math.sqrt(V*V+z*z+I*I);return j?(1!==j&&(V*=j=1/j,z*=j,I*=j),a=Math.sin(r),u=Math.cos(r),i=1-u,o=t[0],c=t[1],f=t[2],s=t[3],v=t[4],M=t[5],h=t[6],l=t[7],m=t[8],b=t[9],y=t[10],d=t[11],p=V*V*i+u,q=z*V*i+I*a,A=I*V*i-z*a,g=V*z*i-I*a,x=z*z*i+u,w=I*z*i+V*a,F=V*I*i+z*a,T=z*I*i-V*a,R=I*I*i+u,e?t!==e&&(e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15]):e=t,e[0]=o*p+v*q+m*A,e[1]=c*p+M*q+b*A,e[2]=f*p+h*q+y*A,e[3]=s*p+l*q+d*A,e[4]=o*g+v*x+m*w,e[5]=c*g+M*x+b*w,e[6]=f*g+h*x+y*w,e[7]=s*g+l*x+d*w,e[8]=o*F+v*T+m*R,e[9]=c*F+M*T+b*R,e[10]=f*F+h*T+y*R,e[11]=s*F+l*T+d*R,e):null},h.rotateX=function(t,r,n){var e=Math.sin(r),a=Math.cos(r),u=t[4],i=t[5],o=t[6],c=t[7],f=t[8],s=t[9],v=t[10],M=t[11];return n?t!==n&&(n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15]):n=t,n[4]=u*a+f*e,n[5]=i*a+s*e,n[6]=o*a+v*e,n[7]=c*a+M*e,n[8]=u*-e+f*a,n[9]=i*-e+s*a,n[10]=o*-e+v*a,n[11]=c*-e+M*a,n},h.rotateY=function(t,r,n){var e=Math.sin(r),a=Math.cos(r),u=t[0],i=t[1],o=t[2],c=t[3],f=t[8],s=t[9],v=t[10],M=t[11];return n?t!==n&&(n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15]):n=t,n[0]=u*a+f*-e,n[1]=i*a+s*-e,n[2]=o*a+v*-e,n[3]=c*a+M*-e,n[8]=u*e+f*a,n[9]=i*e+s*a,n[10]=o*e+v*a,n[11]=c*e+M*a,n},h.rotateZ=function(t,r,n){var e=Math.sin(r),a=Math.cos(r),u=t[0],i=t[1],o=t[2],c=t[3],f=t[4],s=t[5],v=t[6],M=t[7];return n?t!==n&&(n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15]):n=t,n[0]=u*a+f*e,n[1]=i*a+s*e,n[2]=o*a+v*e,n[3]=c*a+M*e,n[4]=u*-e+f*a,n[5]=i*-e+s*a,n[6]=o*-e+v*a,n[7]=c*-e+M*a,n},h.frustum=function(t,r,n,e,a,u,i){i||(i=h.create());var o=r-t,c=e-n,f=u-a;return i[0]=2*a/o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=2*a/c,i[6]=0,i[7]=0,i[8]=(r+t)/o,i[9]=(e+n)/c,i[10]=-(u+a)/f,i[11]=-1,i[12]=0,i[13]=0,i[14]=-u*a*2/f,i[15]=0,i},h.perspective=function(t,r,n,e,a){var u=n*Math.tan(t*Math.PI/360),i=u*r;return h.frustum(-i,i,-u,u,n,e,a)},h.ortho=function(t,r,n,e,a,u,i){i||(i=h.create());var o=r-t,c=e-n,f=u-a;return i[0]=2/o,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=2/c,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=-2/f,i[11]=0,i[12]=-(t+r)/o,i[13]=-(e+n)/c,i[14]=-(u+a)/f,i[15]=1,i},h.lookAt=function(t,r,n,e){e||(e=h.create());var a,u,i,o,c,f,s,v,M,l,m=t[0],b=t[1],y=t[2],d=n[0],p=n[1],q=n[2],A=r[0],g=r[1],x=r[2];return m===A&&b===g&&y===x?h.identity(e):(s=m-A,v=b-g,M=y-x,l=1/Math.sqrt(s*s+v*v+M*M),s*=l,v*=l,M*=l,a=p*M-q*v,u=q*s-d*M,i=d*v-p*s,l=Math.sqrt(a*a+u*u+i*i),l?(a*=l=1/l,u*=l,i*=l):(a=0,u=0,i=0),o=v*i-M*u,c=M*a-s*i,f=s*u-v*a,l=Math.sqrt(o*o+c*c+f*f),l?(o*=l=1/l,c*=l,f*=l):(o=0,c=0,f=0),e[0]=a,e[1]=o,e[2]=s,e[3]=0,e[4]=u,e[5]=c,e[6]=v,e[7]=0,e[8]=i,e[9]=f,e[10]=M,e[11]=0,e[12]=-(a*m+u*b+i*y),e[13]=-(o*m+c*b+f*y),e[14]=-(s*m+v*b+M*y),e[15]=1,e)},h.fromRotationTranslation=function(t,r,n){n||(n=h.create());var e=t[0],a=t[1],u=t[2],i=t[3],o=e+e,c=a+a,f=u+u,s=e*o,v=e*c,M=e*f,l=a*c,m=a*f,b=u*f,y=i*o,d=i*c,p=i*f;return n[0]=1-(l+b),n[1]=v+p,n[2]=M-d,n[3]=0,n[4]=v-p,n[5]=1-(s+b),n[6]=m+y,n[7]=0,n[8]=M+d,n[9]=m-y,n[10]=1-(s+l),n[11]=0,n[12]=r[0],n[13]=r[1],n[14]=r[2],n[15]=1,n},h.str=function(t){return"["+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+", "+t[9]+", "+t[10]+", "+t[11]+", "+t[12]+", "+t[13]+", "+t[14]+", "+t[15]+"]"};var l={};l.create=function(t){var r=new a(4);return t?(r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[3]):r[0]=r[1]=r[2]=r[3]=0,r},l.createFrom=function(t,r,n,e){var u=new a(4);return u[0]=t,u[1]=r,u[2]=n,u[3]=e,u},l.set=function(t,r){return r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[3],r},l.equal=function(t,r){return t===r||Math.abs(t[0]-r[0])<1e-6&&Math.abs(t[1]-r[1])<1e-6&&Math.abs(t[2]-r[2])<1e-6&&Math.abs(t[3]-r[3])<1e-6},l.identity=function(t){return t||(t=l.create()),t[0]=0,t[1]=0,t[2]=0,t[3]=1,t};var m=l.identity();l.calculateW=function(t,r){var n=t[0],e=t[1],a=t[2];return r&&t!==r?(r[0]=n,r[1]=e,r[2]=a,r[3]=-Math.sqrt(Math.abs(1-n*n-e*e-a*a)),r):(t[3]=-Math.sqrt(Math.abs(1-n*n-e*e-a*a)),t)},l.dot=function(t,r){return t[0]*r[0]+t[1]*r[1]+t[2]*r[2]+t[3]*r[3]},l.inverse=function(t,r){var n=t[0],e=t[1],a=t[2],u=t[3],i=n*n+e*e+a*a+u*u,o=i?1/i:0;return r&&t!==r?(r[0]=-t[0]*o,r[1]=-t[1]*o,r[2]=-t[2]*o,r[3]=t[3]*o,r):(t[0]*=-o,t[1]*=-o,t[2]*=-o,t[3]*=o,t)},l.conjugate=function(t,r){return r&&t!==r?(r[0]=-t[0],r[1]=-t[1],r[2]=-t[2],r[3]=t[3],r):(t[0]*=-1,t[1]*=-1,t[2]*=-1,t)},l.length=function(t){var r=t[0],n=t[1],e=t[2],a=t[3];return Math.sqrt(r*r+n*n+e*e+a*a)},l.normalize=function(t,r){r||(r=t);var n=t[0],e=t[1],a=t[2],u=t[3],i=Math.sqrt(n*n+e*e+a*a+u*u);return 0===i?(r[0]=0,r[1]=0,r[2]=0,r[3]=0,r):(i=1/i,r[0]=n*i,r[1]=e*i,r[2]=a*i,r[3]=u*i,r)},l.add=function(t,r,n){return n&&t!==n?(n[0]=t[0]+r[0],n[1]=t[1]+r[1],n[2]=t[2]+r[2],n[3]=t[3]+r[3],n):(t[0]+=r[0],t[1]+=r[1],t[2]+=r[2],t[3]+=r[3],t)},l.multiply=function(t,r,n){n||(n=t);var e=t[0],a=t[1],u=t[2],i=t[3],o=r[0],c=r[1],f=r[2],s=r[3];return n[0]=e*s+i*o+a*f-u*c,n[1]=a*s+i*c+u*o-e*f,n[2]=u*s+i*f+e*c-a*o,n[3]=i*s-e*o-a*c-u*f,n},l.multiplyVec3=function(t,r,n){n||(n=r);var e=r[0],a=r[1],u=r[2],i=t[0],o=t[1],c=t[2],f=t[3],s=f*e+o*u-c*a,v=f*a+c*e-i*u,M=f*u+i*a-o*e,h=-i*e-o*a-c*u;return n[0]=s*f+h*-i+v*-c-M*-o,n[1]=v*f+h*-o+M*-i-s*-c,n[2]=M*f+h*-c+s*-o-v*-i,n},l.scale=function(t,r,n){return n&&t!==n?(n[0]=t[0]*r,n[1]=t[1]*r,n[2]=t[2]*r,n[3]=t[3]*r,n):(t[0]*=r,t[1]*=r,t[2]*=r,t[3]*=r,t)},l.toMat3=function(t,r){r||(r=M.create());var n=t[0],e=t[1],a=t[2],u=t[3],i=n+n,o=e+e,c=a+a,f=n*i,s=n*o,v=n*c,h=e*o,l=e*c,m=a*c,b=u*i,y=u*o,d=u*c;return r[0]=1-(h+m),r[1]=s+d,r[2]=v-y,r[3]=s-d,r[4]=1-(f+m),r[5]=l+b,r[6]=v+y,r[7]=l-b,r[8]=1-(f+h),r},l.toMat4=function(t,r){r||(r=h.create());var n=t[0],e=t[1],a=t[2],u=t[3],i=n+n,o=e+e,c=a+a,f=n*i,s=n*o,v=n*c,M=e*o,l=e*c,m=a*c,b=u*i,y=u*o,d=u*c;return r[0]=1-(M+m),r[1]=s+d,r[2]=v-y,r[3]=0,r[4]=s-d,r[5]=1-(f+m),r[6]=l+b,r[7]=0,r[8]=v+y,r[9]=l-b,r[10]=1-(f+M),r[11]=0,r[12]=0,r[13]=0,r[14]=0,r[15]=1,r},l.slerp=function(t,r,n,e){e||(e=t);var a,u,i,o,c=t[0]*r[0]+t[1]*r[1]+t[2]*r[2]+t[3]*r[3];return Math.abs(c)>=1?(e!==t&&(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3]),e):(a=Math.acos(c),u=Math.sqrt(1-c*c),Math.abs(u)<.001?(e[0]=.5*t[0]+.5*r[0],e[1]=.5*t[1]+.5*r[1],e[2]=.5*t[2]+.5*r[2],e[3]=.5*t[3]+.5*r[3],e):(i=Math.sin((1-n)*a)/u,o=Math.sin(n*a)/u,e[0]=t[0]*i+r[0]*o,e[1]=t[1]*i+r[1]*o,e[2]=t[2]*i+r[2]*o,e[3]=t[3]*i+r[3]*o,e))},l.fromRotationMatrix=function(t,r){r||(r=l.create());var n,e=t[0]+t[4]+t[8];if(e>0)n=Math.sqrt(e+1),r[3]=.5*n,n=.5/n,r[0]=(t[7]-t[5])*n,r[1]=(t[2]-t[6])*n,r[2]=(t[3]-t[1])*n;else{var a=l.fromRotationMatrix.s_iNext=l.fromRotationMatrix.s_iNext||[1,2,0],u=0;t[4]>t[0]&&(u=1),t[8]>t[3*u+u]&&(u=2);var i=a[u],o=a[i];n=Math.sqrt(t[3*u+u]-t[3*i+i]-t[3*o+o]+1),r[u]=.5*n,n=.5/n,r[3]=(t[3*o+i]-t[3*i+o])*n,r[i]=(t[3*i+u]+t[3*u+i])*n,r[o]=(t[3*o+u]+t[3*u+o])*n}return r},M.toQuat4=l.fromRotationMatrix,function(){var t=M.create();l.fromAxes=function(r,n,e,a){return t[0]=n[0],t[3]=n[1],t[6]=n[2],t[1]=e[0],t[4]=e[1],t[7]=e[2],t[2]=r[0],t[5]=r[1],t[8]=r[2],l.fromRotationMatrix(t,a)}}(),l.identity=function(t){return t||(t=l.create()),t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},l.fromAngleAxis=function(t,r,n){n||(n=l.create());var e=.5*t,a=Math.sin(e);return n[3]=Math.cos(e),n[0]=a*r[0],n[1]=a*r[1],n[2]=a*r[2],n},l.toAngleAxis=function(t,r){r||(r=t);var n=t[0]*t[0]+t[1]*t[1]+t[2]*t[2];if(n>0){r[3]=2*Math.acos(t[3]);var a=e.invsqrt(n);r[0]=t[0]*a,r[1]=t[1]*a,r[2]=t[2]*a}else r[3]=0,r[0]=1,r[1]=0,r[2]=0;return r},l.str=function(t){return"["+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+"]"};var b={};b.create=function(t){var r=new a(2);return t?(r[0]=t[0],r[1]=t[1]):(r[0]=0,r[1]=0),r},b.createFrom=function(t,r){var n=new a(2);return n[0]=t,n[1]=r,n},b.add=function(t,r,n){return n||(n=r),n[0]=t[0]+r[0],n[1]=t[1]+r[1],n},b.subtract=function(t,r,n){return n||(n=r),n[0]=t[0]-r[0],n[1]=t[1]-r[1],n},b.multiply=function(t,r,n){return n||(n=r),n[0]=t[0]*r[0],n[1]=t[1]*r[1],n},b.divide=function(t,r,n){return n||(n=r),n[0]=t[0]/r[0],n[1]=t[1]/r[1],n},b.scale=function(t,r,n){return n||(n=t),n[0]=t[0]*r,n[1]=t[1]*r,n},b.dist=function(t,r){var n=r[0]-t[0],e=r[1]-t[1];return Math.sqrt(n*n+e*e)},b.set=function(t,r){return r[0]=t[0],r[1]=t[1],r},b.equal=function(t,r){return t===r||Math.abs(t[0]-r[0])<1e-6&&Math.abs(t[1]-r[1])<1e-6},b.negate=function(t,r){return r||(r=t),r[0]=-t[0],r[1]=-t[1],r},b.normalize=function(t,r){r||(r=t);var n=t[0]*t[0]+t[1]*t[1];return n>0?(n=Math.sqrt(n),r[0]=t[0]/n,r[1]=t[1]/n):r[0]=r[1]=0,r},b.cross=function(t,r,n){var e=t[0]*r[1]-t[1]*r[0];return n?(n[0]=n[1]=0,n[2]=e,n):e},b.length=function(t){var r=t[0],n=t[1];return Math.sqrt(r*r+n*n)},b.squaredLength=function(t){var r=t[0],n=t[1];return r*r+n*n},b.dot=function(t,r){return t[0]*r[0]+t[1]*r[1]},b.direction=function(t,r,n){n||(n=t);var e=t[0]-r[0],a=t[1]-r[1],u=e*e+a*a;return u?(u=1/Math.sqrt(u),n[0]=e*u,n[1]=a*u,n):(n[0]=0,n[1]=0,n[2]=0,n)},b.lerp=function(t,r,n,e){return e||(e=t),e[0]=t[0]+n*(r[0]-t[0]),e[1]=t[1]+n*(r[1]-t[1]),e},b.str=function(t){return"["+t[0]+", "+t[1]+"]"};var y={};y.create=function(t){var r=new a(4);return t?(r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[3]):r[0]=r[1]=r[2]=r[3]=0,r},y.createFrom=function(t,r,n,e){var u=new a(4);return u[0]=t,u[1]=r,u[2]=n,u[3]=e,u},y.set=function(t,r){return r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[3],r},y.equal=function(t,r){return t===r||Math.abs(t[0]-r[0])<1e-6&&Math.abs(t[1]-r[1])<1e-6&&Math.abs(t[2]-r[2])<1e-6&&Math.abs(t[3]-r[3])<1e-6},y.identity=function(t){return t||(t=y.create()),t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},y.transpose=function(t,r){if(!r||t===r){var n=t[1];return t[1]=t[2],t[2]=n,t}return r[0]=t[0],r[1]=t[2],r[2]=t[1],r[3]=t[3],r},y.determinant=function(t){return t[0]*t[3]-t[2]*t[1]},y.inverse=function(t,r){r||(r=t);var n=t[0],e=t[1],a=t[2],u=t[3],i=n*u-a*e;return i?(i=1/i,r[0]=u*i,r[1]=-e*i,r[2]=-a*i,r[3]=n*i,r):null},y.multiply=function(t,r,n){n||(n=t);var e=t[0],a=t[1],u=t[2],i=t[3];return n[0]=e*r[0]+a*r[2],n[1]=e*r[1]+a*r[3],n[2]=u*r[0]+i*r[2],n[3]=u*r[1]+i*r[3],n},y.rotate=function(t,r,n){n||(n=t);var e=t[0],a=t[1],u=t[2],i=t[3],o=Math.sin(r),c=Math.cos(r);return n[0]=e*c+a*o,n[1]=e*-o+a*c,n[2]=u*c+i*o,n[3]=u*-o+i*c,n},y.multiplyVec2=function(t,r,n){n||(n=r);var e=r[0],a=r[1];return n[0]=e*t[0]+a*t[1],n[1]=e*t[2]+a*t[3],n},y.scale=function(t,r,n){n||(n=t);var e=t[0],a=t[1],u=t[2],i=t[3],o=r[0],c=r[1];return n[0]=e*o,n[1]=a*c,n[2]=u*o,n[3]=i*c,n},y.str=function(t){return"["+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+"]"};var d={};return d.create=function(t){var r=new a(4);return t?(r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[3]):(r[0]=0,r[1]=0,r[2]=0,r[3]=0),r},d.createFrom=function(t,r,n,e){var u=new a(4);return u[0]=t,u[1]=r,u[2]=n,u[3]=e,u},d.add=function(t,r,n){return n||(n=r),n[0]=t[0]+r[0],n[1]=t[1]+r[1],n[2]=t[2]+r[2],n[3]=t[3]+r[3],n},d.subtract=function(t,r,n){return n||(n=r),n[0]=t[0]-r[0],n[1]=t[1]-r[1],n[2]=t[2]-r[2],n[3]=t[3]-r[3],n},d.multiply=function(t,r,n){return n||(n=r),n[0]=t[0]*r[0],n[1]=t[1]*r[1],n[2]=t[2]*r[2],n[3]=t[3]*r[3],n},d.divide=function(t,r,n){return n||(n=r),n[0]=t[0]/r[0],n[1]=t[1]/r[1],n[2]=t[2]/r[2],n[3]=t[3]/r[3],n},d.scale=function(t,r,n){return n||(n=t),n[0]=t[0]*r,n[1]=t[1]*r,n[2]=t[2]*r,n[3]=t[3]*r,n},d.set=function(t,r){return r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[3],r},d.equal=function(t,r){return t===r||Math.abs(t[0]-r[0])<1e-6&&Math.abs(t[1]-r[1])<1e-6&&Math.abs(t[2]-r[2])<1e-6&&Math.abs(t[3]-r[3])<1e-6},d.negate=function(t,r){return r||(r=t),r[0]=-t[0],r[1]=-t[1],r[2]=-t[2],r[3]=-t[3],r},d.length=function(t){var r=t[0],n=t[1],e=t[2],a=t[3];return Math.sqrt(r*r+n*n+e*e+a*a)},d.squaredLength=function(t){var r=t[0],n=t[1],e=t[2],a=t[3];return r*r+n*n+e*e+a*a},d.lerp=function(t,r,n,e){return e||(e=t),e[0]=t[0]+n*(r[0]-t[0]),e[1]=t[1]+n*(r[1]-t[1]),e[2]=t[2]+n*(r[2]-t[2]),e[3]=t[3]+n*(r[3]-t[3]),e},d.str=function(t){return"["+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+"]"},t&&(t.glMatrixArrayType=a,t.MatrixArray=a,t.setMatrixArrayType=r,t.determineMatrixArrayType=n,t.glMath=e,t.vec2=b,t.vec3=u,t.vec4=d,t.mat2=y,t.mat3=M,t.mat4=h,t.quat4=l),{glMatrixArrayType:a,MatrixArray:a,setMatrixArrayType:r,determineMatrixArrayType:n,glMath:e,vec2:b,vec3:u,vec4:d,mat2:y,mat3:M,mat4:h,quat4:l}});
+++ /dev/null
-/**
- * @fileoverview gl-matrix - High performance matrix and vector operations for WebGL
- * @author Brandon Jones
- * @author Colin MacKenzie IV
- * @version 1.3.7
- */
-
-/*
- * Copyright (c) 2012 Brandon Jones, Colin MacKenzie IV
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software. If you use this software
- * in a product, an acknowledgment in the product documentation would be
- * appreciated but is not required.
- *
- * 2. Altered source versions must be plainly marked as such, and must not
- * be misrepresented as being the original software.
- *
- * 3. This notice may not be removed or altered from any source
- * distribution.
- */
-
-// Updated to use a modification of the "returnExportsGlobal" pattern from https://github.com/umdjs/umd
-
-(function (root, factory) {
- if (typeof exports === 'object') {
- // Node. Does not work with strict CommonJS, but
- // only CommonJS-like enviroments that support module.exports,
- // like Node.
- module.exports = factory(global);
- } else if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define([], function () {
- return factory(root);
- });
- } else {
- // Browser globals
- factory(root);
- }
-}(this, function (root) {
- "use strict";
-
- // Tweak to your liking
- var FLOAT_EPSILON = 0.000001;
-
- var glMath = {};
- (function() {
- if (typeof(Float32Array) != 'undefined') {
- var y = new Float32Array(1);
- var i = new Int32Array(y.buffer);
-
- /**
- * Fast way to calculate the inverse square root,
- * see http://jsperf.com/inverse-square-root/5
- *
- * If typed arrays are not available, a slower
- * implementation will be used.
- *
- * @param {Number} number the number
- * @returns {Number} Inverse square root
- */
- glMath.invsqrt = function(number) {
- var x2 = number * 0.5;
- y[0] = number;
- var threehalfs = 1.5;
-
- i[0] = 0x5f3759df - (i[0] >> 1);
-
- var number2 = y[0];
-
- return number2 * (threehalfs - (x2 * number2 * number2));
- };
- } else {
- glMath.invsqrt = function(number) { return 1.0 / Math.sqrt(number); };
- }
- })();
-
- /**
- * @class System-specific optimal array type
- * @name MatrixArray
- */
- var MatrixArray = null;
-
- // explicitly sets and returns the type of array to use within glMatrix
- function setMatrixArrayType(type) {
- MatrixArray = type;
- return MatrixArray;
- }
-
- // auto-detects and returns the best type of array to use within glMatrix, falling
- // back to Array if typed arrays are unsupported
- function determineMatrixArrayType() {
- MatrixArray = (typeof Float32Array !== 'undefined') ? Float32Array : Array;
- return MatrixArray;
- }
-
- determineMatrixArrayType();
-
- /**
- * @class 3 Dimensional Vector
- * @name vec3
- */
- var vec3 = {};
-
- /**
- * Creates a new instance of a vec3 using the default array type
- * Any javascript array-like objects containing at least 3 numeric elements can serve as a vec3
- *
- * @param {vec3} [vec] vec3 containing values to initialize with
- *
- * @returns {vec3} New vec3
- */
- vec3.create = function (vec) {
- var dest = new MatrixArray(3);
-
- if (vec) {
- dest[0] = vec[0];
- dest[1] = vec[1];
- dest[2] = vec[2];
- } else {
- dest[0] = dest[1] = dest[2] = 0;
- }
-
- return dest;
- };
-
- /**
- * Creates a new instance of a vec3, initializing it with the given arguments
- *
- * @param {number} x X value
- * @param {number} y Y value
- * @param {number} z Z value
-
- * @returns {vec3} New vec3
- */
- vec3.createFrom = function (x, y, z) {
- var dest = new MatrixArray(3);
-
- dest[0] = x;
- dest[1] = y;
- dest[2] = z;
-
- return dest;
- };
-
- /**
- * Copies the values of one vec3 to another
- *
- * @param {vec3} vec vec3 containing values to copy
- * @param {vec3} dest vec3 receiving copied values
- *
- * @returns {vec3} dest
- */
- vec3.set = function (vec, dest) {
- dest[0] = vec[0];
- dest[1] = vec[1];
- dest[2] = vec[2];
-
- return dest;
- };
-
- /**
- * Compares two vectors for equality within a certain margin of error
- *
- * @param {vec3} a First vector
- * @param {vec3} b Second vector
- *
- * @returns {Boolean} True if a is equivalent to b
- */
- vec3.equal = function (a, b) {
- return a === b || (
- Math.abs(a[0] - b[0]) < FLOAT_EPSILON &&
- Math.abs(a[1] - b[1]) < FLOAT_EPSILON &&
- Math.abs(a[2] - b[2]) < FLOAT_EPSILON
- );
- };
-
- /**
- * Performs a vector addition
- *
- * @param {vec3} vec First operand
- * @param {vec3} vec2 Second operand
- * @param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec
- *
- * @returns {vec3} dest if specified, vec otherwise
- */
- vec3.add = function (vec, vec2, dest) {
- if (!dest || vec === dest) {
- vec[0] += vec2[0];
- vec[1] += vec2[1];
- vec[2] += vec2[2];
- return vec;
- }
-
- dest[0] = vec[0] + vec2[0];
- dest[1] = vec[1] + vec2[1];
- dest[2] = vec[2] + vec2[2];
- return dest;
- };
-
- /**
- * Performs a vector subtraction
- *
- * @param {vec3} vec First operand
- * @param {vec3} vec2 Second operand
- * @param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec
- *
- * @returns {vec3} dest if specified, vec otherwise
- */
- vec3.subtract = function (vec, vec2, dest) {
- if (!dest || vec === dest) {
- vec[0] -= vec2[0];
- vec[1] -= vec2[1];
- vec[2] -= vec2[2];
- return vec;
- }
-
- dest[0] = vec[0] - vec2[0];
- dest[1] = vec[1] - vec2[1];
- dest[2] = vec[2] - vec2[2];
- return dest;
- };
-
- /**
- * Performs a vector multiplication
- *
- * @param {vec3} vec First operand
- * @param {vec3} vec2 Second operand
- * @param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec
- *
- * @returns {vec3} dest if specified, vec otherwise
- */
- vec3.multiply = function (vec, vec2, dest) {
- if (!dest || vec === dest) {
- vec[0] *= vec2[0];
- vec[1] *= vec2[1];
- vec[2] *= vec2[2];
- return vec;
- }
-
- dest[0] = vec[0] * vec2[0];
- dest[1] = vec[1] * vec2[1];
- dest[2] = vec[2] * vec2[2];
- return dest;
- };
-
- /**
- * Negates the components of a vec3
- *
- * @param {vec3} vec vec3 to negate
- * @param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec
- *
- * @returns {vec3} dest if specified, vec otherwise
- */
- vec3.negate = function (vec, dest) {
- if (!dest) { dest = vec; }
-
- dest[0] = -vec[0];
- dest[1] = -vec[1];
- dest[2] = -vec[2];
- return dest;
- };
-
- /**
- * Multiplies the components of a vec3 by a scalar value
- *
- * @param {vec3} vec vec3 to scale
- * @param {number} val Value to scale by
- * @param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec
- *
- * @returns {vec3} dest if specified, vec otherwise
- */
- vec3.scale = function (vec, val, dest) {
- if (!dest || vec === dest) {
- vec[0] *= val;
- vec[1] *= val;
- vec[2] *= val;
- return vec;
- }
-
- dest[0] = vec[0] * val;
- dest[1] = vec[1] * val;
- dest[2] = vec[2] * val;
- return dest;
- };
-
- /**
- * Generates a unit vector of the same direction as the provided vec3
- * If vector length is 0, returns [0, 0, 0]
- *
- * @param {vec3} vec vec3 to normalize
- * @param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec
- *
- * @returns {vec3} dest if specified, vec otherwise
- */
- vec3.normalize = function (vec, dest) {
- if (!dest) { dest = vec; }
-
- var x = vec[0], y = vec[1], z = vec[2],
- len = Math.sqrt(x * x + y * y + z * z);
-
- if (!len) {
- dest[0] = 0;
- dest[1] = 0;
- dest[2] = 0;
- return dest;
- } else if (len === 1) {
- dest[0] = x;
- dest[1] = y;
- dest[2] = z;
- return dest;
- }
-
- len = 1 / len;
- dest[0] = x * len;
- dest[1] = y * len;
- dest[2] = z * len;
- return dest;
- };
-
- /**
- * Generates the cross product of two vec3s
- *
- * @param {vec3} vec First operand
- * @param {vec3} vec2 Second operand
- * @param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec
- *
- * @returns {vec3} dest if specified, vec otherwise
- */
- vec3.cross = function (vec, vec2, dest) {
- if (!dest) { dest = vec; }
-
- var x = vec[0], y = vec[1], z = vec[2],
- x2 = vec2[0], y2 = vec2[1], z2 = vec2[2];
-
- dest[0] = y * z2 - z * y2;
- dest[1] = z * x2 - x * z2;
- dest[2] = x * y2 - y * x2;
- return dest;
- };
-
- /**
- * Caclulates the length of a vec3
- *
- * @param {vec3} vec vec3 to calculate length of
- *
- * @returns {number} Length of vec
- */
- vec3.length = function (vec) {
- var x = vec[0], y = vec[1], z = vec[2];
- return Math.sqrt(x * x + y * y + z * z);
- };
-
- /**
- * Caclulates the squared length of a vec3
- *
- * @param {vec3} vec vec3 to calculate squared length of
- *
- * @returns {number} Squared Length of vec
- */
- vec3.squaredLength = function (vec) {
- var x = vec[0], y = vec[1], z = vec[2];
- return x * x + y * y + z * z;
- };
-
- /**
- * Caclulates the dot product of two vec3s
- *
- * @param {vec3} vec First operand
- * @param {vec3} vec2 Second operand
- *
- * @returns {number} Dot product of vec and vec2
- */
- vec3.dot = function (vec, vec2) {
- return vec[0] * vec2[0] + vec[1] * vec2[1] + vec[2] * vec2[2];
- };
-
- /**
- * Generates a unit vector pointing from one vector to another
- *
- * @param {vec3} vec Origin vec3
- * @param {vec3} vec2 vec3 to point to
- * @param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec
- *
- * @returns {vec3} dest if specified, vec otherwise
- */
- vec3.direction = function (vec, vec2, dest) {
- if (!dest) { dest = vec; }
-
- var x = vec[0] - vec2[0],
- y = vec[1] - vec2[1],
- z = vec[2] - vec2[2],
- len = Math.sqrt(x * x + y * y + z * z);
-
- if (!len) {
- dest[0] = 0;
- dest[1] = 0;
- dest[2] = 0;
- return dest;
- }
-
- len = 1 / len;
- dest[0] = x * len;
- dest[1] = y * len;
- dest[2] = z * len;
- return dest;
- };
-
- /**
- * Performs a linear interpolation between two vec3
- *
- * @param {vec3} vec First vector
- * @param {vec3} vec2 Second vector
- * @param {number} lerp Interpolation amount between the two inputs
- * @param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec
- *
- * @returns {vec3} dest if specified, vec otherwise
- */
- vec3.lerp = function (vec, vec2, lerp, dest) {
- if (!dest) { dest = vec; }
-
- dest[0] = vec[0] + lerp * (vec2[0] - vec[0]);
- dest[1] = vec[1] + lerp * (vec2[1] - vec[1]);
- dest[2] = vec[2] + lerp * (vec2[2] - vec[2]);
-
- return dest;
- };
-
- /**
- * Calculates the euclidian distance between two vec3
- *
- * Params:
- * @param {vec3} vec First vector
- * @param {vec3} vec2 Second vector
- *
- * @returns {number} Distance between vec and vec2
- */
- vec3.dist = function (vec, vec2) {
- var x = vec2[0] - vec[0],
- y = vec2[1] - vec[1],
- z = vec2[2] - vec[2];
-
- return Math.sqrt(x*x + y*y + z*z);
- };
-
- // Pre-allocated to prevent unecessary garbage collection
- var unprojectMat = null;
- var unprojectVec = new MatrixArray(4);
- /**
- * Projects the specified vec3 from screen space into object space
- * Based on the <a href="http://webcvs.freedesktop.org/mesa/Mesa/src/glu/mesa/project.c?revision=1.4&view=markup">Mesa gluUnProject implementation</a>
- *
- * @param {vec3} vec Screen-space vector to project
- * @param {mat4} view View matrix
- * @param {mat4} proj Projection matrix
- * @param {vec4} viewport Viewport as given to gl.viewport [x, y, width, height]
- * @param {vec3} [dest] vec3 receiving unprojected result. If not specified result is written to vec
- *
- * @returns {vec3} dest if specified, vec otherwise
- */
- vec3.unproject = function (vec, view, proj, viewport, dest) {
- if (!dest) { dest = vec; }
-
- if(!unprojectMat) {
- unprojectMat = mat4.create();
- }
-
- var m = unprojectMat;
- var v = unprojectVec;
-
- v[0] = (vec[0] - viewport[0]) * 2.0 / viewport[2] - 1.0;
- v[1] = (vec[1] - viewport[1]) * 2.0 / viewport[3] - 1.0;
- v[2] = 2.0 * vec[2] - 1.0;
- v[3] = 1.0;
-
- mat4.multiply(proj, view, m);
- if(!mat4.inverse(m)) { return null; }
-
- mat4.multiplyVec4(m, v);
- if(v[3] === 0.0) { return null; }
-
- dest[0] = v[0] / v[3];
- dest[1] = v[1] / v[3];
- dest[2] = v[2] / v[3];
-
- return dest;
- };
-
- var xUnitVec3 = vec3.createFrom(1,0,0);
- var yUnitVec3 = vec3.createFrom(0,1,0);
- var zUnitVec3 = vec3.createFrom(0,0,1);
-
- var tmpvec3 = vec3.create();
- /**
- * Generates a quaternion of rotation between two given normalized vectors
- *
- * @param {vec3} a Normalized source vector
- * @param {vec3} b Normalized target vector
- * @param {quat4} [dest] quat4 receiving operation result.
- *
- * @returns {quat4} dest if specified, a new quat4 otherwise
- */
- vec3.rotationTo = function (a, b, dest) {
- if (!dest) { dest = quat4.create(); }
-
- var d = vec3.dot(a, b);
- var axis = tmpvec3;
- if (d >= 1.0) {
- quat4.set(identityQuat4, dest);
- } else if (d < (0.000001 - 1.0)) {
- vec3.cross(xUnitVec3, a, axis);
- if (vec3.length(axis) < 0.000001)
- vec3.cross(yUnitVec3, a, axis);
- if (vec3.length(axis) < 0.000001)
- vec3.cross(zUnitVec3, a, axis);
- vec3.normalize(axis);
- quat4.fromAngleAxis(Math.PI, axis, dest);
- } else {
- var s = Math.sqrt((1.0 + d) * 2.0);
- var sInv = 1.0 / s;
- vec3.cross(a, b, axis);
- dest[0] = axis[0] * sInv;
- dest[1] = axis[1] * sInv;
- dest[2] = axis[2] * sInv;
- dest[3] = s * 0.5;
- quat4.normalize(dest);
- }
- if (dest[3] > 1.0) dest[3] = 1.0;
- else if (dest[3] < -1.0) dest[3] = -1.0;
- return dest;
- };
-
- /**
- * Returns a string representation of a vector
- *
- * @param {vec3} vec Vector to represent as a string
- *
- * @returns {string} String representation of vec
- */
- vec3.str = function (vec) {
- return '[' + vec[0] + ', ' + vec[1] + ', ' + vec[2] + ']';
- };
-
- /**
- * @class 3x3 Matrix
- * @name mat3
- */
- var mat3 = {};
-
- /**
- * Creates a new instance of a mat3 using the default array type
- * Any javascript array-like object containing at least 9 numeric elements can serve as a mat3
- *
- * @param {mat3} [mat] mat3 containing values to initialize with
- *
- * @returns {mat3} New mat3
- */
- mat3.create = function (mat) {
- var dest = new MatrixArray(9);
-
- if (mat) {
- dest[0] = mat[0];
- dest[1] = mat[1];
- dest[2] = mat[2];
- dest[3] = mat[3];
- dest[4] = mat[4];
- dest[5] = mat[5];
- dest[6] = mat[6];
- dest[7] = mat[7];
- dest[8] = mat[8];
- } else {
- dest[0] = dest[1] =
- dest[2] = dest[3] =
- dest[4] = dest[5] =
- dest[6] = dest[7] =
- dest[8] = 0;
- }
-
- return dest;
- };
-
- /**
- * Creates a new instance of a mat3, initializing it with the given arguments
- *
- * @param {number} m00
- * @param {number} m01
- * @param {number} m02
- * @param {number} m10
- * @param {number} m11
- * @param {number} m12
- * @param {number} m20
- * @param {number} m21
- * @param {number} m22
-
- * @returns {mat3} New mat3
- */
- mat3.createFrom = function (m00, m01, m02, m10, m11, m12, m20, m21, m22) {
- var dest = new MatrixArray(9);
-
- dest[0] = m00;
- dest[1] = m01;
- dest[2] = m02;
- dest[3] = m10;
- dest[4] = m11;
- dest[5] = m12;
- dest[6] = m20;
- dest[7] = m21;
- dest[8] = m22;
-
- return dest;
- };
-
- /**
- * Calculates the determinant of a mat3
- *
- * @param {mat3} mat mat3 to calculate determinant of
- *
- * @returns {Number} determinant of mat
- */
- mat3.determinant = function (mat) {
- var a00 = mat[0], a01 = mat[1], a02 = mat[2],
- a10 = mat[3], a11 = mat[4], a12 = mat[5],
- a20 = mat[6], a21 = mat[7], a22 = mat[8];
-
- return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20);
- };
-
- /**
- * Calculates the inverse matrix of a mat3
- *
- * @param {mat3} mat mat3 to calculate inverse of
- * @param {mat3} [dest] mat3 receiving inverse matrix. If not specified result is written to mat
- *
- * @param {mat3} dest is specified, mat otherwise, null if matrix cannot be inverted
- */
- mat3.inverse = function (mat, dest) {
- var a00 = mat[0], a01 = mat[1], a02 = mat[2],
- a10 = mat[3], a11 = mat[4], a12 = mat[5],
- a20 = mat[6], a21 = mat[7], a22 = mat[8],
-
- b01 = a22 * a11 - a12 * a21,
- b11 = -a22 * a10 + a12 * a20,
- b21 = a21 * a10 - a11 * a20,
-
- d = a00 * b01 + a01 * b11 + a02 * b21,
- id;
-
- if (!d) { return null; }
- id = 1 / d;
-
- if (!dest) { dest = mat3.create(); }
-
- dest[0] = b01 * id;
- dest[1] = (-a22 * a01 + a02 * a21) * id;
- dest[2] = (a12 * a01 - a02 * a11) * id;
- dest[3] = b11 * id;
- dest[4] = (a22 * a00 - a02 * a20) * id;
- dest[5] = (-a12 * a00 + a02 * a10) * id;
- dest[6] = b21 * id;
- dest[7] = (-a21 * a00 + a01 * a20) * id;
- dest[8] = (a11 * a00 - a01 * a10) * id;
- return dest;
- };
-
- /**
- * Performs a matrix multiplication
- *
- * @param {mat3} mat First operand
- * @param {mat3} mat2 Second operand
- * @param {mat3} [dest] mat3 receiving operation result. If not specified result is written to mat
- *
- * @returns {mat3} dest if specified, mat otherwise
- */
- mat3.multiply = function (mat, mat2, dest) {
- if (!dest) { dest = mat; }
-
-
- // Cache the matrix values (makes for huge speed increases!)
- var a00 = mat[0], a01 = mat[1], a02 = mat[2],
- a10 = mat[3], a11 = mat[4], a12 = mat[5],
- a20 = mat[6], a21 = mat[7], a22 = mat[8],
-
- b00 = mat2[0], b01 = mat2[1], b02 = mat2[2],
- b10 = mat2[3], b11 = mat2[4], b12 = mat2[5],
- b20 = mat2[6], b21 = mat2[7], b22 = mat2[8];
-
- dest[0] = b00 * a00 + b01 * a10 + b02 * a20;
- dest[1] = b00 * a01 + b01 * a11 + b02 * a21;
- dest[2] = b00 * a02 + b01 * a12 + b02 * a22;
-
- dest[3] = b10 * a00 + b11 * a10 + b12 * a20;
- dest[4] = b10 * a01 + b11 * a11 + b12 * a21;
- dest[5] = b10 * a02 + b11 * a12 + b12 * a22;
-
- dest[6] = b20 * a00 + b21 * a10 + b22 * a20;
- dest[7] = b20 * a01 + b21 * a11 + b22 * a21;
- dest[8] = b20 * a02 + b21 * a12 + b22 * a22;
-
- return dest;
- };
-
- /**
- * Transforms the vec2 according to the given mat3.
- *
- * @param {mat3} matrix mat3 to multiply against
- * @param {vec2} vec the vector to multiply
- * @param {vec2} [dest] an optional receiving vector. If not given, vec is used.
- *
- * @returns {vec2} The multiplication result
- **/
- mat3.multiplyVec2 = function(matrix, vec, dest) {
- if (!dest) dest = vec;
- var x = vec[0], y = vec[1];
- dest[0] = x * matrix[0] + y * matrix[3] + matrix[6];
- dest[1] = x * matrix[1] + y * matrix[4] + matrix[7];
- return dest;
- };
-
- /**
- * Transforms the vec3 according to the given mat3
- *
- * @param {mat3} matrix mat3 to multiply against
- * @param {vec3} vec the vector to multiply
- * @param {vec3} [dest] an optional receiving vector. If not given, vec is used.
- *
- * @returns {vec3} The multiplication result
- **/
- mat3.multiplyVec3 = function(matrix, vec, dest) {
- if (!dest) dest = vec;
- var x = vec[0], y = vec[1], z = vec[2];
- dest[0] = x * matrix[0] + y * matrix[3] + z * matrix[6];
- dest[1] = x * matrix[1] + y * matrix[4] + z * matrix[7];
- dest[2] = x * matrix[2] + y * matrix[5] + z * matrix[8];
-
- return dest;
- };
-
- /**
- * Copies the values of one mat3 to another
- *
- * @param {mat3} mat mat3 containing values to copy
- * @param {mat3} dest mat3 receiving copied values
- *
- * @returns {mat3} dest
- */
- mat3.set = function (mat, dest) {
- dest[0] = mat[0];
- dest[1] = mat[1];
- dest[2] = mat[2];
- dest[3] = mat[3];
- dest[4] = mat[4];
- dest[5] = mat[5];
- dest[6] = mat[6];
- dest[7] = mat[7];
- dest[8] = mat[8];
- return dest;
- };
-
- /**
- * Compares two matrices for equality within a certain margin of error
- *
- * @param {mat3} a First matrix
- * @param {mat3} b Second matrix
- *
- * @returns {Boolean} True if a is equivalent to b
- */
- mat3.equal = function (a, b) {
- return a === b || (
- Math.abs(a[0] - b[0]) < FLOAT_EPSILON &&
- Math.abs(a[1] - b[1]) < FLOAT_EPSILON &&
- Math.abs(a[2] - b[2]) < FLOAT_EPSILON &&
- Math.abs(a[3] - b[3]) < FLOAT_EPSILON &&
- Math.abs(a[4] - b[4]) < FLOAT_EPSILON &&
- Math.abs(a[5] - b[5]) < FLOAT_EPSILON &&
- Math.abs(a[6] - b[6]) < FLOAT_EPSILON &&
- Math.abs(a[7] - b[7]) < FLOAT_EPSILON &&
- Math.abs(a[8] - b[8]) < FLOAT_EPSILON
- );
- };
-
- /**
- * Sets a mat3 to an identity matrix
- *
- * @param {mat3} dest mat3 to set
- *
- * @returns dest if specified, otherwise a new mat3
- */
- mat3.identity = function (dest) {
- if (!dest) { dest = mat3.create(); }
- dest[0] = 1;
- dest[1] = 0;
- dest[2] = 0;
- dest[3] = 0;
- dest[4] = 1;
- dest[5] = 0;
- dest[6] = 0;
- dest[7] = 0;
- dest[8] = 1;
- return dest;
- };
-
- /**
- * Transposes a mat3 (flips the values over the diagonal)
- *
- * Params:
- * @param {mat3} mat mat3 to transpose
- * @param {mat3} [dest] mat3 receiving transposed values. If not specified result is written to mat
- *
- * @returns {mat3} dest is specified, mat otherwise
- */
- mat3.transpose = function (mat, dest) {
- // If we are transposing ourselves we can skip a few steps but have to cache some values
- if (!dest || mat === dest) {
- var a01 = mat[1], a02 = mat[2],
- a12 = mat[5];
-
- mat[1] = mat[3];
- mat[2] = mat[6];
- mat[3] = a01;
- mat[5] = mat[7];
- mat[6] = a02;
- mat[7] = a12;
- return mat;
- }
-
- dest[0] = mat[0];
- dest[1] = mat[3];
- dest[2] = mat[6];
- dest[3] = mat[1];
- dest[4] = mat[4];
- dest[5] = mat[7];
- dest[6] = mat[2];
- dest[7] = mat[5];
- dest[8] = mat[8];
- return dest;
- };
-
- /**
- * Copies the elements of a mat3 into the upper 3x3 elements of a mat4
- *
- * @param {mat3} mat mat3 containing values to copy
- * @param {mat4} [dest] mat4 receiving copied values
- *
- * @returns {mat4} dest if specified, a new mat4 otherwise
- */
- mat3.toMat4 = function (mat, dest) {
- if (!dest) { dest = mat4.create(); }
-
- dest[15] = 1;
- dest[14] = 0;
- dest[13] = 0;
- dest[12] = 0;
-
- dest[11] = 0;
- dest[10] = mat[8];
- dest[9] = mat[7];
- dest[8] = mat[6];
-
- dest[7] = 0;
- dest[6] = mat[5];
- dest[5] = mat[4];
- dest[4] = mat[3];
-
- dest[3] = 0;
- dest[2] = mat[2];
- dest[1] = mat[1];
- dest[0] = mat[0];
-
- return dest;
- };
-
- /**
- * Returns a string representation of a mat3
- *
- * @param {mat3} mat mat3 to represent as a string
- *
- * @param {string} String representation of mat
- */
- mat3.str = function (mat) {
- return '[' + mat[0] + ', ' + mat[1] + ', ' + mat[2] +
- ', ' + mat[3] + ', ' + mat[4] + ', ' + mat[5] +
- ', ' + mat[6] + ', ' + mat[7] + ', ' + mat[8] + ']';
- };
-
- /**
- * @class 4x4 Matrix
- * @name mat4
- */
- var mat4 = {};
-
- /**
- * Creates a new instance of a mat4 using the default array type
- * Any javascript array-like object containing at least 16 numeric elements can serve as a mat4
- *
- * @param {mat4} [mat] mat4 containing values to initialize with
- *
- * @returns {mat4} New mat4
- */
- mat4.create = function (mat) {
- var dest = new MatrixArray(16);
-
- if (mat) {
- dest[0] = mat[0];
- dest[1] = mat[1];
- dest[2] = mat[2];
- dest[3] = mat[3];
- dest[4] = mat[4];
- dest[5] = mat[5];
- dest[6] = mat[6];
- dest[7] = mat[7];
- dest[8] = mat[8];
- dest[9] = mat[9];
- dest[10] = mat[10];
- dest[11] = mat[11];
- dest[12] = mat[12];
- dest[13] = mat[13];
- dest[14] = mat[14];
- dest[15] = mat[15];
- }
-
- return dest;
- };
-
- /**
- * Creates a new instance of a mat4, initializing it with the given arguments
- *
- * @param {number} m00
- * @param {number} m01
- * @param {number} m02
- * @param {number} m03
- * @param {number} m10
- * @param {number} m11
- * @param {number} m12
- * @param {number} m13
- * @param {number} m20
- * @param {number} m21
- * @param {number} m22
- * @param {number} m23
- * @param {number} m30
- * @param {number} m31
- * @param {number} m32
- * @param {number} m33
-
- * @returns {mat4} New mat4
- */
- mat4.createFrom = function (m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
- var dest = new MatrixArray(16);
-
- dest[0] = m00;
- dest[1] = m01;
- dest[2] = m02;
- dest[3] = m03;
- dest[4] = m10;
- dest[5] = m11;
- dest[6] = m12;
- dest[7] = m13;
- dest[8] = m20;
- dest[9] = m21;
- dest[10] = m22;
- dest[11] = m23;
- dest[12] = m30;
- dest[13] = m31;
- dest[14] = m32;
- dest[15] = m33;
-
- return dest;
- };
-
- /**
- * Copies the values of one mat4 to another
- *
- * @param {mat4} mat mat4 containing values to copy
- * @param {mat4} dest mat4 receiving copied values
- *
- * @returns {mat4} dest
- */
- mat4.set = function (mat, dest) {
- dest[0] = mat[0];
- dest[1] = mat[1];
- dest[2] = mat[2];
- dest[3] = mat[3];
- dest[4] = mat[4];
- dest[5] = mat[5];
- dest[6] = mat[6];
- dest[7] = mat[7];
- dest[8] = mat[8];
- dest[9] = mat[9];
- dest[10] = mat[10];
- dest[11] = mat[11];
- dest[12] = mat[12];
- dest[13] = mat[13];
- dest[14] = mat[14];
- dest[15] = mat[15];
- return dest;
- };
-
- /**
- * Compares two matrices for equality within a certain margin of error
- *
- * @param {mat4} a First matrix
- * @param {mat4} b Second matrix
- *
- * @returns {Boolean} True if a is equivalent to b
- */
- mat4.equal = function (a, b) {
- return a === b || (
- Math.abs(a[0] - b[0]) < FLOAT_EPSILON &&
- Math.abs(a[1] - b[1]) < FLOAT_EPSILON &&
- Math.abs(a[2] - b[2]) < FLOAT_EPSILON &&
- Math.abs(a[3] - b[3]) < FLOAT_EPSILON &&
- Math.abs(a[4] - b[4]) < FLOAT_EPSILON &&
- Math.abs(a[5] - b[5]) < FLOAT_EPSILON &&
- Math.abs(a[6] - b[6]) < FLOAT_EPSILON &&
- Math.abs(a[7] - b[7]) < FLOAT_EPSILON &&
- Math.abs(a[8] - b[8]) < FLOAT_EPSILON &&
- Math.abs(a[9] - b[9]) < FLOAT_EPSILON &&
- Math.abs(a[10] - b[10]) < FLOAT_EPSILON &&
- Math.abs(a[11] - b[11]) < FLOAT_EPSILON &&
- Math.abs(a[12] - b[12]) < FLOAT_EPSILON &&
- Math.abs(a[13] - b[13]) < FLOAT_EPSILON &&
- Math.abs(a[14] - b[14]) < FLOAT_EPSILON &&
- Math.abs(a[15] - b[15]) < FLOAT_EPSILON
- );
- };
-
- /**
- * Sets a mat4 to an identity matrix
- *
- * @param {mat4} dest mat4 to set
- *
- * @returns {mat4} dest
- */
- mat4.identity = function (dest) {
- if (!dest) { dest = mat4.create(); }
- dest[0] = 1;
- dest[1] = 0;
- dest[2] = 0;
- dest[3] = 0;
- dest[4] = 0;
- dest[5] = 1;
- dest[6] = 0;
- dest[7] = 0;
- dest[8] = 0;
- dest[9] = 0;
- dest[10] = 1;
- dest[11] = 0;
- dest[12] = 0;
- dest[13] = 0;
- dest[14] = 0;
- dest[15] = 1;
- return dest;
- };
-
- /**
- * Transposes a mat4 (flips the values over the diagonal)
- *
- * @param {mat4} mat mat4 to transpose
- * @param {mat4} [dest] mat4 receiving transposed values. If not specified result is written to mat
- *
- * @param {mat4} dest is specified, mat otherwise
- */
- mat4.transpose = function (mat, dest) {
- // If we are transposing ourselves we can skip a few steps but have to cache some values
- if (!dest || mat === dest) {
- var a01 = mat[1], a02 = mat[2], a03 = mat[3],
- a12 = mat[6], a13 = mat[7],
- a23 = mat[11];
-
- mat[1] = mat[4];
- mat[2] = mat[8];
- mat[3] = mat[12];
- mat[4] = a01;
- mat[6] = mat[9];
- mat[7] = mat[13];
- mat[8] = a02;
- mat[9] = a12;
- mat[11] = mat[14];
- mat[12] = a03;
- mat[13] = a13;
- mat[14] = a23;
- return mat;
- }
-
- dest[0] = mat[0];
- dest[1] = mat[4];
- dest[2] = mat[8];
- dest[3] = mat[12];
- dest[4] = mat[1];
- dest[5] = mat[5];
- dest[6] = mat[9];
- dest[7] = mat[13];
- dest[8] = mat[2];
- dest[9] = mat[6];
- dest[10] = mat[10];
- dest[11] = mat[14];
- dest[12] = mat[3];
- dest[13] = mat[7];
- dest[14] = mat[11];
- dest[15] = mat[15];
- return dest;
- };
-
- /**
- * Calculates the determinant of a mat4
- *
- * @param {mat4} mat mat4 to calculate determinant of
- *
- * @returns {number} determinant of mat
- */
- mat4.determinant = function (mat) {
- // Cache the matrix values (makes for huge speed increases!)
- var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3],
- a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7],
- a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11],
- a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15];
-
- return (a30 * a21 * a12 * a03 - a20 * a31 * a12 * a03 - a30 * a11 * a22 * a03 + a10 * a31 * a22 * a03 +
- a20 * a11 * a32 * a03 - a10 * a21 * a32 * a03 - a30 * a21 * a02 * a13 + a20 * a31 * a02 * a13 +
- a30 * a01 * a22 * a13 - a00 * a31 * a22 * a13 - a20 * a01 * a32 * a13 + a00 * a21 * a32 * a13 +
- a30 * a11 * a02 * a23 - a10 * a31 * a02 * a23 - a30 * a01 * a12 * a23 + a00 * a31 * a12 * a23 +
- a10 * a01 * a32 * a23 - a00 * a11 * a32 * a23 - a20 * a11 * a02 * a33 + a10 * a21 * a02 * a33 +
- a20 * a01 * a12 * a33 - a00 * a21 * a12 * a33 - a10 * a01 * a22 * a33 + a00 * a11 * a22 * a33);
- };
-
- /**
- * Calculates the inverse matrix of a mat4
- *
- * @param {mat4} mat mat4 to calculate inverse of
- * @param {mat4} [dest] mat4 receiving inverse matrix. If not specified result is written to mat
- *
- * @param {mat4} dest is specified, mat otherwise, null if matrix cannot be inverted
- */
- mat4.inverse = function (mat, dest) {
- if (!dest) { dest = mat; }
-
- // Cache the matrix values (makes for huge speed increases!)
- var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3],
- a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7],
- a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11],
- a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15],
-
- b00 = a00 * a11 - a01 * a10,
- b01 = a00 * a12 - a02 * a10,
- b02 = a00 * a13 - a03 * a10,
- b03 = a01 * a12 - a02 * a11,
- b04 = a01 * a13 - a03 * a11,
- b05 = a02 * a13 - a03 * a12,
- b06 = a20 * a31 - a21 * a30,
- b07 = a20 * a32 - a22 * a30,
- b08 = a20 * a33 - a23 * a30,
- b09 = a21 * a32 - a22 * a31,
- b10 = a21 * a33 - a23 * a31,
- b11 = a22 * a33 - a23 * a32,
-
- d = (b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06),
- invDet;
-
- // Calculate the determinant
- if (!d) { return null; }
- invDet = 1 / d;
-
- dest[0] = (a11 * b11 - a12 * b10 + a13 * b09) * invDet;
- dest[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet;
- dest[2] = (a31 * b05 - a32 * b04 + a33 * b03) * invDet;
- dest[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet;
- dest[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet;
- dest[5] = (a00 * b11 - a02 * b08 + a03 * b07) * invDet;
- dest[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet;
- dest[7] = (a20 * b05 - a22 * b02 + a23 * b01) * invDet;
- dest[8] = (a10 * b10 - a11 * b08 + a13 * b06) * invDet;
- dest[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet;
- dest[10] = (a30 * b04 - a31 * b02 + a33 * b00) * invDet;
- dest[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet;
- dest[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet;
- dest[13] = (a00 * b09 - a01 * b07 + a02 * b06) * invDet;
- dest[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet;
- dest[15] = (a20 * b03 - a21 * b01 + a22 * b00) * invDet;
-
- return dest;
- };
-
- /**
- * Copies the upper 3x3 elements of a mat4 into another mat4
- *
- * @param {mat4} mat mat4 containing values to copy
- * @param {mat4} [dest] mat4 receiving copied values
- *
- * @returns {mat4} dest is specified, a new mat4 otherwise
- */
- mat4.toRotationMat = function (mat, dest) {
- if (!dest) { dest = mat4.create(); }
-
- dest[0] = mat[0];
- dest[1] = mat[1];
- dest[2] = mat[2];
- dest[3] = mat[3];
- dest[4] = mat[4];
- dest[5] = mat[5];
- dest[6] = mat[6];
- dest[7] = mat[7];
- dest[8] = mat[8];
- dest[9] = mat[9];
- dest[10] = mat[10];
- dest[11] = mat[11];
- dest[12] = 0;
- dest[13] = 0;
- dest[14] = 0;
- dest[15] = 1;
-
- return dest;
- };
-
- /**
- * Copies the upper 3x3 elements of a mat4 into a mat3
- *
- * @param {mat4} mat mat4 containing values to copy
- * @param {mat3} [dest] mat3 receiving copied values
- *
- * @returns {mat3} dest is specified, a new mat3 otherwise
- */
- mat4.toMat3 = function (mat, dest) {
- if (!dest) { dest = mat3.create(); }
-
- dest[0] = mat[0];
- dest[1] = mat[1];
- dest[2] = mat[2];
- dest[3] = mat[4];
- dest[4] = mat[5];
- dest[5] = mat[6];
- dest[6] = mat[8];
- dest[7] = mat[9];
- dest[8] = mat[10];
-
- return dest;
- };
-
- /**
- * Calculates the inverse of the upper 3x3 elements of a mat4 and copies the result into a mat3
- * The resulting matrix is useful for calculating transformed normals
- *
- * Params:
- * @param {mat4} mat mat4 containing values to invert and copy
- * @param {mat3} [dest] mat3 receiving values
- *
- * @returns {mat3} dest is specified, a new mat3 otherwise, null if the matrix cannot be inverted
- */
- mat4.toInverseMat3 = function (mat, dest) {
- // Cache the matrix values (makes for huge speed increases!)
- var a00 = mat[0], a01 = mat[1], a02 = mat[2],
- a10 = mat[4], a11 = mat[5], a12 = mat[6],
- a20 = mat[8], a21 = mat[9], a22 = mat[10],
-
- b01 = a22 * a11 - a12 * a21,
- b11 = -a22 * a10 + a12 * a20,
- b21 = a21 * a10 - a11 * a20,
-
- d = a00 * b01 + a01 * b11 + a02 * b21,
- id;
-
- if (!d) { return null; }
- id = 1 / d;
-
- if (!dest) { dest = mat3.create(); }
-
- dest[0] = b01 * id;
- dest[1] = (-a22 * a01 + a02 * a21) * id;
- dest[2] = (a12 * a01 - a02 * a11) * id;
- dest[3] = b11 * id;
- dest[4] = (a22 * a00 - a02 * a20) * id;
- dest[5] = (-a12 * a00 + a02 * a10) * id;
- dest[6] = b21 * id;
- dest[7] = (-a21 * a00 + a01 * a20) * id;
- dest[8] = (a11 * a00 - a01 * a10) * id;
-
- return dest;
- };
-
- /**
- * Performs a matrix multiplication
- *
- * @param {mat4} mat First operand
- * @param {mat4} mat2 Second operand
- * @param {mat4} [dest] mat4 receiving operation result. If not specified result is written to mat
- *
- * @returns {mat4} dest if specified, mat otherwise
- */
- mat4.multiply = function (mat, mat2, dest) {
- if (!dest) { dest = mat; }
-
- // Cache the matrix values (makes for huge speed increases!)
- var a00 = mat[ 0], a01 = mat[ 1], a02 = mat[ 2], a03 = mat[3];
- var a10 = mat[ 4], a11 = mat[ 5], a12 = mat[ 6], a13 = mat[7];
- var a20 = mat[ 8], a21 = mat[ 9], a22 = mat[10], a23 = mat[11];
- var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15];
-
- // Cache only the current line of the second matrix
- var b0 = mat2[0], b1 = mat2[1], b2 = mat2[2], b3 = mat2[3];
- dest[0] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[1] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[4];
- b1 = mat2[5];
- b2 = mat2[6];
- b3 = mat2[7];
- dest[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[8];
- b1 = mat2[9];
- b2 = mat2[10];
- b3 = mat2[11];
- dest[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[12];
- b1 = mat2[13];
- b2 = mat2[14];
- b3 = mat2[15];
- dest[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- return dest;
- };
-
- /**
- * Transforms a vec3 with the given matrix
- * 4th vector component is implicitly '1'
- *
- * @param {mat4} mat mat4 to transform the vector with
- * @param {vec3} vec vec3 to transform
- * @param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec
- *
- * @returns {vec3} dest if specified, vec otherwise
- */
- mat4.multiplyVec3 = function (mat, vec, dest) {
- if (!dest) { dest = vec; }
-
- var x = vec[0], y = vec[1], z = vec[2];
-
- dest[0] = mat[0] * x + mat[4] * y + mat[8] * z + mat[12];
- dest[1] = mat[1] * x + mat[5] * y + mat[9] * z + mat[13];
- dest[2] = mat[2] * x + mat[6] * y + mat[10] * z + mat[14];
-
- return dest;
- };
-
- /**
- * Transforms a vec4 with the given matrix
- *
- * @param {mat4} mat mat4 to transform the vector with
- * @param {vec4} vec vec4 to transform
- * @param {vec4} [dest] vec4 receiving operation result. If not specified result is written to vec
- *
- * @returns {vec4} dest if specified, vec otherwise
- */
- mat4.multiplyVec4 = function (mat, vec, dest) {
- if (!dest) { dest = vec; }
-
- var x = vec[0], y = vec[1], z = vec[2], w = vec[3];
-
- dest[0] = mat[0] * x + mat[4] * y + mat[8] * z + mat[12] * w;
- dest[1] = mat[1] * x + mat[5] * y + mat[9] * z + mat[13] * w;
- dest[2] = mat[2] * x + mat[6] * y + mat[10] * z + mat[14] * w;
- dest[3] = mat[3] * x + mat[7] * y + mat[11] * z + mat[15] * w;
-
- return dest;
- };
-
- /**
- * Translates a matrix by the given vector
- *
- * @param {mat4} mat mat4 to translate
- * @param {vec3} vec vec3 specifying the translation
- * @param {mat4} [dest] mat4 receiving operation result. If not specified result is written to mat
- *
- * @returns {mat4} dest if specified, mat otherwise
- */
- mat4.translate = function (mat, vec, dest) {
- var x = vec[0], y = vec[1], z = vec[2],
- a00, a01, a02, a03,
- a10, a11, a12, a13,
- a20, a21, a22, a23;
-
- if (!dest || mat === dest) {
- mat[12] = mat[0] * x + mat[4] * y + mat[8] * z + mat[12];
- mat[13] = mat[1] * x + mat[5] * y + mat[9] * z + mat[13];
- mat[14] = mat[2] * x + mat[6] * y + mat[10] * z + mat[14];
- mat[15] = mat[3] * x + mat[7] * y + mat[11] * z + mat[15];
- return mat;
- }
-
- a00 = mat[0]; a01 = mat[1]; a02 = mat[2]; a03 = mat[3];
- a10 = mat[4]; a11 = mat[5]; a12 = mat[6]; a13 = mat[7];
- a20 = mat[8]; a21 = mat[9]; a22 = mat[10]; a23 = mat[11];
-
- dest[0] = a00; dest[1] = a01; dest[2] = a02; dest[3] = a03;
- dest[4] = a10; dest[5] = a11; dest[6] = a12; dest[7] = a13;
- dest[8] = a20; dest[9] = a21; dest[10] = a22; dest[11] = a23;
-
- dest[12] = a00 * x + a10 * y + a20 * z + mat[12];
- dest[13] = a01 * x + a11 * y + a21 * z + mat[13];
- dest[14] = a02 * x + a12 * y + a22 * z + mat[14];
- dest[15] = a03 * x + a13 * y + a23 * z + mat[15];
- return dest;
- };
-
- /**
- * Scales a matrix by the given vector
- *
- * @param {mat4} mat mat4 to scale
- * @param {vec3} vec vec3 specifying the scale for each axis
- * @param {mat4} [dest] mat4 receiving operation result. If not specified result is written to mat
- *
- * @param {mat4} dest if specified, mat otherwise
- */
- mat4.scale = function (mat, vec, dest) {
- var x = vec[0], y = vec[1], z = vec[2];
-
- if (!dest || mat === dest) {
- mat[0] *= x;
- mat[1] *= x;
- mat[2] *= x;
- mat[3] *= x;
- mat[4] *= y;
- mat[5] *= y;
- mat[6] *= y;
- mat[7] *= y;
- mat[8] *= z;
- mat[9] *= z;
- mat[10] *= z;
- mat[11] *= z;
- return mat;
- }
-
- dest[0] = mat[0] * x;
- dest[1] = mat[1] * x;
- dest[2] = mat[2] * x;
- dest[3] = mat[3] * x;
- dest[4] = mat[4] * y;
- dest[5] = mat[5] * y;
- dest[6] = mat[6] * y;
- dest[7] = mat[7] * y;
- dest[8] = mat[8] * z;
- dest[9] = mat[9] * z;
- dest[10] = mat[10] * z;
- dest[11] = mat[11] * z;
- dest[12] = mat[12];
- dest[13] = mat[13];
- dest[14] = mat[14];
- dest[15] = mat[15];
- return dest;
- };
-
- /**
- * Rotates a matrix by the given angle around the specified axis
- * If rotating around a primary axis (X,Y,Z) one of the specialized rotation functions should be used instead for performance
- *
- * @param {mat4} mat mat4 to rotate
- * @param {number} angle Angle (in radians) to rotate
- * @param {vec3} axis vec3 representing the axis to rotate around
- * @param {mat4} [dest] mat4 receiving operation result. If not specified result is written to mat
- *
- * @returns {mat4} dest if specified, mat otherwise
- */
- mat4.rotate = function (mat, angle, axis, dest) {
- var x = axis[0], y = axis[1], z = axis[2],
- len = Math.sqrt(x * x + y * y + z * z),
- s, c, t,
- a00, a01, a02, a03,
- a10, a11, a12, a13,
- a20, a21, a22, a23,
- b00, b01, b02,
- b10, b11, b12,
- b20, b21, b22;
-
- if (!len) { return null; }
- if (len !== 1) {
- len = 1 / len;
- x *= len;
- y *= len;
- z *= len;
- }
-
- s = Math.sin(angle);
- c = Math.cos(angle);
- t = 1 - c;
-
- a00 = mat[0]; a01 = mat[1]; a02 = mat[2]; a03 = mat[3];
- a10 = mat[4]; a11 = mat[5]; a12 = mat[6]; a13 = mat[7];
- a20 = mat[8]; a21 = mat[9]; a22 = mat[10]; a23 = mat[11];
-
- // Construct the elements of the rotation matrix
- b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s;
- b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s;
- b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c;
-
- if (!dest) {
- dest = mat;
- } else if (mat !== dest) { // If the source and destination differ, copy the unchanged last row
- dest[12] = mat[12];
- dest[13] = mat[13];
- dest[14] = mat[14];
- dest[15] = mat[15];
- }
-
- // Perform rotation-specific matrix multiplication
- dest[0] = a00 * b00 + a10 * b01 + a20 * b02;
- dest[1] = a01 * b00 + a11 * b01 + a21 * b02;
- dest[2] = a02 * b00 + a12 * b01 + a22 * b02;
- dest[3] = a03 * b00 + a13 * b01 + a23 * b02;
-
- dest[4] = a00 * b10 + a10 * b11 + a20 * b12;
- dest[5] = a01 * b10 + a11 * b11 + a21 * b12;
- dest[6] = a02 * b10 + a12 * b11 + a22 * b12;
- dest[7] = a03 * b10 + a13 * b11 + a23 * b12;
-
- dest[8] = a00 * b20 + a10 * b21 + a20 * b22;
- dest[9] = a01 * b20 + a11 * b21 + a21 * b22;
- dest[10] = a02 * b20 + a12 * b21 + a22 * b22;
- dest[11] = a03 * b20 + a13 * b21 + a23 * b22;
- return dest;
- };
-
- /**
- * Rotates a matrix by the given angle around the X axis
- *
- * @param {mat4} mat mat4 to rotate
- * @param {number} angle Angle (in radians) to rotate
- * @param {mat4} [dest] mat4 receiving operation result. If not specified result is written to mat
- *
- * @returns {mat4} dest if specified, mat otherwise
- */
- mat4.rotateX = function (mat, angle, dest) {
- var s = Math.sin(angle),
- c = Math.cos(angle),
- a10 = mat[4],
- a11 = mat[5],
- a12 = mat[6],
- a13 = mat[7],
- a20 = mat[8],
- a21 = mat[9],
- a22 = mat[10],
- a23 = mat[11];
-
- if (!dest) {
- dest = mat;
- } else if (mat !== dest) { // If the source and destination differ, copy the unchanged rows
- dest[0] = mat[0];
- dest[1] = mat[1];
- dest[2] = mat[2];
- dest[3] = mat[3];
-
- dest[12] = mat[12];
- dest[13] = mat[13];
- dest[14] = mat[14];
- dest[15] = mat[15];
- }
-
- // Perform axis-specific matrix multiplication
- dest[4] = a10 * c + a20 * s;
- dest[5] = a11 * c + a21 * s;
- dest[6] = a12 * c + a22 * s;
- dest[7] = a13 * c + a23 * s;
-
- dest[8] = a10 * -s + a20 * c;
- dest[9] = a11 * -s + a21 * c;
- dest[10] = a12 * -s + a22 * c;
- dest[11] = a13 * -s + a23 * c;
- return dest;
- };
-
- /**
- * Rotates a matrix by the given angle around the Y axis
- *
- * @param {mat4} mat mat4 to rotate
- * @param {number} angle Angle (in radians) to rotate
- * @param {mat4} [dest] mat4 receiving operation result. If not specified result is written to mat
- *
- * @returns {mat4} dest if specified, mat otherwise
- */
- mat4.rotateY = function (mat, angle, dest) {
- var s = Math.sin(angle),
- c = Math.cos(angle),
- a00 = mat[0],
- a01 = mat[1],
- a02 = mat[2],
- a03 = mat[3],
- a20 = mat[8],
- a21 = mat[9],
- a22 = mat[10],
- a23 = mat[11];
-
- if (!dest) {
- dest = mat;
- } else if (mat !== dest) { // If the source and destination differ, copy the unchanged rows
- dest[4] = mat[4];
- dest[5] = mat[5];
- dest[6] = mat[6];
- dest[7] = mat[7];
-
- dest[12] = mat[12];
- dest[13] = mat[13];
- dest[14] = mat[14];
- dest[15] = mat[15];
- }
-
- // Perform axis-specific matrix multiplication
- dest[0] = a00 * c + a20 * -s;
- dest[1] = a01 * c + a21 * -s;
- dest[2] = a02 * c + a22 * -s;
- dest[3] = a03 * c + a23 * -s;
-
- dest[8] = a00 * s + a20 * c;
- dest[9] = a01 * s + a21 * c;
- dest[10] = a02 * s + a22 * c;
- dest[11] = a03 * s + a23 * c;
- return dest;
- };
-
- /**
- * Rotates a matrix by the given angle around the Z axis
- *
- * @param {mat4} mat mat4 to rotate
- * @param {number} angle Angle (in radians) to rotate
- * @param {mat4} [dest] mat4 receiving operation result. If not specified result is written to mat
- *
- * @returns {mat4} dest if specified, mat otherwise
- */
- mat4.rotateZ = function (mat, angle, dest) {
- var s = Math.sin(angle),
- c = Math.cos(angle),
- a00 = mat[0],
- a01 = mat[1],
- a02 = mat[2],
- a03 = mat[3],
- a10 = mat[4],
- a11 = mat[5],
- a12 = mat[6],
- a13 = mat[7];
-
- if (!dest) {
- dest = mat;
- } else if (mat !== dest) { // If the source and destination differ, copy the unchanged last row
- dest[8] = mat[8];
- dest[9] = mat[9];
- dest[10] = mat[10];
- dest[11] = mat[11];
-
- dest[12] = mat[12];
- dest[13] = mat[13];
- dest[14] = mat[14];
- dest[15] = mat[15];
- }
-
- // Perform axis-specific matrix multiplication
- dest[0] = a00 * c + a10 * s;
- dest[1] = a01 * c + a11 * s;
- dest[2] = a02 * c + a12 * s;
- dest[3] = a03 * c + a13 * s;
-
- dest[4] = a00 * -s + a10 * c;
- dest[5] = a01 * -s + a11 * c;
- dest[6] = a02 * -s + a12 * c;
- dest[7] = a03 * -s + a13 * c;
-
- return dest;
- };
-
- /**
- * Generates a frustum matrix with the given bounds
- *
- * @param {number} left Left bound of the frustum
- * @param {number} right Right bound of the frustum
- * @param {number} bottom Bottom bound of the frustum
- * @param {number} top Top bound of the frustum
- * @param {number} near Near bound of the frustum
- * @param {number} far Far bound of the frustum
- * @param {mat4} [dest] mat4 frustum matrix will be written into
- *
- * @returns {mat4} dest if specified, a new mat4 otherwise
- */
- mat4.frustum = function (left, right, bottom, top, near, far, dest) {
- if (!dest) { dest = mat4.create(); }
- var rl = (right - left),
- tb = (top - bottom),
- fn = (far - near);
- dest[0] = (near * 2) / rl;
- dest[1] = 0;
- dest[2] = 0;
- dest[3] = 0;
- dest[4] = 0;
- dest[5] = (near * 2) / tb;
- dest[6] = 0;
- dest[7] = 0;
- dest[8] = (right + left) / rl;
- dest[9] = (top + bottom) / tb;
- dest[10] = -(far + near) / fn;
- dest[11] = -1;
- dest[12] = 0;
- dest[13] = 0;
- dest[14] = -(far * near * 2) / fn;
- dest[15] = 0;
- return dest;
- };
-
- /**
- * Generates a perspective projection matrix with the given bounds
- *
- * @param {number} fovy Vertical field of view
- * @param {number} aspect Aspect ratio. typically viewport width/height
- * @param {number} near Near bound of the frustum
- * @param {number} far Far bound of the frustum
- * @param {mat4} [dest] mat4 frustum matrix will be written into
- *
- * @returns {mat4} dest if specified, a new mat4 otherwise
- */
- mat4.perspective = function (fovy, aspect, near, far, dest) {
- var top = near * Math.tan(fovy * Math.PI / 360.0),
- right = top * aspect;
- return mat4.frustum(-right, right, -top, top, near, far, dest);
- };
-
- /**
- * Generates a orthogonal projection matrix with the given bounds
- *
- * @param {number} left Left bound of the frustum
- * @param {number} right Right bound of the frustum
- * @param {number} bottom Bottom bound of the frustum
- * @param {number} top Top bound of the frustum
- * @param {number} near Near bound of the frustum
- * @param {number} far Far bound of the frustum
- * @param {mat4} [dest] mat4 frustum matrix will be written into
- *
- * @returns {mat4} dest if specified, a new mat4 otherwise
- */
- mat4.ortho = function (left, right, bottom, top, near, far, dest) {
- if (!dest) { dest = mat4.create(); }
- var rl = (right - left),
- tb = (top - bottom),
- fn = (far - near);
- dest[0] = 2 / rl;
- dest[1] = 0;
- dest[2] = 0;
- dest[3] = 0;
- dest[4] = 0;
- dest[5] = 2 / tb;
- dest[6] = 0;
- dest[7] = 0;
- dest[8] = 0;
- dest[9] = 0;
- dest[10] = -2 / fn;
- dest[11] = 0;
- dest[12] = -(left + right) / rl;
- dest[13] = -(top + bottom) / tb;
- dest[14] = -(far + near) / fn;
- dest[15] = 1;
- return dest;
- };
-
- /**
- * Generates a look-at matrix with the given eye position, focal point, and up axis
- *
- * @param {vec3} eye Position of the viewer
- * @param {vec3} center Point the viewer is looking at
- * @param {vec3} up vec3 pointing "up"
- * @param {mat4} [dest] mat4 frustum matrix will be written into
- *
- * @returns {mat4} dest if specified, a new mat4 otherwise
- */
- mat4.lookAt = function (eye, center, up, dest) {
- if (!dest) { dest = mat4.create(); }
-
- var x0, x1, x2, y0, y1, y2, z0, z1, z2, len,
- eyex = eye[0],
- eyey = eye[1],
- eyez = eye[2],
- upx = up[0],
- upy = up[1],
- upz = up[2],
- centerx = center[0],
- centery = center[1],
- centerz = center[2];
-
- if (eyex === centerx && eyey === centery && eyez === centerz) {
- return mat4.identity(dest);
- }
-
- //vec3.direction(eye, center, z);
- z0 = eyex - centerx;
- z1 = eyey - centery;
- z2 = eyez - centerz;
-
- // normalize (no check needed for 0 because of early return)
- len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);
- z0 *= len;
- z1 *= len;
- z2 *= len;
-
- //vec3.normalize(vec3.cross(up, z, x));
- x0 = upy * z2 - upz * z1;
- x1 = upz * z0 - upx * z2;
- x2 = upx * z1 - upy * z0;
- len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);
- if (!len) {
- x0 = 0;
- x1 = 0;
- x2 = 0;
- } else {
- len = 1 / len;
- x0 *= len;
- x1 *= len;
- x2 *= len;
- }
-
- //vec3.normalize(vec3.cross(z, x, y));
- y0 = z1 * x2 - z2 * x1;
- y1 = z2 * x0 - z0 * x2;
- y2 = z0 * x1 - z1 * x0;
-
- len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);
- if (!len) {
- y0 = 0;
- y1 = 0;
- y2 = 0;
- } else {
- len = 1 / len;
- y0 *= len;
- y1 *= len;
- y2 *= len;
- }
-
- dest[0] = x0;
- dest[1] = y0;
- dest[2] = z0;
- dest[3] = 0;
- dest[4] = x1;
- dest[5] = y1;
- dest[6] = z1;
- dest[7] = 0;
- dest[8] = x2;
- dest[9] = y2;
- dest[10] = z2;
- dest[11] = 0;
- dest[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);
- dest[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);
- dest[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);
- dest[15] = 1;
-
- return dest;
- };
-
- /**
- * Creates a matrix from a quaternion rotation and vector translation
- * This is equivalent to (but much faster than):
- *
- * mat4.identity(dest);
- * mat4.translate(dest, vec);
- * var quatMat = mat4.create();
- * quat4.toMat4(quat, quatMat);
- * mat4.multiply(dest, quatMat);
- *
- * @param {quat4} quat Rotation quaternion
- * @param {vec3} vec Translation vector
- * @param {mat4} [dest] mat4 receiving operation result. If not specified result is written to a new mat4
- *
- * @returns {mat4} dest if specified, a new mat4 otherwise
- */
- mat4.fromRotationTranslation = function (quat, vec, dest) {
- if (!dest) { dest = mat4.create(); }
-
- // Quaternion math
- var x = quat[0], y = quat[1], z = quat[2], w = quat[3],
- x2 = x + x,
- y2 = y + y,
- z2 = z + z,
-
- xx = x * x2,
- xy = x * y2,
- xz = x * z2,
- yy = y * y2,
- yz = y * z2,
- zz = z * z2,
- wx = w * x2,
- wy = w * y2,
- wz = w * z2;
-
- dest[0] = 1 - (yy + zz);
- dest[1] = xy + wz;
- dest[2] = xz - wy;
- dest[3] = 0;
- dest[4] = xy - wz;
- dest[5] = 1 - (xx + zz);
- dest[6] = yz + wx;
- dest[7] = 0;
- dest[8] = xz + wy;
- dest[9] = yz - wx;
- dest[10] = 1 - (xx + yy);
- dest[11] = 0;
- dest[12] = vec[0];
- dest[13] = vec[1];
- dest[14] = vec[2];
- dest[15] = 1;
-
- return dest;
- };
-
- /**
- * Returns a string representation of a mat4
- *
- * @param {mat4} mat mat4 to represent as a string
- *
- * @returns {string} String representation of mat
- */
- mat4.str = function (mat) {
- return '[' + mat[0] + ', ' + mat[1] + ', ' + mat[2] + ', ' + mat[3] +
- ', ' + mat[4] + ', ' + mat[5] + ', ' + mat[6] + ', ' + mat[7] +
- ', ' + mat[8] + ', ' + mat[9] + ', ' + mat[10] + ', ' + mat[11] +
- ', ' + mat[12] + ', ' + mat[13] + ', ' + mat[14] + ', ' + mat[15] + ']';
- };
-
- /**
- * @class Quaternion
- * @name quat4
- */
- var quat4 = {};
-
- /**
- * Creates a new instance of a quat4 using the default array type
- * Any javascript array containing at least 4 numeric elements can serve as a quat4
- *
- * @param {quat4} [quat] quat4 containing values to initialize with
- *
- * @returns {quat4} New quat4
- */
- quat4.create = function (quat) {
- var dest = new MatrixArray(4);
-
- if (quat) {
- dest[0] = quat[0];
- dest[1] = quat[1];
- dest[2] = quat[2];
- dest[3] = quat[3];
- } else {
- dest[0] = dest[1] = dest[2] = dest[3] = 0;
- }
-
- return dest;
- };
-
- /**
- * Creates a new instance of a quat4, initializing it with the given arguments
- *
- * @param {number} x X value
- * @param {number} y Y value
- * @param {number} z Z value
- * @param {number} w W value
-
- * @returns {quat4} New quat4
- */
- quat4.createFrom = function (x, y, z, w) {
- var dest = new MatrixArray(4);
-
- dest[0] = x;
- dest[1] = y;
- dest[2] = z;
- dest[3] = w;
-
- return dest;
- };
-
- /**
- * Copies the values of one quat4 to another
- *
- * @param {quat4} quat quat4 containing values to copy
- * @param {quat4} dest quat4 receiving copied values
- *
- * @returns {quat4} dest
- */
- quat4.set = function (quat, dest) {
- dest[0] = quat[0];
- dest[1] = quat[1];
- dest[2] = quat[2];
- dest[3] = quat[3];
-
- return dest;
- };
-
- /**
- * Compares two quaternions for equality within a certain margin of error
- *
- * @param {quat4} a First vector
- * @param {quat4} b Second vector
- *
- * @returns {Boolean} True if a is equivalent to b
- */
- quat4.equal = function (a, b) {
- return a === b || (
- Math.abs(a[0] - b[0]) < FLOAT_EPSILON &&
- Math.abs(a[1] - b[1]) < FLOAT_EPSILON &&
- Math.abs(a[2] - b[2]) < FLOAT_EPSILON &&
- Math.abs(a[3] - b[3]) < FLOAT_EPSILON
- );
- };
-
- /**
- * Creates a new identity Quat4
- *
- * @param {quat4} [dest] quat4 receiving copied values
- *
- * @returns {quat4} dest is specified, new quat4 otherwise
- */
- quat4.identity = function (dest) {
- if (!dest) { dest = quat4.create(); }
- dest[0] = 0;
- dest[1] = 0;
- dest[2] = 0;
- dest[3] = 1;
- return dest;
- };
-
- var identityQuat4 = quat4.identity();
-
- /**
- * Calculates the W component of a quat4 from the X, Y, and Z components.
- * Assumes that quaternion is 1 unit in length.
- * Any existing W component will be ignored.
- *
- * @param {quat4} quat quat4 to calculate W component of
- * @param {quat4} [dest] quat4 receiving calculated values. If not specified result is written to quat
- *
- * @returns {quat4} dest if specified, quat otherwise
- */
- quat4.calculateW = function (quat, dest) {
- var x = quat[0], y = quat[1], z = quat[2];
-
- if (!dest || quat === dest) {
- quat[3] = -Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z));
- return quat;
- }
- dest[0] = x;
- dest[1] = y;
- dest[2] = z;
- dest[3] = -Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z));
- return dest;
- };
-
- /**
- * Calculates the dot product of two quaternions
- *
- * @param {quat4} quat First operand
- * @param {quat4} quat2 Second operand
- *
- * @return {number} Dot product of quat and quat2
- */
- quat4.dot = function(quat, quat2){
- return quat[0]*quat2[0] + quat[1]*quat2[1] + quat[2]*quat2[2] + quat[3]*quat2[3];
- };
-
- /**
- * Calculates the inverse of a quat4
- *
- * @param {quat4} quat quat4 to calculate inverse of
- * @param {quat4} [dest] quat4 receiving inverse values. If not specified result is written to quat
- *
- * @returns {quat4} dest if specified, quat otherwise
- */
- quat4.inverse = function(quat, dest) {
- var q0 = quat[0], q1 = quat[1], q2 = quat[2], q3 = quat[3],
- dot = q0*q0 + q1*q1 + q2*q2 + q3*q3,
- invDot = dot ? 1.0/dot : 0;
-
- // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0
-
- if(!dest || quat === dest) {
- quat[0] *= -invDot;
- quat[1] *= -invDot;
- quat[2] *= -invDot;
- quat[3] *= invDot;
- return quat;
- }
- dest[0] = -quat[0]*invDot;
- dest[1] = -quat[1]*invDot;
- dest[2] = -quat[2]*invDot;
- dest[3] = quat[3]*invDot;
- return dest;
- };
-
-
- /**
- * Calculates the conjugate of a quat4
- * If the quaternion is normalized, this function is faster than quat4.inverse and produces the same result.
- *
- * @param {quat4} quat quat4 to calculate conjugate of
- * @param {quat4} [dest] quat4 receiving conjugate values. If not specified result is written to quat
- *
- * @returns {quat4} dest if specified, quat otherwise
- */
- quat4.conjugate = function (quat, dest) {
- if (!dest || quat === dest) {
- quat[0] *= -1;
- quat[1] *= -1;
- quat[2] *= -1;
- return quat;
- }
- dest[0] = -quat[0];
- dest[1] = -quat[1];
- dest[2] = -quat[2];
- dest[3] = quat[3];
- return dest;
- };
-
- /**
- * Calculates the length of a quat4
- *
- * Params:
- * @param {quat4} quat quat4 to calculate length of
- *
- * @returns Length of quat
- */
- quat4.length = function (quat) {
- var x = quat[0], y = quat[1], z = quat[2], w = quat[3];
- return Math.sqrt(x * x + y * y + z * z + w * w);
- };
-
- /**
- * Generates a unit quaternion of the same direction as the provided quat4
- * If quaternion length is 0, returns [0, 0, 0, 0]
- *
- * @param {quat4} quat quat4 to normalize
- * @param {quat4} [dest] quat4 receiving operation result. If not specified result is written to quat
- *
- * @returns {quat4} dest if specified, quat otherwise
- */
- quat4.normalize = function (quat, dest) {
- if (!dest) { dest = quat; }
-
- var x = quat[0], y = quat[1], z = quat[2], w = quat[3],
- len = Math.sqrt(x * x + y * y + z * z + w * w);
- if (len === 0) {
- dest[0] = 0;
- dest[1] = 0;
- dest[2] = 0;
- dest[3] = 0;
- return dest;
- }
- len = 1 / len;
- dest[0] = x * len;
- dest[1] = y * len;
- dest[2] = z * len;
- dest[3] = w * len;
-
- return dest;
- };
-
- /**
- * Performs quaternion addition
- *
- * @param {quat4} quat First operand
- * @param {quat4} quat2 Second operand
- * @param {quat4} [dest] quat4 receiving operation result. If not specified result is written to quat
- *
- * @returns {quat4} dest if specified, quat otherwise
- */
- quat4.add = function (quat, quat2, dest) {
- if(!dest || quat === dest) {
- quat[0] += quat2[0];
- quat[1] += quat2[1];
- quat[2] += quat2[2];
- quat[3] += quat2[3];
- return quat;
- }
- dest[0] = quat[0]+quat2[0];
- dest[1] = quat[1]+quat2[1];
- dest[2] = quat[2]+quat2[2];
- dest[3] = quat[3]+quat2[3];
- return dest;
- };
-
- /**
- * Performs a quaternion multiplication
- *
- * @param {quat4} quat First operand
- * @param {quat4} quat2 Second operand
- * @param {quat4} [dest] quat4 receiving operation result. If not specified result is written to quat
- *
- * @returns {quat4} dest if specified, quat otherwise
- */
- quat4.multiply = function (quat, quat2, dest) {
- if (!dest) { dest = quat; }
-
- var qax = quat[0], qay = quat[1], qaz = quat[2], qaw = quat[3],
- qbx = quat2[0], qby = quat2[1], qbz = quat2[2], qbw = quat2[3];
-
- dest[0] = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
- dest[1] = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
- dest[2] = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
- dest[3] = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
-
- return dest;
- };
-
- /**
- * Transforms a vec3 with the given quaternion
- *
- * @param {quat4} quat quat4 to transform the vector with
- * @param {vec3} vec vec3 to transform
- * @param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec
- *
- * @returns dest if specified, vec otherwise
- */
- quat4.multiplyVec3 = function (quat, vec, dest) {
- if (!dest) { dest = vec; }
-
- var x = vec[0], y = vec[1], z = vec[2],
- qx = quat[0], qy = quat[1], qz = quat[2], qw = quat[3],
-
- // calculate quat * vec
- ix = qw * x + qy * z - qz * y,
- iy = qw * y + qz * x - qx * z,
- iz = qw * z + qx * y - qy * x,
- iw = -qx * x - qy * y - qz * z;
-
- // calculate result * inverse quat
- dest[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
- dest[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
- dest[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
-
- return dest;
- };
-
- /**
- * Multiplies the components of a quaternion by a scalar value
- *
- * @param {quat4} quat to scale
- * @param {number} val Value to scale by
- * @param {quat4} [dest] quat4 receiving operation result. If not specified result is written to quat
- *
- * @returns {quat4} dest if specified, quat otherwise
- */
- quat4.scale = function (quat, val, dest) {
- if(!dest || quat === dest) {
- quat[0] *= val;
- quat[1] *= val;
- quat[2] *= val;
- quat[3] *= val;
- return quat;
- }
- dest[0] = quat[0]*val;
- dest[1] = quat[1]*val;
- dest[2] = quat[2]*val;
- dest[3] = quat[3]*val;
- return dest;
- };
-
- /**
- * Calculates a 3x3 matrix from the given quat4
- *
- * @param {quat4} quat quat4 to create matrix from
- * @param {mat3} [dest] mat3 receiving operation result
- *
- * @returns {mat3} dest if specified, a new mat3 otherwise
- */
- quat4.toMat3 = function (quat, dest) {
- if (!dest) { dest = mat3.create(); }
-
- var x = quat[0], y = quat[1], z = quat[2], w = quat[3],
- x2 = x + x,
- y2 = y + y,
- z2 = z + z,
-
- xx = x * x2,
- xy = x * y2,
- xz = x * z2,
- yy = y * y2,
- yz = y * z2,
- zz = z * z2,
- wx = w * x2,
- wy = w * y2,
- wz = w * z2;
-
- dest[0] = 1 - (yy + zz);
- dest[1] = xy + wz;
- dest[2] = xz - wy;
-
- dest[3] = xy - wz;
- dest[4] = 1 - (xx + zz);
- dest[5] = yz + wx;
-
- dest[6] = xz + wy;
- dest[7] = yz - wx;
- dest[8] = 1 - (xx + yy);
-
- return dest;
- };
-
- /**
- * Calculates a 4x4 matrix from the given quat4
- *
- * @param {quat4} quat quat4 to create matrix from
- * @param {mat4} [dest] mat4 receiving operation result
- *
- * @returns {mat4} dest if specified, a new mat4 otherwise
- */
- quat4.toMat4 = function (quat, dest) {
- if (!dest) { dest = mat4.create(); }
-
- var x = quat[0], y = quat[1], z = quat[2], w = quat[3],
- x2 = x + x,
- y2 = y + y,
- z2 = z + z,
-
- xx = x * x2,
- xy = x * y2,
- xz = x * z2,
- yy = y * y2,
- yz = y * z2,
- zz = z * z2,
- wx = w * x2,
- wy = w * y2,
- wz = w * z2;
-
- dest[0] = 1 - (yy + zz);
- dest[1] = xy + wz;
- dest[2] = xz - wy;
- dest[3] = 0;
-
- dest[4] = xy - wz;
- dest[5] = 1 - (xx + zz);
- dest[6] = yz + wx;
- dest[7] = 0;
-
- dest[8] = xz + wy;
- dest[9] = yz - wx;
- dest[10] = 1 - (xx + yy);
- dest[11] = 0;
-
- dest[12] = 0;
- dest[13] = 0;
- dest[14] = 0;
- dest[15] = 1;
-
- return dest;
- };
-
- /**
- * Performs a spherical linear interpolation between two quat4
- *
- * @param {quat4} quat First quaternion
- * @param {quat4} quat2 Second quaternion
- * @param {number} slerp Interpolation amount between the two inputs
- * @param {quat4} [dest] quat4 receiving operation result. If not specified result is written to quat
- *
- * @returns {quat4} dest if specified, quat otherwise
- */
- quat4.slerp = function (quat, quat2, slerp, dest) {
- if (!dest) { dest = quat; }
-
- var cosHalfTheta = quat[0] * quat2[0] + quat[1] * quat2[1] + quat[2] * quat2[2] + quat[3] * quat2[3],
- halfTheta,
- sinHalfTheta,
- ratioA,
- ratioB;
-
- if (Math.abs(cosHalfTheta) >= 1.0) {
- if (dest !== quat) {
- dest[0] = quat[0];
- dest[1] = quat[1];
- dest[2] = quat[2];
- dest[3] = quat[3];
- }
- return dest;
- }
-
- halfTheta = Math.acos(cosHalfTheta);
- sinHalfTheta = Math.sqrt(1.0 - cosHalfTheta * cosHalfTheta);
-
- if (Math.abs(sinHalfTheta) < 0.001) {
- dest[0] = (quat[0] * 0.5 + quat2[0] * 0.5);
- dest[1] = (quat[1] * 0.5 + quat2[1] * 0.5);
- dest[2] = (quat[2] * 0.5 + quat2[2] * 0.5);
- dest[3] = (quat[3] * 0.5 + quat2[3] * 0.5);
- return dest;
- }
-
- ratioA = Math.sin((1 - slerp) * halfTheta) / sinHalfTheta;
- ratioB = Math.sin(slerp * halfTheta) / sinHalfTheta;
-
- dest[0] = (quat[0] * ratioA + quat2[0] * ratioB);
- dest[1] = (quat[1] * ratioA + quat2[1] * ratioB);
- dest[2] = (quat[2] * ratioA + quat2[2] * ratioB);
- dest[3] = (quat[3] * ratioA + quat2[3] * ratioB);
-
- return dest;
- };
-
- /**
- * Creates a quaternion from the given 3x3 rotation matrix.
- * If dest is omitted, a new quaternion will be created.
- *
- * @param {mat3} mat the rotation matrix
- * @param {quat4} [dest] an optional receiving quaternion
- *
- * @returns {quat4} the quaternion constructed from the rotation matrix
- *
- */
- quat4.fromRotationMatrix = function(mat, dest) {
- if (!dest) dest = quat4.create();
-
- // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
- // article "Quaternion Calculus and Fast Animation".
-
- var fTrace = mat[0] + mat[4] + mat[8];
- var fRoot;
-
- if ( fTrace > 0.0 ) {
- // |w| > 1/2, may as well choose w > 1/2
- fRoot = Math.sqrt(fTrace + 1.0); // 2w
- dest[3] = 0.5 * fRoot;
- fRoot = 0.5/fRoot; // 1/(4w)
- dest[0] = (mat[7]-mat[5])*fRoot;
- dest[1] = (mat[2]-mat[6])*fRoot;
- dest[2] = (mat[3]-mat[1])*fRoot;
- } else {
- // |w| <= 1/2
- var s_iNext = quat4.fromRotationMatrix.s_iNext = quat4.fromRotationMatrix.s_iNext || [1,2,0];
- var i = 0;
- if ( mat[4] > mat[0] )
- i = 1;
- if ( mat[8] > mat[i*3+i] )
- i = 2;
- var j = s_iNext[i];
- var k = s_iNext[j];
-
- fRoot = Math.sqrt(mat[i*3+i]-mat[j*3+j]-mat[k*3+k] + 1.0);
- dest[i] = 0.5 * fRoot;
- fRoot = 0.5 / fRoot;
- dest[3] = (mat[k*3+j] - mat[j*3+k]) * fRoot;
- dest[j] = (mat[j*3+i] + mat[i*3+j]) * fRoot;
- dest[k] = (mat[k*3+i] + mat[i*3+k]) * fRoot;
- }
-
- return dest;
- };
-
- /**
- * Alias. See the description for quat4.fromRotationMatrix().
- */
- mat3.toQuat4 = quat4.fromRotationMatrix;
-
- (function() {
- var mat = mat3.create();
-
- /**
- * Creates a quaternion from the 3 given vectors. They must be perpendicular
- * to one another and represent the X, Y and Z axes.
- *
- * If dest is omitted, a new quat4 will be created.
- *
- * Example: The default OpenGL orientation has a view vector [0, 0, -1],
- * right vector [1, 0, 0], and up vector [0, 1, 0]. A quaternion representing
- * this orientation could be constructed with:
- *
- * quat = quat4.fromAxes([0, 0, -1], [1, 0, 0], [0, 1, 0], quat4.create());
- *
- * @param {vec3} view the view vector, or direction the object is pointing in
- * @param {vec3} right the right vector, or direction to the "right" of the object
- * @param {vec3} up the up vector, or direction towards the object's "up"
- * @param {quat4} [dest] an optional receiving quat4
- *
- * @returns {quat4} dest
- **/
- quat4.fromAxes = function(view, right, up, dest) {
- mat[0] = right[0];
- mat[3] = right[1];
- mat[6] = right[2];
-
- mat[1] = up[0];
- mat[4] = up[1];
- mat[7] = up[2];
-
- mat[2] = view[0];
- mat[5] = view[1];
- mat[8] = view[2];
-
- return quat4.fromRotationMatrix(mat, dest);
- };
- })();
-
- /**
- * Sets a quat4 to the Identity and returns it.
- *
- * @param {quat4} [dest] quat4 to set. If omitted, a
- * new quat4 will be created.
- *
- * @returns {quat4} dest
- */
- quat4.identity = function(dest) {
- if (!dest) dest = quat4.create();
- dest[0] = 0;
- dest[1] = 0;
- dest[2] = 0;
- dest[3] = 1;
- return dest;
- };
-
- /**
- * Sets a quat4 from the given angle and rotation axis,
- * then returns it. If dest is not given, a new quat4 is created.
- *
- * @param {Number} angle the angle in radians
- * @param {vec3} axis the axis around which to rotate
- * @param {quat4} [dest] the optional quat4 to store the result
- *
- * @returns {quat4} dest
- **/
- quat4.fromAngleAxis = function(angle, axis, dest) {
- // The quaternion representing the rotation is
- // q = cos(A/2)+sin(A/2)*(x*i+y*j+z*k)
- if (!dest) dest = quat4.create();
-
- var half = angle * 0.5;
- var s = Math.sin(half);
- dest[3] = Math.cos(half);
- dest[0] = s * axis[0];
- dest[1] = s * axis[1];
- dest[2] = s * axis[2];
-
- return dest;
- };
-
- /**
- * Stores the angle and axis in a vec4, where the XYZ components represent
- * the axis and the W (4th) component is the angle in radians.
- *
- * If dest is not given, src will be modified in place and returned, after
- * which it should not be considered not a quaternion (just an axis and angle).
- *
- * @param {quat4} quat the quaternion whose angle and axis to store
- * @param {vec4} [dest] the optional vec4 to receive the data
- *
- * @returns {vec4} dest
- */
- quat4.toAngleAxis = function(src, dest) {
- if (!dest) dest = src;
- // The quaternion representing the rotation is
- // q = cos(A/2)+sin(A/2)*(x*i+y*j+z*k)
-
- var sqrlen = src[0]*src[0]+src[1]*src[1]+src[2]*src[2];
- if (sqrlen > 0)
- {
- dest[3] = 2 * Math.acos(src[3]);
- var invlen = glMath.invsqrt(sqrlen);
- dest[0] = src[0]*invlen;
- dest[1] = src[1]*invlen;
- dest[2] = src[2]*invlen;
- } else {
- // angle is 0 (mod 2*pi), so any axis will do
- dest[3] = 0;
- dest[0] = 1;
- dest[1] = 0;
- dest[2] = 0;
- }
-
- return dest;
- };
-
- /**
- * Returns a string representation of a quaternion
- *
- * @param {quat4} quat quat4 to represent as a string
- *
- * @returns {string} String representation of quat
- */
- quat4.str = function (quat) {
- return '[' + quat[0] + ', ' + quat[1] + ', ' + quat[2] + ', ' + quat[3] + ']';
- };
-
- /**
- * @class 2 Dimensional Vector
- * @name vec2
- */
- var vec2 = {};
-
- /**
- * Creates a new vec2, initializing it from vec if vec
- * is given.
- *
- * @param {vec2} [vec] the vector's initial contents
- * @returns {vec2} a new 2D vector
- */
- vec2.create = function(vec) {
- var dest = new MatrixArray(2);
-
- if (vec) {
- dest[0] = vec[0];
- dest[1] = vec[1];
- } else {
- dest[0] = 0;
- dest[1] = 0;
- }
- return dest;
- };
-
- /**
- * Creates a new instance of a vec2, initializing it with the given arguments
- *
- * @param {number} x X value
- * @param {number} y Y value
-
- * @returns {vec2} New vec2
- */
- vec2.createFrom = function (x, y) {
- var dest = new MatrixArray(2);
-
- dest[0] = x;
- dest[1] = y;
-
- return dest;
- };
-
- /**
- * Adds the vec2's together. If dest is given, the result
- * is stored there. Otherwise, the result is stored in vecB.
- *
- * @param {vec2} vecA the first operand
- * @param {vec2} vecB the second operand
- * @param {vec2} [dest] the optional receiving vector
- * @returns {vec2} dest
- */
- vec2.add = function(vecA, vecB, dest) {
- if (!dest) dest = vecB;
- dest[0] = vecA[0] + vecB[0];
- dest[1] = vecA[1] + vecB[1];
- return dest;
- };
-
- /**
- * Subtracts vecB from vecA. If dest is given, the result
- * is stored there. Otherwise, the result is stored in vecB.
- *
- * @param {vec2} vecA the first operand
- * @param {vec2} vecB the second operand
- * @param {vec2} [dest] the optional receiving vector
- * @returns {vec2} dest
- */
- vec2.subtract = function(vecA, vecB, dest) {
- if (!dest) dest = vecB;
- dest[0] = vecA[0] - vecB[0];
- dest[1] = vecA[1] - vecB[1];
- return dest;
- };
-
- /**
- * Multiplies vecA with vecB. If dest is given, the result
- * is stored there. Otherwise, the result is stored in vecB.
- *
- * @param {vec2} vecA the first operand
- * @param {vec2} vecB the second operand
- * @param {vec2} [dest] the optional receiving vector
- * @returns {vec2} dest
- */
- vec2.multiply = function(vecA, vecB, dest) {
- if (!dest) dest = vecB;
- dest[0] = vecA[0] * vecB[0];
- dest[1] = vecA[1] * vecB[1];
- return dest;
- };
-
- /**
- * Divides vecA by vecB. If dest is given, the result
- * is stored there. Otherwise, the result is stored in vecB.
- *
- * @param {vec2} vecA the first operand
- * @param {vec2} vecB the second operand
- * @param {vec2} [dest] the optional receiving vector
- * @returns {vec2} dest
- */
- vec2.divide = function(vecA, vecB, dest) {
- if (!dest) dest = vecB;
- dest[0] = vecA[0] / vecB[0];
- dest[1] = vecA[1] / vecB[1];
- return dest;
- };
-
- /**
- * Scales vecA by some scalar number. If dest is given, the result
- * is stored there. Otherwise, the result is stored in vecA.
- *
- * This is the same as multiplying each component of vecA
- * by the given scalar.
- *
- * @param {vec2} vecA the vector to be scaled
- * @param {Number} scalar the amount to scale the vector by
- * @param {vec2} [dest] the optional receiving vector
- * @returns {vec2} dest
- */
- vec2.scale = function(vecA, scalar, dest) {
- if (!dest) dest = vecA;
- dest[0] = vecA[0] * scalar;
- dest[1] = vecA[1] * scalar;
- return dest;
- };
-
- /**
- * Calculates the euclidian distance between two vec2
- *
- * Params:
- * @param {vec2} vecA First vector
- * @param {vec2} vecB Second vector
- *
- * @returns {number} Distance between vecA and vecB
- */
- vec2.dist = function (vecA, vecB) {
- var x = vecB[0] - vecA[0],
- y = vecB[1] - vecA[1];
- return Math.sqrt(x*x + y*y);
- };
-
- /**
- * Copies the values of one vec2 to another
- *
- * @param {vec2} vec vec2 containing values to copy
- * @param {vec2} dest vec2 receiving copied values
- *
- * @returns {vec2} dest
- */
- vec2.set = function (vec, dest) {
- dest[0] = vec[0];
- dest[1] = vec[1];
- return dest;
- };
-
- /**
- * Compares two vectors for equality within a certain margin of error
- *
- * @param {vec2} a First vector
- * @param {vec2} b Second vector
- *
- * @returns {Boolean} True if a is equivalent to b
- */
- vec2.equal = function (a, b) {
- return a === b || (
- Math.abs(a[0] - b[0]) < FLOAT_EPSILON &&
- Math.abs(a[1] - b[1]) < FLOAT_EPSILON
- );
- };
-
- /**
- * Negates the components of a vec2
- *
- * @param {vec2} vec vec2 to negate
- * @param {vec2} [dest] vec2 receiving operation result. If not specified result is written to vec
- *
- * @returns {vec2} dest if specified, vec otherwise
- */
- vec2.negate = function (vec, dest) {
- if (!dest) { dest = vec; }
- dest[0] = -vec[0];
- dest[1] = -vec[1];
- return dest;
- };
-
- /**
- * Normlize a vec2
- *
- * @param {vec2} vec vec2 to normalize
- * @param {vec2} [dest] vec2 receiving operation result. If not specified result is written to vec
- *
- * @returns {vec2} dest if specified, vec otherwise
- */
- vec2.normalize = function (vec, dest) {
- if (!dest) { dest = vec; }
- var mag = vec[0] * vec[0] + vec[1] * vec[1];
- if (mag > 0) {
- mag = Math.sqrt(mag);
- dest[0] = vec[0] / mag;
- dest[1] = vec[1] / mag;
- } else {
- dest[0] = dest[1] = 0;
- }
- return dest;
- };
-
- /**
- * Computes the cross product of two vec2's. Note that the cross product must by definition
- * produce a 3D vector. If a dest vector is given, it will contain the resultant 3D vector.
- * Otherwise, a scalar number will be returned, representing the vector's Z coordinate, since
- * its X and Y must always equal 0.
- *
- * Examples:
- * var crossResult = vec3.create();
- * vec2.cross([1, 2], [3, 4], crossResult);
- * //=> [0, 0, -2]
- *
- * vec2.cross([1, 2], [3, 4]);
- * //=> -2
- *
- * See http://stackoverflow.com/questions/243945/calculating-a-2d-vectors-cross-product
- * for some interesting facts.
- *
- * @param {vec2} vecA left operand
- * @param {vec2} vecB right operand
- * @param {vec2} [dest] optional vec2 receiving result. If not specified a scalar is returned
- *
- */
- vec2.cross = function (vecA, vecB, dest) {
- var z = vecA[0] * vecB[1] - vecA[1] * vecB[0];
- if (!dest) return z;
- dest[0] = dest[1] = 0;
- dest[2] = z;
- return dest;
- };
-
- /**
- * Caclulates the length of a vec2
- *
- * @param {vec2} vec vec2 to calculate length of
- *
- * @returns {Number} Length of vec
- */
- vec2.length = function (vec) {
- var x = vec[0], y = vec[1];
- return Math.sqrt(x * x + y * y);
- };
-
- /**
- * Caclulates the squared length of a vec2
- *
- * @param {vec2} vec vec2 to calculate squared length of
- *
- * @returns {Number} Squared Length of vec
- */
- vec2.squaredLength = function (vec) {
- var x = vec[0], y = vec[1];
- return x * x + y * y;
- };
-
- /**
- * Caclulates the dot product of two vec2s
- *
- * @param {vec2} vecA First operand
- * @param {vec2} vecB Second operand
- *
- * @returns {Number} Dot product of vecA and vecB
- */
- vec2.dot = function (vecA, vecB) {
- return vecA[0] * vecB[0] + vecA[1] * vecB[1];
- };
-
- /**
- * Generates a 2D unit vector pointing from one vector to another
- *
- * @param {vec2} vecA Origin vec2
- * @param {vec2} vecB vec2 to point to
- * @param {vec2} [dest] vec2 receiving operation result. If not specified result is written to vecA
- *
- * @returns {vec2} dest if specified, vecA otherwise
- */
- vec2.direction = function (vecA, vecB, dest) {
- if (!dest) { dest = vecA; }
-
- var x = vecA[0] - vecB[0],
- y = vecA[1] - vecB[1],
- len = x * x + y * y;
-
- if (!len) {
- dest[0] = 0;
- dest[1] = 0;
- dest[2] = 0;
- return dest;
- }
-
- len = 1 / Math.sqrt(len);
- dest[0] = x * len;
- dest[1] = y * len;
- return dest;
- };
-
- /**
- * Performs a linear interpolation between two vec2
- *
- * @param {vec2} vecA First vector
- * @param {vec2} vecB Second vector
- * @param {Number} lerp Interpolation amount between the two inputs
- * @param {vec2} [dest] vec2 receiving operation result. If not specified result is written to vecA
- *
- * @returns {vec2} dest if specified, vecA otherwise
- */
- vec2.lerp = function (vecA, vecB, lerp, dest) {
- if (!dest) { dest = vecA; }
- dest[0] = vecA[0] + lerp * (vecB[0] - vecA[0]);
- dest[1] = vecA[1] + lerp * (vecB[1] - vecA[1]);
- return dest;
- };
-
- /**
- * Returns a string representation of a vector
- *
- * @param {vec2} vec Vector to represent as a string
- *
- * @returns {String} String representation of vec
- */
- vec2.str = function (vec) {
- return '[' + vec[0] + ', ' + vec[1] + ']';
- };
-
- /**
- * @class 2x2 Matrix
- * @name mat2
- */
- var mat2 = {};
-
- /**
- * Creates a new 2x2 matrix. If src is given, the new matrix
- * is initialized to those values.
- *
- * @param {mat2} [src] the seed values for the new matrix, if any
- * @returns {mat2} a new matrix
- */
- mat2.create = function(src) {
- var dest = new MatrixArray(4);
-
- if (src) {
- dest[0] = src[0];
- dest[1] = src[1];
- dest[2] = src[2];
- dest[3] = src[3];
- } else {
- dest[0] = dest[1] = dest[2] = dest[3] = 0;
- }
- return dest;
- };
-
- /**
- * Creates a new instance of a mat2, initializing it with the given arguments
- *
- * @param {number} m00
- * @param {number} m01
- * @param {number} m10
- * @param {number} m11
-
- * @returns {mat2} New mat2
- */
- mat2.createFrom = function (m00, m01, m10, m11) {
- var dest = new MatrixArray(4);
-
- dest[0] = m00;
- dest[1] = m01;
- dest[2] = m10;
- dest[3] = m11;
-
- return dest;
- };
-
- /**
- * Copies the values of one mat2 to another
- *
- * @param {mat2} mat mat2 containing values to copy
- * @param {mat2} dest mat2 receiving copied values
- *
- * @returns {mat2} dest
- */
- mat2.set = function (mat, dest) {
- dest[0] = mat[0];
- dest[1] = mat[1];
- dest[2] = mat[2];
- dest[3] = mat[3];
- return dest;
- };
-
- /**
- * Compares two matrices for equality within a certain margin of error
- *
- * @param {mat2} a First matrix
- * @param {mat2} b Second matrix
- *
- * @returns {Boolean} True if a is equivalent to b
- */
- mat2.equal = function (a, b) {
- return a === b || (
- Math.abs(a[0] - b[0]) < FLOAT_EPSILON &&
- Math.abs(a[1] - b[1]) < FLOAT_EPSILON &&
- Math.abs(a[2] - b[2]) < FLOAT_EPSILON &&
- Math.abs(a[3] - b[3]) < FLOAT_EPSILON
- );
- };
-
- /**
- * Sets a mat2 to an identity matrix
- *
- * @param {mat2} [dest] mat2 to set. If omitted a new one will be created.
- *
- * @returns {mat2} dest
- */
- mat2.identity = function (dest) {
- if (!dest) { dest = mat2.create(); }
- dest[0] = 1;
- dest[1] = 0;
- dest[2] = 0;
- dest[3] = 1;
- return dest;
- };
-
- /**
- * Transposes a mat2 (flips the values over the diagonal)
- *
- * @param {mat2} mat mat2 to transpose
- * @param {mat2} [dest] mat2 receiving transposed values. If not specified result is written to mat
- *
- * @param {mat2} dest if specified, mat otherwise
- */
- mat2.transpose = function (mat, dest) {
- // If we are transposing ourselves we can skip a few steps but have to cache some values
- if (!dest || mat === dest) {
- var a00 = mat[1];
- mat[1] = mat[2];
- mat[2] = a00;
- return mat;
- }
-
- dest[0] = mat[0];
- dest[1] = mat[2];
- dest[2] = mat[1];
- dest[3] = mat[3];
- return dest;
- };
-
- /**
- * Calculates the determinant of a mat2
- *
- * @param {mat2} mat mat2 to calculate determinant of
- *
- * @returns {Number} determinant of mat
- */
- mat2.determinant = function (mat) {
- return mat[0] * mat[3] - mat[2] * mat[1];
- };
-
- /**
- * Calculates the inverse matrix of a mat2
- *
- * @param {mat2} mat mat2 to calculate inverse of
- * @param {mat2} [dest] mat2 receiving inverse matrix. If not specified result is written to mat
- *
- * @param {mat2} dest is specified, mat otherwise, null if matrix cannot be inverted
- */
- mat2.inverse = function (mat, dest) {
- if (!dest) { dest = mat; }
- var a0 = mat[0], a1 = mat[1], a2 = mat[2], a3 = mat[3];
- var det = a0 * a3 - a2 * a1;
- if (!det) return null;
-
- det = 1.0 / det;
- dest[0] = a3 * det;
- dest[1] = -a1 * det;
- dest[2] = -a2 * det;
- dest[3] = a0 * det;
- return dest;
- };
-
- /**
- * Performs a matrix multiplication
- *
- * @param {mat2} matA First operand
- * @param {mat2} matB Second operand
- * @param {mat2} [dest] mat2 receiving operation result. If not specified result is written to matA
- *
- * @returns {mat2} dest if specified, matA otherwise
- */
- mat2.multiply = function (matA, matB, dest) {
- if (!dest) { dest = matA; }
- var a11 = matA[0],
- a12 = matA[1],
- a21 = matA[2],
- a22 = matA[3];
- dest[0] = a11 * matB[0] + a12 * matB[2];
- dest[1] = a11 * matB[1] + a12 * matB[3];
- dest[2] = a21 * matB[0] + a22 * matB[2];
- dest[3] = a21 * matB[1] + a22 * matB[3];
- return dest;
- };
-
- /**
- * Rotates a 2x2 matrix by an angle
- *
- * @param {mat2} mat The matrix to rotate
- * @param {Number} angle The angle in radians
- * @param {mat2} [dest] Optional mat2 receiving the result. If omitted mat will be used.
- *
- * @returns {mat2} dest if specified, mat otherwise
- */
- mat2.rotate = function (mat, angle, dest) {
- if (!dest) { dest = mat; }
- var a11 = mat[0],
- a12 = mat[1],
- a21 = mat[2],
- a22 = mat[3],
- s = Math.sin(angle),
- c = Math.cos(angle);
- dest[0] = a11 * c + a12 * s;
- dest[1] = a11 * -s + a12 * c;
- dest[2] = a21 * c + a22 * s;
- dest[3] = a21 * -s + a22 * c;
- return dest;
- };
-
- /**
- * Multiplies the vec2 by the given 2x2 matrix
- *
- * @param {mat2} matrix the 2x2 matrix to multiply against
- * @param {vec2} vec the vector to multiply
- * @param {vec2} [dest] an optional receiving vector. If not given, vec is used.
- *
- * @returns {vec2} The multiplication result
- **/
- mat2.multiplyVec2 = function(matrix, vec, dest) {
- if (!dest) dest = vec;
- var x = vec[0], y = vec[1];
- dest[0] = x * matrix[0] + y * matrix[1];
- dest[1] = x * matrix[2] + y * matrix[3];
- return dest;
- };
-
- /**
- * Scales the mat2 by the dimensions in the given vec2
- *
- * @param {mat2} matrix the 2x2 matrix to scale
- * @param {vec2} vec the vector containing the dimensions to scale by
- * @param {vec2} [dest] an optional receiving mat2. If not given, matrix is used.
- *
- * @returns {mat2} dest if specified, matrix otherwise
- **/
- mat2.scale = function(matrix, vec, dest) {
- if (!dest) { dest = matrix; }
- var a11 = matrix[0],
- a12 = matrix[1],
- a21 = matrix[2],
- a22 = matrix[3],
- b11 = vec[0],
- b22 = vec[1];
- dest[0] = a11 * b11;
- dest[1] = a12 * b22;
- dest[2] = a21 * b11;
- dest[3] = a22 * b22;
- return dest;
- };
-
- /**
- * Returns a string representation of a mat2
- *
- * @param {mat2} mat mat2 to represent as a string
- *
- * @param {String} String representation of mat
- */
- mat2.str = function (mat) {
- return '[' + mat[0] + ', ' + mat[1] + ', ' + mat[2] + ', ' + mat[3] + ']';
- };
-
- /**
- * @class 4 Dimensional Vector
- * @name vec4
- */
- var vec4 = {};
-
- /**
- * Creates a new vec4, initializing it from vec if vec
- * is given.
- *
- * @param {vec4} [vec] the vector's initial contents
- * @returns {vec4} a new 2D vector
- */
- vec4.create = function(vec) {
- var dest = new MatrixArray(4);
-
- if (vec) {
- dest[0] = vec[0];
- dest[1] = vec[1];
- dest[2] = vec[2];
- dest[3] = vec[3];
- } else {
- dest[0] = 0;
- dest[1] = 0;
- dest[2] = 0;
- dest[3] = 0;
- }
- return dest;
- };
-
- /**
- * Creates a new instance of a vec4, initializing it with the given arguments
- *
- * @param {number} x X value
- * @param {number} y Y value
- * @param {number} z Z value
- * @param {number} w W value
-
- * @returns {vec4} New vec4
- */
- vec4.createFrom = function (x, y, z, w) {
- var dest = new MatrixArray(4);
-
- dest[0] = x;
- dest[1] = y;
- dest[2] = z;
- dest[3] = w;
-
- return dest;
- };
-
- /**
- * Adds the vec4's together. If dest is given, the result
- * is stored there. Otherwise, the result is stored in vecB.
- *
- * @param {vec4} vecA the first operand
- * @param {vec4} vecB the second operand
- * @param {vec4} [dest] the optional receiving vector
- * @returns {vec4} dest
- */
- vec4.add = function(vecA, vecB, dest) {
- if (!dest) dest = vecB;
- dest[0] = vecA[0] + vecB[0];
- dest[1] = vecA[1] + vecB[1];
- dest[2] = vecA[2] + vecB[2];
- dest[3] = vecA[3] + vecB[3];
- return dest;
- };
-
- /**
- * Subtracts vecB from vecA. If dest is given, the result
- * is stored there. Otherwise, the result is stored in vecB.
- *
- * @param {vec4} vecA the first operand
- * @param {vec4} vecB the second operand
- * @param {vec4} [dest] the optional receiving vector
- * @returns {vec4} dest
- */
- vec4.subtract = function(vecA, vecB, dest) {
- if (!dest) dest = vecB;
- dest[0] = vecA[0] - vecB[0];
- dest[1] = vecA[1] - vecB[1];
- dest[2] = vecA[2] - vecB[2];
- dest[3] = vecA[3] - vecB[3];
- return dest;
- };
-
- /**
- * Multiplies vecA with vecB. If dest is given, the result
- * is stored there. Otherwise, the result is stored in vecB.
- *
- * @param {vec4} vecA the first operand
- * @param {vec4} vecB the second operand
- * @param {vec4} [dest] the optional receiving vector
- * @returns {vec4} dest
- */
- vec4.multiply = function(vecA, vecB, dest) {
- if (!dest) dest = vecB;
- dest[0] = vecA[0] * vecB[0];
- dest[1] = vecA[1] * vecB[1];
- dest[2] = vecA[2] * vecB[2];
- dest[3] = vecA[3] * vecB[3];
- return dest;
- };
-
- /**
- * Divides vecA by vecB. If dest is given, the result
- * is stored there. Otherwise, the result is stored in vecB.
- *
- * @param {vec4} vecA the first operand
- * @param {vec4} vecB the second operand
- * @param {vec4} [dest] the optional receiving vector
- * @returns {vec4} dest
- */
- vec4.divide = function(vecA, vecB, dest) {
- if (!dest) dest = vecB;
- dest[0] = vecA[0] / vecB[0];
- dest[1] = vecA[1] / vecB[1];
- dest[2] = vecA[2] / vecB[2];
- dest[3] = vecA[3] / vecB[3];
- return dest;
- };
-
- /**
- * Scales vecA by some scalar number. If dest is given, the result
- * is stored there. Otherwise, the result is stored in vecA.
- *
- * This is the same as multiplying each component of vecA
- * by the given scalar.
- *
- * @param {vec4} vecA the vector to be scaled
- * @param {Number} scalar the amount to scale the vector by
- * @param {vec4} [dest] the optional receiving vector
- * @returns {vec4} dest
- */
- vec4.scale = function(vecA, scalar, dest) {
- if (!dest) dest = vecA;
- dest[0] = vecA[0] * scalar;
- dest[1] = vecA[1] * scalar;
- dest[2] = vecA[2] * scalar;
- dest[3] = vecA[3] * scalar;
- return dest;
- };
-
- /**
- * Copies the values of one vec4 to another
- *
- * @param {vec4} vec vec4 containing values to copy
- * @param {vec4} dest vec4 receiving copied values
- *
- * @returns {vec4} dest
- */
- vec4.set = function (vec, dest) {
- dest[0] = vec[0];
- dest[1] = vec[1];
- dest[2] = vec[2];
- dest[3] = vec[3];
- return dest;
- };
-
- /**
- * Compares two vectors for equality within a certain margin of error
- *
- * @param {vec4} a First vector
- * @param {vec4} b Second vector
- *
- * @returns {Boolean} True if a is equivalent to b
- */
- vec4.equal = function (a, b) {
- return a === b || (
- Math.abs(a[0] - b[0]) < FLOAT_EPSILON &&
- Math.abs(a[1] - b[1]) < FLOAT_EPSILON &&
- Math.abs(a[2] - b[2]) < FLOAT_EPSILON &&
- Math.abs(a[3] - b[3]) < FLOAT_EPSILON
- );
- };
-
- /**
- * Negates the components of a vec4
- *
- * @param {vec4} vec vec4 to negate
- * @param {vec4} [dest] vec4 receiving operation result. If not specified result is written to vec
- *
- * @returns {vec4} dest if specified, vec otherwise
- */
- vec4.negate = function (vec, dest) {
- if (!dest) { dest = vec; }
- dest[0] = -vec[0];
- dest[1] = -vec[1];
- dest[2] = -vec[2];
- dest[3] = -vec[3];
- return dest;
- };
-
- /**
- * Caclulates the length of a vec2
- *
- * @param {vec2} vec vec2 to calculate length of
- *
- * @returns {Number} Length of vec
- */
- vec4.length = function (vec) {
- var x = vec[0], y = vec[1], z = vec[2], w = vec[3];
- return Math.sqrt(x * x + y * y + z * z + w * w);
- };
-
- /**
- * Caclulates the squared length of a vec4
- *
- * @param {vec4} vec vec4 to calculate squared length of
- *
- * @returns {Number} Squared Length of vec
- */
- vec4.squaredLength = function (vec) {
- var x = vec[0], y = vec[1], z = vec[2], w = vec[3];
- return x * x + y * y + z * z + w * w;
- };
-
- /**
- * Performs a linear interpolation between two vec4
- *
- * @param {vec4} vecA First vector
- * @param {vec4} vecB Second vector
- * @param {Number} lerp Interpolation amount between the two inputs
- * @param {vec4} [dest] vec4 receiving operation result. If not specified result is written to vecA
- *
- * @returns {vec4} dest if specified, vecA otherwise
- */
- vec4.lerp = function (vecA, vecB, lerp, dest) {
- if (!dest) { dest = vecA; }
- dest[0] = vecA[0] + lerp * (vecB[0] - vecA[0]);
- dest[1] = vecA[1] + lerp * (vecB[1] - vecA[1]);
- dest[2] = vecA[2] + lerp * (vecB[2] - vecA[2]);
- dest[3] = vecA[3] + lerp * (vecB[3] - vecA[3]);
- return dest;
- };
-
- /**
- * Returns a string representation of a vector
- *
- * @param {vec4} vec Vector to represent as a string
- *
- * @returns {String} String representation of vec
- */
- vec4.str = function (vec) {
- return '[' + vec[0] + ', ' + vec[1] + ', ' + vec[2] + ', ' + vec[3] + ']';
- };
-
- /*
- * Exports
- */
-
- if(root) {
- root.glMatrixArrayType = MatrixArray;
- root.MatrixArray = MatrixArray;
- root.setMatrixArrayType = setMatrixArrayType;
- root.determineMatrixArrayType = determineMatrixArrayType;
- root.glMath = glMath;
- root.vec2 = vec2;
- root.vec3 = vec3;
- root.vec4 = vec4;
- root.mat2 = mat2;
- root.mat3 = mat3;
- root.mat4 = mat4;
- root.quat4 = quat4;
- }
-
- return {
- glMatrixArrayType: MatrixArray,
- MatrixArray: MatrixArray,
- setMatrixArrayType: setMatrixArrayType,
- determineMatrixArrayType: determineMatrixArrayType,
- glMath: glMath,
- vec2: vec2,
- vec3: vec3,
- vec4: vec4,
- mat2: mat2,
- mat3: mat3,
- mat4: mat4,
- quat4: quat4
- };
-}));
+++ /dev/null
-function clamp(e,t,r){return e<=t?t:e>=r?r:e}function degToRad(e){return e*Math.PI/180}function initGL(e){try{(gl=e.getContext("experimental-webgl")).viewportWidth=e.width,gl.viewportHeight=e.height}catch(e){}gl||alert("Could not initialise WebGL, sorry :-(")}function camera(){this.front=vec3.create([0,0,1]),this.up=vec3.create([0,1,0]),this.pos=vec3.create([-1.5,6.8,-11]),this.viewMatrix=mat4.create(),this.lastx=0,this.lasty=0,this.yaw=0,this.pitch=0,this.roll=0,this.sensitivity=.1,this.moveForward=function(e){var t=vec3.create();vec3.add(t,this.front),vec3.multiply(t,[e*deltaTime,e*deltaTime,e*deltaTime]),vec3.add(this.pos,t)},this.moveHorizontal=function(e){var t=vec3.create();vec3.cross(this.front,this.up,t),vec3.normalize(t),vec3.multiply(t,[e*deltaTime,e*deltaTime,e*deltaTime]),vec3.add(this.pos,t)},this.getMatrix=function(){mat4.identity(this.viewMatrix);var e=vec3.create();return vec3.add(e,this.pos),vec3.add(e,this.front),mat4.lookAt(this.pos,e,this.up,this.viewMatrix),this.viewMatrix},this.mouseUpdate=function(e,t){var r=e,i=t;this.lastx=e,this.lasty=t,r*=-this.sensitivity,i*=-this.sensitivity,this.pitch=clamp(this.pitch+i,-89,89),this.yaw+=r;var a=vec3.create();a[2]=Math.cos(degToRad(this.pitch))*Math.cos(degToRad(this.yaw)),a[1]=Math.sin(degToRad(this.pitch)),a[0]=Math.cos(degToRad(this.pitch))*Math.sin(degToRad(this.yaw)),this.front=a}}function getShader(e,t){var r=document.getElementById(t);if(!r)return null;for(var i="",a=r.firstChild;a;)3==a.nodeType&&(i+=a.textContent),a=a.nextSibling;var s;if("x-shader/x-fragment"==r.type)s=e.createShader(e.FRAGMENT_SHADER);else{if("x-shader/x-vertex"!=r.type)return null;s=e.createShader(e.VERTEX_SHADER)}return e.shaderSource(s,i),e.compileShader(s),e.getShaderParameter(s,e.COMPILE_STATUS)?s:(alert(e.getShaderInfoLog(s)),null)}function shader(e){var t=getShader(gl,e+"-fs"),r=getShader(gl,e+"-vs");this.program=gl.createProgram(),gl.attachShader(this.program,r),gl.attachShader(this.program,t),gl.linkProgram(this.program),gl.getProgramParameter(this.program,gl.LINK_STATUS)||alert("SHADER::INITIALIZE::FAIL SHADER("+e+")"),gl.enableVertexAttribArray(gl.getAttribLocation(this.program,"aVertexPosition")),gl.enableVertexAttribArray(gl.getAttribLocation(this.program,"aVertexNormal")),gl.enableVertexAttribArray(gl.getAttribLocation(this.program,"aTextureCoord")),this.setMatrix4fv=function(e,t){gl.uniformMatrix4fv(gl.getUniformLocation(this.program,e),!1,t)},this.setMatrix3fv=function(e,t){gl.uniformMatrix3fv(gl.getUniformLocation(this.program,e),!1,t)},this.setVector3f=function(e,t,r,i){gl.uniform3f(gl.getUniformLocation(this.program,e),t,r,i)},this.setVector3fv=function(e,t){gl.uniform3fv(gl.getUniformLocation(this.program,e),t)},this.setFloat=function(e,t){gl.uniform1f(gl.getUniformLocation(this.program,e),t)},this.setInt=function(e,t){gl.uniform1i(gl.getUniformLocation(this.program,e),t)},this.use=function(){gl.useProgram(this.program)}}function initShaders(){testShader=new shader("shader")}function handleLoadedTexture(e){gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,!0),gl.bindTexture(gl.TEXTURE_2D,e),gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,e.image),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR_MIPMAP_NEAREST),gl.generateMipmap(gl.TEXTURE_2D),gl.bindTexture(gl.TEXTURE_2D,null)}function initTexture(){(crateTexture=gl.createTexture()).image=new Image,crateTexture.image.onload=function(){handleLoadedTexture(crateTexture)},crateTexture.image.src="bsp.png",(modelTexture=gl.createTexture()).image=new Image,modelTexture.image.onload=function(){handleLoadedTexture(modelTexture)},modelTexture.image.src="model.png"}function mvPushMatrix(){var e=mat4.create();mat4.set(mvMatrix,e),mvMatrixStack.push(e)}function mvPopMatrix(){if(0==mvMatrixStack.length)throw"Invalid popMatrix!";mvMatrix=mvMatrixStack.pop()}function setMatrixUniforms(){return}function handleKeyDown(e){currentlyPressedKeys[e.keyCode]=!0}function handleKeyUp(e){currentlyPressedKeys[e.keyCode]=!1}function handleKeys(){currentlyPressedKeys[33]&&(z-=.05),currentlyPressedKeys[34]&&(z+=.05),currentlyPressedKeys[37]&&(ySpeed-=1),currentlyPressedKeys[39]&&(ySpeed+=1),currentlyPressedKeys[38]&&(xSpeed-=1),currentlyPressedKeys[40]&&(xSpeed+=1),currentlyPressedKeys[87]&&test_camera.moveForward(.5),currentlyPressedKeys[65]&&test_camera.moveHorizontal(-.5),currentlyPressedKeys[83]&&test_camera.moveForward(-.5),currentlyPressedKeys[68]&&test_camera.moveHorizontal(.5)}function handleMouseMove(e){1==e.which&&test_camera.mouseUpdate(e.movementX,e.movementY)}function handleClick(e){clicking=!0}function handleClickUp(e){clicking=!1}function gl_mesh(e,t,r,i){this.vertexPositionBuffer=gl.createBuffer(),gl.bindBuffer(gl.ARRAY_BUFFER,this.vertexPositionBuffer),gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(e),gl.STATIC_DRAW),this.vertexPositionBuffer.itemSize=3,this.vertexPositionBuffer.numItems=e.length/3,this.normalBuffer=gl.createBuffer(),gl.bindBuffer(gl.ARRAY_BUFFER,this.normalBuffer),gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(t),gl.STATIC_DRAW),this.normalBuffer.itemSize=3,this.normalBuffer.numItems=t.length/3,this.texCoordBuffer=gl.createBuffer(),gl.bindBuffer(gl.ARRAY_BUFFER,this.texCoordBuffer),gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(r),gl.STATIC_DRAW),this.texCoordBuffer.itemSize=2,this.texCoordBuffer.numItems=r.length/2,this.indicesBuffer=gl.createBuffer(),gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,this.indicesBuffer),gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,new Uint16Array(i),gl.STATIC_DRAW),this.indicesBuffer.itemSize=1,this.indicesBuffer.numItems=i.length,console.log(this.vertexPositionBuffer),console.log(this.normalBuffer),this.draw=function(){gl.bindBuffer(gl.ARRAY_BUFFER,this.vertexPositionBuffer),gl.vertexAttribPointer(0,this.vertexPositionBuffer.itemSize,gl.FLOAT,!1,0,0),gl.bindBuffer(gl.ARRAY_BUFFER,this.normalBuffer),gl.vertexAttribPointer(1,this.normalBuffer.itemSize,gl.FLOAT,!1,0,0),gl.bindBuffer(gl.ARRAY_BUFFER,this.texCoordBuffer),gl.vertexAttribPointer(2,this.texCoordBuffer.itemSize,gl.FLOAT,!1,0,0),gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,this.indicesBuffer),gl.drawElements(gl.TRIANGLES,this.indicesBuffer.numItems,gl.UNSIGNED_SHORT,0)}}function initBuffers(){for(e=0;e<level.meshes.length;e++)level.meshes[e].indices.length>0&&all_meshes.push(new gl_mesh(level.meshes[e].positions,level.meshes[e].normals,level.meshes[e].uvCoords,level.meshes[e].indices));for(var e=0;e<level.cached_models.length;e++)level.cached_models[e].internal_mesh.indices.length>0&&cached_models.push(new gl_mesh(level.cached_models[e].internal_mesh.positions,level.cached_models[e].internal_mesh.normals,level.cached_models[e].internal_mesh.uvCoords,level.cached_models[e].internal_mesh.indices));return}function drawScene(){gl.viewport(0,0,gl.viewportWidth,gl.viewportHeight),gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT),mat4.perspective(50,gl.viewportWidth/gl.viewportHeight,.1,100,pMatrix),mat4.identity(mvMatrix),mat4.translate(mvMatrix,[0,0,0]),mat4.rotate(mvMatrix,degToRad(xRot),[1,0,0]),mat4.rotate(mvMatrix,degToRad(yRot),[0,1,0]),mat4.identity(viewMatrix),mat4.translate(viewMatrix,[0,-10,-30]),testShader.use(),gl.activeTexture(gl.TEXTURE0),gl.bindTexture(gl.TEXTURE_2D,crateTexture),testShader.setInt("uSampler",0),testShader.setVector3f("uAmbientColor",.3,.3,.3);var e=[-.5,-.4,-.7],t=vec3.create();vec3.normalize(e,t),vec3.scale(t,-1),testShader.setVector3fv("uLightingDirection",t),testShader.setVector3f("uDirectionalColor",1,1,1),testShader.setMatrix4fv("uPMatrix",pMatrix),testShader.setMatrix4fv("uMVMatrix",mvMatrix),testShader.setMatrix4fv("viewMatrix",test_camera.getMatrix());var r=mat3.create();mat4.toInverseMat3(mvMatrix,r),mat3.transpose(r),testShader.setMatrix3fv("uNMatrix",r);for(i=0;i<all_meshes.length;i++)all_meshes[i].draw();gl.bindTexture(gl.TEXTURE_2D,modelTexture);for(var i=0;i<level.models.length;i++)mat4.identity(mvMatrix),mat4.translate(mvMatrix,[.025*level.models[i].position[0],.025*level.models[i].position[2],-.025*level.models[i].position[1]]),mat4.rotate(mvMatrix,degToRad(level.models[i].rotation[0]),[0,0,1]),mat4.rotate(mvMatrix,degToRad(level.models[i].rotation[1]),[0,1,0]),mat4.rotate(mvMatrix,degToRad(level.models[i].rotation[2]),[1,0,0]),testShader.setMatrix4fv("uMVMatrix",mvMatrix),cached_models[level.models[i].modelID].draw()}function animate(){var e=(new Date).getTime();if(0!=lastTime){var t=e-lastTime;z+=t/1e3,deltaTime=.1*(e-lastTime),fps_time_counter+=t,frames+=1,fps_time_counter>1e3&&(fps_dom.innerHTML=frames+"fps",fps_time_counter=0,frames=0)}lastTime=e}function tick(){requestAnimFrame(tick),handleKeys(),drawScene(),animate()}function webGLStart(){var e=document.getElementById("glCanvas");e.width=window.innerWidth,e.height=window.innerHeight,fps_dom=document.getElementById("fps"),initGL(e),initShaders(),initBuffers(),initTexture(),gl.clearColor(.1,.1,.15,1),gl.enable(gl.DEPTH_TEST),document.onkeydown=handleKeyDown,document.onkeyup=handleKeyUp,document.onmousemove=handleMouseMove,document.onclick=handleClick,document.onclickup=handleClickUp,tick()}var gl,deltaTime=0,map_data=load_binary_resource("ar_baggage_raw.tbsp"),level=new tbsp_level(map_data),test_camera=new camera,tMatrix=test_camera.getMatrix(),shaderProgram,testShader,crateTexture,modelTexture,mvMatrix=mat4.create(),viewMatrix=mat4.create(),mvMatrixStack=[],pMatrix=mat4.create(),xRot=0,xSpeed=3,yRot=0,ySpeed=-3,z=-5,currentlyPressedKeys={},mouse_x=0,mouse_y=0,clicking=!1,test_mesh,test_mesh2,all_meshes=[],cached_models=[],z=0,viewMatrix=mat4.create(),lastTime=0,fps_time_counter=0;frames=0;var fps_dom;
+++ /dev/null
-var gl;
-
-function clamp(num, min, max) {
- return num <= min ? min : num >= max ? max : num;
-}
-
-function degToRad(degrees) {
- return degrees * Math.PI / 180;
-}
-
-
-var deltaTime = 0.0;
-
-//Load level as binary resource
-var map_data = load_binary_resource("ar_baggage_raw.tbsp");
-var level = new tbsp_level(map_data);
-
-//var model_data = load_binary_resource("test.tmdl");
-//var model_test = new tbsp_model(model_data);
-
-function initGL(canvas) {
- try {
- gl = canvas.getContext("experimental-webgl");
- gl.viewportWidth = canvas.width;
- gl.viewportHeight = canvas.height;
- } catch (e) {
- }
- if (!gl) {
- alert("Could not initialise WebGL, sorry :-(");
- }
-}
-
-
-function camera(){
- this.front = vec3.create([0.0, 0.0, 1.0]);
- this.up = vec3.create([0.0, 1.0, 0.0]);
- this.pos = vec3.create([-1.5, 6.8, -11]);
- this.viewMatrix = mat4.create();
-
- this.lastx = 0;
- this.lasty = 0;
-
- this.yaw = 0;
- this.pitch = 0;
- this.roll = 0;
-
- this.sensitivity = 0.1;
-
- this.moveForward = function(amount)
- {
- //this.pos += amount * this.front;
- var temp = vec3.create();
- vec3.add(temp, this.front);
- vec3.multiply(temp, [amount * deltaTime, amount * deltaTime, amount * deltaTime]);
-
- vec3.add(this.pos, temp);
- }
-
- this.moveHorizontal = function(amount)
- {
- var travelVector = vec3.create();
- vec3.cross(this.front, this.up, travelVector);
- vec3.normalize(travelVector);
- vec3.multiply(travelVector, [amount * deltaTime, amount * deltaTime, amount * deltaTime])
-
- vec3.add(this.pos, travelVector);
- }
-
- this.getMatrix = function()
- {
- mat4.identity(this.viewMatrix); //Reset view matrix
-
- var temp = vec3.create();
- vec3.add(temp, this.pos);
- vec3.add(temp, this.front);
-
- mat4.lookAt(this.pos, temp, this.up, this.viewMatrix);
- return this.viewMatrix; //Return it
- }
-
- this.mouseUpdate = function(xpos, ypos)
- {
- var xoffset = xpos;// - this.lastx;
- var yoffset = ypos;// - this.lasty;
-
- this.lastx = xpos;
- this.lasty = ypos;
-
- xoffset *= -this.sensitivity;
- yoffset *= -this.sensitivity;
-
- //this.yaw = this.yaw % 360.0;
- this.pitch = clamp(this.pitch + yoffset, -89, 89);
- this.yaw += xoffset;
- //this.pitch += yoffset;
-
- //Front facing vector
- var front = vec3.create();
- front[2] = Math.cos(degToRad(this.pitch)) * Math.cos(degToRad(this.yaw));
- front[1] = Math.sin(degToRad(this.pitch));
- front[0] = Math.cos(degToRad(this.pitch)) * Math.sin(degToRad(this.yaw));
-
- //Update class vectors
- this.front = front;
- }
-}
-
-//test camera
-var test_camera = new camera();
-
-var tMatrix = test_camera.getMatrix();
-
-var shaderProgram;
-
-
-function getShader(gl, id) {
- var shaderScript = document.getElementById(id);
- if (!shaderScript) {
- return null;
- }
-
- var str = "";
- var k = shaderScript.firstChild;
- while (k) {
- if (k.nodeType == 3) {
- str += k.textContent;
- }
- k = k.nextSibling;
- }
-
- var shader;
- if (shaderScript.type == "x-shader/x-fragment") {
- shader = gl.createShader(gl.FRAGMENT_SHADER);
- } else if (shaderScript.type == "x-shader/x-vertex") {
- shader = gl.createShader(gl.VERTEX_SHADER);
- } else {
- return null;
- }
-
- gl.shaderSource(shader, str);
- gl.compileShader(shader);
-
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
- alert(gl.getShaderInfoLog(shader));
- return null;
- }
-
- return shader;
-}
-function shader(name)
-{
- //Get shader sources from html
- var fragShaderSource = getShader(gl, name + "-fs");
- var vertShaderSource = getShader(gl, name + "-vs");
-
- //Create program
- this.program = gl.createProgram();
- gl.attachShader(this.program, vertShaderSource);
- gl.attachShader(this.program, fragShaderSource);
- //Link shaders
- gl.linkProgram(this.program);
-
- //Check for errors
- if (!gl.getProgramParameter(this.program, gl.LINK_STATUS)) {
- alert("SHADER::INITIALIZE::FAIL SHADER(" + name + ")");
- }
-
- gl.enableVertexAttribArray(gl.getAttribLocation(this.program, "aVertexPosition"));
- gl.enableVertexAttribArray(gl.getAttribLocation(this.program, "aVertexNormal"));
- gl.enableVertexAttribArray(gl.getAttribLocation(this.program, "aTextureCoord"));
-
- //==============================================================================
- // SHADER PARAMETER FUNCTIONS
- this.setMatrix4fv = function(name, matrix){
- gl.uniformMatrix4fv(gl.getUniformLocation(this.program, name), false, matrix);
- }
-
- this.setMatrix3fv = function(name, matrix){
- gl.uniformMatrix3fv(gl.getUniformLocation(this.program, name), false, matrix);
- }
-
- this.setVector3f = function(name, v0, v1, v2){
- gl.uniform3f(gl.getUniformLocation(this.program, name), v0, v1, v2);
- }
-
- this.setVector3fv = function(name, vector){
- gl.uniform3fv(gl.getUniformLocation(this.program, name), vector);
- }
-
- this.setFloat = function(name, value){
- gl.uniform1f(gl.getUniformLocation(this.program, name), value);
- }
-
- this.setInt = function(name, value){
- gl.uniform1i(gl.getUniformLocation(this.program, name), value);
- }
-
- /* Activate this shader */
- this.use = function(){
- gl.useProgram(this.program);
- }
-}
-
-var testShader;
-
-
-function initShaders() {
- testShader = new shader("shader");
- return;
- /*
- var fragmentShader = getShader(gl, "shader-fs");
- var vertexShader = getShader(gl, "shader-vs");
-
- shaderProgram = gl.createProgram();
- gl.attachShader(shaderProgram, vertexShader);
- gl.attachShader(shaderProgram, fragmentShader);
- gl.linkProgram(shaderProgram);
-
- if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
- alert("Could not initialise shaders");
- }
-
- gl.useProgram(shaderProgram);
-
- shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
- gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
-
- shaderProgram.vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal");
- gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute);
-
- shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
- gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);
-
- shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
- shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
- shaderProgram.nMatrixUniform = gl.getUniformLocation(shaderProgram, "uNMatrix");
- shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
- shaderProgram.viewMatrixUniform = gl.getUniformLocation(shaderProgram, "viewMatrix")
- shaderProgram.useLightingUniform = gl.getUniformLocation(shaderProgram, "uUseLighting");
- shaderProgram.ambientColorUniform = gl.getUniformLocation(shaderProgram, "uAmbientColor");
- shaderProgram.lightingDirectionUniform = gl.getUniformLocation(shaderProgram, "uLightingDirection");
- shaderProgram.directionalColorUniform = gl.getUniformLocation(shaderProgram, "uDirectionalColor");*/
-}
-
-function handleLoadedTexture(texture) {
- gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
-
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.image);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
- gl.generateMipmap(gl.TEXTURE_2D);
-
- gl.bindTexture(gl.TEXTURE_2D, null);
-}
-
-var crateTexture;
-var modelTexture;
-
-function initTexture() {
- crateTexture = gl.createTexture();
- crateTexture.image = new Image();
- crateTexture.image.onload = function () {
- handleLoadedTexture(crateTexture);
- }
-
- crateTexture.image.src = "bsp.png";
-
-
- modelTexture = gl.createTexture();
- modelTexture.image = new Image();
- modelTexture.image.onload = function (){
- handleLoadedTexture(modelTexture);
- }
-
- modelTexture.image.src = "model.png";
-}
-
-
-var mvMatrix = mat4.create();
-var viewMatrix = mat4.create();
-var mvMatrixStack = [];
-var pMatrix = mat4.create();
-
-function mvPushMatrix() {
- var copy = mat4.create();
- mat4.set(mvMatrix, copy);
- mvMatrixStack.push(copy);
-}
-
-function mvPopMatrix() {
- if (mvMatrixStack.length == 0) {
- throw "Invalid popMatrix!";
- }
- mvMatrix = mvMatrixStack.pop();
-}
-
-
-function setMatrixUniforms() {
- return;
- gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
- gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
- gl.uniformMatrix4fv(shaderProgram.viewMatrixUniform, false, test_camera.getMatrix());
-
- var normalMatrix = mat3.create();
- mat4.toInverseMat3(mvMatrix, normalMatrix);
- mat3.transpose(normalMatrix);
- gl.uniformMatrix3fv(shaderProgram.nMatrixUniform, false, normalMatrix);
-}
-
-
-
-
-
-
-
-var xRot = 0;
-var xSpeed = 3;
-
-var yRot = 0;
-var ySpeed = -3;
-
-var z = -5.0;
-
-var currentlyPressedKeys = {};
-function handleKeyDown(event) {
- currentlyPressedKeys[event.keyCode] = true;
-}
-function handleKeyUp(event) {
- currentlyPressedKeys[event.keyCode] = false;
-}
-
-var mouse_x = 0;
-var mouse_y = 0;
-
-var clicking = false;
-function handleKeys() {
- if (currentlyPressedKeys[33]) {
- // Page Up
- z -= 0.05;
- }
- if (currentlyPressedKeys[34]) {
- // Page Down
- z += 0.05;
- }
- if (currentlyPressedKeys[37]) {
- // Left cursor key
- ySpeed -= 1;
- }
- if (currentlyPressedKeys[39]) {
- // Right cursor key
- ySpeed += 1;
- }
- if (currentlyPressedKeys[38]) {
- // Up cursor key
- xSpeed -= 1;
- }
- if (currentlyPressedKeys[40]) {
- // Down cursor key
- xSpeed += 1;
- }
-
- //Camera controller
- // W key
- if (currentlyPressedKeys[87]){
- test_camera.moveForward(0.5);
- }
- //A key
- if(currentlyPressedKeys[65]){
- test_camera.moveHorizontal(-0.5);
- }
- //S key
- if(currentlyPressedKeys[83]){
- test_camera.moveForward(-0.5);
- }
- //D key
- if(currentlyPressedKeys[68]){
- test_camera.moveHorizontal(0.5);
- }
-}
-function handleMouseMove(event){
- //test_camera.mouseUpdate(event.clientX, event.clientY);
- if(event.which ==1)
- test_camera.mouseUpdate(event.movementX, event.movementY);
-}
-function handleClick(event){
- clicking = true;
-}
-function handleClickUp(event){
- clicking = false;
-}
-
-function gl_mesh(verts, normals, uvs, indices){
- //=======================================================================
- // Create vertex position buffer
- this.vertexPositionBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexPositionBuffer);
- //Upload vertex positions to GPU
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW);
- this.vertexPositionBuffer.itemSize = 3; //VEC3
- this.vertexPositionBuffer.numItems = verts.length / 3;
-
- //=======================================================================
- // Create normal vector buffer
- this.normalBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, this.normalBuffer);
- //Upload normal vectors
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW);
- this.normalBuffer.itemSize = 3;
- this.normalBuffer.numItems = normals.length / 3;
-
- //======================================================================
- // Create Texture coordinaate buffers
- this.texCoordBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, this.texCoordBuffer);
- //Upload texture textureCoordinates
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(uvs), gl.STATIC_DRAW);
- this.texCoordBuffer.itemSize = 2;
- this.texCoordBuffer.numItems = uvs.length / 2;
-
- //=====================================================================
- // Create Indices buffers
- this.indicesBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
- //Upload indices
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
- this.indicesBuffer.itemSize = 1;
- this.indicesBuffer.numItems = indices.length;
-
- //=====================================================================
- // Setup buffer pointers
- /*
- gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexPositionBuffer);
- gl.vertexAttribPointer(0, this.vertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.normalBuffer);
- gl.vertexAttribPointer(1, this.normalBuffer.itemSize, gl.FLOAT, false, 0, 0);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.texCoordBuffer);
- gl.vertexAttribPointer(2, this.texCoordBuffer.itemSize, gl.FLOAT, false, 0, 0);*/
-
- console.log(this.vertexPositionBuffer);
- console.log(this.normalBuffer);
-
- this.draw = function()
- {
- gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexPositionBuffer);
- gl.vertexAttribPointer(0, this.vertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.normalBuffer);
- gl.vertexAttribPointer(1, this.normalBuffer.itemSize, gl.FLOAT, false, 0, 0);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.texCoordBuffer);
- gl.vertexAttribPointer(2, this.texCoordBuffer.itemSize, gl.FLOAT, false, 0, 0);
-
-
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
-
- //Draw
- gl.drawElements(gl.TRIANGLES, this.indicesBuffer.numItems, gl.UNSIGNED_SHORT, 0);
- }
-}
-
-//Create test mesh
-var test_mesh;
-var test_mesh2;
-
-
-var all_meshes = [];
-var cached_models = [];
-function initBuffers() {
- /*all_meshes.push(new gl_mesh(model_test.internal_mesh.positions,
- model_test.internal_mesh.normals,
- model_test.internal_mesh.uvCoords,
- model_test.internal_mesh.indices));*/
-
- for(var x = 0; x < level.meshes.length; x++){
- if(level.meshes[x].indices.length > 0)
- {
-
- all_meshes.push(new gl_mesh(level.meshes[x].positions,
- level.meshes[x].normals,
- level.meshes[x].uvCoords,
- level.meshes[x].indices));
- }
- }
-
- // ===================
- // Load cached models
- for(var x = 0; x < level.cached_models.length; x++){
- if(level.cached_models[x].internal_mesh.indices.length > 0)
- {
- cached_models.push(new gl_mesh(level.cached_models[x].internal_mesh.positions,
- level.cached_models[x].internal_mesh.normals,
- level.cached_models[x].internal_mesh.uvCoords,
- level.cached_models[x].internal_mesh.indices));
- }
- }
-
- return;
- //NOTE: Testing only
- var y = 4;
- test_mesh = new gl_mesh(level.meshes[y].positions,
- level.meshes[y].normals,
- level.meshes[y].uvCoords,
- level.meshes[y].indices);
- test_mesh2 = new gl_mesh(level.meshes[0].positions,
- level.meshes[0].normals,
- level.meshes[0].uvCoords,
- level.meshes[0].indices);
-}
-
-
-
-
-
-//var location = vec3.create(0.0, 0.0, -10.0);;
-var z = 0.0;
-
-var viewMatrix = mat4.create();
-
-function drawScene() {
- //===========================================================
- // Clear screen
-
- gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
-
- mat4.perspective(50, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);
-
- mat4.identity(mvMatrix);
-
- //Model matrix
- mat4.translate(mvMatrix, [0.0, 0.0, 0.0]);
-
- mat4.rotate(mvMatrix, degToRad(xRot), [1, 0, 0]);
- mat4.rotate(mvMatrix, degToRad(yRot), [0, 1, 0]);
-
- //View matrix (global transform)
- mat4.identity(viewMatrix);
- //mat4.lookAt(viewMatrix, [0,0,6],[0,0,0],[0,1,0]);
- mat4.translate(viewMatrix, [0.0,-10.0,-30.0]);
-
- //Use test shader
- testShader.use();
-
- // Shader texture props
- //---------------------
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, crateTexture);
-
- testShader.setInt("uSampler", 0);
-
- // Shader lighting props
- //----------------------
- testShader.setVector3f("uAmbientColor", 0.3, 0.3, 0.3);
-
- var lightingDirection = [-0.5, -0.4, -0.7];
- var adjustedLD = vec3.create();
- vec3.normalize(lightingDirection, adjustedLD);
- vec3.scale(adjustedLD, -1);
- testShader.setVector3fv("uLightingDirection", adjustedLD);
-
- testShader.setVector3f("uDirectionalColor", 1, 1, 1);
-
- // Shader matrices
- //----------------
- testShader.setMatrix4fv("uPMatrix", pMatrix);
- testShader.setMatrix4fv("uMVMatrix", mvMatrix);
- testShader.setMatrix4fv("viewMatrix", test_camera.getMatrix()); //View matrix (global transform)
-
- var normalMatrix = mat3.create();
- mat4.toInverseMat3(mvMatrix, normalMatrix);
- mat3.transpose(normalMatrix);
- testShader.setMatrix3fv("uNMatrix", normalMatrix);
-
- //test_mesh.draw();
- //test_mesh2.draw();
- //all_meshes[1].draw();
-
- for(var x = 0; x < all_meshes.length; x++)
- {
- all_meshes[x].draw();
- }
-
- gl.bindTexture(gl.TEXTURE_2D, modelTexture);
-
- for(var x = 0; x < level.models.length; x++)
- {
- //Reset model matrix
- mat4.identity(mvMatrix);
-
- //Translate model into position
- mat4.translate(mvMatrix, [
- level.models[x].position[0] * (2.5 / 100),
- level.models[x].position[2] * (2.5 / 100),
- level.models[x].position[1] * -(2.5 / 100)]);
-
- //Rotate the matrix to match
- mat4.rotate(mvMatrix, degToRad(level.models[x].rotation[0]), [0, 0, 1]);
- mat4.rotate(mvMatrix, degToRad(level.models[x].rotation[1]), [0, 1, 0]);
- mat4.rotate(mvMatrix, degToRad(level.models[x].rotation[2]), [1, 0, 0]);
-
- testShader.setMatrix4fv("uMVMatrix", mvMatrix);
-
- cached_models[level.models[x].modelID].draw();
- }
-}
-
-
-var lastTime = 0;
-
-var fps_time_counter = 0.0;
-frames = 0;
-
-var fps_dom;
-
-function animate() {
-
- var timeNow = new Date().getTime();
- if (lastTime != 0) {
- var elapsed = timeNow - lastTime;
-
- //vec3.translate(location, [0,0,-0.1]);
- z += elapsed / 1000.0;
- //xRot += (xSpeed * elapsed) / 1000.0;
- //yRot += (ySpeed * elapsed) / 1000.0;
-
- deltaTime = (timeNow - lastTime) * 0.1;
-
- fps_time_counter += elapsed;
- frames += 1;
- if(fps_time_counter > 1000.0){
- fps_dom.innerHTML = frames+"fps";
- fps_time_counter = 0.0;
- frames = 0;
- }
- }
- lastTime = timeNow;
-}
-
-
-function tick() {
- requestAnimFrame(tick);
- handleKeys();
- drawScene();
- animate();
-}
-
-function webGLStart() {
- var canvas = document.getElementById("glCanvas");
-
- canvas.width = window.innerWidth;
- canvas.height = window.innerHeight;
-
-
- fps_dom = document.getElementById("fps");
- initGL(canvas);
- initShaders(); //NOTE: Get rid of this
- initBuffers();
- initTexture();
-
-
- gl.clearColor(0.1, 0.1, 0.15, 1.0);
- gl.enable(gl.DEPTH_TEST);
-
- document.onkeydown = handleKeyDown;
- document.onkeyup = handleKeyUp;
- document.onmousemove = handleMouseMove;
-
- document.onclick = handleClick;
- document.onclickup = handleClickUp;
-
- tick();
-}
+++ /dev/null
-<head>
-
-</head>
-
-<body>
-
-<canvas id="glCanvas" width="640" height="480"></canvas>
-
-</body>
-
-<script src="gl-matrix.js"></script>
-<script>
-var cubeRotation = 0.0;
-
-main();
-
-//
-// Start here
-//
-function main() {
- const canvas = document.querySelector('#glcanvas');
- const gl = canvas.getContext('webgl');
-
- // If we don't have a GL context, give up now
-
- if (!gl) {
- alert('Unable to initialize WebGL. Your browser or machine may not support it.');
- return;
- }
-
- // Vertex shader program
-
- const vsSource = `
- attribute vec4 aVertexPosition;
- attribute vec2 aTextureCoord;
- uniform mat4 uModelViewMatrix;
- uniform mat4 uProjectionMatrix;
- varying highp vec2 vTextureCoord;
- void main(void) {
- gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
- vTextureCoord = aTextureCoord;
- }
- `;
-
- // Fragment shader program
-
- const fsSource = `
- varying highp vec2 vTextureCoord;
- uniform sampler2D uSampler;
- void main(void) {
- gl_FragColor = texture2D(uSampler, vTextureCoord);
- }
- `;
-
- // Initialize a shader program; this is where all the lighting
- // for the vertices and so forth is established.
- const shaderProgram = initShaderProgram(gl, vsSource, fsSource);
-
- // Collect all the info needed to use the shader program.
- // Look up which attributes our shader program is using
- // for aVertexPosition, aTextureCoord and also
- // look up uniform locations.
- const programInfo = {
- program: shaderProgram,
- attribLocations: {
- vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'),
- textureCoord: gl.getAttribLocation(shaderProgram, 'aTextureCoord'),
- },
- uniformLocations: {
- projectionMatrix: gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'),
- modelViewMatrix: gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'),
- uSampler: gl.getUniformLocation(shaderProgram, 'uSampler'),
- },
- };
-
- // Here's where we call the routine that builds all the
- // objects we'll be drawing.
- const buffers = initBuffers(gl);
-
- const texture = loadTexture(gl, 'cubetexture.png');
-
- var then = 0;
-
- // Draw the scene repeatedly
- function render(now) {
- now *= 0.001; // convert to seconds
- const deltaTime = now - then;
- then = now;
-
- drawScene(gl, programInfo, buffers, texture, deltaTime);
-
- requestAnimationFrame(render);
- }
- requestAnimationFrame(render);
-}
-
-//
-// initBuffers
-//
-// Initialize the buffers we'll need. For this demo, we just
-// have one object -- a simple three-dimensional cube.
-//
-function initBuffers(gl) {
-
- // Create a buffer for the cube's vertex positions.
-
- const positionBuffer = gl.createBuffer();
-
- // Select the positionBuffer as the one to apply buffer
- // operations to from here out.
-
- gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
-
- // Now create an array of positions for the cube.
-
- const positions = [
- // Front face
- -1.0, -1.0, 1.0,
- 1.0, -1.0, 1.0,
- 1.0, 1.0, 1.0,
- -1.0, 1.0, 1.0,
-
- // Back face
- -1.0, -1.0, -1.0,
- -1.0, 1.0, -1.0,
- 1.0, 1.0, -1.0,
- 1.0, -1.0, -1.0,
-
- // Top face
- -1.0, 1.0, -1.0,
- -1.0, 1.0, 1.0,
- 1.0, 1.0, 1.0,
- 1.0, 1.0, -1.0,
-
- // Bottom face
- -1.0, -1.0, -1.0,
- 1.0, -1.0, -1.0,
- 1.0, -1.0, 1.0,
- -1.0, -1.0, 1.0,
-
- // Right face
- 1.0, -1.0, -1.0,
- 1.0, 1.0, -1.0,
- 1.0, 1.0, 1.0,
- 1.0, -1.0, 1.0,
-
- // Left face
- -1.0, -1.0, -1.0,
- -1.0, -1.0, 1.0,
- -1.0, 1.0, 1.0,
- -1.0, 1.0, -1.0,
- ];
-
- // Now pass the list of positions into WebGL to build the
- // shape. We do this by creating a Float32Array from the
- // JavaScript array, then use it to fill the current buffer.
-
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
-
- // Now set up the texture coordinates for the faces.
-
- const textureCoordBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer);
-
- const textureCoordinates = [
- // Front
- 0.0, 0.0,
- 1.0, 0.0,
- 1.0, 1.0,
- 0.0, 1.0,
- // Back
- 0.0, 0.0,
- 1.0, 0.0,
- 1.0, 1.0,
- 0.0, 1.0,
- // Top
- 0.0, 0.0,
- 1.0, 0.0,
- 1.0, 1.0,
- 0.0, 1.0,
- // Bottom
- 0.0, 0.0,
- 1.0, 0.0,
- 1.0, 1.0,
- 0.0, 1.0,
- // Right
- 0.0, 0.0,
- 1.0, 0.0,
- 1.0, 1.0,
- 0.0, 1.0,
- // Left
- 0.0, 0.0,
- 1.0, 0.0,
- 1.0, 1.0,
- 0.0, 1.0,
- ];
-
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates),
- gl.STATIC_DRAW);
-
- // Build the element array buffer; this specifies the indices
- // into the vertex arrays for each face's vertices.
-
- const indexBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
-
- // This array defines each face as two triangles, using the
- // indices into the vertex array to specify each triangle's
- // position.
-
- const indices = [
- 0, 1, 2, 0, 2, 3, // front
- 4, 5, 6, 4, 6, 7, // back
- 8, 9, 10, 8, 10, 11, // top
- 12, 13, 14, 12, 14, 15, // bottom
- 16, 17, 18, 16, 18, 19, // right
- 20, 21, 22, 20, 22, 23, // left
- ];
-
- // Now send the element array to GL
-
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
- new Uint16Array(indices), gl.STATIC_DRAW);
-
- return {
- position: positionBuffer,
- textureCoord: textureCoordBuffer,
- indices: indexBuffer,
- };
-}
-
-//
-// Initialize a texture and load an image.
-// When the image finished loading copy it into the texture.
-//
-function loadTexture(gl, url) {
- const texture = gl.createTexture();
- gl.bindTexture(gl.TEXTURE_2D, texture);
-
- // Because images have to be download over the internet
- // they might take a moment until they are ready.
- // Until then put a single pixel in the texture so we can
- // use it immediately. When the image has finished downloading
- // we'll update the texture with the contents of the image.
- const level = 0;
- const internalFormat = gl.RGBA;
- const width = 1;
- const height = 1;
- const border = 0;
- const srcFormat = gl.RGBA;
- const srcType = gl.UNSIGNED_BYTE;
- const pixel = new Uint8Array([0, 0, 255, 255]); // opaque blue
- gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,
- width, height, border, srcFormat, srcType,
- pixel);
-
- const image = new Image();
- image.onload = function() {
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,
- srcFormat, srcType, image);
-
- // WebGL1 has different requirements for power of 2 images
- // vs non power of 2 images so check if the image is a
- // power of 2 in both dimensions.
- if (isPowerOf2(image.width) && isPowerOf2(image.height)) {
- // Yes, it's a power of 2. Generate mips.
- gl.generateMipmap(gl.TEXTURE_2D);
- } else {
- // No, it's not a power of 2. Turn of mips and set
- // wrapping to clamp to edge
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
- }
- };
- image.src = url;
-
- return texture;
-}
-
-function isPowerOf2(value) {
- return (value & (value - 1)) == 0;
-}
-
-//
-// Draw the scene.
-//
-function drawScene(gl, programInfo, buffers, texture, deltaTime) {
- gl.clearColor(0.0, 0.0, 0.0, 1.0); // Clear to black, fully opaque
- gl.clearDepth(1.0); // Clear everything
- gl.enable(gl.DEPTH_TEST); // Enable depth testing
- gl.depthFunc(gl.LEQUAL); // Near things obscure far things
-
- // Clear the canvas before we start drawing on it.
-
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
-
- // Create a perspective matrix, a special matrix that is
- // used to simulate the distortion of perspective in a camera.
- // Our field of view is 45 degrees, with a width/height
- // ratio that matches the display size of the canvas
- // and we only want to see objects between 0.1 units
- // and 100 units away from the camera.
-
- const fieldOfView = 45 * Math.PI / 180; // in radians
- const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
- const zNear = 0.1;
- const zFar = 100.0;
- const projectionMatrix = mat4.create();
-
- // note: glmatrix.js always has the first argument
- // as the destination to receive the result.
- mat4.perspective(projectionMatrix,
- fieldOfView,
- aspect,
- zNear,
- zFar);
-
- // Set the drawing position to the "identity" point, which is
- // the center of the scene.
- const modelViewMatrix = mat4.create();
-
- // Now move the drawing position a bit to where we want to
- // start drawing the square.
-
- mat4.translate(modelViewMatrix, // destination matrix
- modelViewMatrix, // matrix to translate
- [-0.0, 0.0, -6.0]); // amount to translate
- mat4.rotate(modelViewMatrix, // destination matrix
- modelViewMatrix, // matrix to rotate
- cubeRotation, // amount to rotate in radians
- [0, 0, 1]); // axis to rotate around (Z)
- mat4.rotate(modelViewMatrix, // destination matrix
- modelViewMatrix, // matrix to rotate
- cubeRotation * .7,// amount to rotate in radians
- [0, 1, 0]); // axis to rotate around (X)
-
- // Tell WebGL how to pull out the positions from the position
- // buffer into the vertexPosition attribute
- {
- const numComponents = 3;
- const type = gl.FLOAT;
- const normalize = false;
- const stride = 0;
- const offset = 0;
- gl.bindBuffer(gl.ARRAY_BUFFER, buffers.position);
- gl.vertexAttribPointer(
- programInfo.attribLocations.vertexPosition,
- numComponents,
- type,
- normalize,
- stride,
- offset);
- gl.enableVertexAttribArray(
- programInfo.attribLocations.vertexPosition);
- }
-
- // Tell WebGL how to pull out the texture coordinates from
- // the texture coordinate buffer into the textureCoord attribute.
- {
- const numComponents = 2;
- const type = gl.FLOAT;
- const normalize = false;
- const stride = 0;
- const offset = 0;
- gl.bindBuffer(gl.ARRAY_BUFFER, buffers.textureCoord);
- gl.vertexAttribPointer(
- programInfo.attribLocations.textureCoord,
- numComponents,
- type,
- normalize,
- stride,
- offset);
- gl.enableVertexAttribArray(
- programInfo.attribLocations.textureCoord);
- }
-
- // Tell WebGL which indices to use to index the vertices
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers.indices);
-
- // Tell WebGL to use our program when drawing
-
- gl.useProgram(programInfo.program);
-
- // Set the shader uniforms
-
- gl.uniformMatrix4fv(
- programInfo.uniformLocations.projectionMatrix,
- false,
- projectionMatrix);
- gl.uniformMatrix4fv(
- programInfo.uniformLocations.modelViewMatrix,
- false,
- modelViewMatrix);
-
- // Specify the texture to map onto the faces.
-
- // Tell WebGL we want to affect texture unit 0
- gl.activeTexture(gl.TEXTURE0);
-
- // Bind the texture to texture unit 0
- gl.bindTexture(gl.TEXTURE_2D, texture);
-
- // Tell the shader we bound the texture to texture unit 0
- gl.uniform1i(programInfo.uniformLocations.uSampler, 0);
-
- {
- const vertexCount = 36;
- const type = gl.UNSIGNED_SHORT;
- const offset = 0;
- gl.drawElements(gl.TRIANGLES, vertexCount, type, offset);
- }
-
- // Update the rotation for the next draw
-
- cubeRotation += deltaTime;
-}
-
-//
-// Initialize a shader program, so WebGL knows how to draw our data
-//
-function initShaderProgram(gl, vsSource, fsSource) {
- const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
- const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
-
- // Create the shader program
-
- const shaderProgram = gl.createProgram();
- gl.attachShader(shaderProgram, vertexShader);
- gl.attachShader(shaderProgram, fragmentShader);
- gl.linkProgram(shaderProgram);
-
- // If creating the shader program failed, alert
-
- if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
- alert('Unable to initialize the shader program: ' + gl.getProgramInfoLog(shaderProgram));
- return null;
- }
-
- return shaderProgram;
-}
-
-//
-// creates a shader of the given type, uploads the source and
-// compiles it.
-//
-function loadShader(gl, type, source) {
- const shader = gl.createShader(type);
-
- // Send the source to the shader object
-
- gl.shaderSource(shader, source);
-
- // Compile the shader program
-
- gl.compileShader(shader);
-
- // See if it compiled successfully
-
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
- alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
- gl.deleteShader(shader);
- return null;
- }
-
- return shader;
-}
-</script>
+++ /dev/null
-function mesh(){this.positions=[],this.normals=[],this.uvCoords=[],this.indices=[]}function info_model(){this.position=vec3.create(),this.rotation=vec3.create(),this.modelID=0}function load_binary_resource(t){var s=[],a=new XMLHttpRequest;if(a.open("GET",t,!1),a.overrideMimeType("text/plain; charset=x-user-defined"),a.send(null),200!=a.status)return s;for(var e=0;e<a.responseText.length;++e)s.push(255&a.responseText.charCodeAt(e));return s}function binaryReader(t){this.pos=0,this.data=t,this.readUint32=function(){var t=(this.data[this.pos+3]<<24)+(this.data[this.pos+2]<<16)+(this.data[this.pos+1]<<8)+this.data[this.pos+0];return this.pos+=4,t},this.readString=function(){for(var t="";;){if(0==this.data[this.pos]){this.pos++;break}t+=String.fromCharCode(this.data[this.pos]),this.pos++}return t},this.readFloat=function(){var t=[this.data[this.pos+3],this.data[this.pos+2],this.data[this.pos+1],this.data[this.pos+0]],s=new ArrayBuffer(4),a=new DataView(s);t.forEach(function(t,s){a.setUint8(s,t)});var e=a.getFloat32(0);return this.pos+=4,e}}function tbsp_model(t){var s=new binaryReader(t),a=(s.readUint32(),s.readUint32(),s.readUint32()),e=s.readUint32();this.internal_mesh=new mesh;for(var i=0;i<a;i++)this.internal_mesh.positions.push(s.readFloat()),this.internal_mesh.positions.push(s.readFloat()),this.internal_mesh.positions.push(s.readFloat()),this.internal_mesh.normals.push(s.readFloat()),this.internal_mesh.normals.push(s.readFloat()),this.internal_mesh.normals.push(s.readFloat()),this.internal_mesh.uvCoords.push(s.readFloat()),this.internal_mesh.uvCoords.push(s.readFloat());for(var r=0;r<e;r++)this.internal_mesh.indices.push(s.readUint32())}function tbsp_level(t){var s=new binaryReader(t),a=(s.readUint32(),s.readUint32(),s.readUint32()),e=s.readUint32(),i=s.readUint32(),r=s.readUint32(),o=s.readUint32(),n=s.readUint32();s.readUint32(),s.readUint32();s.pos=e,this.meshes=[];for(var h=0;h<a;h++){for(var d=s.readUint32(),l=s.readUint32(),p=new mesh,u=0;u<d;u++)p.positions.push(s.readFloat()),p.positions.push(s.readFloat()),p.positions.push(s.readFloat()),p.normals.push(s.readFloat()),p.normals.push(s.readFloat()),p.normals.push(s.readFloat()),p.uvCoords.push(s.readFloat()),p.uvCoords.push(s.readFloat());for(var m=0;m<l;m++)p.indices.push(s.readUint32());this.meshes.push(p)}s.pos=n,this.cached_models=[];for(var c=0;c<o;c++){v=new tbsp_model(load_binary_resource("ar_baggage.resources/"+s.readString().replace(".mdl",".tmdl")));this.cached_models.push(v)}s.pos=r,this.models=[];for(var f=0;f<i;f++){var v=new info_model,F=s.readFloat(),_=s.readFloat(),U=s.readFloat();v.position[0]=F,v.position[1]=_,v.position[2]=U;var b=s.readFloat(),w=s.readFloat(),g=s.readFloat();v.rotation[0]=b,v.rotation[1]=w,v.rotation[2]=g,v.modelID=s.readUint32(),this.models.push(v)}}
+++ /dev/null
-//===================================================
-// STRUCTURES
-function mesh()
-{
- this.positions = [];
- this.normals = [];
- this.uvCoords = [];
- this.indices = [];
-}
-
-function info_model()
-{
- this.position = vec3.create();
- this.rotation = vec3.create();
- this.modelID = 0;
-}
-
-//====================================================================
-// RESOURCE TO BYTE ARRAY LOADER
-//Deprecated
-function load_binary_resource(url) {
- var byteArray = [];
- var req = new XMLHttpRequest();
- req.open('GET', url, false);
- req.overrideMimeType('text\/plain; charset=x-user-defined');
- req.send(null);
- if (req.status != 200) return byteArray;
- for (var i = 0; i < req.responseText.length; ++i) {
- byteArray.push(req.responseText.charCodeAt(i) & 0xff)
- }
- return byteArray;
-}
-
-
-//=========================================================
-// BINARY READER class
-
-//Takes in a byte array as source data
-//Works like fstream from c++
-function binaryReader(bytes)
-{
- this.pos = 0;
- this.data = bytes;
-
- this.readUint32 = function()
- {
- var val = (this.data[this.pos + 3] << 24) +
- (this.data[this.pos + 2] << 16) +
- (this.data[this.pos + 1] << 8) +
- this.data[this.pos + 0];
- this.pos += 4;
- return val;
- }
-
- this.readString = function()
- {
- var val = "";
- while(true)
- {
- if(this.data[this.pos] != 0x0)
- {
- val += String.fromCharCode(this.data[this.pos]);
- this.pos++;
- }
- else
- {
- this.pos++;
- break;
- }
- }
-
- return val;
- }
-
- this.readFloat = function()
- {
- var dat = [this.data[this.pos+3],
- this.data[this.pos+2],
- this.data[this.pos+1],
- this.data[this.pos+0]];
- var buf = new ArrayBuffer(4);
- var view = new DataView(buf);
-
- dat.forEach(function (b, i) {
- view.setUint8(i, b);
- });
-
- var val = view.getFloat32(0);
-
- this.pos += 4;
- return val;
- }
-}
-
-//====================================================================
-// TMDL class
-function tbsp_model(bytes)
-{
- var reader = new binaryReader(bytes);
-
- //Read magic number
- var magicNum = reader.readUint32();
- var version = reader.readUint32();
-
- var vertCount = reader.readUint32();
- var indexCount = reader.readUint32();
-
- this.internal_mesh = new mesh();
-
- //Read vertex data
- for(var c_vert = 0; c_vert < vertCount; c_vert++)
- {
- this.internal_mesh.positions.push(reader.readFloat()); //v_position
- this.internal_mesh.positions.push(reader.readFloat());
- this.internal_mesh.positions.push(reader.readFloat());
-
- this.internal_mesh.normals.push(reader.readFloat()); //v_normal
- this.internal_mesh.normals.push(reader.readFloat());
- this.internal_mesh.normals.push(reader.readFloat());
-
- this.internal_mesh.uvCoords.push(reader.readFloat()); //v_texCoord
- this.internal_mesh.uvCoords.push(reader.readFloat());
- }
-
- //Read indices data
- for(var c_index = 0; c_index < indexCount; c_index++)
- {
- this.internal_mesh.indices.push(reader.readUint32());
- }
-}
-
-//================================================================
-// TBSP Level class
-
-function tbsp_level(bytes)
-{
- var reader = new binaryReader(bytes);
-
- //===========================================
- // Read in the header
- var magicNum = reader.readUint32();
- var version = reader.readUint32();
-
- var meshCount = reader.readUint32();
- var meshLocation = reader.readUint32();
-
- var modelCount = reader.readUint32();
- var modelLocation = reader.readUint32();
-
- var modelDictCount = reader.readUint32();
- var modelDictLocation = reader.readUint32();
-
- var entityCount = reader.readUint32();
- var entityLocation = reader.readUint32();
-
-//Print some debug info if set
-if(false)
-{
- console.log("Reading TBSP level. Info:");
- console.log("Magic num: " + magicNum);
- console.log("Ver: " + version);
- console.log("mesh count: " + meshCount);
- console.log("Mesh location: " + meshLocation);
- console.log("Model count: " + modelCount);
- console.log("Model location: " + modelLocation);
- console.log("Model dict size: " + modelDictCount);
- console.log("Model dict location: " + modelDictLocation);
- console.log("Entity count: " + entityCount);
- console.log("Entity location: " + entityLocation);
-}
-
- //====================================================
- // READ BSP MESHES
- reader.pos = meshLocation;
- this.meshes = [];
- for(var c_mesh = 0; c_mesh < meshCount; c_mesh++)
- {
- var h_vert_count = reader.readUint32();
- var h_indices_count = reader.readUint32();
-
- var c_mesh_obj = new mesh();
-
-
- for(var c_vert = 0; c_vert < h_vert_count; c_vert++)
- {
- c_mesh_obj.positions.push(reader.readFloat());
- c_mesh_obj.positions.push(reader.readFloat());
- c_mesh_obj.positions.push(reader.readFloat());
-
- c_mesh_obj.normals.push(reader.readFloat());
- c_mesh_obj.normals.push(reader.readFloat());
- c_mesh_obj.normals.push(reader.readFloat());
-
- c_mesh_obj.uvCoords.push(reader.readFloat());
- c_mesh_obj.uvCoords.push(reader.readFloat());
- }
-
- for(var c_index = 0; c_index < h_indices_count; c_index++)
- {
- c_mesh_obj.indices.push(reader.readUint32());
- }
-
- this.meshes.push(c_mesh_obj);
- }
-
- reader.pos = modelDictLocation;
- this.cached_models = [];
-
- for(var c_mdl = 0; c_mdl < modelDictCount; c_mdl++)
- {
- //Read the model String
- var mdlStr = reader.readString();
-
- //Load the model data
- var mdlData = load_binary_resource("ar_baggage.resources/" + mdlStr.replace(".mdl", ".tmdl"));
- var model = new tbsp_model(mdlData);
-
- this.cached_models.push(model);
- }
-
- reader.pos = modelLocation;
- this.models = [];
-
- for(var c_model = 0; c_model < modelCount; c_model++)
- {
- var model = new info_model();
-
- //Read model positions
- var m_v1 = reader.readFloat();
- var m_v2 = reader.readFloat();
- var m_v3 = reader.readFloat();
-
- model.position[0] = m_v1;
- model.position[1] = m_v2;
- model.position[2] = m_v3;
-
- var r_v1 = reader.readFloat();
- var r_v2 = reader.readFloat();
- var r_v3 = reader.readFloat();
-
- model.rotation[0] = r_v1;
- model.rotation[1] = r_v2;
- model.rotation[2] = r_v3;
-
- model.modelID = reader.readUint32();
-
- this.models.push(model);
- }
-}
+++ /dev/null
-<head>
- <script type="text/javascript" src="gl-matrix.js"></script>
- <script type="text/javascript" src="webgl-utils.js"></script>
-
- <script id="shader-fs" type="x-shader/x-fragment">
- precision mediump float;
- varying vec2 vTextureCoord;
- varying vec3 vLightWeighting;
- uniform sampler2D uSampler;
- void main(void) {
- vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
-
- float z = (gl_FragCoord.z / gl_FragCoord.w) * 0.003;
- //gl_FragColor = vec4(z, z, z, 255);
- gl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a) + z;
- }
- </script>
-
- <script id="shader-vs" type="x-shader/x-vertex">
- attribute vec3 aVertexPosition;
- attribute vec3 aVertexNormal;
- attribute vec2 aTextureCoord;
- uniform mat4 uMVMatrix;
- uniform mat4 uPMatrix;
- uniform mat4 viewMatrix;
- uniform mat3 uNMatrix;
- uniform vec3 uAmbientColor;
- uniform vec3 uLightingDirection;
- uniform vec3 uDirectionalColor;
- varying vec2 vTextureCoord;
- varying vec3 vLightWeighting;
- void main(void) {
- gl_Position = uPMatrix * viewMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
- vTextureCoord = aTextureCoord;
-
- vec3 transformedNormal = uNMatrix * aVertexNormal;
- float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);
- vLightWeighting = uAmbientColor + uDirectionalColor * directionalLightWeighting;
- }
- </script>
-
- <script src="tbsp.js"></script>
- <script src="level-viewer.js"></script>
-
-</head>
-
-<body onload="webGLStart();">
-
- <canvas id="glCanvas" width="640" height="480"></canvas>
-
- <p style="position:fixed;top:0px;right:60px;color:#FFF;">Click and drag to move around<br>WASD to move<br><br>:))</p>
-
- <p id="fps">0fps</p>
-</body>
+++ /dev/null
-<head>
- <script type="text/javascript" src="gl-matrix.js"></script>
- <script type="text/javascript" src="webgl-utils.js"></script>
-
- <script id="shader-fs" type="x-shader/x-fragment">
- precision mediump float;
- varying vec2 vTextureCoord;
- varying vec3 vLightWeighting;
- uniform sampler2D uSampler;
- void main(void) {
- vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
-
- float z = (gl_FragCoord.z / gl_FragCoord.w) * 0.003;
- //gl_FragColor = vec4(z, z, z, 255);
- gl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a) + z;
- }
- </script>
-
- <script id="shader-vs" type="x-shader/x-vertex">
- attribute vec3 aVertexPosition;
- attribute vec3 aVertexNormal;
- attribute vec2 aTextureCoord;
- uniform mat4 uMVMatrix;
- uniform mat4 uPMatrix;
- uniform mat4 viewMatrix;
- uniform mat3 uNMatrix;
- uniform vec3 uAmbientColor;
- uniform vec3 uLightingDirection;
- uniform vec3 uDirectionalColor;
- varying vec2 vTextureCoord;
- varying vec3 vLightWeighting;
- void main(void) {
- gl_Position = uPMatrix * viewMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
- vTextureCoord = aTextureCoord;
-
- vec3 transformedNormal = uNMatrix * aVertexNormal;
- float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);
- vLightWeighting = uAmbientColor + uDirectionalColor * directionalLightWeighting;
- }
- </script>
-
- <script src="tbsp.js"></script>
- <script src="level-viewer.js"></script>
-
-</head>
-
-<body onload="webGLStart();">
-
- <canvas id="glCanvas" width="640" height="480"></canvas>
-
- <p style="position:fixed;top:0px;right:60px;color:#FFF;">Click and drag to move around<br>WASD to move<br><br>:))</p>
-
- <p id="fps">0fps</p>
-</body>
+++ /dev/null
-/*
- * Copyright 2010, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * @fileoverview This file contains functions every webgl program will need
- * a version of one way or another.
- *
- * Instead of setting up a context manually it is recommended to
- * use. This will check for success or failure. On failure it
- * will attempt to present an approriate message to the user.
- *
- * gl = WebGLUtils.setupWebGL(canvas);
- *
- * For animated WebGL apps use of setTimeout or setInterval are
- * discouraged. It is recommended you structure your rendering
- * loop like this.
- *
- * function render() {
- * window.requestAnimFrame(render, canvas);
- *
- * // do rendering
- * ...
- * }
- * render();
- *
- * This will call your rendering function up to the refresh rate
- * of your display but will stop rendering if your app is not
- * visible.
- */
-
-WebGLUtils = function() {
-
-/**
- * Creates the HTLM for a failure message
- * @param {string} canvasContainerId id of container of th
- * canvas.
- * @return {string} The html.
- */
-var makeFailHTML = function(msg) {
- return '' +
- '<table style="background-color: #8CE; width: 100%; height: 100%;"><tr>' +
- '<td align="center">' +
- '<div style="display: table-cell; vertical-align: middle;">' +
- '<div style="">' + msg + '</div>' +
- '</div>' +
- '</td></tr></table>';
-};
-
-/**
- * Mesasge for getting a webgl browser
- * @type {string}
- */
-var GET_A_WEBGL_BROWSER = '' +
- 'This page requires a browser that supports WebGL.<br/>' +
- '<a href="http://get.webgl.org">Click here to upgrade your browser.</a>';
-
-/**
- * Mesasge for need better hardware
- * @type {string}
- */
-var OTHER_PROBLEM = '' +
- "It doesn't appear your computer can support WebGL.<br/>" +
- '<a href="http://get.webgl.org/troubleshooting/">Click here for more information.</a>';
-
-/**
- * Creates a webgl context. If creation fails it will
- * change the contents of the container of the <canvas>
- * tag to an error message with the correct links for WebGL.
- * @param {Element} canvas. The canvas element to create a
- * context from.
- * @param {WebGLContextCreationAttirbutes} opt_attribs Any
- * creation attributes you want to pass in.
- * @param {function:(msg)} opt_onError An function to call
- * if there is an error during creation.
- * @return {WebGLRenderingContext} The created context.
- */
-var setupWebGL = function(canvas, opt_attribs, opt_onError) {
- function handleCreationError(msg) {
- var container = canvas.parentNode;
- if (container) {
- var str = window.WebGLRenderingContext ?
- OTHER_PROBLEM :
- GET_A_WEBGL_BROWSER;
- if (msg) {
- str += "<br/><br/>Status: " + msg;
- }
- container.innerHTML = makeFailHTML(str);
- }
- };
-
- opt_onError = opt_onError || handleCreationError;
-
- if (canvas.addEventListener) {
- canvas.addEventListener("webglcontextcreationerror", function(event) {
- opt_onError(event.statusMessage);
- }, false);
- }
- var context = create3DContext(canvas, opt_attribs);
- if (!context) {
- if (!window.WebGLRenderingContext) {
- opt_onError("");
- }
- }
- return context;
-};
-
-/**
- * Creates a webgl context.
- * @param {!Canvas} canvas The canvas tag to get context
- * from. If one is not passed in one will be created.
- * @return {!WebGLContext} The created context.
- */
-var create3DContext = function(canvas, opt_attribs) {
- var names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"];
- var context = null;
- for (var ii = 0; ii < names.length; ++ii) {
- try {
- context = canvas.getContext(names[ii], opt_attribs);
- } catch(e) {}
- if (context) {
- break;
- }
- }
- return context;
-}
-
-return {
- create3DContext: create3DContext,
- setupWebGL: setupWebGL
-};
-}();
-
-/**
- * Provides requestAnimationFrame in a cross browser way.
- */
-window.requestAnimFrame = (function() {
- return window.requestAnimationFrame ||
- window.webkitRequestAnimationFrame ||
- window.mozRequestAnimationFrame ||
- window.oRequestAnimationFrame ||
- window.msRequestAnimationFrame ||
- function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
- window.setTimeout(callback, 1000/60);
- };
-})();