diff options
author | jjesswan <jessica_wan@brown.edu> | 2024-04-22 21:56:26 -0400 |
---|---|---|
committer | jjesswan <jessica_wan@brown.edu> | 2024-04-22 21:56:26 -0400 |
commit | a556b45abf18f1bd509daaf63b66b7d55e9fd291 (patch) | |
tree | bc9b8a2d184c12aee236e7f9f276a34b84ca552d /engine-ocean/Graphics | |
parent | cd7c76017a12bb548036571c1ff13e551369d06d (diff) |
add engine version
Diffstat (limited to 'engine-ocean/Graphics')
29 files changed, 9515 insertions, 0 deletions
diff --git a/engine-ocean/Graphics/GLWrappers/shader.cpp b/engine-ocean/Graphics/GLWrappers/shader.cpp new file mode 100644 index 0000000..4ae1aa2 --- /dev/null +++ b/engine-ocean/Graphics/GLWrappers/shader.cpp @@ -0,0 +1,121 @@ +#include "shader.h" + +Shader::Shader(std::vector<GLenum> shaderTypes, std::vector<const char*> filepaths){ + m_handle = ShaderLoader::createShaderProgram(shaderTypes, filepaths); +} + +Shader::~Shader(){ + glDeleteProgram(m_handle); +} + +void Shader::bind(){ + glUseProgram(m_handle); +} + +void Shader::unbind(){ + glUseProgram(0); +} + +GLuint Shader::getHandle(){ + return m_handle; +} + +void Shader::setMaterial(std::shared_ptr<Material> material){ + ColorSource color_source = material->getColorSource(); + switch(color_source){ + case ColorSource::SOLID_COLOR: + glUniform1i(glGetUniformLocation(m_handle, "colorSource"), 0); + glUniform3f(glGetUniformLocation(m_handle, "objColor"), material->getColor().r, material->getColor().g, material->getColor().b); + break; + case ColorSource::TEXTURE_COLOR: + glUniform1i(glGetUniformLocation(m_handle, "colorSource"), 1); + material->getTexture()->bind(); + glUniform1i(glGetUniformLocation(m_handle, "objTexture"), material->getTexture()->getTexUnitUint()); + break; + case ColorSource::PER_VERTEX_COLOR: + glUniform1i(glGetUniformLocation(m_handle, "colorSource"), 2); + break; + } + float shininess = material->getShininess(); + glUniform1f(glGetUniformLocation(m_handle, "shininess"), shininess); +} + +void Shader::setCamera(std::shared_ptr<Camera> camera){ + glUniformMatrix4fv(glGetUniformLocation(m_handle, "view"), 1, GL_FALSE, glm::value_ptr(camera->getView()[0])); + glUniformMatrix4fv(glGetUniformLocation(m_handle, "projection"), 1, GL_FALSE, glm::value_ptr(camera->getProjection()[0])); + glUniform3f(glGetUniformLocation(m_handle, "worldSpace_camPos"), camera->getPos().x, camera->getPos().y, camera->getPos().z); + glUniform3f(glGetUniformLocation(m_handle, "skyColor"), 1.f, 1.f, 1.f); + +} + +void Shader::setModelTransform(std::shared_ptr<ModelTransform> modelTransform){ + glUniformMatrix4fv(glGetUniformLocation(m_handle, "model"), 1, GL_FALSE, glm::value_ptr(modelTransform->getModelMatrix()[0])); +} + +void Shader::setModelTransform(glm::mat4 modelMatrix){ + glUniformMatrix4fv(glGetUniformLocation(m_handle, "model"), 1, GL_FALSE, glm::value_ptr(modelMatrix)); +} + +void Shader::setGlobalCoeffs(glm::vec3 coeffs){ + glUniform3f(glGetUniformLocation(m_handle, "coeffs"), coeffs.x, coeffs.y, coeffs.z); +} + +void Shader::setLights(std::vector<std::shared_ptr<Light>> lights){ + int numLights = std::min(int(lights.size()), 16); + std::vector<int> lightType; + std::vector<float> lightColor; + std::vector<float> lightFunction; + std::vector<float> worldSpace_lightPos; + std::vector<float> worldSpace_lightDir; + lightType.resize(numLights); + lightColor.resize(numLights*3); + lightFunction.resize(numLights*3); + worldSpace_lightPos.resize(numLights*3); + worldSpace_lightDir.resize(numLights*3); + for(int i = 0; i<numLights; i++){ + lightColor[i*3] = lights[i]->getColor().r; + lightColor[i*3+1] = lights[i]->getColor().g; + lightColor[i*3+2] = lights[i]->getColor().b; + glm::vec3 camLightData; + switch(lights[i]->getType()){ + case LightType::POINT: + lightType[i] = 0; + lightFunction[i*3] = lights[i]->getAttenuation().x; + lightFunction[i*3+1] = lights[i]->getAttenuation().y; + lightFunction[i*3+2] = lights[i]->getAttenuation().z; + worldSpace_lightPos[i*3] = lights[i]->getPos().x; + worldSpace_lightPos[i*3+1] = lights[i]->getPos().y; + worldSpace_lightPos[i*3+2] = lights[i]->getPos().z; + break; + case LightType::DIRECTIONAL: + lightType[i] = 1; + worldSpace_lightDir[i*3] = lights[i]->getDir().x; + worldSpace_lightDir[i*3+1] = lights[i]->getDir().y; + worldSpace_lightDir[i*3+2] = lights[i]->getDir().z; + break; + } + } + glUniform1i(glGetUniformLocation(m_handle, "numLights"), numLights); + Debug::checkGLError(); + glUniform1iv(glGetUniformLocation(m_handle, "lightType"), numLights, lightType.data()); + Debug::checkGLError(); + glUniform3fv(glGetUniformLocation(m_handle, "lightColor"), numLights, lightColor.data()); + Debug::checkGLError(); + glUniform3fv(glGetUniformLocation(m_handle, "lightFunction"), numLights, lightFunction.data()); + Debug::checkGLError(); + glUniform3fv(glGetUniformLocation(m_handle, "worldSpace_lightPos"), numLights, worldSpace_lightPos.data()); + Debug::checkGLError(); + std::cout<<worldSpace_lightDir[0]<<std::endl; + glUniform3fv(glGetUniformLocation(m_handle, "worldSpace_lightDir"), numLights, worldSpace_lightDir.data()); + Debug::checkGLError(); +} + +void Shader::clearLights(){ + glUniform1i(glGetUniformLocation(m_handle, "numLights"), 0); +} + +void Shader::setTextUniforms(float screenWidth, float screenHeight, glm::vec3 color){ + glm::mat4 projection = glm::ortho(0.0f, screenWidth, 0.0f, screenHeight); + glUniformMatrix4fv(glGetUniformLocation(m_handle, "projection"), 1, GL_FALSE, glm::value_ptr(projection)); + glUniform3f(glGetUniformLocation(m_handle, "textColor"), color.r, color.g, color.b); +} diff --git a/engine-ocean/Graphics/GLWrappers/shader.h b/engine-ocean/Graphics/GLWrappers/shader.h new file mode 100644 index 0000000..da0ae5d --- /dev/null +++ b/engine-ocean/Graphics/GLWrappers/shader.h @@ -0,0 +1,28 @@ +#pragma once + +#include "../shaderloader.h" +#include "../camera.h" +#include "../material.h" +#include "../modeltransform.h" +#include "../light.h" + +class Shader{ +public: + Shader(std::vector<GLenum> shaderTypes, std::vector<const char*> filepaths); + ~Shader(); + + void bind(); + void unbind(); + GLuint getHandle(); + void setMaterial(std::shared_ptr<Material> material); + void setCamera(std::shared_ptr<Camera> camera); + void setModelTransform(std::shared_ptr<ModelTransform> modelTransform); + void setModelTransform(glm::mat4 modelMatrix); + void setGlobalCoeffs(glm::vec3 coeffs); + void setLights(std::vector<std::shared_ptr<Light>> lights); + void clearLights(); + void setTextUniforms(float screenWidth, float screenHeight, glm::vec3 color); + +private: + GLuint m_handle; +}; diff --git a/engine-ocean/Graphics/GLWrappers/texture.cpp b/engine-ocean/Graphics/GLWrappers/texture.cpp new file mode 100644 index 0000000..1c76165 --- /dev/null +++ b/engine-ocean/Graphics/GLWrappers/texture.cpp @@ -0,0 +1,91 @@ +#include "texture.h" + +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" + +#include <iostream> + +#include "../debug.h" + +Texture::Texture(int width, int height, GLenum texUnit, GLint internalFormat, GLenum texTarget): + m_texTarget(texTarget), + m_texUnit(texUnit) +{ + glGenTextures(1, &m_handle); + bind(); + glTexParameteri(m_texTarget, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(m_texTarget, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(m_texTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(m_texTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexImage2D(m_texTarget, 0, internalFormat, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + m_height = height; + m_width = width; + unbind(); +} + +Texture::Texture(std::string filepath, GLenum texUnit, GLint internalFormat, GLenum texTarget): + m_texTarget(texTarget), + m_texUnit(texUnit) +{ + glGenTextures(1, &m_handle); + bind(); + glTexParameteri(m_texTarget, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(m_texTarget, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(m_texTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(m_texTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + stbi_set_flip_vertically_on_load(1); + int width, height, numChannels; + unsigned char* data = stbi_load(filepath.c_str(), &width, &height, &numChannels, 4); + if (stbi_failure_reason()){ + std::cout << stbi_failure_reason() << std::endl; + } + glTexImage2D(m_texTarget, 0, internalFormat, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + m_height = height; + m_width = width; + stbi_image_free(data); + unbind(); +} + +Texture::~Texture(){ + glDeleteTextures(1, &m_handle); +} + +void Texture::bind(){ + glActiveTexture(m_texUnit); + glBindTexture(m_texTarget, m_handle); +} + +void Texture::bind(GLenum texUnit){ + glActiveTexture(texUnit); + glBindTexture(m_texTarget, m_handle); +} + +void Texture::unbind(){ + glActiveTexture(m_texUnit); + glBindTexture(m_texTarget, 0); +} + +void Texture::unbind(GLenum texUnit){ + glActiveTexture(texUnit); + glBindTexture(m_texTarget, 0); +} + +GLuint Texture::getHandle(){ + return m_handle; +} + +GLuint Texture::getTexUnitUint(){ + return GLuint(m_texUnit) - GLuint(GL_TEXTURE0); +} + +GLenum Texture::getTexUnitEnum(){ + return m_texUnit; +} + +int Texture::getWidth(){ + return m_width; +} + +int Texture::getHeight(){ + return m_width; +} diff --git a/engine-ocean/Graphics/GLWrappers/texture.h b/engine-ocean/Graphics/GLWrappers/texture.h new file mode 100644 index 0000000..3ad2f13 --- /dev/null +++ b/engine-ocean/Graphics/GLWrappers/texture.h @@ -0,0 +1,31 @@ +#pragma once + +#include "GL/glew.h" +#include <string> + +#include "glm/glm.hpp" + +class Texture +{ +public: + Texture(int width, int height, GLenum texUnit = GL_TEXTURE0, GLint internalFormat = GL_RGBA, GLenum texTarget = GL_TEXTURE_2D); + Texture(std::string filePath, GLenum texUnit = GL_TEXTURE0, GLint internalFormat = GL_RGBA, GLenum texTarget = GL_TEXTURE_2D); + ~Texture(); + + void bind(); + void bind(GLenum texUnit); + void unbind(); + void unbind(GLenum texUnit); + GLuint getHandle(); + GLuint getTexUnitUint(); + GLenum getTexUnitEnum(); + int getWidth(); + int getHeight(); + +private: + GLuint m_handle; + GLenum m_texUnit; + GLenum m_texTarget; + int m_width; + int m_height; +}; diff --git a/engine-ocean/Graphics/GLWrappers/vao.cpp b/engine-ocean/Graphics/GLWrappers/vao.cpp new file mode 100644 index 0000000..43a1062 --- /dev/null +++ b/engine-ocean/Graphics/GLWrappers/vao.cpp @@ -0,0 +1,68 @@ +#include "vao.h" +#include <iostream> + +VAO::VAO(std::shared_ptr<VBO> vbo, VAOAttrib attribs): + m_vbo(vbo), + m_curr_offset(0), + m_vert_size(0) +{ + glGenVertexArrays(1, &m_handle); + bind(); + + if(attribs & VAOAttrib::POS){ + m_vert_size += 3; + } + if(attribs & VAOAttrib::NORM){ + m_vert_size += 3; + } + if(attribs & VAOAttrib::UV){ + m_vert_size += 2; + } + if(attribs & VAOAttrib::COLOR){ + m_vert_size += 3; + } + + + //Attach layout to vbo depending on which of the above attributes it has + m_vbo->bind(); + + if(attribs & VAOAttrib::POS){ + addAttribute(0, 3); + } + if(attribs & VAOAttrib::NORM){ + addAttribute(1, 3); + } + if(attribs & VAOAttrib::UV){ + addAttribute(2, 2); + } + if(attribs & VAOAttrib::COLOR){ + addAttribute(3, 3); + } + + m_vbo->unbind(); + unbind(); +} + +VAO::~VAO(){ + glDeleteVertexArrays(1, &m_handle); +} + +void VAO::bind(){ + glBindVertexArray(m_handle); +} + +void VAO::unbind(){ + glBindVertexArray(0); +} + +void VAO::draw(){ + bind(); + glDrawArrays(GL_TRIANGLES, 0, m_vbo->getLength()/m_vert_size); + unbind(); +} + +void VAO::addAttribute(GLuint attrib_index, GLint attrib_size){ + glEnableVertexAttribArray(attrib_index); + glVertexAttribPointer(attrib_index, attrib_size, GL_FLOAT, GL_FALSE, m_vert_size*sizeof(GLfloat), reinterpret_cast<void*>(m_curr_offset*sizeof(GLfloat))); + m_curr_offset += attrib_size; +}
\ No newline at end of file diff --git a/engine-ocean/Graphics/GLWrappers/vao.h b/engine-ocean/Graphics/GLWrappers/vao.h new file mode 100644 index 0000000..8f9bc6a --- /dev/null +++ b/engine-ocean/Graphics/GLWrappers/vao.h @@ -0,0 +1,42 @@ +#pragma once + +#include "vbo.h" +#include <memory> + +enum class VAOAttrib{ + POS = 1, + NORM = 2, + UV = 4, + COLOR = 8 +}; + +inline VAOAttrib operator|(VAOAttrib lhs, VAOAttrib rhs){ + using VAOAttribType = std::underlying_type<VAOAttrib>::type; + return VAOAttrib(static_cast<VAOAttribType>(lhs) | static_cast<VAOAttribType>(rhs)); +} + +inline bool operator&(VAOAttrib lhs, VAOAttrib rhs){ + using VAOAttribType = std::underlying_type<VAOAttrib>::type; + return static_cast<bool>(VAOAttrib(static_cast<VAOAttribType>(lhs) & static_cast<VAOAttribType>(rhs))); +} + +class VAO +{ +public: + VAO(std::shared_ptr<VBO> vbo, VAOAttrib attribs); + ~VAO(); + + void bind(); + void unbind(); + + void draw(); + +private: + void addAttribute(GLuint attrib_index, GLint attrib_size); + + std::shared_ptr<VBO> m_vbo; + GLuint m_handle; + GLint m_curr_offset; + GLuint m_vert_size; + +};
\ No newline at end of file diff --git a/engine-ocean/Graphics/GLWrappers/vbo.cpp b/engine-ocean/Graphics/GLWrappers/vbo.cpp new file mode 100644 index 0000000..a8d08fb --- /dev/null +++ b/engine-ocean/Graphics/GLWrappers/vbo.cpp @@ -0,0 +1,27 @@ +#include "vbo.h" +#include <iostream> + +VBO::VBO(std::vector<float> data): + m_length(data.size()) +{ + glGenBuffers(1, &m_handle); + bind(); + glBufferData(GL_ARRAY_BUFFER, m_length*sizeof(float), data.data(), GL_STATIC_DRAW); + unbind(); +} + +VBO::~VBO(){ + glDeleteBuffers(1, &m_handle); +} + +void VBO::bind(){ + glBindBuffer(GL_ARRAY_BUFFER, m_handle); +} + +void VBO::unbind(){ + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +GLsizei VBO::getLength(){ + return m_length; +}
\ No newline at end of file diff --git a/engine-ocean/Graphics/GLWrappers/vbo.h b/engine-ocean/Graphics/GLWrappers/vbo.h new file mode 100644 index 0000000..bd63877 --- /dev/null +++ b/engine-ocean/Graphics/GLWrappers/vbo.h @@ -0,0 +1,19 @@ +#pragma once + +#include <GL/glew.h> +#include <vector> + +class VBO +{ +public: + VBO(std::vector<float> data); + ~VBO(); + + void bind(); + void unbind(); + GLsizei getLength(); + +private: + GLuint m_handle; + GLsizei m_length; +};
\ No newline at end of file diff --git a/engine-ocean/Graphics/camera.cpp b/engine-ocean/Graphics/camera.cpp new file mode 100644 index 0000000..0a5fd9d --- /dev/null +++ b/engine-ocean/Graphics/camera.cpp @@ -0,0 +1,124 @@ +#include "camera.h" +#include <iostream> + +Camera::Camera(int width, int height, glm::vec3 pos, glm::vec3 look, + glm::vec3 up, float fov, float nearPlane, float farPlane): + m_width(width), + m_height(height), + m_pos(pos), + m_look(look), + m_up(up), + m_fov(fov), + m_aspect(width/float(height)), + m_near(nearPlane), + m_far(farPlane) +{ + calculateProjection(); + calculateView(); +} + +Camera::~Camera(){ + +} + +glm::mat4 Camera::getProjection(){ + return m_proj; +} + +glm::mat4 Camera::getView(){ + return m_view; +} + +void Camera::resize(int width, int height){ + m_width = width; + m_height = height; + m_aspect = float(width)/float(height); + + calculateProjection(); +} + +void Camera::translate(glm::vec3 move){ + m_pos += move; + + calculateView(); +} + +void Camera::setPos(glm::vec3 newPos){ + m_pos = newPos; + + calculateView(); +} + +glm::vec3 Camera::getPos(){ + return m_pos; +} + +void Camera::rotate(float angle, glm::vec3 axis){ + glm::mat4 lookRotation = glm::rotate(glm::mat4(1), angle, axis); + glm::vec3 tempLook = glm::vec3(lookRotation * glm::vec4(m_look, 0)); + if(glm::cross(tempLook, m_up) != glm::vec3(0)){ + m_look = tempLook; + calculateView(); + } +} + +void Camera::setLook(glm::vec3 newLook){ +// std::cout << "up: " << m_up.x << "," << m_up.y << "," << m_up.z << std::endl; +// std::cout << "look: " << newLook.x << "," << newLook.y << "," << newLook.z << std::endl; + if(glm::cross(newLook, m_up) == glm::vec3(0)){ + std::cout<<"Error: Look vector cannot be parallel to up vector!"<<std::endl; + return; + } + m_look = newLook; + + calculateView(); +} + +glm::vec3 Camera::getLook(){ + return m_look; +} + +void Camera::setUp(glm::vec3 newUp){ + if(glm::cross(newUp, m_look) == glm::vec3(0)){ + std::cout<<"Error: Up vector cannot be parallel to look vector!"<<std::endl; + return; + } + m_up = newUp; + + calculateView(); +} + +glm::vec3 Camera::getUp(){ + return m_up; +} + +void Camera::calculateProjection(){ + m_proj = glm::perspective(m_fov, m_aspect, m_near, m_far); +} + +void Camera::calculateView(){ + // eye, lookat, up + m_view = glm::lookAt(m_pos, m_look, m_up); +} + +// + +glm::vec3 Camera::getViewDirection(){ + return -glm::transpose(m_view)[2]; +} + +glm::vec3 Camera::getRight(){ + return glm::transpose(m_view)[0]; +} + +glm::vec3 Camera::getLookAt(){ + return m_look; +} + +int Camera::getWidth(){ + return m_width; +} + +int Camera::getHeight(){ + return m_height; +} diff --git a/engine-ocean/Graphics/camera.h b/engine-ocean/Graphics/camera.h new file mode 100644 index 0000000..e23b0b1 --- /dev/null +++ b/engine-ocean/Graphics/camera.h @@ -0,0 +1,57 @@ +#pragma once + +#include "glm/glm.hpp" +#include "glm/ext.hpp" + +class Camera +{ +public: + Camera(int width = 640, int height = 480, + glm::vec3 pos = glm::vec3(0, 0, 0), glm::vec3 look = glm::vec3(0, 0, 1), + glm::vec3 up = glm::vec3(0, 1, 0), float fov = 1.f, + float nearPlane = 0.1f, float farPlane = 100.f); + ~Camera(); + + // Functions to get camera data for drawing + glm::mat4 getProjection(); + glm::mat4 getView(); + + // Functions to edit camera + void resize(int width, int height); + void translate(glm::vec3 move); + void setPos(glm::vec3 newPos); + glm::vec3 getPos(); + void rotate(float angle, glm::vec3 axis); + void setLook(glm::vec3 newLook); + glm::vec3 getLook(); + void setUp(glm::vec3 newUp); + glm::vec3 getUp(); + + glm::vec3 getLookAt(); + glm::vec3 getViewDirection(); + glm::vec3 getRight(); + + + int getHeight(); + int getWidth(); + + + +private: + // Internal functions to update projection and view matrices + void calculateProjection(); + void calculateView(); + + int m_width; + int m_height; + glm::vec3 m_pos; + glm::vec3 m_look; + glm::vec3 m_up; + float m_fov; + float m_aspect; + float m_near; + float m_far; + + glm::mat4 m_proj = glm::mat4(1); + glm::mat4 m_view = glm::mat4(1); +}; diff --git a/engine-ocean/Graphics/debug.h b/engine-ocean/Graphics/debug.h new file mode 100644 index 0000000..6d2be6c --- /dev/null +++ b/engine-ocean/Graphics/debug.h @@ -0,0 +1,30 @@ +#pragma once + +#include <GL/glew.h> + +#include <iostream> + +namespace Debug{ + inline GLenum checkGLError(const char *file, int line) + { + GLenum errorCode; + while ((errorCode = glGetError()) != GL_NO_ERROR) + { + std::string error; + switch (errorCode) + { + case GL_INVALID_ENUM: error = "INVALID_ENUM"; break; + case GL_INVALID_VALUE: error = "INVALID_VALUE"; break; + case GL_INVALID_OPERATION: error = "INVALID_OPERATION"; break; + case GL_STACK_OVERFLOW: error = "STACK_OVERFLOW"; break; + case GL_STACK_UNDERFLOW: error = "STACK_UNDERFLOW"; break; + case GL_OUT_OF_MEMORY: error = "OUT_OF_MEMORY"; break; + case GL_INVALID_FRAMEBUFFER_OPERATION: error = "INVALID_FRAMEBUFFER_OPERATION"; break; + } + std::cout << error << " | " << file << " (" << line << ")" << std::endl; + } + return errorCode; + } + + #define checkGLError() checkGLError(__FILE__, __LINE__) +}
\ No newline at end of file diff --git a/engine-ocean/Graphics/font.cpp b/engine-ocean/Graphics/font.cpp new file mode 100644 index 0000000..b5bc7a1 --- /dev/null +++ b/engine-ocean/Graphics/font.cpp @@ -0,0 +1,74 @@ +#include "font.h" +#include <iostream> + +Font::Font(const std::string filepath){ + FT_Library ft; + if (FT_Init_FreeType(&ft)) + { + std::cout << "ERROR::FREETYPE: Could not init FreeType Library" << std::endl; + } + + FT_Face face; + if (FT_New_Face(ft, filepath.data(), 0, &face)) + { + std::cout << "ERROR::FREETYPE: Failed to load font" << std::endl; + } + + FT_Set_Pixel_Sizes(face, 0, 48); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // disable byte-alignment restriction + + for (unsigned char c = 0; c < 128; c++) + { + createGlyphTexture(c, face); + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // Back to default value + FT_Done_Face(face); + FT_Done_FreeType(ft); +} + +Font::~Font(){ + +} + +void Font::createGlyphTexture(unsigned char c, FT_Face &face){ + if (FT_Load_Char(face, c, FT_LOAD_RENDER)) + { + std::cout << "ERROR::FREETYTPE: Failed to load Glyph" << std::endl; + return; + } + // generate texture + unsigned int texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_RED, + face->glyph->bitmap.width, + face->glyph->bitmap.rows, + 0, + GL_RED, + GL_UNSIGNED_BYTE, + face->glyph->bitmap.buffer + ); + // set texture options + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + // now store character for later use + unsigned int advance = static_cast<unsigned int>(face->glyph->advance.x); + Character character = { + texture, + glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows), + glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top), + advance + }; + m_characters.insert(std::pair<char, Character>(c, character)); +} + +Character& Font::getCharacter(char c){ + return m_characters[c]; +} diff --git a/engine-ocean/Graphics/font.h b/engine-ocean/Graphics/font.h new file mode 100644 index 0000000..ea42a29 --- /dev/null +++ b/engine-ocean/Graphics/font.h @@ -0,0 +1,29 @@ +#pragma once + +// Credit to https://learnopengl.com/In-Practice/Text-Rendering + +#include "ft2build.h" +#include "freetype/freetype.h" +#include <GL/glew.h> +#include "glm/glm.hpp" +#include <map> +#include <string> + +struct Character { + GLuint textureID; + glm::ivec2 size; + glm::ivec2 bearing; + unsigned int advance; +}; + +class Font { +public: + Font(const std::string filepath); + ~Font(); + + Character& getCharacter(char c); + +private: + void createGlyphTexture(unsigned char c, FT_Face &face); + std::map<char, Character> m_characters; +};
\ No newline at end of file diff --git a/engine-ocean/Graphics/global.h b/engine-ocean/Graphics/global.h new file mode 100644 index 0000000..eb3e503 --- /dev/null +++ b/engine-ocean/Graphics/global.h @@ -0,0 +1,7 @@ +#pragma once + +#include "graphics.h" + +namespace Global{ + inline Graphics graphics; +}
\ No newline at end of file diff --git a/engine-ocean/Graphics/graphics.cpp b/engine-ocean/Graphics/graphics.cpp new file mode 100644 index 0000000..2b283a2 --- /dev/null +++ b/engine-ocean/Graphics/graphics.cpp @@ -0,0 +1,963 @@ +#include "graphics.h" +#include "shapedata.h" +#include <Eigen/Dense> + + +#define TINYOBJLOADER_IMPLEMENTATION +#include "tiny_obj_loader.h" + + +#include "stb_image.h" + +Graphics::Graphics(): + m_textRenderer(std::make_shared<TextRenderer>()) +{ + + +} + +Graphics::~Graphics(){ + deleteFBOS(); + +} + +void Graphics::initializeGLEW(){ + glewExperimental = GL_TRUE; + std::cout<<"GLEWInit status: "<<glewInit()<<std::endl; +} + +void Graphics::initialize(){ + glEnable(GL_DEPTH_TEST); + //glDisable(GL_CULL_FACE); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + std::cout<<"initialize text renderer"<<std::endl; + m_textRenderer->initialize(); + + std::cout<<"add shapes"<<std::endl; + addShape("quad", quadVertexBufferData, VAOAttrib::POS | VAOAttrib::NORM | VAOAttrib::UV); + addShape("cube", cubeVertexBufferData, VAOAttrib::POS | VAOAttrib::NORM | VAOAttrib::UV); + addShape("sphere", sphereVertexBufferData, VAOAttrib::POS | VAOAttrib::NORM | VAOAttrib::UV); + addShape("cylinder", cylinderVertexBufferData, VAOAttrib::POS | VAOAttrib::NORM | VAOAttrib::UV); + addShape("cone", coneVertexBufferData, VAOAttrib::POS | VAOAttrib::NORM | VAOAttrib::UV); + + addShader("phong", {GL_VERTEX_SHADER, GL_FRAGMENT_SHADER}, {"Resources/Shaders/phong.vert", "Resources/Shaders/phong.frag"}); + addShader("text", {GL_VERTEX_SHADER, GL_FRAGMENT_SHADER}, {"Resources/Shaders/text.vert", "Resources/Shaders/text.frag"}); + addShader("grass", {GL_VERTEX_SHADER, GL_GEOMETRY_SHADER, GL_FRAGMENT_SHADER}, {"Resources/Shaders/grass.vert", "Resources/Shaders/grassgeom.geom", "Resources/Shaders/grass.frag"}); + addShader("skybox", {GL_VERTEX_SHADER, GL_FRAGMENT_SHADER}, {"Resources/Shaders/skybox.vert", "Resources/Shaders/skybox.frag"}); + addShader("ui", {GL_VERTEX_SHADER, GL_FRAGMENT_SHADER}, {"Resources/Shaders/UIShader.vert", "Resources/Shaders/UIShader.frag"}); + addShader("inventory", {GL_VERTEX_SHADER, GL_FRAGMENT_SHADER}, {"Resources/Shaders/UIShader.vert", "Resources/Shaders/InventoryShader.frag"}); + addShader("water", {GL_VERTEX_SHADER, GL_FRAGMENT_SHADER}, {"Resources/Shaders/water.vert", "Resources/Shaders/water.frag"}); + + + + + + bindShader("phong"); + + addMaterial("default", glm::vec3(1)); + + std::cout<<"add font"<<std::endl; + addFont("opensans", "Resources/Fonts/OpenSans.ttf"); + getFont("opensans"); + + // specify texture for grass shader + bindShader("grass"); + glUniform1i(glGetUniformLocation(getShaderID("grass"), "grass_texture"),0); + glUniform1i(glGetUniformLocation(getShaderID("grass"), "wind_texture"),1); + glUniform1i(glGetUniformLocation(getShaderID("grass"), "meadow_texture"),7); + + //glUniform1f(glGetUniformLocation(getShaderID("grass"), "numRows"), 2); + + + // specify texture for skybox + bindShader("skybox"); + glUniform1i(glGetUniformLocation(getShaderID("skybox"), "cubeMap"), 3); + + bindShader("ui"); + glUniform1i(glGetUniformLocation(getShaderID("ui"), "guiTexture0"), 5); + + + bindShader("inventory"); + glUniform1i(glGetUniformLocation(getShaderID("inventory"), "inventoryTexture0"), 6); + + initializeReflectionFBO(); + initializeRefractionFBO(); + + bindShader("water"); + glUniform1i(glGetUniformLocation(getShaderID("water"), "reflect_texture"), 8); + glUniform1i(glGetUniformLocation(getShaderID("water"), "refract_texture"), 9); + glUniform1i(glGetUniformLocation(getShaderID("water"), "du_dv_map"), 10); + + + glm::vec3 sc = glm::vec3(.77f, .85f, .99f); + bindShader("skybox"); + glUniform3f(glGetUniformLocation(getShaderID("skybox"), "skyColor"), sc.x, sc.y, sc.z); + bindShader("water"); + glUniform3f(glGetUniformLocation(getShaderID("water"), "skyColor"), sc.x, sc.y, sc.z); + bindShader("grass"); + glUniform3f(glGetUniformLocation(getShaderID("grass"), "skyColor"), sc.x, sc.y, sc.z); + bindShader("phong"); + glUniform3f(glGetUniformLocation(getShaderID("phong"), "skyColor"), sc.x, sc.y, sc.z); + + + + + +} + +void Graphics::setClipPlane(glm::vec4 plane){ + bindShader("phong"); + glUniform4f(glGetUniformLocation(getShaderID("phong"), "plane"), plane.x, plane.y, plane.z, plane.w); + bindShader("grass"); + glUniform4f(glGetUniformLocation(getShaderID("grass"), "plane"), plane.x, plane.y, plane.z, plane.w); + bindShader("water"); + glUniform4f(glGetUniformLocation(getShaderID("water"), "plane"), plane.x, plane.y, plane.z, plane.w); +} + +float Graphics::generateRandomNumbers(float lb, float ub){ + float random = lb + static_cast <float>(rand()) / (static_cast <float>(RAND_MAX/(ub-lb))); + + return random; +} + + +GLuint Graphics::loadCubeMap(std::vector<const char*> textureFiles){ + // create empty texture + GLuint textureID; + glGenTextures(1, &textureID); + + //glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_CUBE_MAP, textureID); + + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + + GLuint target = GL_TEXTURE_CUBE_MAP_POSITIVE_X; + for (int i=0; i<6; i++){ + std::string filename = std::string(textureFiles[i]);//directory + '/' + filename; + int width, height, nrChannels; + unsigned char* data = stbi_load(filename.c_str(), &width, &height, &nrChannels, 0); + + if (data){ + stbi_set_flip_vertically_on_load(false); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); + stbi_image_free(data); + + } else { + std::cout << "Texture failed to load at path: " << textureFiles[i] << std::endl; + stbi_image_free(data); + } + } + + return textureID; +} + + +TextureData Graphics::loadTextureFromFile(const char *path) +{ + std::string filename = std::string(path); + + GLuint textureID; + glGenTextures(1, &textureID); + + int width, height, nrComponents; + stbi_set_flip_vertically_on_load(true); + unsigned char *data = stbi_load(filename.c_str(), &width, &height, &nrComponents, 0); + stbi_set_flip_vertically_on_load(false); + if (data) + { + GLenum format; + if (nrComponents == 1) + format = GL_RED; + else if (nrComponents == 3) + format = GL_RGB; + else if (nrComponents == 4) + format = GL_RGBA; + + glBindTexture(GL_TEXTURE_2D, textureID); + glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); + glGenerateMipmap(GL_TEXTURE_2D); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + stbi_image_free(data); + } + else + { + std::cout << "Texture failed to load at path: " << path << std::endl; + stbi_image_free(data); + } + + TextureData newtex; + newtex.textureID = textureID; + newtex.height = height; + newtex.width = width; + return newtex; +} + +TextureData Graphics::loadTextureFromFile_Repeat(const char *path) +{ + std::string filename = std::string(path); + + GLuint textureID; + glGenTextures(1, &textureID); + + int width, height, nrComponents; + stbi_set_flip_vertically_on_load(true); + unsigned char *data = stbi_load(filename.c_str(), &width, &height, &nrComponents, 0); + stbi_set_flip_vertically_on_load(false); + if (data) + { + GLenum format; + if (nrComponents == 1) + format = GL_RED; + else if (nrComponents == 3) + format = GL_RGB; + else if (nrComponents == 4) + format = GL_RGBA; + + glBindTexture(GL_TEXTURE_2D, textureID); + glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); + glGenerateMipmap(GL_TEXTURE_2D); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + stbi_image_free(data); + } + else + { + std::cout << "Texture failed to load at path: " << path << std::endl; + stbi_image_free(data); + } + + TextureData newtex; + newtex.textureID = textureID; + newtex.height = height; + newtex.width = width; + return newtex; +} + + + +GLuint Graphics::makeVAO(std::vector<float> positions){ + int numVertices = positions.size()/2; + GLuint vao, vbo; + + glGenVertexArrays(1, &vao); + glGenBuffers(1, &vbo); + glBindVertexArray(vao); + + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, positions.size()*sizeof(float), positions.data(), GL_STATIC_DRAW); + + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), (void*)0); + + // unbind + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + return vao; +} + +void Graphics::clearScreen(GLbitfield mask){ + glClear(mask); +} + +void Graphics::setClearColor(glm::vec3 clearColor){ + glClearColor(clearColor.r, clearColor.g, clearColor.b, 1); +} + +void Graphics::setCameraData(std::shared_ptr<Camera> camera){ + m_active_shader->setCamera(camera); +} + +void Graphics::addShader(std::string shaderName, std::vector<GLenum> shaderTypes, std::vector<const char*> filepaths){ + m_shaders.insert({shaderName, std::make_shared<Shader>(shaderTypes, filepaths)}); +} + +void Graphics::removeShader(std::string shaderName){ + if(shaderName != "phong" && shaderName != "text"){ + m_shaders.erase(shaderName); + } +} + +void Graphics::bindShader(std::string shaderName){ + m_shaders.at(shaderName)->bind(); + m_active_shader = m_shaders.at(shaderName); +} + +GLuint Graphics::getShaderID(std::string shaderName){ + return m_shaders.at(shaderName)->getHandle(); + +} + +std::shared_ptr<Shape> Graphics::addShape(std::string shapeName, std::vector<float> data, VAOAttrib attribs){ + m_shapes.insert({shapeName, std::make_shared<Shape>(std::make_shared<VAO>(std::make_shared<VBO>(data), attribs))}); + return m_shapes.at(shapeName); +} +std::vector<glm::vec3> Graphics::addShape(std::string shapeName, std::string filepath, bool hasUV){ + tinyobj::attrib_t attrib; + std::vector<tinyobj::shape_t> shapes; + std::vector<tinyobj::material_t> materials; + std::string warn, err; + + if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, filepath.c_str())) { + throw std::runtime_error(warn + err); + } + + int numTriangles = 0; + for(size_t s = 0; s < shapes.size(); s++){ + numTriangles += shapes[s].mesh.num_face_vertices.size(); + } + + std::vector<float> drawData; + drawData.resize(numTriangles * 3 * 8); + std::vector<glm::vec3> collisionData; + collisionData.resize(numTriangles * 3); + + int i = 0; + int j = 0; + for(size_t s = 0; s < shapes.size(); s++) { + size_t index_offset = 0; + for(size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) { + unsigned int fv = shapes[s].mesh.num_face_vertices[f]; + + for(size_t v = 0; v < fv; v++) { + tinyobj::index_t idx = shapes[s].mesh.indices[index_offset + v]; + + // Add position + drawData[i] = attrib.vertices[3*idx.vertex_index]; + drawData[i + 1] = attrib.vertices[3*idx.vertex_index + 1]; + drawData[i + 2] = attrib.vertices[3*idx.vertex_index + 2]; + // Add normal + drawData[i + 3] = attrib.normals[3*idx.normal_index]; + drawData[i + 4] = attrib.normals[3*idx.normal_index + 1]; + drawData[i + 5] = attrib.normals[3*idx.normal_index + 2]; + // Add uv + drawData[i + 6] = 0; + drawData[i + 7] = 0; + if(hasUV){ + drawData[i + 6] = attrib.texcoords[2*idx.texcoord_index]; + drawData[i + 7] = attrib.texcoords[2*idx.texcoord_index + 1]; + } + + // Add collision position data + collisionData[j] = glm::vec3(attrib.vertices[3*idx.vertex_index], attrib.vertices[3*idx.vertex_index + 1], attrib.vertices[3*idx.vertex_index + 2]); + i += 8; + j += 1; + } + + index_offset += fv; + } + } + + m_shapes.insert({shapeName, std::make_shared<Shape>(std::make_shared<VAO>(std::make_shared<VBO>(drawData), VAOAttrib::POS | VAOAttrib::NORM | VAOAttrib::UV))}); + + std::cout << "coliision data size normal: " << collisionData.size() << std::endl; + return collisionData; +} + +std::vector<glm::vec3> Graphics::addShape_manual(std::string shapeName, + const std::vector<Eigen::Vector3f> &verts, + const std::vector<Eigen::Vector3i> &faces, + bool hasUV){ + + std::pair<std::vector<glm::vec3>, std::shared_ptr<VAO>> info = makeVAOFromData(verts, faces, hasUV); + + m_shapes.insert({shapeName, std::make_shared<Shape>(info.second)}); + + std::cout << "ADD SHAPE MANUAL" << std::endl; + + return info.first; +} + +std::pair<std::vector<glm::vec3>, std::shared_ptr<VAO>> Graphics::makeVAOFromData(const std::vector<Eigen::Vector3f> &verts, + const std::vector<Eigen::Vector3i> &faces, + bool hasUV, bool needsCollisionData){ + + + + std::vector<float> drawData; + drawData.resize(faces.size() * 3 * 8); + std::vector<glm::vec3> collisionData; + collisionData.resize(faces.size() * 3); + + int i = 0; + int j = 0; + + float uv = 0; + + size_t index_offset = 0; + for(size_t f = 0; f < faces.size(); f++) { + Eigen::Vector3i face = faces[f]; + Eigen::Vector3f faceNormal = getFaceNormal(verts, face); + + + for(int v = 0; v < 3; v++) { + int idx = face[v]; + Eigen::Vector3f vertexPos = verts[idx]; + + // Add position + drawData[i] = vertexPos[0]; + drawData[i + 1] = vertexPos[1]; + drawData[i + 2] = vertexPos[2]; + // Add normal + drawData[i + 3] = 0.f; + drawData[i + 4] = 1.f; + drawData[i + 5] = 0.f; + // Add uv + drawData[i + 6] = 0; + drawData[i + 7] = 0; + + if(hasUV){ + drawData[i + 6] = uv; + drawData[i + 7] = uv; + + uv += .01; + } + + if (needsCollisionData){ + // Add collision position data + collisionData[j] = glm::vec3(vertexPos[0], vertexPos[1], vertexPos[2]); + } + i += 8; + j += 1; + } + } + + + std::shared_ptr<VAO> vao = std::make_shared<VAO>(std::make_shared<VBO>(drawData), VAOAttrib::POS | VAOAttrib::NORM | VAOAttrib::UV); + return std::make_pair(collisionData, vao); + + +} + +Eigen::Vector3f Graphics::getFaceNormal(const std::vector<Eigen::Vector3f> &verts, const Eigen::Vector3i& face) +{ + Eigen::Vector3f v1 = verts[face[0]]; + Eigen::Vector3f v2 = verts[face[1]]; + Eigen::Vector3f v3 = verts[face[2]]; + Eigen::Vector3f e1 = v2 - v1; + Eigen::Vector3f e2 = v3 - v1; + Eigen::Vector3f n = e1.cross(e2); + return n.normalized(); +} + + + +// MATERIALSS +std::vector<glm::vec3> Graphics::addShape_withMaterial(std::string shapeName, std::string filepath, std::string mtl_file, bool hasUV){ + tinyobj::attrib_t attrib; + std::vector<tinyobj::shape_t> shapes; + std::vector<tinyobj::material_t> materials; + std::string warn, err; + + if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, filepath.c_str(), mtl_file.c_str())) { + throw std::runtime_error(warn + err); + } + + int numTriangles = 0; + for(size_t s = 0; s < shapes.size(); s++){ + numTriangles += shapes[s].mesh.num_face_vertices.size(); + } + + std::cout << "materials size: " << materials.size() << std::endl; + for (auto m : materials){ + std::cout << "material: " << m.name << std::endl; + } + + + std::vector<std::string> shape_names; + std::vector<glm::vec3> collisionData; + std::cout << "---- NUM Triangles: " << numTriangles * 3 << std::endl; + collisionData.resize(numTriangles * 3); + + + + int j = 0; + for(size_t s = 0; s < shapes.size(); s++) { + int i = 0; + bool hasMaterial = true; + std::shared_ptr<Material> shape_material; + std::vector<float> drawData; + drawData.resize(shapes[s].mesh.num_face_vertices.size() * 3 * 8); + + size_t index_offset = 0; + + int shape_material_id = shapes[s].mesh.material_ids[0]; + + if (shape_material_id < 0) hasMaterial = false; + if (hasMaterial){ + std::string shape_material_name = materials[shape_material_id].name; + //std::cout << "load: " << shape_material_name << std::endl; + std::string shape_material_path = "/Users/jesswan/Desktop/cs1950u/cs1950u-jjesswan/Resources/Images/" + shape_material_name + ".png"; + shape_material = addMaterial(shape_material_name, shape_material_path, 1.f); + } + +// std::cout << "shape name:" << shapes[s].name << std::endl; +// std::cout << "mesh material id sample:" << shapes[s].mesh.material_ids[0] << std::endl; +// std::cout << "mesh material id sample2:" << shapes[s].mesh.material_ids[5] << std::endl; + +// std::cout << "mesh material id size:" << shapes[s].mesh.material_ids.size() << std::endl; +// std::cout << "num faces:" << shapes[s].mesh.num_face_vertices.size() << std::endl; + + for(size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) { + unsigned int fv = shapes[s].mesh.num_face_vertices[f]; + + for(size_t v = 0; v < fv; v++) { + tinyobj::index_t idx = shapes[s].mesh.indices[index_offset + v]; + + // Add position + drawData[i] = attrib.vertices[3*idx.vertex_index]; + drawData[i + 1] = attrib.vertices[3*idx.vertex_index + 1]; + drawData[i + 2] = attrib.vertices[3*idx.vertex_index + 2]; + // Add normal + drawData[i + 3] = attrib.normals[3*idx.normal_index]; + drawData[i + 4] = attrib.normals[3*idx.normal_index + 1]; + drawData[i + 5] = attrib.normals[3*idx.normal_index + 2]; + // Add uv + drawData[i + 6] = 0; + drawData[i + 7] = 0; + if(hasUV){ + drawData[i + 6] = attrib.texcoords[2*idx.texcoord_index]; + drawData[i + 7] = attrib.texcoords[2*idx.texcoord_index + 1]; + } + + // Add collision position data + collisionData[j] = glm::vec3(attrib.vertices[3*idx.vertex_index], attrib.vertices[3*idx.vertex_index + 1], attrib.vertices[3*idx.vertex_index + 2]); + i += 8; + j += 1; + } + + index_offset += fv; + } + + if (hasMaterial){ + m_shapes.insert({shapeName + std::to_string(s), std::make_shared<Shape>(std::make_shared<VAO>(std::make_shared<VBO>(drawData), VAOAttrib::POS | VAOAttrib::NORM | VAOAttrib::UV), shape_material)}); + } else { + m_shapes.insert({shapeName + std::to_string(s), std::make_shared<Shape>(std::make_shared<VAO>(std::make_shared<VBO>(drawData), VAOAttrib::POS | VAOAttrib::NORM | VAOAttrib::UV))}); + } + + shape_names.push_back(shapeName + std::to_string(s)); + } + + std::cout << "DONE LOADING MTL" << std::endl; + m_shape_groups.insert({shapeName, shape_names}); + std::cout << "collision data size: " << collisionData.size() << std::endl; + return collisionData; +} + +std::pair<std::vector<glm::vec3>, std::vector<glm::ivec3>> Graphics::getNavmeshData(std::string filepath){ + tinyobj::attrib_t attrib; + std::vector<tinyobj::shape_t> shapes; + std::vector<tinyobj::material_t> materials; + std::string warn, err; + + if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, filepath.c_str())) { + throw std::runtime_error(warn + err); + } + + int numTriangles = 0; + for(size_t s = 0; s < shapes.size(); s++){ + numTriangles += shapes[s].mesh.num_face_vertices.size(); + } + + std::vector<glm::vec3> positions; + std::vector<glm::ivec3> faces; + + for(int i = 0; i<attrib.vertices.size(); i+=3){ + positions.push_back(glm::vec3(attrib.vertices[i], attrib.vertices[i+1], attrib.vertices[i+2])); + } + + + int i = 0; + int j = 0; + for(size_t s = 0; s < shapes.size(); s++) { + for(size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) { + tinyobj::index_t idx1 = shapes[s].mesh.indices[3* f]; + tinyobj::index_t idx2 = shapes[s].mesh.indices[3* f + 1]; + tinyobj::index_t idx3 = shapes[s].mesh.indices[3* f + 2]; + faces.push_back(glm::ivec3(idx1.vertex_index, idx2.vertex_index, idx3.vertex_index)); + } + } + + return std::make_pair(positions, faces); +} + +void Graphics::removeShape(std::string shapeName){ + m_shapes.erase(shapeName); +} + +std::shared_ptr<Shape> Graphics::getShape(std::string shapeName){ + return m_shapes.at(shapeName); +} + +std::vector<std::shared_ptr<Shape>> Graphics::getShapeGroup(std::string shapeName){ + std::vector<std::string> shape_ids = m_shape_groups.at(shapeName); + std::vector<std::shared_ptr<Shape>> all_shapes; + + for (std::string id : shape_ids){ + all_shapes.push_back(m_shapes.at(id)); + } + + return all_shapes; +} + +void Graphics::drawShape(std::shared_ptr<Shape> myShape, std::shared_ptr<ModelTransform> modelTransform, std::shared_ptr<Material> material){ + if(material == nullptr){ + m_active_shader->setMaterial(getMaterial("default")); + } + else{ + m_active_shader->setMaterial(material); + } + m_active_shader->setModelTransform(modelTransform); + myShape->draw(); +} + +void Graphics::drawShape(std::shared_ptr<Shape> myShape, glm::mat4 modelMatrix, std::shared_ptr<Material> material){ + if(material == nullptr){ + m_active_shader->setMaterial(getMaterial("default")); + } + else{ + m_active_shader->setMaterial(material); + } + m_active_shader->setModelTransform(modelMatrix); + myShape->draw(); +} + +std::vector<float> Graphics::getObjData(std::string filepath){ + tinyobj::attrib_t attrib; + std::vector<tinyobj::shape_t> shapes; + std::vector<tinyobj::material_t> materials; + std::string warn, err; + + if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, filepath.c_str())) { + throw std::runtime_error(warn + err); + } + + std::vector<glm::vec3> faces; + std::vector<glm::vec3> vertices; + + for(size_t s = 0; s < shapes.size(); s++) { + size_t index_offset = 0; + for(size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) { + unsigned int fv = shapes[s].mesh.num_face_vertices[f]; + + glm::vec3 face; + for(size_t v = 0; v < fv; v++) { + tinyobj::index_t idx = shapes[s].mesh.indices[index_offset + v]; + + face[v] = idx.vertex_index; + + } + faces.push_back(face); + + index_offset += fv; + } + } + for (size_t i = 0; i < attrib.vertices.size(); i += 3) { + vertices.emplace_back(attrib.vertices[i], attrib.vertices[i + 1], attrib.vertices[i + 2]); + } + + std::vector<float> data; + data.resize(18 * faces.size()); + for(int i = 0; i<faces.size(); i++){ + glm::vec3 v0 = vertices[static_cast<int>(faces[i].x)]; + glm::vec3 v1 = vertices[static_cast<int>(faces[i].y)]; + glm::vec3 v2 = vertices[static_cast<int>(faces[i].z)]; + glm::vec3 normal = glm::normalize(glm::cross(v1 - v0, v2 - v0)); + + data[18*i] = v0.x; + data[18*i+1] = v0.y; + data[18*i+2] = v0.z; + data[18*i+3] = normal.x; + data[18*i+4] = normal.y; + data[18*i+5] = normal.z; + data[18*i+6] = v1.x; + data[18*i+7] = v1.y; + data[18*i+8] = v1.z; + data[18*i+9] = normal.x; + data[18*i+10] = normal.y; + data[18*i+11] = normal.z; + data[18*i+12] = v2.x; + data[18*i+13] = v2.y; + data[18*i+14] = v2.z; + data[18*i+15] = normal.x; + data[18*i+16] = normal.y; + data[18*i+17] = normal.z; + } + + return data; +} + +std::shared_ptr<Material> Graphics::addMaterial(std::string materialName, glm::vec3 color, float shininess){ + std::shared_ptr<Material> newMaterial = std::make_shared<Material>(color, shininess); + m_materials.insert({materialName, newMaterial}); + return m_materials.at(materialName); +} + +std::shared_ptr<Material> Graphics::addMaterial(std::string materialName, float shininess){ + std::shared_ptr<Material> newMaterial = std::make_shared<Material>(shininess); + m_materials.insert({materialName, newMaterial}); + return m_materials.at(materialName); +} + +std::shared_ptr<Material> Graphics::addMaterial(std::string materialName, std::string filePath, float shininess){ + std::shared_ptr<Texture> newTexture = std::make_shared<Texture>(filePath); + std::shared_ptr<Material> newMaterial = std::make_shared<Material>(newTexture, shininess); + m_materials.insert({materialName, newMaterial}); + return m_materials.at(materialName); +} + +void Graphics::removeMaterial(std::string materialName){ + if(materialName != "default"){ + m_materials.erase(materialName); + } +} + +std::shared_ptr<Material> Graphics::getMaterial(std::string materialName){ + return m_materials.at(materialName); +} + +std::shared_ptr<Font> Graphics::addFont(std::string fontName, std::string filepath){ + std::shared_ptr<Font> newFont = std::make_shared<Font>(filepath); + m_fonts.insert({fontName, newFont}); + return m_fonts.at(fontName); +} + +void Graphics::removeFont(std::string fontName){ + m_fonts.erase(fontName); +} + +std::shared_ptr<Font> Graphics::getFont(std::string fontName){ + return m_fonts.at(fontName); +} + +void Graphics::drawUIText(std::shared_ptr<Font> font, std::string text, glm::vec2 anchorPosition, AnchorPoint anchorPoint, float textBoxWidth, float fontSize, float lineSpacing, glm::vec3 textColor){ + m_active_shader->setTextUniforms(m_windowSize.x, m_windowSize.y, textColor); + m_textRenderer->renderUIText(font, text, anchorPosition, anchorPoint, textBoxWidth, fontSize, lineSpacing, textColor); +} + +void Graphics::setGlobalData(glm::vec3 globalCoeffs){ + m_active_shader->setGlobalCoeffs(globalCoeffs); +} + +void Graphics::setLights(std::vector<std::shared_ptr<Light>> lights){ + m_active_shader->setLights(lights); +} + +void Graphics::clearLights(){ + m_active_shader->clearLights(); +} + +void Graphics::setWindowSize(glm::ivec2 windowSize){ + m_windowSize = windowSize; +} + +glm::ivec2 Graphics::getWindowSize(){ + return m_windowSize; +} + +void Graphics::setFramebufferSize(glm::ivec2 framebufferSize){ + m_framebufferSize = framebufferSize; + glViewport(0, 0, m_framebufferSize.x, m_framebufferSize.y); +} + +glm::ivec2 Graphics::getFramebufferSize(){ + return m_framebufferSize; +} + + +// WATERRRR ////// + +void Graphics::setWaterHeight(float height){ + m_water_height = height; + +} + +float Graphics::getWaterHeight(){ + return m_water_height; +} + + +void Graphics::bindReflection(){ + Debug::checkGLError(); + bindFBO(reflectionFBO, REFLECTION_W, REFLECTION_H); + Debug::checkGLError(); + +} + +void Graphics::bindRefraction(){ + Debug::checkGLError(); + + bindFBO(refractionFBO, REFRACTION_W, REFRACTION_H); + Debug::checkGLError(); + +} + +GLuint Graphics::getReflectionTexture(){ + return reflectionTexture; +} + +GLuint Graphics::getRefractionTexture(){ + return refractionTexture; +} + +GLuint Graphics::getReflectionRBO(){ + return reflectionDepthBuffer; +} + +GLuint Graphics::getRefractionDepth(){ + return refractionDepthTexture; +} + + +void Graphics::initializeReflectionFBO(){ + Debug::checkGLError(); + + reflectionFBO = createFBO(); + Debug::checkGLError(); + + reflectionTexture = createTextureAttachment(REFLECTION_W, REFLECTION_H); + Debug::checkGLError(); + + reflectionDepthBuffer = createDepthBuffer(REFLECTION_W, REFLECTION_H); + Debug::checkGLError(); + + unbindFBO(); + Debug::checkGLError(); + +} + +void Graphics::initializeRefractionFBO(){ + Debug::checkGLError(); + + refractionFBO = createFBO(); + Debug::checkGLError(); + + refractionTexture = createTextureAttachment(REFRACTION_W, REFRACTION_H); + Debug::checkGLError(); + + // glDrawBuffer(GL_NONE); + refractionDepthTexture = createDepthTextureAttachment(REFRACTION_W, REFRACTION_H); + Debug::checkGLError(); + unbindFBO(); + Debug::checkGLError(); + + +} +void Graphics::bindFBO(GLuint fbo, int width, int height){ + // make sure texture isnt already bound + Debug::checkGLError(); + glBindTexture(GL_TEXTURE_2D, 0); + Debug::checkGLError(); + + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + Debug::checkGLError(); + + glViewport(0, 0, width, height); + Debug::checkGLError(); + + auto fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (fboStatus != GL_FRAMEBUFFER_COMPLETE){ + std::cout << "Framebuffer not complete: " << fboStatus << std::endl; + } + Debug::checkGLError(); + + +} + +void Graphics::unbindFBO(){ + Debug::checkGLError(); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, m_framebufferSize.x, m_framebufferSize.y); +} + +GLuint Graphics::createFBO(){ + GLuint fbo; + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glDrawBuffer(GL_COLOR_ATTACHMENT0); + return fbo; +} + +GLuint Graphics::createTextureAttachment(int width, int height){ + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + // adds texture attachement to currently bound fbo + std::cout << "Color buffer: " << texture << std::endl; + + //glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); + + return texture; +} + +GLuint Graphics::createDepthTextureAttachment(int width, int height){ + GLuint texture; + glBindTexture(GL_TEXTURE_2D, 0); + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + Debug::checkGLError(); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, width, height, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + Debug::checkGLError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + std::cout << "Depth texture: " << texture << std::endl; + + Debug::checkGLError(); + + glBindTexture(GL_TEXTURE_2D, 0); + + Debug::checkGLError(); + + // adds texture attachement to currently bound fbo + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texture, 0); + Debug::checkGLError(); + + return texture; +} + +GLuint Graphics::createDepthBuffer(int width, int height){ + GLuint depthBuffer; + glGenRenderbuffers(1, &depthBuffer); + glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + std::cout << "Depth buffer: " << depthBuffer << std::endl; + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer); + return depthBuffer; +} + +void Graphics::deleteFBOS(){ + glDeleteFramebuffers(1, &reflectionFBO); + glDeleteFramebuffers(1, &refractionFBO); + + glDeleteTextures(1, &reflectionTexture); + glDeleteTextures(1, &refractionTexture); + glDeleteTextures(1, &refractionDepthTexture); + + glDeleteRenderbuffers(1, &reflectionDepthBuffer); +} diff --git a/engine-ocean/Graphics/graphics.h b/engine-ocean/Graphics/graphics.h new file mode 100644 index 0000000..ce07727 --- /dev/null +++ b/engine-ocean/Graphics/graphics.h @@ -0,0 +1,166 @@ +#pragma once + +#include "GLWrappers/vao.h" +#include "camera.h" +#include "GLWrappers/shader.h" +#include "material.h" +#include <map> +#include <GL/glew.h> +#include <memory> +#include <vector> +#include "shape.h" +#include "modeltransform.h" +#include "light.h" +#include "textrenderer.h" + +#include <Eigen/Dense> + +struct TextureData{ + GLuint textureID; + int width; + int height; +}; + +class Graphics +{ +public: + Graphics(); + ~Graphics(); + + void initialize(); + void clearScreen(GLbitfield mask); + void setClearColor(glm::vec3 clearColor); + TextureData loadTextureFromFile(const char *path); + TextureData loadTextureFromFile_Repeat(const char *path); + + GLuint loadCubeMap(std::vector<const char*> textureFiles); + + GLuint makeVAO(std::vector<float> positions); + std::pair<std::vector<glm::vec3>, std::shared_ptr<VAO>> makeVAOFromData(const std::vector<Eigen::Vector3f> &verts, + const std::vector<Eigen::Vector3i> &faces, + bool hasUV, bool needsCollisionData = true); + float generateRandomNumbers(float lb, float ub); + + void setClipPlane(glm::vec4 plane); + + + + + + + + + void setCameraData(std::shared_ptr<Camera> camera); + + void addShader(std::string shaderName, std::vector<GLenum> shaderTypes, std::vector<const char*> filepaths); + void removeShader(std::string shaderName); + void bindShader(std::string shaderName = "phong"); + GLuint getShaderID(std::string shaderName); + + + // Shape-related methods + std::shared_ptr<Shape> addShape(std::string shapeName, std::vector<float> data, VAOAttrib attribs); + std::vector<glm::vec3> addShape(std::string shapeName, std::string filepath, bool hasUV = true); + std::vector<glm::vec3> addShape_manual(std::string shapeName, + const std::vector<Eigen::Vector3f> &verts, + const std::vector<Eigen::Vector3i> &faces, + bool hasUV = true); + + std::vector<glm::vec3> addShape_withMaterial(std::string shapeName, std::string filepath, std::string mtl_file, bool hasUV); + + // Returns pair containing positions followed by triangles indexed into the positions vector + std::pair<std::vector<glm::vec3>, std::vector<glm::ivec3>> getNavmeshData(std::string filepath); + void removeShape(std::string shapeName); + std::shared_ptr<Shape> getShape(std::string shapeName); + std::vector<std::shared_ptr<Shape>> getShapeGroup(std::string shapeName); + void drawShape(std::shared_ptr<Shape> myShape, std::shared_ptr<ModelTransform> modelTransform, std::shared_ptr<Material> material = nullptr); + void drawShape(std::shared_ptr<Shape> myShape, glm::mat4 modelMatrix, std::shared_ptr<Material> material = nullptr); + + // Obj-loading method + std::vector<float> getObjData(std::string filepath); + + // Material-related methods + std::shared_ptr<Material> addMaterial(std::string materialName, glm::vec3 color, float shininess = 1.f); + std::shared_ptr<Material> addMaterial(std::string materialName, float shininess = 1.f); + std::shared_ptr<Material> addMaterial(std::string materialName, std::string filePath, float shininess = 1.f); + void removeMaterial(std::string materialName); + std::shared_ptr<Material> getMaterial(std::string materialName); + + // Text and Font-related methods + std::shared_ptr<Font> addFont(std::string fontName, std::string filepath); + void removeFont(std::string fontName); + std::shared_ptr<Font> getFont(std::string fontName); + void drawUIText(std::shared_ptr<Font> font, std::string text, glm::vec2 anchorPosition, AnchorPoint anchorPoint, float textBoxWidth, float fontSize, float lineSpacing, glm::vec3 textColor); + + void setGlobalData(glm::vec3 globalCoeffs); + + void setLights(std::vector<std::shared_ptr<Light>> lights); + void clearLights(); + + void initializeGLEW(); + + void setWindowSize(glm::ivec2 windowSize); + glm::ivec2 getWindowSize(); + + void setFramebufferSize(glm::ivec2 framebufferSize); + glm::ivec2 getFramebufferSize(); + + + // WATER STUFF + GLuint reflectionFBO, reflectionTexture, reflectionDepthBuffer; + GLuint refractionFBO, refractionTexture, refractionDepthTexture; + + void bindRefraction(); + void bindReflection(); + GLuint getRefractionTexture(); + GLuint getReflectionTexture(); + void unbindFBO(); + GLuint getReflectionRBO(); + GLuint getRefractionDepth(); + + + + + const int REFLECTION_W = 512; + const int REFLECTION_H = 256; + const int REFRACTION_W = 512; + const int REFRACTION_H = 256; + + void setWaterHeight(float height); + float getWaterHeight(); + + + + +private: + void initializeReflectionFBO(); + void initializeRefractionFBO(); + void deleteFBOS(); + void bindFBO(GLuint fbo, int width, int height); + GLuint createFBO(); + GLuint createTextureAttachment(int width, int height); + GLuint createDepthTextureAttachment(int width, int height); + GLuint createDepthBuffer(int width, int height); + + + + + glm::ivec2 m_windowSize; + glm::ivec2 m_framebufferSize; + + std::shared_ptr<TextRenderer> m_textRenderer; + + std::map<std::string, std::shared_ptr<Shader>> m_shaders; + std::map<std::string, std::shared_ptr<Shape>> m_shapes; + std::map<std::string, std::vector<std::string>> m_shape_groups; // stores the shape names kept in m_shapes associated with object + std::map<std::string, std::shared_ptr<Material>> m_materials; + std::map<std::string, std::shared_ptr<Font>> m_fonts; + + std::shared_ptr<Shader> m_active_shader; + + float m_water_height = 0.f; + + + Eigen::Vector3f getFaceNormal(const std::vector<Eigen::Vector3f> &verts, const Eigen::Vector3i& face); + +}; diff --git a/engine-ocean/Graphics/light.cpp b/engine-ocean/Graphics/light.cpp new file mode 100644 index 0000000..e2e5a38 --- /dev/null +++ b/engine-ocean/Graphics/light.cpp @@ -0,0 +1,69 @@ +#include "light.h" + + +Light::Light(LightType type, glm::vec3 lightData, glm::vec3 lightColor): + m_lightType(type), + m_lightColor(lightColor), + m_lightFunction(glm::vec3(1)) +{ + switch(type){ + case LightType::POINT: + m_lightPos = lightData; + break; + case LightType::DIRECTIONAL: + m_lightDir = lightData; + break; + } +} + +Light::~Light(){ + +} + +void Light::setPos(glm::vec3 newPos){ + m_lightPos = newPos; +} + +glm::vec3 Light::getPos(){ + return m_lightPos; +} + +void Light::translate(glm::vec3 delta){ + m_lightPos += delta; +} + +void Light::setAttenuation(glm::vec3 attenuation){ + m_lightFunction = attenuation; +} + +glm::vec3 Light::getAttenuation(){ + return m_lightFunction; +} + +void Light::setDir(glm::vec3 newDir){ + m_lightDir = newDir; +} + +glm::vec3 Light::getDir(){ + return m_lightDir; +} + +void Light::rotate(float angle, glm::vec3 axis){ + m_lightDir = glm::vec3(glm::rotate(glm::mat4(1), angle, axis)*glm::vec4(m_lightDir, 0)); +} + +void Light::setColor(glm::vec3 newColor){ + m_lightColor = newColor; +} + +glm::vec3 Light::getColor(){ + return m_lightColor; +} + +void Light::setType(LightType newType){ + m_lightType = newType; +} + +LightType Light::getType(){ + return m_lightType; +} diff --git a/engine-ocean/Graphics/light.h b/engine-ocean/Graphics/light.h new file mode 100644 index 0000000..0c42b7f --- /dev/null +++ b/engine-ocean/Graphics/light.h @@ -0,0 +1,42 @@ +#pragma once + +#include "glm/glm.hpp" +#include "glm/ext.hpp" + +enum LightType{ + POINT, + DIRECTIONAL +}; + +class Light{ +public: + Light(LightType type, glm::vec3 lightData, glm::vec3 lightColor = glm::vec3(1)); + ~Light(); + + // Functions for point lights + void setPos(glm::vec3 newPos); + glm::vec3 getPos(); + void translate(glm::vec3 delta); + void setAttenuation(glm::vec3 attenuation); + glm::vec3 getAttenuation(); + + // Functions for directional lights + void setDir(glm::vec3 newDir); + glm::vec3 getDir(); + void rotate(float angle, glm::vec3 axis); + + // Utility functions for light color + void setColor(glm::vec3 newColor); + glm::vec3 getColor(); + + // Utility functions for the light type + void setType(LightType newType); + LightType getType(); + +private: + LightType m_lightType; + glm::vec3 m_lightPos; + glm::vec3 m_lightDir; + glm::vec3 m_lightColor; + glm::vec3 m_lightFunction; +};
\ No newline at end of file diff --git a/engine-ocean/Graphics/material.cpp b/engine-ocean/Graphics/material.cpp new file mode 100644 index 0000000..8e0c561 --- /dev/null +++ b/engine-ocean/Graphics/material.cpp @@ -0,0 +1,62 @@ +#include "material.h" +#include <Eigen/Dense> + + +Material::Material(glm::vec3 color, float shininess): + m_colorSource(ColorSource::SOLID_COLOR), + m_color(color), + m_shininess(shininess) +{ + +} + +Material::Material(float shininess): + m_colorSource(ColorSource::PER_VERTEX_COLOR), + m_shininess(shininess) +{ + +} + +Material::Material(std::shared_ptr<Texture> texture, float shininess): + m_colorSource(ColorSource::TEXTURE_COLOR), + m_texture(texture), + m_shininess(shininess) +{ + +} + +Material::~Material(){ + +} + +ColorSource Material::getColorSource(){ + return m_colorSource; +} + +void Material::setColorSource(ColorSource source){ + m_colorSource = source; +} + +std::shared_ptr<Texture> Material::getTexture(){ + return m_texture; +} + +void Material::setTexture(std::shared_ptr<Texture> texture){ + m_texture = texture; +} + +glm::vec3 Material::getColor(){ + return m_color; +} + +void Material::setColor(glm::vec3 color){ + m_color = color; +} + +float Material::getShininess(){ + return m_shininess; +} + +void Material::setShininess(float shininess){ + m_shininess = shininess; +} diff --git a/engine-ocean/Graphics/material.h b/engine-ocean/Graphics/material.h new file mode 100644 index 0000000..3434e72 --- /dev/null +++ b/engine-ocean/Graphics/material.h @@ -0,0 +1,36 @@ +#pragma once + +#include "GLWrappers/texture.h" +#include <memory> + +#include "glm/glm.hpp" + +enum ColorSource{ + SOLID_COLOR, + TEXTURE_COLOR, + PER_VERTEX_COLOR +}; + +class Material{ +public: + Material(glm::vec3 color, float shininess = 1.f); //Constructor for setting SOLID_COLOR based material + Material(float shininess = 1.f); //Constructor for setting PER_VERTEX_COLOR based material + Material(std::shared_ptr<Texture> texture, float shininess = 1.f); //Constructor for setting TEXTURE_COLOR based material + ~Material(); + + // Functions for setting uniforms + ColorSource getColorSource(); + void setColorSource(ColorSource source); + std::shared_ptr<Texture> getTexture(); + void setTexture(std::shared_ptr<Texture> texture); + glm::vec3 getColor(); + void setColor(glm::vec3 color); + float getShininess(); + void setShininess(float shininess); + +private: + ColorSource m_colorSource; + std::shared_ptr<Texture> m_texture; + glm::vec3 m_color; + float m_shininess; +};
\ No newline at end of file diff --git a/engine-ocean/Graphics/modeltransform.cpp b/engine-ocean/Graphics/modeltransform.cpp new file mode 100644 index 0000000..895f64d --- /dev/null +++ b/engine-ocean/Graphics/modeltransform.cpp @@ -0,0 +1,90 @@ +#include "modeltransform.h" +#include <iostream> + +ModelTransform::ModelTransform(): + m_pos(glm::vec3(0)), + m_scale(glm::vec3(1)), + m_rotation(glm::mat4(1)) +{ + +} + +ModelTransform::~ModelTransform(){ + +} + +void ModelTransform::setPos(glm::vec3 pos){ + m_pos = pos; +} + +void ModelTransform::translate(glm::vec3 delta) { + m_pos += delta; +} + +glm::vec3 ModelTransform::getPos() { + return m_pos; +} + +void ModelTransform::setScale(glm::vec3 scale) { + m_scale = scale; +} + +void ModelTransform::setScale(float scale) { + m_scale = glm::vec3(scale); +} + +void ModelTransform::scale(glm::vec3 scale) { + m_scale *= scale; +} + +void ModelTransform::scale(float scale) { + m_scale *= scale; +} + +glm::vec3 ModelTransform::getScale() { + return m_scale; +} + +void ModelTransform::setRotation(float angle, glm::vec3 axis) { + m_rotation = glm::rotate(glm::mat4(1), angle, axis); +} + +void ModelTransform::setRotation(glm::mat4 r) { + m_rotation = r; +} + +void ModelTransform::rotate(float angle, glm::vec3 axis) { + m_rotation = glm::rotate(m_rotation, angle, axis); +} + +void ModelTransform::rotate(glm::mat4 r) { + m_rotation = r * m_rotation; +} + +glm::mat4 ModelTransform::getRotation() { + return m_rotation; +} + +//float ModelTransform::getYRotationAngle(){ +// glm::mat4 rotMat = getRotation(); +// float ry0 = rotMat[0][2]; +// float ry1 = rotMat[1][2]; +// float ry2 = rotMat[2][2]; + +// float angley = std::atan2(-ry0, pow((pow(ry1, 2) + pow(ry2,2)), .5)); +// return angley; +//} + +glm::mat4 ModelTransform::getModelMatrix() { + glm::mat4 model = glm::mat4(1); + model = glm::translate(model, m_pos); + model = model * m_rotation; + model = glm::scale(model, m_scale); + return model; +} + +void ModelTransform::clear(){ + m_pos = glm::vec3(0, 0, 0); + m_scale = glm::vec3(1, 1, 1); + m_rotation = glm::mat4(1); +} diff --git a/engine-ocean/Graphics/modeltransform.h b/engine-ocean/Graphics/modeltransform.h new file mode 100644 index 0000000..46f5b73 --- /dev/null +++ b/engine-ocean/Graphics/modeltransform.h @@ -0,0 +1,34 @@ +#pragma once + +#include "glm/glm.hpp" +#include "glm/ext.hpp" + +class ModelTransform{ +public: + ModelTransform(); + ~ModelTransform(); + + void setPos(glm::vec3 pos); + void translate(glm::vec3 delta); + glm::vec3 getPos(); + void setScale(glm::vec3 scale); + void setScale(float scale); + void scale(glm::vec3 scale); + void scale(float scale); + glm::vec3 getScale(); + void setRotation(float angle, glm::vec3 axis); + void setRotation(glm::mat4 r); + void rotate(float angle, glm::vec3 axis); + void rotate(glm::mat4 r); + glm::mat4 getRotation(); + glm::mat4 getModelMatrix(); + void clear(); + + float getYRotationAngle(); + + +private: + glm::vec3 m_pos; + glm::vec3 m_scale; + glm::mat4 m_rotation = glm::mat4(1); +}; diff --git a/engine-ocean/Graphics/shaderloader.h b/engine-ocean/Graphics/shaderloader.h new file mode 100644 index 0000000..eeb8e8c --- /dev/null +++ b/engine-ocean/Graphics/shaderloader.h @@ -0,0 +1,98 @@ +#pragma once + +#include "debug.h" + +#include <vector> +#include <string> +#include <stdexcept> +#include <fstream> +#include <iostream> + +class ShaderLoader{ +public: + static GLuint createShaderProgram(std::vector<GLenum> shaderTypes, std::vector<const char*> filepaths){ + // Create and compile shaders + std::vector<GLuint> shaderIDs; + for(int i = 0; i<shaderTypes.size(); i++){ + shaderIDs.push_back(createAndCompileShader(shaderTypes[i], filepaths[i])); + } + + // Link the shader program + GLuint programID = glCreateProgram(); + for(int i = 0; i<shaderIDs.size(); i++){ + glAttachShader(programID, shaderIDs[i]); + } + glLinkProgram(programID); + + // Print the info log if program fails to link + GLint status; + glGetProgramiv(programID, GL_LINK_STATUS, &status); + if(status == GL_FALSE){ + GLint length; + glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &length); + std::string log(length, '\0'); + glGetProgramInfoLog(programID, length, nullptr, &log[0]); + glDeleteProgram(programID); + throw std::runtime_error(log); + } + + // Individual shaders no longer necessary, stored in program + for(int i = 0; i<shaderIDs.size(); i++){ + glDeleteShader(shaderIDs[i]); + } + + std::cout<<"END OF SHADERLOADER"<<std::endl; + return programID; + } + +private: + static std::string readFile(const char *filePath) { + std::cout<<"READ FILE: "<<std::string(filePath)<<std::endl; + std::string content; + std::ifstream fileStream(filePath, std::ios::in); + + if(!fileStream.is_open()) { + std::string log = "Could not read file "+std::string(filePath)+". File does not exist."; + throw std::runtime_error(log); + return ""; + } + + std::string line = ""; + while(std::getline(fileStream, line)) { + content.append(line + "\n"); + } + + fileStream.close(); + + return content; + } + + static GLuint createAndCompileShader(GLenum shaderType, const char* filepath){ + std::cout<<"CREATE AND COMPILE SHADER: "<<shaderType<<std::endl; + GLuint shaderID = glCreateShader(shaderType); + + // Read shader file + std::string shaderStr = readFile(filepath); + const char* shaderSrc = shaderStr.c_str(); + + std::cout<<"GL SHADER SOURCE"<<std::endl; + glShaderSource(shaderID, 1, &shaderSrc, NULL); + + std::cout<<"GL COMPILE SHADER: "<<shaderID<<std::endl; + glCompileShader(shaderID); + + // Print info log if shader fails to compile + GLint status; + glGetShaderiv(shaderID, GL_COMPILE_STATUS, &status); + if(status == GL_FALSE){ + GLint length; + glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &length); + std::string log(length, '\0'); + glGetShaderInfoLog(shaderID, length, nullptr, &log[0]); + glDeleteShader(shaderID); + throw std::runtime_error(log); + } + + return shaderID; + } +};
\ No newline at end of file diff --git a/engine-ocean/Graphics/shape.cpp b/engine-ocean/Graphics/shape.cpp new file mode 100644 index 0000000..cd0b9b4 --- /dev/null +++ b/engine-ocean/Graphics/shape.cpp @@ -0,0 +1,46 @@ +#include "shape.h" +#include <Eigen/Dense> +#include "Graphics/global.h" +#include "Graphics/material.h" +#include <iostream> + +Shape::Shape(std::shared_ptr<VAO> vao): + m_vao(vao) +{ + +} + +Shape::Shape(std::shared_ptr<VAO> vao, std::shared_ptr<Material> shape_material): + m_vao(vao), + m_shape_material(shape_material) +{ + hasShapeSpecificMaterial = true; + +} + +Shape::~Shape(){ + +} + +std::shared_ptr<Material> Shape::getShapeMaterial(){ + if (hasShapeSpecificMaterial){ + return m_shape_material; + } + std::cout << "this shape does not have material." << std::endl; +} + +bool Shape::hasMaterial(){ + return hasShapeSpecificMaterial; +} + +void Shape::draw(){ + m_vao->draw(); +} + +void Shape::updateVAO(const std::vector<Eigen::Vector3f> &vertices, const std::vector<Eigen::Vector3i> &faces){ + + + m_vao = Global::graphics.makeVAOFromData(vertices, faces, true, false).second; + + +} diff --git a/engine-ocean/Graphics/shape.h b/engine-ocean/Graphics/shape.h new file mode 100644 index 0000000..6385d2b --- /dev/null +++ b/engine-ocean/Graphics/shape.h @@ -0,0 +1,27 @@ +#pragma once + +#include "GLWrappers/vao.h" +#include "Graphics/material.h" +#include <Eigen/Dense> + +class Shape{ +public: + Shape(std::shared_ptr<VAO> vao); + Shape(std::shared_ptr<VAO> vao, std::shared_ptr<Material> shape_material); + + ~Shape(); + + // Draw function + void draw(); + std::shared_ptr<Material> getShapeMaterial(); + bool hasMaterial(); + void updateVAO(const std::vector<Eigen::Vector3f> &vertices, const std::vector<Eigen::Vector3i> &faces); + + + + +private: + std::shared_ptr<VAO> m_vao; + std::shared_ptr<Material> m_shape_material; + bool hasShapeSpecificMaterial = false; +}; diff --git a/engine-ocean/Graphics/shapedata.h b/engine-ocean/Graphics/shapedata.h new file mode 100644 index 0000000..c2ff4b8 --- /dev/null +++ b/engine-ocean/Graphics/shapedata.h @@ -0,0 +1,3549 @@ +#pragma once + +#include "GL/glew.h" +#include <vector> + +//Quad, Cube, Sphere, Cylinder, and Cone data with pos, norm, uvs + +std::vector<GLfloat> quadVertexBufferData = { + -0.5f, 0, 0.5f, 0, 1, 0, 0, 0, + 0.5f, 0, 0.5f, 0, 1, 0, 1, 0, + 0.5f, 0, -0.5f, 0, 1, 0, 1, 1, + -0.5f, 0, 0.5f, 0, 1, 0, 0, 0, + 0.5f, 0, -0.5f, 0, 1, 0, 1, 1, + -0.5f, 0, -0.5f, 0, 1, 0, 0, 1 +}; + +std::vector<GLfloat> cubeVertexBufferData = { + // front + -0.5f, -0.5f, 0.5f, 0, 0, 1, 0, 0, + 0.5f, -0.5f, 0.5f, 0, 0, 1, 1, 0, + 0.5f, 0.5f, 0.5f, 0, 0, 1, 1, 1, + -0.5f, -0.5f, 0.5f, 0, 0, 1, 0, 0, + 0.5f, 0.5f, 0.5f, 0, 0, 1, 1, 1, + -0.5f, 0.5f, 0.5f, 0, 0, 1, 0, 1, + // top + -0.5f, 0.5f, 0.5f, 0, 1, 0, 0, 0, + 0.5f, 0.5f, 0.5f, 0, 1, 0, 1, 0, + 0.5f, 0.5f, -0.5f, 0, 1, 0, 1, 1, + -0.5f, 0.5f, 0.5f, 0, 1, 0, 0, 0, + 0.5f, 0.5f, -0.5f, 0, 1, 0, 1, 1, + -0.5f, 0.5f, -0.5f, 0, 1, 0, 0, 1, + // back + 0.5f, -0.5f, -0.5f, 0, 0, -1, 0, 0, + -0.5f, -0.5f, -0.5f, 0, 0, -1, 1, 0, + -0.5f, 0.5f, -0.5f, 0, 0, -1, 1, 1, + 0.5f, -0.5f, -0.5f, 0, 0, -1, 0, 0, + -0.5f, 0.5f, -0.5f, 0, 0, -1, 1, 1, + 0.5f, 0.5f, -0.5f, 0, 0, -1, 0, 1, + // bottom + -0.5f, -0.5f, -0.5f, 0, -1, 0, 0, 0, + 0.5f, -0.5f, -0.5f, 0, -1, 0, 1, 0, + 0.5f, -0.5f, 0.5f, 0, -1, 0, 1, 1, + -0.5f, -0.5f, -0.5f, 0, -1, 0, 0, 0, + 0.5f, -0.5f, 0.5f, 0, -1, 0, 1, 1, + -0.5f, -0.5f, 0.5f, 0, -1, 0, 0, 1, + // left + -0.5f, -0.5f, -0.5f, -1, 0, 0, 0, 0, + -0.5f, -0.5f, 0.5f, -1, 0, 0, 1, 0, + -0.5f, 0.5f, 0.5f, -1, 0, 0, 1, 1, + -0.5f, -0.5f, -0.5f, -1, 0, 0, 0, 0, + -0.5f, 0.5f, 0.5f, -1, 0, 0, 1, 1, + -0.5f, 0.5f, -0.5f, -1, 0, 0, 0, 1, + // right + 0.5f, -0.5f, 0.5f, 1, 0, 0, 0, 0, + 0.5f, -0.5f, -0.5f, 1, 0, 0, 1, 0, + 0.5f, 0.5f, -0.5f, 1, 0, 0, 1, 1, + 0.5f, -0.5f, 0.5f, 1, 0, 0, 0, 0, + 0.5f, 0.5f, -0.5f, 1, 0, 0, 1, 1, + 0.5f, 0.5f, 0.5f, 1, 0, 0, 0, 1 +}; + +std::vector<GLfloat> sphereVertexBufferData = { + 0.154509, 0.475528, 0, 0.309017, 0.951057, 0, 0, 0.9, + 0, 0.5, 0, 0, 1, 0, 0, 1, + 0, 0.5, 0, 0, 1, 0, 0.1, 1, + 0, 0.5, 0, 0, 1, 0, 0.1, 1, + 0.125, 0.475528, 0.0908178, 0.25, 0.951057, 0.181636, 0.1, 0.9, + 0.154509, 0.475528, 0, 0.309017, 0.951057, 0, 0, 0.9, + 0.293893, 0.404509, 0, 0.587785, 0.809017, 0, 0, 0.8, + 0.154509, 0.475528, 0, 0.309017, 0.951057, 0, 0, 0.9, + 0.125, 0.475528, 0.0908178, 0.25, 0.951057, 0.181636, 0.1, 0.9, + 0.125, 0.475528, 0.0908178, 0.25, 0.951057, 0.181636, 0.1, 0.9, + 0.237764, 0.404509, 0.172746, 0.475528, 0.809017, 0.345491, 0.1, 0.8, + 0.293893, 0.404509, 0, 0.587785, 0.809017, 0, 0, 0.8, + 0.404509, 0.293893, 0, 0.809017, 0.587785, 0, 0, 0.7, + 0.293893, 0.404509, 0, 0.587785, 0.809017, 0, 0, 0.8, + 0.237764, 0.404509, 0.172746, 0.475528, 0.809017, 0.345491, 0.1, 0.8, + 0.237764, 0.404509, 0.172746, 0.475528, 0.809017, 0.345491, 0.1, 0.8, + 0.327254, 0.293893, 0.237764, 0.654509, 0.587785, 0.475528, 0.1, 0.7, + 0.404509, 0.293893, 0, 0.809017, 0.587785, 0, 0, 0.7, + 0.475528, 0.154508, 0, 0.951057, 0.309017, 0, 0, 0.6, + 0.404509, 0.293893, 0, 0.809017, 0.587785, 0, 0, 0.7, + 0.327254, 0.293893, 0.237764, 0.654509, 0.587785, 0.475528, 0.1, 0.7, + 0.327254, 0.293893, 0.237764, 0.654509, 0.587785, 0.475528, 0.1, 0.7, + 0.38471, 0.154508, 0.279509, 0.769421, 0.309017, 0.559017, 0.1, 0.6, + 0.475528, 0.154508, 0, 0.951057, 0.309017, 0, 0, 0.6, + 0.5, -2.18557e-08, 0, 1, -4.37114e-08, 0, 0, 0.5, + 0.475528, 0.154508, 0, 0.951057, 0.309017, 0, 0, 0.6, + 0.38471, 0.154508, 0.279509, 0.769421, 0.309017, 0.559017, 0.1, 0.6, + 0.38471, 0.154508, 0.279509, 0.769421, 0.309017, 0.559017, 0.1, 0.6, + 0.404509, -2.18557e-08, 0.293893, 0.809017, -4.37114e-08, 0.587785, 0.1, 0.5, + 0.5, -2.18557e-08, 0, 1, -4.37114e-08, 0, 0, 0.5, + 0.475528, -0.154509, 0, 0.951057, -0.309017, 0, 0, 0.4, + 0.5, -2.18557e-08, 0, 1, -4.37114e-08, 0, 0, 0.5, + 0.404509, -2.18557e-08, 0.293893, 0.809017, -4.37114e-08, 0.587785, 0.1, 0.5, + 0.404509, -2.18557e-08, 0.293893, 0.809017, -4.37114e-08, 0.587785, 0.1, 0.5, + 0.38471, -0.154509, 0.279508, 0.769421, -0.309017, 0.559017, 0.1, 0.4, + 0.475528, -0.154509, 0, 0.951057, -0.309017, 0, 0, 0.4, + 0.404509, -0.293893, 0, 0.809017, -0.587785, 0, 0, 0.3, + 0.475528, -0.154509, 0, 0.951057, -0.309017, 0, 0, 0.4, + 0.38471, -0.154509, 0.279508, 0.769421, -0.309017, 0.559017, 0.1, 0.4, + 0.38471, -0.154509, 0.279508, 0.769421, -0.309017, 0.559017, 0.1, 0.4, + 0.327254, -0.293893, 0.237764, 0.654509, -0.587785, 0.475528, 0.1, 0.3, + 0.404509, -0.293893, 0, 0.809017, -0.587785, 0, 0, 0.3, + 0.293893, -0.404509, 0, 0.587785, -0.809017, 0, 0, 0.2, + 0.404509, -0.293893, 0, 0.809017, -0.587785, 0, 0, 0.3, + 0.327254, -0.293893, 0.237764, 0.654509, -0.587785, 0.475528, 0.1, 0.3, + 0.327254, -0.293893, 0.237764, 0.654509, -0.587785, 0.475528, 0.1, 0.3, + 0.237764, -0.404509, 0.172746, 0.475528, -0.809017, 0.345491, 0.1, 0.2, + 0.293893, -0.404509, 0, 0.587785, -0.809017, 0, 0, 0.2, + 0.154508, -0.475528, 0, 0.309017, -0.951057, 0, 0, 0.1, + 0.293893, -0.404509, 0, 0.587785, -0.809017, 0, 0, 0.2, + 0.237764, -0.404509, 0.172746, 0.475528, -0.809017, 0.345491, 0.1, 0.2, + 0.237764, -0.404509, 0.172746, 0.475528, -0.809017, 0.345491, 0.1, 0.2, + 0.125, -0.475528, 0.0908178, 0.25, -0.951057, 0.181636, 0.1, 0.1, + 0.154508, -0.475528, 0, 0.309017, -0.951057, 0, 0, 0.1, + -4.37114e-08, -0.5, -0, -8.74228e-08, -1, -0, 0, 0, + 0.154508, -0.475528, 0, 0.309017, -0.951057, 0, 0, 0.1, + 0.125, -0.475528, 0.0908178, 0.25, -0.951057, 0.181636, 0.1, 0.1, + 0.125, -0.475528, 0.0908178, 0.25, -0.951057, 0.181636, 0.1, 0.1, + -3.53633e-08, -0.5, -2.56929e-08, -7.07265e-08, -1, -5.13858e-08, 0.1, 0, + -4.37114e-08, -0.5, -0, -8.74228e-08, -1, -0, 0, 0, + 0.125, 0.475528, 0.0908178, 0.25, 0.951057, 0.181636, 0.1, 0.9, + 0, 0.5, 0, 0, 1, 0, 0.1, 1, + 0, 0.5, 0, 0, 1, 0, 0.2, 1, + 0, 0.5, 0, 0, 1, 0, 0.2, 1, + 0.0477457, 0.475528, 0.146946, 0.0954915, 0.951057, 0.293893, 0.2, 0.9, + 0.125, 0.475528, 0.0908178, 0.25, 0.951057, 0.181636, 0.1, 0.9, + 0.237764, 0.404509, 0.172746, 0.475528, 0.809017, 0.345491, 0.1, 0.8, + 0.125, 0.475528, 0.0908178, 0.25, 0.951057, 0.181636, 0.1, 0.9, + 0.0477457, 0.475528, 0.146946, 0.0954915, 0.951057, 0.293893, 0.2, 0.9, + 0.0477457, 0.475528, 0.146946, 0.0954915, 0.951057, 0.293893, 0.2, 0.9, + 0.0908178, 0.404509, 0.279509, 0.181636, 0.809017, 0.559017, 0.2, 0.8, + 0.237764, 0.404509, 0.172746, 0.475528, 0.809017, 0.345491, 0.1, 0.8, + 0.327254, 0.293893, 0.237764, 0.654509, 0.587785, 0.475528, 0.1, 0.7, + 0.237764, 0.404509, 0.172746, 0.475528, 0.809017, 0.345491, 0.1, 0.8, + 0.0908178, 0.404509, 0.279509, 0.181636, 0.809017, 0.559017, 0.2, 0.8, + 0.0908178, 0.404509, 0.279509, 0.181636, 0.809017, 0.559017, 0.2, 0.8, + 0.125, 0.293893, 0.38471, 0.25, 0.587785, 0.769421, 0.2, 0.7, + 0.327254, 0.293893, 0.237764, 0.654509, 0.587785, 0.475528, 0.1, 0.7, + 0.38471, 0.154508, 0.279509, 0.769421, 0.309017, 0.559017, 0.1, 0.6, + 0.327254, 0.293893, 0.237764, 0.654509, 0.587785, 0.475528, 0.1, 0.7, + 0.125, 0.293893, 0.38471, 0.25, 0.587785, 0.769421, 0.2, 0.7, + 0.125, 0.293893, 0.38471, 0.25, 0.587785, 0.769421, 0.2, 0.7, + 0.146946, 0.154508, 0.452254, 0.293893, 0.309017, 0.904509, 0.2, 0.6, + 0.38471, 0.154508, 0.279509, 0.769421, 0.309017, 0.559017, 0.1, 0.6, + 0.404509, -2.18557e-08, 0.293893, 0.809017, -4.37114e-08, 0.587785, 0.1, 0.5, + 0.38471, 0.154508, 0.279509, 0.769421, 0.309017, 0.559017, 0.1, 0.6, + 0.146946, 0.154508, 0.452254, 0.293893, 0.309017, 0.904509, 0.2, 0.6, + 0.146946, 0.154508, 0.452254, 0.293893, 0.309017, 0.904509, 0.2, 0.6, + 0.154508, -2.18557e-08, 0.475528, 0.309017, -4.37114e-08, 0.951057, 0.2, 0.5, + 0.404509, -2.18557e-08, 0.293893, 0.809017, -4.37114e-08, 0.587785, 0.1, 0.5, + 0.38471, -0.154509, 0.279508, 0.769421, -0.309017, 0.559017, 0.1, 0.4, + 0.404509, -2.18557e-08, 0.293893, 0.809017, -4.37114e-08, 0.587785, 0.1, 0.5, + 0.154508, -2.18557e-08, 0.475528, 0.309017, -4.37114e-08, 0.951057, 0.2, 0.5, + 0.154508, -2.18557e-08, 0.475528, 0.309017, -4.37114e-08, 0.951057, 0.2, 0.5, + 0.146946, -0.154509, 0.452254, 0.293893, -0.309017, 0.904509, 0.2, 0.4, + 0.38471, -0.154509, 0.279508, 0.769421, -0.309017, 0.559017, 0.1, 0.4, + 0.327254, -0.293893, 0.237764, 0.654509, -0.587785, 0.475528, 0.1, 0.3, + 0.38471, -0.154509, 0.279508, 0.769421, -0.309017, 0.559017, 0.1, 0.4, + 0.146946, -0.154509, 0.452254, 0.293893, -0.309017, 0.904509, 0.2, 0.4, + 0.146946, -0.154509, 0.452254, 0.293893, -0.309017, 0.904509, 0.2, 0.4, + 0.125, -0.293893, 0.38471, 0.25, -0.587785, 0.769421, 0.2, 0.3, + 0.327254, -0.293893, 0.237764, 0.654509, -0.587785, 0.475528, 0.1, 0.3, + 0.237764, -0.404509, 0.172746, 0.475528, -0.809017, 0.345491, 0.1, 0.2, + 0.327254, -0.293893, 0.237764, 0.654509, -0.587785, 0.475528, 0.1, 0.3, + 0.125, -0.293893, 0.38471, 0.25, -0.587785, 0.769421, 0.2, 0.3, + 0.125, -0.293893, 0.38471, 0.25, -0.587785, 0.769421, 0.2, 0.3, + 0.0908178, -0.404509, 0.279508, 0.181636, -0.809017, 0.559017, 0.2, 0.2, + 0.237764, -0.404509, 0.172746, 0.475528, -0.809017, 0.345491, 0.1, 0.2, + 0.125, -0.475528, 0.0908178, 0.25, -0.951057, 0.181636, 0.1, 0.1, + 0.237764, -0.404509, 0.172746, 0.475528, -0.809017, 0.345491, 0.1, 0.2, + 0.0908178, -0.404509, 0.279508, 0.181636, -0.809017, 0.559017, 0.2, 0.2, + 0.0908178, -0.404509, 0.279508, 0.181636, -0.809017, 0.559017, 0.2, 0.2, + 0.0477457, -0.475528, 0.146946, 0.0954914, -0.951057, 0.293892, 0.2, 0.1, + 0.125, -0.475528, 0.0908178, 0.25, -0.951057, 0.181636, 0.1, 0.1, + -3.53633e-08, -0.5, -2.56929e-08, -7.07265e-08, -1, -5.13858e-08, 0.1, 0, + 0.125, -0.475528, 0.0908178, 0.25, -0.951057, 0.181636, 0.1, 0.1, + 0.0477457, -0.475528, 0.146946, 0.0954914, -0.951057, 0.293892, 0.2, 0.1, + 0.0477457, -0.475528, 0.146946, 0.0954914, -0.951057, 0.293892, 0.2, 0.1, + -1.35076e-08, -0.5, -4.1572e-08, -2.70151e-08, -1, -8.3144e-08, 0.2, 0, + -3.53633e-08, -0.5, -2.56929e-08, -7.07265e-08, -1, -5.13858e-08, 0.1, 0, + 0.0477457, 0.475528, 0.146946, 0.0954915, 0.951057, 0.293893, 0.2, 0.9, + 0, 0.5, 0, 0, 1, 0, 0.2, 1, + -0, 0.5, 0, -0, 1, 0, 0.3, 1, + -0, 0.5, 0, -0, 1, 0, 0.3, 1, + -0.0477458, 0.475528, 0.146946, -0.0954915, 0.951057, 0.293893, 0.3, 0.9, + 0.0477457, 0.475528, 0.146946, 0.0954915, 0.951057, 0.293893, 0.2, 0.9, + 0.0908178, 0.404509, 0.279509, 0.181636, 0.809017, 0.559017, 0.2, 0.8, + 0.0477457, 0.475528, 0.146946, 0.0954915, 0.951057, 0.293893, 0.2, 0.9, + -0.0477458, 0.475528, 0.146946, -0.0954915, 0.951057, 0.293893, 0.3, 0.9, + -0.0477458, 0.475528, 0.146946, -0.0954915, 0.951057, 0.293893, 0.3, 0.9, + -0.0908178, 0.404509, 0.279508, -0.181636, 0.809017, 0.559017, 0.3, 0.8, + 0.0908178, 0.404509, 0.279509, 0.181636, 0.809017, 0.559017, 0.2, 0.8, + 0.125, 0.293893, 0.38471, 0.25, 0.587785, 0.769421, 0.2, 0.7, + 0.0908178, 0.404509, 0.279509, 0.181636, 0.809017, 0.559017, 0.2, 0.8, + -0.0908178, 0.404509, 0.279508, -0.181636, 0.809017, 0.559017, 0.3, 0.8, + -0.0908178, 0.404509, 0.279508, -0.181636, 0.809017, 0.559017, 0.3, 0.8, + -0.125, 0.293893, 0.38471, -0.25, 0.587785, 0.769421, 0.3, 0.7, + 0.125, 0.293893, 0.38471, 0.25, 0.587785, 0.769421, 0.2, 0.7, + 0.146946, 0.154508, 0.452254, 0.293893, 0.309017, 0.904509, 0.2, 0.6, + 0.125, 0.293893, 0.38471, 0.25, 0.587785, 0.769421, 0.2, 0.7, + -0.125, 0.293893, 0.38471, -0.25, 0.587785, 0.769421, 0.3, 0.7, + -0.125, 0.293893, 0.38471, -0.25, 0.587785, 0.769421, 0.3, 0.7, + -0.146946, 0.154508, 0.452254, -0.293893, 0.309017, 0.904508, 0.3, 0.6, + 0.146946, 0.154508, 0.452254, 0.293893, 0.309017, 0.904509, 0.2, 0.6, + 0.154508, -2.18557e-08, 0.475528, 0.309017, -4.37114e-08, 0.951057, 0.2, 0.5, + 0.146946, 0.154508, 0.452254, 0.293893, 0.309017, 0.904509, 0.2, 0.6, + -0.146946, 0.154508, 0.452254, -0.293893, 0.309017, 0.904508, 0.3, 0.6, + -0.146946, 0.154508, 0.452254, -0.293893, 0.309017, 0.904508, 0.3, 0.6, + -0.154509, -2.18557e-08, 0.475528, -0.309017, -4.37114e-08, 0.951057, 0.3, 0.5, + 0.154508, -2.18557e-08, 0.475528, 0.309017, -4.37114e-08, 0.951057, 0.2, 0.5, + 0.146946, -0.154509, 0.452254, 0.293893, -0.309017, 0.904509, 0.2, 0.4, + 0.154508, -2.18557e-08, 0.475528, 0.309017, -4.37114e-08, 0.951057, 0.2, 0.5, + -0.154509, -2.18557e-08, 0.475528, -0.309017, -4.37114e-08, 0.951057, 0.3, 0.5, + -0.154509, -2.18557e-08, 0.475528, -0.309017, -4.37114e-08, 0.951057, 0.3, 0.5, + -0.146946, -0.154509, 0.452254, -0.293893, -0.309017, 0.904509, 0.3, 0.4, + 0.146946, -0.154509, 0.452254, 0.293893, -0.309017, 0.904509, 0.2, 0.4, + 0.125, -0.293893, 0.38471, 0.25, -0.587785, 0.769421, 0.2, 0.3, + 0.146946, -0.154509, 0.452254, 0.293893, -0.309017, 0.904509, 0.2, 0.4, + -0.146946, -0.154509, 0.452254, -0.293893, -0.309017, 0.904509, 0.3, 0.4, + -0.146946, -0.154509, 0.452254, -0.293893, -0.309017, 0.904509, 0.3, 0.4, + -0.125, -0.293893, 0.38471, -0.25, -0.587785, 0.769421, 0.3, 0.3, + 0.125, -0.293893, 0.38471, 0.25, -0.587785, 0.769421, 0.2, 0.3, + 0.0908178, -0.404509, 0.279508, 0.181636, -0.809017, 0.559017, 0.2, 0.2, + 0.125, -0.293893, 0.38471, 0.25, -0.587785, 0.769421, 0.2, 0.3, + -0.125, -0.293893, 0.38471, -0.25, -0.587785, 0.769421, 0.3, 0.3, + -0.125, -0.293893, 0.38471, -0.25, -0.587785, 0.769421, 0.3, 0.3, + -0.0908178, -0.404509, 0.279508, -0.181636, -0.809017, 0.559017, 0.3, 0.2, + 0.0908178, -0.404509, 0.279508, 0.181636, -0.809017, 0.559017, 0.2, 0.2, + 0.0477457, -0.475528, 0.146946, 0.0954914, -0.951057, 0.293892, 0.2, 0.1, + 0.0908178, -0.404509, 0.279508, 0.181636, -0.809017, 0.559017, 0.2, 0.2, + -0.0908178, -0.404509, 0.279508, -0.181636, -0.809017, 0.559017, 0.3, 0.2, + -0.0908178, -0.404509, 0.279508, -0.181636, -0.809017, 0.559017, 0.3, 0.2, + -0.0477457, -0.475528, 0.146946, -0.0954915, -0.951057, 0.293892, 0.3, 0.1, + 0.0477457, -0.475528, 0.146946, 0.0954914, -0.951057, 0.293892, 0.2, 0.1, + -1.35076e-08, -0.5, -4.1572e-08, -2.70151e-08, -1, -8.3144e-08, 0.2, 0, + 0.0477457, -0.475528, 0.146946, 0.0954914, -0.951057, 0.293892, 0.2, 0.1, + -0.0477457, -0.475528, 0.146946, -0.0954915, -0.951057, 0.293892, 0.3, 0.1, + -0.0477457, -0.475528, 0.146946, -0.0954915, -0.951057, 0.293892, 0.3, 0.1, + 1.35076e-08, -0.5, -4.1572e-08, 2.70151e-08, -1, -8.3144e-08, 0.3, 0, + -1.35076e-08, -0.5, -4.1572e-08, -2.70151e-08, -1, -8.3144e-08, 0.2, 0, + -0.0477458, 0.475528, 0.146946, -0.0954915, 0.951057, 0.293893, 0.3, 0.9, + -0, 0.5, 0, -0, 1, 0, 0.3, 1, + -0, 0.5, 0, -0, 1, 0, 0.4, 1, + -0, 0.5, 0, -0, 1, 0, 0.4, 1, + -0.125, 0.475528, 0.0908178, -0.25, 0.951057, 0.181636, 0.4, 0.9, + -0.0477458, 0.475528, 0.146946, -0.0954915, 0.951057, 0.293893, 0.3, 0.9, + -0.0908178, 0.404509, 0.279508, -0.181636, 0.809017, 0.559017, 0.3, 0.8, + -0.0477458, 0.475528, 0.146946, -0.0954915, 0.951057, 0.293893, 0.3, 0.9, + -0.125, 0.475528, 0.0908178, -0.25, 0.951057, 0.181636, 0.4, 0.9, + -0.125, 0.475528, 0.0908178, -0.25, 0.951057, 0.181636, 0.4, 0.9, + -0.237764, 0.404509, 0.172746, -0.475528, 0.809017, 0.345491, 0.4, 0.8, + -0.0908178, 0.404509, 0.279508, -0.181636, 0.809017, 0.559017, 0.3, 0.8, + -0.125, 0.293893, 0.38471, -0.25, 0.587785, 0.769421, 0.3, 0.7, + -0.0908178, 0.404509, 0.279508, -0.181636, 0.809017, 0.559017, 0.3, 0.8, + -0.237764, 0.404509, 0.172746, -0.475528, 0.809017, 0.345491, 0.4, 0.8, + -0.237764, 0.404509, 0.172746, -0.475528, 0.809017, 0.345491, 0.4, 0.8, + -0.327254, 0.293893, 0.237764, -0.654509, 0.587785, 0.475528, 0.4, 0.7, + -0.125, 0.293893, 0.38471, -0.25, 0.587785, 0.769421, 0.3, 0.7, + -0.146946, 0.154508, 0.452254, -0.293893, 0.309017, 0.904508, 0.3, 0.6, + -0.125, 0.293893, 0.38471, -0.25, 0.587785, 0.769421, 0.3, 0.7, + -0.327254, 0.293893, 0.237764, -0.654509, 0.587785, 0.475528, 0.4, 0.7, + -0.327254, 0.293893, 0.237764, -0.654509, 0.587785, 0.475528, 0.4, 0.7, + -0.38471, 0.154508, 0.279508, -0.769421, 0.309017, 0.559017, 0.4, 0.6, + -0.146946, 0.154508, 0.452254, -0.293893, 0.309017, 0.904508, 0.3, 0.6, + -0.154509, -2.18557e-08, 0.475528, -0.309017, -4.37114e-08, 0.951057, 0.3, 0.5, + -0.146946, 0.154508, 0.452254, -0.293893, 0.309017, 0.904508, 0.3, 0.6, + -0.38471, 0.154508, 0.279508, -0.769421, 0.309017, 0.559017, 0.4, 0.6, + -0.38471, 0.154508, 0.279508, -0.769421, 0.309017, 0.559017, 0.4, 0.6, + -0.404509, -2.18557e-08, 0.293893, -0.809017, -4.37114e-08, 0.587785, 0.4, 0.5, + -0.154509, -2.18557e-08, 0.475528, -0.309017, -4.37114e-08, 0.951057, 0.3, 0.5, + -0.146946, -0.154509, 0.452254, -0.293893, -0.309017, 0.904509, 0.3, 0.4, + -0.154509, -2.18557e-08, 0.475528, -0.309017, -4.37114e-08, 0.951057, 0.3, 0.5, + -0.404509, -2.18557e-08, 0.293893, -0.809017, -4.37114e-08, 0.587785, 0.4, 0.5, + -0.404509, -2.18557e-08, 0.293893, -0.809017, -4.37114e-08, 0.587785, 0.4, 0.5, + -0.38471, -0.154509, 0.279508, -0.769421, -0.309017, 0.559017, 0.4, 0.4, + -0.146946, -0.154509, 0.452254, -0.293893, -0.309017, 0.904509, 0.3, 0.4, + -0.125, -0.293893, 0.38471, -0.25, -0.587785, 0.769421, 0.3, 0.3, + -0.146946, -0.154509, 0.452254, -0.293893, -0.309017, 0.904509, 0.3, 0.4, + -0.38471, -0.154509, 0.279508, -0.769421, -0.309017, 0.559017, 0.4, 0.4, + -0.38471, -0.154509, 0.279508, -0.769421, -0.309017, 0.559017, 0.4, 0.4, + -0.327254, -0.293893, 0.237764, -0.654509, -0.587785, 0.475528, 0.4, 0.3, + -0.125, -0.293893, 0.38471, -0.25, -0.587785, 0.769421, 0.3, 0.3, + -0.0908178, -0.404509, 0.279508, -0.181636, -0.809017, 0.559017, 0.3, 0.2, + -0.125, -0.293893, 0.38471, -0.25, -0.587785, 0.769421, 0.3, 0.3, + -0.327254, -0.293893, 0.237764, -0.654509, -0.587785, 0.475528, 0.4, 0.3, + -0.327254, -0.293893, 0.237764, -0.654509, -0.587785, 0.475528, 0.4, 0.3, + -0.237764, -0.404509, 0.172746, -0.475528, -0.809017, 0.345491, 0.4, 0.2, + -0.0908178, -0.404509, 0.279508, -0.181636, -0.809017, 0.559017, 0.3, 0.2, + -0.0477457, -0.475528, 0.146946, -0.0954915, -0.951057, 0.293892, 0.3, 0.1, + -0.0908178, -0.404509, 0.279508, -0.181636, -0.809017, 0.559017, 0.3, 0.2, + -0.237764, -0.404509, 0.172746, -0.475528, -0.809017, 0.345491, 0.4, 0.2, + -0.237764, -0.404509, 0.172746, -0.475528, -0.809017, 0.345491, 0.4, 0.2, + -0.125, -0.475528, 0.0908177, -0.25, -0.951057, 0.181635, 0.4, 0.1, + -0.0477457, -0.475528, 0.146946, -0.0954915, -0.951057, 0.293892, 0.3, 0.1, + 1.35076e-08, -0.5, -4.1572e-08, 2.70151e-08, -1, -8.3144e-08, 0.3, 0, + -0.0477457, -0.475528, 0.146946, -0.0954915, -0.951057, 0.293892, 0.3, 0.1, + -0.125, -0.475528, 0.0908177, -0.25, -0.951057, 0.181635, 0.4, 0.1, + -0.125, -0.475528, 0.0908177, -0.25, -0.951057, 0.181635, 0.4, 0.1, + 3.53633e-08, -0.5, -2.56929e-08, 7.07265e-08, -1, -5.13858e-08, 0.4, 0, + 1.35076e-08, -0.5, -4.1572e-08, 2.70151e-08, -1, -8.3144e-08, 0.3, 0, + -0.125, 0.475528, 0.0908178, -0.25, 0.951057, 0.181636, 0.4, 0.9, + -0, 0.5, 0, -0, 1, 0, 0.4, 1, + -0, 0.5, -0, -0, 1, -0, 0.5, 1, + -0, 0.5, -0, -0, 1, -0, 0.5, 1, + -0.154509, 0.475528, -1.35076e-08, -0.309017, 0.951057, -2.70151e-08, 0.5, 0.9, + -0.125, 0.475528, 0.0908178, -0.25, 0.951057, 0.181636, 0.4, 0.9, + -0.237764, 0.404509, 0.172746, -0.475528, 0.809017, 0.345491, 0.4, 0.8, + -0.125, 0.475528, 0.0908178, -0.25, 0.951057, 0.181636, 0.4, 0.9, + -0.154509, 0.475528, -1.35076e-08, -0.309017, 0.951057, -2.70151e-08, 0.5, 0.9, + -0.154509, 0.475528, -1.35076e-08, -0.309017, 0.951057, -2.70151e-08, 0.5, 0.9, + -0.293893, 0.404509, -2.56929e-08, -0.587785, 0.809017, -5.13858e-08, 0.5, 0.8, + -0.237764, 0.404509, 0.172746, -0.475528, 0.809017, 0.345491, 0.4, 0.8, + -0.327254, 0.293893, 0.237764, -0.654509, 0.587785, 0.475528, 0.4, 0.7, + -0.237764, 0.404509, 0.172746, -0.475528, 0.809017, 0.345491, 0.4, 0.8, + -0.293893, 0.404509, -2.56929e-08, -0.587785, 0.809017, -5.13858e-08, 0.5, 0.8, + -0.293893, 0.404509, -2.56929e-08, -0.587785, 0.809017, -5.13858e-08, 0.5, 0.8, + -0.404509, 0.293893, -3.53633e-08, -0.809017, 0.587785, -7.07265e-08, 0.5, 0.7, + -0.327254, 0.293893, 0.237764, -0.654509, 0.587785, 0.475528, 0.4, 0.7, + -0.38471, 0.154508, 0.279508, -0.769421, 0.309017, 0.559017, 0.4, 0.6, + -0.327254, 0.293893, 0.237764, -0.654509, 0.587785, 0.475528, 0.4, 0.7, + -0.404509, 0.293893, -3.53633e-08, -0.809017, 0.587785, -7.07265e-08, 0.5, 0.7, + -0.404509, 0.293893, -3.53633e-08, -0.809017, 0.587785, -7.07265e-08, 0.5, 0.7, + -0.475528, 0.154508, -4.1572e-08, -0.951057, 0.309017, -8.3144e-08, 0.5, 0.6, + -0.38471, 0.154508, 0.279508, -0.769421, 0.309017, 0.559017, 0.4, 0.6, + -0.404509, -2.18557e-08, 0.293893, -0.809017, -4.37114e-08, 0.587785, 0.4, 0.5, + -0.38471, 0.154508, 0.279508, -0.769421, 0.309017, 0.559017, 0.4, 0.6, + -0.475528, 0.154508, -4.1572e-08, -0.951057, 0.309017, -8.3144e-08, 0.5, 0.6, + -0.475528, 0.154508, -4.1572e-08, -0.951057, 0.309017, -8.3144e-08, 0.5, 0.6, + -0.5, -2.18557e-08, -4.37114e-08, -1, -4.37114e-08, -8.74228e-08, 0.5, 0.5, + -0.404509, -2.18557e-08, 0.293893, -0.809017, -4.37114e-08, 0.587785, 0.4, 0.5, + -0.38471, -0.154509, 0.279508, -0.769421, -0.309017, 0.559017, 0.4, 0.4, + -0.404509, -2.18557e-08, 0.293893, -0.809017, -4.37114e-08, 0.587785, 0.4, 0.5, + -0.5, -2.18557e-08, -4.37114e-08, -1, -4.37114e-08, -8.74228e-08, 0.5, 0.5, + -0.5, -2.18557e-08, -4.37114e-08, -1, -4.37114e-08, -8.74228e-08, 0.5, 0.5, + -0.475528, -0.154509, -4.1572e-08, -0.951057, -0.309017, -8.3144e-08, 0.5, 0.4, + -0.38471, -0.154509, 0.279508, -0.769421, -0.309017, 0.559017, 0.4, 0.4, + -0.327254, -0.293893, 0.237764, -0.654509, -0.587785, 0.475528, 0.4, 0.3, + -0.38471, -0.154509, 0.279508, -0.769421, -0.309017, 0.559017, 0.4, 0.4, + -0.475528, -0.154509, -4.1572e-08, -0.951057, -0.309017, -8.3144e-08, 0.5, 0.4, + -0.475528, -0.154509, -4.1572e-08, -0.951057, -0.309017, -8.3144e-08, 0.5, 0.4, + -0.404509, -0.293893, -3.53633e-08, -0.809017, -0.587785, -7.07265e-08, 0.5, 0.3, + -0.327254, -0.293893, 0.237764, -0.654509, -0.587785, 0.475528, 0.4, 0.3, + -0.237764, -0.404509, 0.172746, -0.475528, -0.809017, 0.345491, 0.4, 0.2, + -0.327254, -0.293893, 0.237764, -0.654509, -0.587785, 0.475528, 0.4, 0.3, + -0.404509, -0.293893, -3.53633e-08, -0.809017, -0.587785, -7.07265e-08, 0.5, 0.3, + -0.404509, -0.293893, -3.53633e-08, -0.809017, -0.587785, -7.07265e-08, 0.5, 0.3, + -0.293893, -0.404509, -2.56929e-08, -0.587785, -0.809017, -5.13858e-08, 0.5, 0.2, + -0.237764, -0.404509, 0.172746, -0.475528, -0.809017, 0.345491, 0.4, 0.2, + -0.125, -0.475528, 0.0908177, -0.25, -0.951057, 0.181635, 0.4, 0.1, + -0.237764, -0.404509, 0.172746, -0.475528, -0.809017, 0.345491, 0.4, 0.2, + -0.293893, -0.404509, -2.56929e-08, -0.587785, -0.809017, -5.13858e-08, 0.5, 0.2, + -0.293893, -0.404509, -2.56929e-08, -0.587785, -0.809017, -5.13858e-08, 0.5, 0.2, + -0.154508, -0.475528, -1.35076e-08, -0.309017, -0.951057, -2.70151e-08, 0.5, 0.1, + -0.125, -0.475528, 0.0908177, -0.25, -0.951057, 0.181635, 0.4, 0.1, + 3.53633e-08, -0.5, -2.56929e-08, 7.07265e-08, -1, -5.13858e-08, 0.4, 0, + -0.125, -0.475528, 0.0908177, -0.25, -0.951057, 0.181635, 0.4, 0.1, + -0.154508, -0.475528, -1.35076e-08, -0.309017, -0.951057, -2.70151e-08, 0.5, 0.1, + -0.154508, -0.475528, -1.35076e-08, -0.309017, -0.951057, -2.70151e-08, 0.5, 0.1, + 4.37114e-08, -0.5, 3.82137e-15, 8.74228e-08, -1, 7.64274e-15, 0.5, 0, + 3.53633e-08, -0.5, -2.56929e-08, 7.07265e-08, -1, -5.13858e-08, 0.4, 0, + -0.154509, 0.475528, -1.35076e-08, -0.309017, 0.951057, -2.70151e-08, 0.5, 0.9, + -0, 0.5, -0, -0, 1, -0, 0.5, 1, + -0, 0.5, -0, -0, 1, -0, 0.6, 1, + -0, 0.5, -0, -0, 1, -0, 0.6, 1, + -0.125, 0.475528, -0.0908178, -0.25, 0.951057, -0.181636, 0.6, 0.9, + -0.154509, 0.475528, -1.35076e-08, -0.309017, 0.951057, -2.70151e-08, 0.5, 0.9, + -0.293893, 0.404509, -2.56929e-08, -0.587785, 0.809017, -5.13858e-08, 0.5, 0.8, + -0.154509, 0.475528, -1.35076e-08, -0.309017, 0.951057, -2.70151e-08, 0.5, 0.9, + -0.125, 0.475528, -0.0908178, -0.25, 0.951057, -0.181636, 0.6, 0.9, + -0.125, 0.475528, -0.0908178, -0.25, 0.951057, -0.181636, 0.6, 0.9, + -0.237764, 0.404509, -0.172746, -0.475528, 0.809017, -0.345492, 0.6, 0.8, + -0.293893, 0.404509, -2.56929e-08, -0.587785, 0.809017, -5.13858e-08, 0.5, 0.8, + -0.404509, 0.293893, -3.53633e-08, -0.809017, 0.587785, -7.07265e-08, 0.5, 0.7, + -0.293893, 0.404509, -2.56929e-08, -0.587785, 0.809017, -5.13858e-08, 0.5, 0.8, + -0.237764, 0.404509, -0.172746, -0.475528, 0.809017, -0.345492, 0.6, 0.8, + -0.237764, 0.404509, -0.172746, -0.475528, 0.809017, -0.345492, 0.6, 0.8, + -0.327254, 0.293893, -0.237764, -0.654508, 0.587785, -0.475528, 0.6, 0.7, + -0.404509, 0.293893, -3.53633e-08, -0.809017, 0.587785, -7.07265e-08, 0.5, 0.7, + -0.475528, 0.154508, -4.1572e-08, -0.951057, 0.309017, -8.3144e-08, 0.5, 0.6, + -0.404509, 0.293893, -3.53633e-08, -0.809017, 0.587785, -7.07265e-08, 0.5, 0.7, + -0.327254, 0.293893, -0.237764, -0.654508, 0.587785, -0.475528, 0.6, 0.7, + -0.327254, 0.293893, -0.237764, -0.654508, 0.587785, -0.475528, 0.6, 0.7, + -0.38471, 0.154508, -0.279509, -0.769421, 0.309017, -0.559017, 0.6, 0.6, + -0.475528, 0.154508, -4.1572e-08, -0.951057, 0.309017, -8.3144e-08, 0.5, 0.6, + -0.5, -2.18557e-08, -4.37114e-08, -1, -4.37114e-08, -8.74228e-08, 0.5, 0.5, + -0.475528, 0.154508, -4.1572e-08, -0.951057, 0.309017, -8.3144e-08, 0.5, 0.6, + -0.38471, 0.154508, -0.279509, -0.769421, 0.309017, -0.559017, 0.6, 0.6, + -0.38471, 0.154508, -0.279509, -0.769421, 0.309017, -0.559017, 0.6, 0.6, + -0.404508, -2.18557e-08, -0.293893, -0.809017, -4.37114e-08, -0.587785, 0.6, 0.5, + -0.5, -2.18557e-08, -4.37114e-08, -1, -4.37114e-08, -8.74228e-08, 0.5, 0.5, + -0.475528, -0.154509, -4.1572e-08, -0.951057, -0.309017, -8.3144e-08, 0.5, 0.4, + -0.5, -2.18557e-08, -4.37114e-08, -1, -4.37114e-08, -8.74228e-08, 0.5, 0.5, + -0.404508, -2.18557e-08, -0.293893, -0.809017, -4.37114e-08, -0.587785, 0.6, 0.5, + -0.404508, -2.18557e-08, -0.293893, -0.809017, -4.37114e-08, -0.587785, 0.6, 0.5, + -0.38471, -0.154509, -0.279509, -0.769421, -0.309017, -0.559017, 0.6, 0.4, + -0.475528, -0.154509, -4.1572e-08, -0.951057, -0.309017, -8.3144e-08, 0.5, 0.4, + -0.404509, -0.293893, -3.53633e-08, -0.809017, -0.587785, -7.07265e-08, 0.5, 0.3, + -0.475528, -0.154509, -4.1572e-08, -0.951057, -0.309017, -8.3144e-08, 0.5, 0.4, + -0.38471, -0.154509, -0.279509, -0.769421, -0.309017, -0.559017, 0.6, 0.4, + -0.38471, -0.154509, -0.279509, -0.769421, -0.309017, -0.559017, 0.6, 0.4, + -0.327254, -0.293893, -0.237764, -0.654509, -0.587785, -0.475528, 0.6, 0.3, + -0.404509, -0.293893, -3.53633e-08, -0.809017, -0.587785, -7.07265e-08, 0.5, 0.3, + -0.293893, -0.404509, -2.56929e-08, -0.587785, -0.809017, -5.13858e-08, 0.5, 0.2, + -0.404509, -0.293893, -3.53633e-08, -0.809017, -0.587785, -7.07265e-08, 0.5, 0.3, + -0.327254, -0.293893, -0.237764, -0.654509, -0.587785, -0.475528, 0.6, 0.3, + -0.327254, -0.293893, -0.237764, -0.654509, -0.587785, -0.475528, 0.6, 0.3, + -0.237764, -0.404509, -0.172746, -0.475528, -0.809017, -0.345492, 0.6, 0.2, + -0.293893, -0.404509, -2.56929e-08, -0.587785, -0.809017, -5.13858e-08, 0.5, 0.2, + -0.154508, -0.475528, -1.35076e-08, -0.309017, -0.951057, -2.70151e-08, 0.5, 0.1, + -0.293893, -0.404509, -2.56929e-08, -0.587785, -0.809017, -5.13858e-08, 0.5, 0.2, + -0.237764, -0.404509, -0.172746, -0.475528, -0.809017, -0.345492, 0.6, 0.2, + -0.237764, -0.404509, -0.172746, -0.475528, -0.809017, -0.345492, 0.6, 0.2, + -0.125, -0.475528, -0.0908178, -0.25, -0.951057, -0.181636, 0.6, 0.1, + -0.154508, -0.475528, -1.35076e-08, -0.309017, -0.951057, -2.70151e-08, 0.5, 0.1, + 4.37114e-08, -0.5, 3.82137e-15, 8.74228e-08, -1, 7.64274e-15, 0.5, 0, + -0.154508, -0.475528, -1.35076e-08, -0.309017, -0.951057, -2.70151e-08, 0.5, 0.1, + -0.125, -0.475528, -0.0908178, -0.25, -0.951057, -0.181636, 0.6, 0.1, + -0.125, -0.475528, -0.0908178, -0.25, -0.951057, -0.181636, 0.6, 0.1, + 3.53633e-08, -0.5, 2.56929e-08, 7.07265e-08, -1, 5.13858e-08, 0.6, 0, + 4.37114e-08, -0.5, 3.82137e-15, 8.74228e-08, -1, 7.64274e-15, 0.5, 0, + -0.125, 0.475528, -0.0908178, -0.25, 0.951057, -0.181636, 0.6, 0.9, + -0, 0.5, -0, -0, 1, -0, 0.6, 1, + -0, 0.5, -0, -0, 1, -0, 0.7, 1, + -0, 0.5, -0, -0, 1, -0, 0.7, 1, + -0.0477458, 0.475528, -0.146946, -0.0954915, 0.951057, -0.293893, 0.7, 0.9, + -0.125, 0.475528, -0.0908178, -0.25, 0.951057, -0.181636, 0.6, 0.9, + -0.237764, 0.404509, -0.172746, -0.475528, 0.809017, -0.345492, 0.6, 0.8, + -0.125, 0.475528, -0.0908178, -0.25, 0.951057, -0.181636, 0.6, 0.9, + -0.0477458, 0.475528, -0.146946, -0.0954915, 0.951057, -0.293893, 0.7, 0.9, + -0.0477458, 0.475528, -0.146946, -0.0954915, 0.951057, -0.293893, 0.7, 0.9, + -0.0908178, 0.404509, -0.279508, -0.181636, 0.809017, -0.559017, 0.7, 0.8, + -0.237764, 0.404509, -0.172746, -0.475528, 0.809017, -0.345492, 0.6, 0.8, + -0.327254, 0.293893, -0.237764, -0.654508, 0.587785, -0.475528, 0.6, 0.7, + -0.237764, 0.404509, -0.172746, -0.475528, 0.809017, -0.345492, 0.6, 0.8, + -0.0908178, 0.404509, -0.279508, -0.181636, 0.809017, -0.559017, 0.7, 0.8, + -0.0908178, 0.404509, -0.279508, -0.181636, 0.809017, -0.559017, 0.7, 0.8, + -0.125, 0.293893, -0.38471, -0.25, 0.587785, -0.769421, 0.7, 0.7, + -0.327254, 0.293893, -0.237764, -0.654508, 0.587785, -0.475528, 0.6, 0.7, + -0.38471, 0.154508, -0.279509, -0.769421, 0.309017, -0.559017, 0.6, 0.6, + -0.327254, 0.293893, -0.237764, -0.654508, 0.587785, -0.475528, 0.6, 0.7, + -0.125, 0.293893, -0.38471, -0.25, 0.587785, -0.769421, 0.7, 0.7, + -0.125, 0.293893, -0.38471, -0.25, 0.587785, -0.769421, 0.7, 0.7, + -0.146946, 0.154508, -0.452254, -0.293893, 0.309017, -0.904508, 0.7, 0.6, + -0.38471, 0.154508, -0.279509, -0.769421, 0.309017, -0.559017, 0.6, 0.6, + -0.404508, -2.18557e-08, -0.293893, -0.809017, -4.37114e-08, -0.587785, 0.6, 0.5, + -0.38471, 0.154508, -0.279509, -0.769421, 0.309017, -0.559017, 0.6, 0.6, + -0.146946, 0.154508, -0.452254, -0.293893, 0.309017, -0.904508, 0.7, 0.6, + -0.146946, 0.154508, -0.452254, -0.293893, 0.309017, -0.904508, 0.7, 0.6, + -0.154509, -2.18557e-08, -0.475528, -0.309017, -4.37114e-08, -0.951056, 0.7, 0.5, + -0.404508, -2.18557e-08, -0.293893, -0.809017, -4.37114e-08, -0.587785, 0.6, 0.5, + -0.38471, -0.154509, -0.279509, -0.769421, -0.309017, -0.559017, 0.6, 0.4, + -0.404508, -2.18557e-08, -0.293893, -0.809017, -4.37114e-08, -0.587785, 0.6, 0.5, + -0.154509, -2.18557e-08, -0.475528, -0.309017, -4.37114e-08, -0.951056, 0.7, 0.5, + -0.154509, -2.18557e-08, -0.475528, -0.309017, -4.37114e-08, -0.951056, 0.7, 0.5, + -0.146946, -0.154509, -0.452254, -0.293893, -0.309017, -0.904509, 0.7, 0.4, + -0.38471, -0.154509, -0.279509, -0.769421, -0.309017, -0.559017, 0.6, 0.4, + -0.327254, -0.293893, -0.237764, -0.654509, -0.587785, -0.475528, 0.6, 0.3, + -0.38471, -0.154509, -0.279509, -0.769421, -0.309017, -0.559017, 0.6, 0.4, + -0.146946, -0.154509, -0.452254, -0.293893, -0.309017, -0.904509, 0.7, 0.4, + -0.146946, -0.154509, -0.452254, -0.293893, -0.309017, -0.904509, 0.7, 0.4, + -0.125, -0.293893, -0.38471, -0.25, -0.587785, -0.769421, 0.7, 0.3, + -0.327254, -0.293893, -0.237764, -0.654509, -0.587785, -0.475528, 0.6, 0.3, + -0.237764, -0.404509, -0.172746, -0.475528, -0.809017, -0.345492, 0.6, 0.2, + -0.327254, -0.293893, -0.237764, -0.654509, -0.587785, -0.475528, 0.6, 0.3, + -0.125, -0.293893, -0.38471, -0.25, -0.587785, -0.769421, 0.7, 0.3, + -0.125, -0.293893, -0.38471, -0.25, -0.587785, -0.769421, 0.7, 0.3, + -0.0908178, -0.404509, -0.279508, -0.181636, -0.809017, -0.559017, 0.7, 0.2, + -0.237764, -0.404509, -0.172746, -0.475528, -0.809017, -0.345492, 0.6, 0.2, + -0.125, -0.475528, -0.0908178, -0.25, -0.951057, -0.181636, 0.6, 0.1, + -0.237764, -0.404509, -0.172746, -0.475528, -0.809017, -0.345492, 0.6, 0.2, + -0.0908178, -0.404509, -0.279508, -0.181636, -0.809017, -0.559017, 0.7, 0.2, + -0.0908178, -0.404509, -0.279508, -0.181636, -0.809017, -0.559017, 0.7, 0.2, + -0.0477457, -0.475528, -0.146946, -0.0954915, -0.951057, -0.293892, 0.7, 0.1, + -0.125, -0.475528, -0.0908178, -0.25, -0.951057, -0.181636, 0.6, 0.1, + 3.53633e-08, -0.5, 2.56929e-08, 7.07265e-08, -1, 5.13858e-08, 0.6, 0, + -0.125, -0.475528, -0.0908178, -0.25, -0.951057, -0.181636, 0.6, 0.1, + -0.0477457, -0.475528, -0.146946, -0.0954915, -0.951057, -0.293892, 0.7, 0.1, + -0.0477457, -0.475528, -0.146946, -0.0954915, -0.951057, -0.293892, 0.7, 0.1, + 1.35076e-08, -0.5, 4.1572e-08, 2.70151e-08, -1, 8.3144e-08, 0.7, 0, + 3.53633e-08, -0.5, 2.56929e-08, 7.07265e-08, -1, 5.13858e-08, 0.6, 0, + -0.0477458, 0.475528, -0.146946, -0.0954915, 0.951057, -0.293893, 0.7, 0.9, + -0, 0.5, -0, -0, 1, -0, 0.7, 1, + 0, 0.5, -0, 0, 1, -0, 0.8, 1, + 0, 0.5, -0, 0, 1, -0, 0.8, 1, + 0.0477458, 0.475528, -0.146946, 0.0954915, 0.951057, -0.293893, 0.8, 0.9, + -0.0477458, 0.475528, -0.146946, -0.0954915, 0.951057, -0.293893, 0.7, 0.9, + -0.0908178, 0.404509, -0.279508, -0.181636, 0.809017, -0.559017, 0.7, 0.8, + -0.0477458, 0.475528, -0.146946, -0.0954915, 0.951057, -0.293893, 0.7, 0.9, + 0.0477458, 0.475528, -0.146946, 0.0954915, 0.951057, -0.293893, 0.8, 0.9, + 0.0477458, 0.475528, -0.146946, 0.0954915, 0.951057, -0.293893, 0.8, 0.9, + 0.0908179, 0.404509, -0.279508, 0.181636, 0.809017, -0.559017, 0.8, 0.8, + -0.0908178, 0.404509, -0.279508, -0.181636, 0.809017, -0.559017, 0.7, 0.8, + -0.125, 0.293893, -0.38471, -0.25, 0.587785, -0.769421, 0.7, 0.7, + -0.0908178, 0.404509, -0.279508, -0.181636, 0.809017, -0.559017, 0.7, 0.8, + 0.0908179, 0.404509, -0.279508, 0.181636, 0.809017, -0.559017, 0.8, 0.8, + 0.0908179, 0.404509, -0.279508, 0.181636, 0.809017, -0.559017, 0.8, 0.8, + 0.125, 0.293893, -0.38471, 0.25, 0.587785, -0.769421, 0.8, 0.7, + -0.125, 0.293893, -0.38471, -0.25, 0.587785, -0.769421, 0.7, 0.7, + -0.146946, 0.154508, -0.452254, -0.293893, 0.309017, -0.904508, 0.7, 0.6, + -0.125, 0.293893, -0.38471, -0.25, 0.587785, -0.769421, 0.7, 0.7, + 0.125, 0.293893, -0.38471, 0.25, 0.587785, -0.769421, 0.8, 0.7, + 0.125, 0.293893, -0.38471, 0.25, 0.587785, -0.769421, 0.8, 0.7, + 0.146946, 0.154508, -0.452254, 0.293893, 0.309017, -0.904508, 0.8, 0.6, + -0.146946, 0.154508, -0.452254, -0.293893, 0.309017, -0.904508, 0.7, 0.6, + -0.154509, -2.18557e-08, -0.475528, -0.309017, -4.37114e-08, -0.951056, 0.7, 0.5, + -0.146946, 0.154508, -0.452254, -0.293893, 0.309017, -0.904508, 0.7, 0.6, + 0.146946, 0.154508, -0.452254, 0.293893, 0.309017, -0.904508, 0.8, 0.6, + 0.146946, 0.154508, -0.452254, 0.293893, 0.309017, -0.904508, 0.8, 0.6, + 0.154509, -2.18557e-08, -0.475528, 0.309017, -4.37114e-08, -0.951056, 0.8, 0.5, + -0.154509, -2.18557e-08, -0.475528, -0.309017, -4.37114e-08, -0.951056, 0.7, 0.5, + -0.146946, -0.154509, -0.452254, -0.293893, -0.309017, -0.904509, 0.7, 0.4, + -0.154509, -2.18557e-08, -0.475528, -0.309017, -4.37114e-08, -0.951056, 0.7, 0.5, + 0.154509, -2.18557e-08, -0.475528, 0.309017, -4.37114e-08, -0.951056, 0.8, 0.5, + 0.154509, -2.18557e-08, -0.475528, 0.309017, -4.37114e-08, -0.951056, 0.8, 0.5, + 0.146946, -0.154509, -0.452254, 0.293893, -0.309017, -0.904509, 0.8, 0.4, + -0.146946, -0.154509, -0.452254, -0.293893, -0.309017, -0.904509, 0.7, 0.4, + -0.125, -0.293893, -0.38471, -0.25, -0.587785, -0.769421, 0.7, 0.3, + -0.146946, -0.154509, -0.452254, -0.293893, -0.309017, -0.904509, 0.7, 0.4, + 0.146946, -0.154509, -0.452254, 0.293893, -0.309017, -0.904509, 0.8, 0.4, + 0.146946, -0.154509, -0.452254, 0.293893, -0.309017, -0.904509, 0.8, 0.4, + 0.125, -0.293893, -0.38471, 0.25, -0.587785, -0.769421, 0.8, 0.3, + -0.125, -0.293893, -0.38471, -0.25, -0.587785, -0.769421, 0.7, 0.3, + -0.0908178, -0.404509, -0.279508, -0.181636, -0.809017, -0.559017, 0.7, 0.2, + -0.125, -0.293893, -0.38471, -0.25, -0.587785, -0.769421, 0.7, 0.3, + 0.125, -0.293893, -0.38471, 0.25, -0.587785, -0.769421, 0.8, 0.3, + 0.125, -0.293893, -0.38471, 0.25, -0.587785, -0.769421, 0.8, 0.3, + 0.0908178, -0.404509, -0.279508, 0.181636, -0.809017, -0.559017, 0.8, 0.2, + -0.0908178, -0.404509, -0.279508, -0.181636, -0.809017, -0.559017, 0.7, 0.2, + -0.0477457, -0.475528, -0.146946, -0.0954915, -0.951057, -0.293892, 0.7, 0.1, + -0.0908178, -0.404509, -0.279508, -0.181636, -0.809017, -0.559017, 0.7, 0.2, + 0.0908178, -0.404509, -0.279508, 0.181636, -0.809017, -0.559017, 0.8, 0.2, + 0.0908178, -0.404509, -0.279508, 0.181636, -0.809017, -0.559017, 0.8, 0.2, + 0.0477457, -0.475528, -0.146946, 0.0954915, -0.951057, -0.293892, 0.8, 0.1, + -0.0477457, -0.475528, -0.146946, -0.0954915, -0.951057, -0.293892, 0.7, 0.1, + 1.35076e-08, -0.5, 4.1572e-08, 2.70151e-08, -1, 8.3144e-08, 0.7, 0, + -0.0477457, -0.475528, -0.146946, -0.0954915, -0.951057, -0.293892, 0.7, 0.1, + 0.0477457, -0.475528, -0.146946, 0.0954915, -0.951057, -0.293892, 0.8, 0.1, + 0.0477457, -0.475528, -0.146946, 0.0954915, -0.951057, -0.293892, 0.8, 0.1, + -1.35076e-08, -0.5, 4.1572e-08, -2.70151e-08, -1, 8.3144e-08, 0.8, 0, + 1.35076e-08, -0.5, 4.1572e-08, 2.70151e-08, -1, 8.3144e-08, 0.7, 0, + 0.0477458, 0.475528, -0.146946, 0.0954915, 0.951057, -0.293893, 0.8, 0.9, + 0, 0.5, -0, 0, 1, -0, 0.8, 1, + 0, 0.5, -0, 0, 1, -0, 0.9, 1, + 0, 0.5, -0, 0, 1, -0, 0.9, 1, + 0.125, 0.475528, -0.0908178, 0.25, 0.951057, -0.181636, 0.9, 0.9, + 0.0477458, 0.475528, -0.146946, 0.0954915, 0.951057, -0.293893, 0.8, 0.9, + 0.0908179, 0.404509, -0.279508, 0.181636, 0.809017, -0.559017, 0.8, 0.8, + 0.0477458, 0.475528, -0.146946, 0.0954915, 0.951057, -0.293893, 0.8, 0.9, + 0.125, 0.475528, -0.0908178, 0.25, 0.951057, -0.181636, 0.9, 0.9, + 0.125, 0.475528, -0.0908178, 0.25, 0.951057, -0.181636, 0.9, 0.9, + 0.237764, 0.404509, -0.172746, 0.475528, 0.809017, -0.345491, 0.9, 0.8, + 0.0908179, 0.404509, -0.279508, 0.181636, 0.809017, -0.559017, 0.8, 0.8, + 0.125, 0.293893, -0.38471, 0.25, 0.587785, -0.769421, 0.8, 0.7, + 0.0908179, 0.404509, -0.279508, 0.181636, 0.809017, -0.559017, 0.8, 0.8, + 0.237764, 0.404509, -0.172746, 0.475528, 0.809017, -0.345491, 0.9, 0.8, + 0.237764, 0.404509, -0.172746, 0.475528, 0.809017, -0.345491, 0.9, 0.8, + 0.327254, 0.293893, -0.237764, 0.654509, 0.587785, -0.475528, 0.9, 0.7, + 0.125, 0.293893, -0.38471, 0.25, 0.587785, -0.769421, 0.8, 0.7, + 0.146946, 0.154508, -0.452254, 0.293893, 0.309017, -0.904508, 0.8, 0.6, + 0.125, 0.293893, -0.38471, 0.25, 0.587785, -0.769421, 0.8, 0.7, + 0.327254, 0.293893, -0.237764, 0.654509, 0.587785, -0.475528, 0.9, 0.7, + 0.327254, 0.293893, -0.237764, 0.654509, 0.587785, -0.475528, 0.9, 0.7, + 0.384711, 0.154508, -0.279508, 0.769421, 0.309017, -0.559017, 0.9, 0.6, + 0.146946, 0.154508, -0.452254, 0.293893, 0.309017, -0.904508, 0.8, 0.6, + 0.154509, -2.18557e-08, -0.475528, 0.309017, -4.37114e-08, -0.951056, 0.8, 0.5, + 0.146946, 0.154508, -0.452254, 0.293893, 0.309017, -0.904508, 0.8, 0.6, + 0.384711, 0.154508, -0.279508, 0.769421, 0.309017, -0.559017, 0.9, 0.6, + 0.384711, 0.154508, -0.279508, 0.769421, 0.309017, -0.559017, 0.9, 0.6, + 0.404509, -2.18557e-08, -0.293892, 0.809017, -4.37114e-08, -0.587785, 0.9, 0.5, + 0.154509, -2.18557e-08, -0.475528, 0.309017, -4.37114e-08, -0.951056, 0.8, 0.5, + 0.146946, -0.154509, -0.452254, 0.293893, -0.309017, -0.904509, 0.8, 0.4, + 0.154509, -2.18557e-08, -0.475528, 0.309017, -4.37114e-08, -0.951056, 0.8, 0.5, + 0.404509, -2.18557e-08, -0.293892, 0.809017, -4.37114e-08, -0.587785, 0.9, 0.5, + 0.404509, -2.18557e-08, -0.293892, 0.809017, -4.37114e-08, -0.587785, 0.9, 0.5, + 0.384711, -0.154509, -0.279508, 0.769421, -0.309017, -0.559017, 0.9, 0.4, + 0.146946, -0.154509, -0.452254, 0.293893, -0.309017, -0.904509, 0.8, 0.4, + 0.125, -0.293893, -0.38471, 0.25, -0.587785, -0.769421, 0.8, 0.3, + 0.146946, -0.154509, -0.452254, 0.293893, -0.309017, -0.904509, 0.8, 0.4, + 0.384711, -0.154509, -0.279508, 0.769421, -0.309017, -0.559017, 0.9, 0.4, + 0.384711, -0.154509, -0.279508, 0.769421, -0.309017, -0.559017, 0.9, 0.4, + 0.327254, -0.293893, -0.237764, 0.654509, -0.587785, -0.475528, 0.9, 0.3, + 0.125, -0.293893, -0.38471, 0.25, -0.587785, -0.769421, 0.8, 0.3, + 0.0908178, -0.404509, -0.279508, 0.181636, -0.809017, -0.559017, 0.8, 0.2, + 0.125, -0.293893, -0.38471, 0.25, -0.587785, -0.769421, 0.8, 0.3, + 0.327254, -0.293893, -0.237764, 0.654509, -0.587785, -0.475528, 0.9, 0.3, + 0.327254, -0.293893, -0.237764, 0.654509, -0.587785, -0.475528, 0.9, 0.3, + 0.237764, -0.404509, -0.172746, 0.475528, -0.809017, -0.345491, 0.9, 0.2, + 0.0908178, -0.404509, -0.279508, 0.181636, -0.809017, -0.559017, 0.8, 0.2, + 0.0477457, -0.475528, -0.146946, 0.0954915, -0.951057, -0.293892, 0.8, 0.1, + 0.0908178, -0.404509, -0.279508, 0.181636, -0.809017, -0.559017, 0.8, 0.2, + 0.237764, -0.404509, -0.172746, 0.475528, -0.809017, -0.345491, 0.9, 0.2, + 0.237764, -0.404509, -0.172746, 0.475528, -0.809017, -0.345491, 0.9, 0.2, + 0.125, -0.475528, -0.0908177, 0.25, -0.951057, -0.181635, 0.9, 0.1, + 0.0477457, -0.475528, -0.146946, 0.0954915, -0.951057, -0.293892, 0.8, 0.1, + -1.35076e-08, -0.5, 4.1572e-08, -2.70151e-08, -1, 8.3144e-08, 0.8, 0, + 0.0477457, -0.475528, -0.146946, 0.0954915, -0.951057, -0.293892, 0.8, 0.1, + 0.125, -0.475528, -0.0908177, 0.25, -0.951057, -0.181635, 0.9, 0.1, + 0.125, -0.475528, -0.0908177, 0.25, -0.951057, -0.181635, 0.9, 0.1, + -3.53633e-08, -0.5, 2.56929e-08, -7.07265e-08, -1, 5.13858e-08, 0.9, 0, + -1.35076e-08, -0.5, 4.1572e-08, -2.70151e-08, -1, 8.3144e-08, 0.8, 0, + 0.125, 0.475528, -0.0908178, 0.25, 0.951057, -0.181636, 0.9, 0.9, + 0, 0.5, -0, 0, 1, -0, 0.9, 1, + 0, 0.5, 0, 0, 1, 0, 1, 1, + 0, 0.5, 0, 0, 1, 0, 1, 1, + 0.154509, 0.475528, 2.70151e-08, 0.309017, 0.951057, 5.40302e-08, 1, 0.9, + 0.125, 0.475528, -0.0908178, 0.25, 0.951057, -0.181636, 0.9, 0.9, + 0.237764, 0.404509, -0.172746, 0.475528, 0.809017, -0.345491, 0.9, 0.8, + 0.125, 0.475528, -0.0908178, 0.25, 0.951057, -0.181636, 0.9, 0.9, + 0.154509, 0.475528, 2.70151e-08, 0.309017, 0.951057, 5.40302e-08, 1, 0.9, + 0.154509, 0.475528, 2.70151e-08, 0.309017, 0.951057, 5.40302e-08, 1, 0.9, + 0.293893, 0.404509, 5.13858e-08, 0.587785, 0.809017, 1.02772e-07, 1, 0.8, + 0.237764, 0.404509, -0.172746, 0.475528, 0.809017, -0.345491, 0.9, 0.8, + 0.327254, 0.293893, -0.237764, 0.654509, 0.587785, -0.475528, 0.9, 0.7, + 0.237764, 0.404509, -0.172746, 0.475528, 0.809017, -0.345491, 0.9, 0.8, + 0.293893, 0.404509, 5.13858e-08, 0.587785, 0.809017, 1.02772e-07, 1, 0.8, + 0.293893, 0.404509, 5.13858e-08, 0.587785, 0.809017, 1.02772e-07, 1, 0.8, + 0.404509, 0.293893, 7.07265e-08, 0.809017, 0.587785, 1.41453e-07, 1, 0.7, + 0.327254, 0.293893, -0.237764, 0.654509, 0.587785, -0.475528, 0.9, 0.7, + 0.384711, 0.154508, -0.279508, 0.769421, 0.309017, -0.559017, 0.9, 0.6, + 0.327254, 0.293893, -0.237764, 0.654509, 0.587785, -0.475528, 0.9, 0.7, + 0.404509, 0.293893, 7.07265e-08, 0.809017, 0.587785, 1.41453e-07, 1, 0.7, + 0.404509, 0.293893, 7.07265e-08, 0.809017, 0.587785, 1.41453e-07, 1, 0.7, + 0.475528, 0.154508, 8.3144e-08, 0.951057, 0.309017, 1.66288e-07, 1, 0.6, + 0.384711, 0.154508, -0.279508, 0.769421, 0.309017, -0.559017, 0.9, 0.6, + 0.404509, -2.18557e-08, -0.293892, 0.809017, -4.37114e-08, -0.587785, 0.9, 0.5, + 0.384711, 0.154508, -0.279508, 0.769421, 0.309017, -0.559017, 0.9, 0.6, + 0.475528, 0.154508, 8.3144e-08, 0.951057, 0.309017, 1.66288e-07, 1, 0.6, + 0.475528, 0.154508, 8.3144e-08, 0.951057, 0.309017, 1.66288e-07, 1, 0.6, + 0.5, -2.18557e-08, 8.74228e-08, 1, -4.37114e-08, 1.74846e-07, 1, 0.5, + 0.404509, -2.18557e-08, -0.293892, 0.809017, -4.37114e-08, -0.587785, 0.9, 0.5, + 0.384711, -0.154509, -0.279508, 0.769421, -0.309017, -0.559017, 0.9, 0.4, + 0.404509, -2.18557e-08, -0.293892, 0.809017, -4.37114e-08, -0.587785, 0.9, 0.5, + 0.5, -2.18557e-08, 8.74228e-08, 1, -4.37114e-08, 1.74846e-07, 1, 0.5, + 0.5, -2.18557e-08, 8.74228e-08, 1, -4.37114e-08, 1.74846e-07, 1, 0.5, + 0.475528, -0.154509, 8.3144e-08, 0.951057, -0.309017, 1.66288e-07, 1, 0.4, + 0.384711, -0.154509, -0.279508, 0.769421, -0.309017, -0.559017, 0.9, 0.4, + 0.327254, -0.293893, -0.237764, 0.654509, -0.587785, -0.475528, 0.9, 0.3, + 0.384711, -0.154509, -0.279508, 0.769421, -0.309017, -0.559017, 0.9, 0.4, + 0.475528, -0.154509, 8.3144e-08, 0.951057, -0.309017, 1.66288e-07, 1, 0.4, + 0.475528, -0.154509, 8.3144e-08, 0.951057, -0.309017, 1.66288e-07, 1, 0.4, + 0.404509, -0.293893, 7.07265e-08, 0.809017, -0.587785, 1.41453e-07, 1, 0.3, + 0.327254, -0.293893, -0.237764, 0.654509, -0.587785, -0.475528, 0.9, 0.3, + 0.237764, -0.404509, -0.172746, 0.475528, -0.809017, -0.345491, 0.9, 0.2, + 0.327254, -0.293893, -0.237764, 0.654509, -0.587785, -0.475528, 0.9, 0.3, + 0.404509, -0.293893, 7.07265e-08, 0.809017, -0.587785, 1.41453e-07, 1, 0.3, + 0.404509, -0.293893, 7.07265e-08, 0.809017, -0.587785, 1.41453e-07, 1, 0.3, + 0.293893, -0.404509, 5.13858e-08, 0.587785, -0.809017, 1.02772e-07, 1, 0.2, + 0.237764, -0.404509, -0.172746, 0.475528, -0.809017, -0.345491, 0.9, 0.2, + 0.125, -0.475528, -0.0908177, 0.25, -0.951057, -0.181635, 0.9, 0.1, + 0.237764, -0.404509, -0.172746, 0.475528, -0.809017, -0.345491, 0.9, 0.2, + 0.293893, -0.404509, 5.13858e-08, 0.587785, -0.809017, 1.02772e-07, 1, 0.2, + 0.293893, -0.404509, 5.13858e-08, 0.587785, -0.809017, 1.02772e-07, 1, 0.2, + 0.154508, -0.475528, 2.70151e-08, 0.309017, -0.951057, 5.40302e-08, 1, 0.1, + 0.125, -0.475528, -0.0908177, 0.25, -0.951057, -0.181635, 0.9, 0.1, + -3.53633e-08, -0.5, 2.56929e-08, -7.07265e-08, -1, 5.13858e-08, 0.9, 0, + 0.125, -0.475528, -0.0908177, 0.25, -0.951057, -0.181635, 0.9, 0.1, + 0.154508, -0.475528, 2.70151e-08, 0.309017, -0.951057, 5.40302e-08, 1, 0.1, + 0.154508, -0.475528, 2.70151e-08, 0.309017, -0.951057, 5.40302e-08, 1, 0.1, + -4.37114e-08, -0.5, -7.64274e-15, -8.74228e-08, -1, -1.52855e-14, 1, 0, + -3.53633e-08, -0.5, 2.56929e-08, -7.07265e-08, -1, 5.13858e-08, 0.9, 0 +}; + +std::vector<GLfloat> cylinderVertexBufferData = { + 0, -0.5, 0, 0, -1, 0, 0.5, 0.5, + 0.05, -0.5, 0, 0, -1, 0, 0.55, 0.5, + 0.0404509, -0.5, 0.0293893, 0, -1, 0, 0.540451, 0.470611, + 0.0404509, 0.5, 0.0293893, 0, 1, 0, 0.540451, 0.470611, + 0.05, 0.5, 0, 0, 1, 0, 0.55, 0.5, + 0, 0.5, 0, 0, 1, 0, 0.5, 0.5, + 0.404509, 0.4, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.1, + 0.5, 0.4, 0, 1, 0, 0, 0, 0.1, + 0.5, 0.5, 0, 1, 0, 0, 0, 0, + 0.404509, 0.5, 0.293893, 0.809017, 0, 0.587785, 0.1, 0, + 0.404509, 0.4, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.1, + 0.5, 0.5, 0, 1, 0, 0, 0, 0, + 0.05, -0.5, 0, 0, -1, 0, 0.55, 0.5, + 0.1, -0.5, 0, 0, -1, 0, 0.6, 0.5, + 0.0809017, -0.5, 0.0587785, 0, -1, 0, 0.580902, 0.441221, + 0.05, -0.5, 0, 0, -1, 0, 0.55, 0.5, + 0.0809017, -0.5, 0.0587785, 0, -1, 0, 0.580902, 0.441221, + 0.0404509, -0.5, 0.0293893, 0, -1, 0, 0.540451, 0.470611, + 0.0809017, 0.5, 0.0587785, 0, 1, 0, 0.580902, 0.441221, + 0.1, 0.5, 0, 0, 1, 0, 0.6, 0.5, + 0.05, 0.5, 0, 0, 1, 0, 0.55, 0.5, + 0.0404509, 0.5, 0.0293893, 0, 1, 0, 0.540451, 0.470611, + 0.0809017, 0.5, 0.0587785, 0, 1, 0, 0.580902, 0.441221, + 0.05, 0.5, 0, 0, 1, 0, 0.55, 0.5, + 0.404509, 0.3, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.2, + 0.5, 0.3, 0, 1, 0, 0, 0, 0.2, + 0.5, 0.4, 0, 1, 0, 0, 0, 0.1, + 0.404509, 0.4, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.1, + 0.404509, 0.3, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.2, + 0.5, 0.4, 0, 1, 0, 0, 0, 0.1, + 0.1, -0.5, 0, 0, -1, 0, 0.6, 0.5, + 0.15, -0.5, 0, 0, -1, 0, 0.65, 0.5, + 0.121353, -0.5, 0.0881678, 0, -1, 0, 0.621353, 0.411832, + 0.1, -0.5, 0, 0, -1, 0, 0.6, 0.5, + 0.121353, -0.5, 0.0881678, 0, -1, 0, 0.621353, 0.411832, + 0.0809017, -0.5, 0.0587785, 0, -1, 0, 0.580902, 0.441221, + 0.121353, 0.5, 0.0881678, 0, 1, 0, 0.621353, 0.411832, + 0.15, 0.5, 0, 0, 1, 0, 0.65, 0.5, + 0.1, 0.5, 0, 0, 1, 0, 0.6, 0.5, + 0.0809017, 0.5, 0.0587785, 0, 1, 0, 0.580902, 0.441221, + 0.121353, 0.5, 0.0881678, 0, 1, 0, 0.621353, 0.411832, + 0.1, 0.5, 0, 0, 1, 0, 0.6, 0.5, + 0.404509, 0.2, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.3, + 0.5, 0.2, 0, 1, 0, 0, 0, 0.3, + 0.5, 0.3, 0, 1, 0, 0, 0, 0.2, + 0.404509, 0.3, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.2, + 0.404509, 0.2, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.3, + 0.5, 0.3, 0, 1, 0, 0, 0, 0.2, + 0.15, -0.5, 0, 0, -1, 0, 0.65, 0.5, + 0.2, -0.5, 0, 0, -1, 0, 0.7, 0.5, + 0.161803, -0.5, 0.117557, 0, -1, 0, 0.661803, 0.382443, + 0.15, -0.5, 0, 0, -1, 0, 0.65, 0.5, + 0.161803, -0.5, 0.117557, 0, -1, 0, 0.661803, 0.382443, + 0.121353, -0.5, 0.0881678, 0, -1, 0, 0.621353, 0.411832, + 0.161803, 0.5, 0.117557, 0, 1, 0, 0.661803, 0.382443, + 0.2, 0.5, 0, 0, 1, 0, 0.7, 0.5, + 0.15, 0.5, 0, 0, 1, 0, 0.65, 0.5, + 0.121353, 0.5, 0.0881678, 0, 1, 0, 0.621353, 0.411832, + 0.161803, 0.5, 0.117557, 0, 1, 0, 0.661803, 0.382443, + 0.15, 0.5, 0, 0, 1, 0, 0.65, 0.5, + 0.404509, 0.1, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.4, + 0.5, 0.1, 0, 1, 0, 0, 0, 0.4, + 0.5, 0.2, 0, 1, 0, 0, 0, 0.3, + 0.404509, 0.2, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.3, + 0.404509, 0.1, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.4, + 0.5, 0.2, 0, 1, 0, 0, 0, 0.3, + 0.2, -0.5, 0, 0, -1, 0, 0.7, 0.5, + 0.25, -0.5, 0, 0, -1, 0, 0.75, 0.5, + 0.202254, -0.5, 0.146946, 0, -1, 0, 0.702254, 0.353054, + 0.2, -0.5, 0, 0, -1, 0, 0.7, 0.5, + 0.202254, -0.5, 0.146946, 0, -1, 0, 0.702254, 0.353054, + 0.161803, -0.5, 0.117557, 0, -1, 0, 0.661803, 0.382443, + 0.202254, 0.5, 0.146946, 0, 1, 0, 0.702254, 0.353054, + 0.25, 0.5, 0, 0, 1, 0, 0.75, 0.5, + 0.2, 0.5, 0, 0, 1, 0, 0.7, 0.5, + 0.161803, 0.5, 0.117557, 0, 1, 0, 0.661803, 0.382443, + 0.202254, 0.5, 0.146946, 0, 1, 0, 0.702254, 0.353054, + 0.2, 0.5, 0, 0, 1, 0, 0.7, 0.5, + 0.404509, 0, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.5, + 0.5, 0, 0, 1, 0, 0, 0, 0.5, + 0.5, 0.1, 0, 1, 0, 0, 0, 0.4, + 0.404509, 0.1, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.4, + 0.404509, 0, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.5, + 0.5, 0.1, 0, 1, 0, 0, 0, 0.4, + 0.25, -0.5, 0, 0, -1, 0, 0.75, 0.5, + 0.3, -0.5, 0, 0, -1, 0, 0.8, 0.5, + 0.242705, -0.5, 0.176336, 0, -1, 0, 0.742705, 0.323664, + 0.25, -0.5, 0, 0, -1, 0, 0.75, 0.5, + 0.242705, -0.5, 0.176336, 0, -1, 0, 0.742705, 0.323664, + 0.202254, -0.5, 0.146946, 0, -1, 0, 0.702254, 0.353054, + 0.242705, 0.5, 0.176336, 0, 1, 0, 0.742705, 0.323664, + 0.3, 0.5, 0, 0, 1, 0, 0.8, 0.5, + 0.25, 0.5, 0, 0, 1, 0, 0.75, 0.5, + 0.202254, 0.5, 0.146946, 0, 1, 0, 0.702254, 0.353054, + 0.242705, 0.5, 0.176336, 0, 1, 0, 0.742705, 0.323664, + 0.25, 0.5, 0, 0, 1, 0, 0.75, 0.5, + 0.404509, -0.1, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.6, + 0.5, -0.1, 0, 1, 0, 0, 0, 0.6, + 0.5, 0, 0, 1, 0, 0, 0, 0.5, + 0.404509, 0, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.5, + 0.404509, -0.1, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.6, + 0.5, 0, 0, 1, 0, 0, 0, 0.5, + 0.3, -0.5, 0, 0, -1, 0, 0.8, 0.5, + 0.35, -0.5, 0, 0, -1, 0, 0.85, 0.5, + 0.283156, -0.5, 0.205725, 0, -1, 0, 0.783156, 0.294275, + 0.3, -0.5, 0, 0, -1, 0, 0.8, 0.5, + 0.283156, -0.5, 0.205725, 0, -1, 0, 0.783156, 0.294275, + 0.242705, -0.5, 0.176336, 0, -1, 0, 0.742705, 0.323664, + 0.283156, 0.5, 0.205725, 0, 1, 0, 0.783156, 0.294275, + 0.35, 0.5, 0, 0, 1, 0, 0.85, 0.5, + 0.3, 0.5, 0, 0, 1, 0, 0.8, 0.5, + 0.242705, 0.5, 0.176336, 0, 1, 0, 0.742705, 0.323664, + 0.283156, 0.5, 0.205725, 0, 1, 0, 0.783156, 0.294275, + 0.3, 0.5, 0, 0, 1, 0, 0.8, 0.5, + 0.404509, -0.2, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.7, + 0.5, -0.2, 0, 1, 0, 0, 0, 0.7, + 0.5, -0.1, 0, 1, 0, 0, 0, 0.6, + 0.404509, -0.1, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.6, + 0.404509, -0.2, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.7, + 0.5, -0.1, 0, 1, 0, 0, 0, 0.6, + 0.35, -0.5, 0, 0, -1, 0, 0.85, 0.5, + 0.4, -0.5, 0, 0, -1, 0, 0.9, 0.5, + 0.323607, -0.5, 0.235114, 0, -1, 0, 0.823607, 0.264886, + 0.35, -0.5, 0, 0, -1, 0, 0.85, 0.5, + 0.323607, -0.5, 0.235114, 0, -1, 0, 0.823607, 0.264886, + 0.283156, -0.5, 0.205725, 0, -1, 0, 0.783156, 0.294275, + 0.323607, 0.5, 0.235114, 0, 1, 0, 0.823607, 0.264886, + 0.4, 0.5, 0, 0, 1, 0, 0.9, 0.5, + 0.35, 0.5, 0, 0, 1, 0, 0.85, 0.5, + 0.283156, 0.5, 0.205725, 0, 1, 0, 0.783156, 0.294275, + 0.323607, 0.5, 0.235114, 0, 1, 0, 0.823607, 0.264886, + 0.35, 0.5, 0, 0, 1, 0, 0.85, 0.5, + 0.404509, -0.3, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.8, + 0.5, -0.3, 0, 1, 0, 0, 0, 0.8, + 0.5, -0.2, 0, 1, 0, 0, 0, 0.7, + 0.404509, -0.2, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.7, + 0.404509, -0.3, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.8, + 0.5, -0.2, 0, 1, 0, 0, 0, 0.7, + 0.4, -0.5, 0, 0, -1, 0, 0.9, 0.5, + 0.45, -0.5, 0, 0, -1, 0, 0.95, 0.5, + 0.364058, -0.5, 0.264503, 0, -1, 0, 0.864058, 0.235497, + 0.4, -0.5, 0, 0, -1, 0, 0.9, 0.5, + 0.364058, -0.5, 0.264503, 0, -1, 0, 0.864058, 0.235497, + 0.323607, -0.5, 0.235114, 0, -1, 0, 0.823607, 0.264886, + 0.364058, 0.5, 0.264503, 0, 1, 0, 0.864058, 0.235497, + 0.45, 0.5, 0, 0, 1, 0, 0.95, 0.5, + 0.4, 0.5, 0, 0, 1, 0, 0.9, 0.5, + 0.323607, 0.5, 0.235114, 0, 1, 0, 0.823607, 0.264886, + 0.364058, 0.5, 0.264503, 0, 1, 0, 0.864058, 0.235497, + 0.4, 0.5, 0, 0, 1, 0, 0.9, 0.5, + 0.404509, -0.4, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.9, + 0.5, -0.4, 0, 1, 0, 0, 0, 0.9, + 0.5, -0.3, 0, 1, 0, 0, 0, 0.8, + 0.404509, -0.3, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.8, + 0.404509, -0.4, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.9, + 0.5, -0.3, 0, 1, 0, 0, 0, 0.8, + 0.45, -0.5, 0, 0, -1, 0, 0.95, 0.5, + 0.5, -0.5, 0, 0, -1, 0, 1, 0.5, + 0.404509, -0.5, 0.293893, 0, -1, 0, 0.904508, 0.206107, + 0.45, -0.5, 0, 0, -1, 0, 0.95, 0.5, + 0.404509, -0.5, 0.293893, 0, -1, 0, 0.904508, 0.206107, + 0.364058, -0.5, 0.264503, 0, -1, 0, 0.864058, 0.235497, + 0.404509, 0.5, 0.293893, 0, 1, 0, 0.904508, 0.206107, + 0.5, 0.5, 0, 0, 1, 0, 1, 0.5, + 0.45, 0.5, 0, 0, 1, 0, 0.95, 0.5, + 0.364058, 0.5, 0.264503, 0, 1, 0, 0.864058, 0.235497, + 0.404509, 0.5, 0.293893, 0, 1, 0, 0.904508, 0.206107, + 0.45, 0.5, 0, 0, 1, 0, 0.95, 0.5, + 0.404509, -0.5, 0.293893, 0.809017, 0, 0.587785, 0.1, 1, + 0.5, -0.5, 0, 1, 0, 0, 0, 1, + 0.5, -0.4, 0, 1, 0, 0, 0, 0.9, + 0.404509, -0.4, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.9, + 0.404509, -0.5, 0.293893, 0.809017, 0, 0.587785, 0.1, 1, + 0.5, -0.4, 0, 1, 0, 0, 0, 0.9, + 0, -0.5, 0, 0, -1, 0, 0.5, 0.5, + 0.0404509, -0.5, 0.0293893, 0, -1, 0, 0.540451, 0.470611, + 0.0154508, -0.5, 0.0475528, 0, -1, 0, 0.515451, 0.452447, + 0.0154508, 0.5, 0.0475528, 0, 1, 0, 0.515451, 0.452447, + 0.0404509, 0.5, 0.0293893, 0, 1, 0, 0.540451, 0.470611, + 0, 0.5, 0, 0, 1, 0, 0.5, 0.5, + 0.154508, 0.4, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.1, + 0.404509, 0.4, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.1, + 0.404509, 0.5, 0.293893, 0.809017, 0, 0.587785, 0.1, 0, + 0.154508, 0.5, 0.475528, 0.309017, 0, 0.951057, 0.2, 0, + 0.154508, 0.4, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.1, + 0.404509, 0.5, 0.293893, 0.809017, 0, 0.587785, 0.1, 0, + 0.0404509, -0.5, 0.0293893, 0, -1, 0, 0.540451, 0.470611, + 0.0809017, -0.5, 0.0587785, 0, -1, 0, 0.580902, 0.441221, + 0.0309017, -0.5, 0.0951057, 0, -1, 0, 0.530902, 0.404894, + 0.0404509, -0.5, 0.0293893, 0, -1, 0, 0.540451, 0.470611, + 0.0309017, -0.5, 0.0951057, 0, -1, 0, 0.530902, 0.404894, + 0.0154508, -0.5, 0.0475528, 0, -1, 0, 0.515451, 0.452447, + 0.0309017, 0.5, 0.0951057, 0, 1, 0, 0.530902, 0.404894, + 0.0809017, 0.5, 0.0587785, 0, 1, 0, 0.580902, 0.441221, + 0.0404509, 0.5, 0.0293893, 0, 1, 0, 0.540451, 0.470611, + 0.0154508, 0.5, 0.0475528, 0, 1, 0, 0.515451, 0.452447, + 0.0309017, 0.5, 0.0951057, 0, 1, 0, 0.530902, 0.404894, + 0.0404509, 0.5, 0.0293893, 0, 1, 0, 0.540451, 0.470611, + 0.154508, 0.3, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.2, + 0.404509, 0.3, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.2, + 0.404509, 0.4, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.1, + 0.154508, 0.4, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.1, + 0.154508, 0.3, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.2, + 0.404509, 0.4, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.1, + 0.0809017, -0.5, 0.0587785, 0, -1, 0, 0.580902, 0.441221, + 0.121353, -0.5, 0.0881678, 0, -1, 0, 0.621353, 0.411832, + 0.0463525, -0.5, 0.142658, 0, -1, 0, 0.546353, 0.357342, + 0.0809017, -0.5, 0.0587785, 0, -1, 0, 0.580902, 0.441221, + 0.0463525, -0.5, 0.142658, 0, -1, 0, 0.546353, 0.357342, + 0.0309017, -0.5, 0.0951057, 0, -1, 0, 0.530902, 0.404894, + 0.0463525, 0.5, 0.142658, 0, 1, 0, 0.546353, 0.357342, + 0.121353, 0.5, 0.0881678, 0, 1, 0, 0.621353, 0.411832, + 0.0809017, 0.5, 0.0587785, 0, 1, 0, 0.580902, 0.441221, + 0.0309017, 0.5, 0.0951057, 0, 1, 0, 0.530902, 0.404894, + 0.0463525, 0.5, 0.142658, 0, 1, 0, 0.546353, 0.357342, + 0.0809017, 0.5, 0.0587785, 0, 1, 0, 0.580902, 0.441221, + 0.154508, 0.2, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.3, + 0.404509, 0.2, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.3, + 0.404509, 0.3, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.2, + 0.154508, 0.3, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.2, + 0.154508, 0.2, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.3, + 0.404509, 0.3, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.2, + 0.121353, -0.5, 0.0881678, 0, -1, 0, 0.621353, 0.411832, + 0.161803, -0.5, 0.117557, 0, -1, 0, 0.661803, 0.382443, + 0.0618034, -0.5, 0.190211, 0, -1, 0, 0.561803, 0.309789, + 0.121353, -0.5, 0.0881678, 0, -1, 0, 0.621353, 0.411832, + 0.0618034, -0.5, 0.190211, 0, -1, 0, 0.561803, 0.309789, + 0.0463525, -0.5, 0.142658, 0, -1, 0, 0.546353, 0.357342, + 0.0618034, 0.5, 0.190211, 0, 1, 0, 0.561803, 0.309789, + 0.161803, 0.5, 0.117557, 0, 1, 0, 0.661803, 0.382443, + 0.121353, 0.5, 0.0881678, 0, 1, 0, 0.621353, 0.411832, + 0.0463525, 0.5, 0.142658, 0, 1, 0, 0.546353, 0.357342, + 0.0618034, 0.5, 0.190211, 0, 1, 0, 0.561803, 0.309789, + 0.121353, 0.5, 0.0881678, 0, 1, 0, 0.621353, 0.411832, + 0.154508, 0.1, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.4, + 0.404509, 0.1, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.4, + 0.404509, 0.2, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.3, + 0.154508, 0.2, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.3, + 0.154508, 0.1, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.4, + 0.404509, 0.2, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.3, + 0.161803, -0.5, 0.117557, 0, -1, 0, 0.661803, 0.382443, + 0.202254, -0.5, 0.146946, 0, -1, 0, 0.702254, 0.353054, + 0.0772542, -0.5, 0.237764, 0, -1, 0, 0.577254, 0.262236, + 0.161803, -0.5, 0.117557, 0, -1, 0, 0.661803, 0.382443, + 0.0772542, -0.5, 0.237764, 0, -1, 0, 0.577254, 0.262236, + 0.0618034, -0.5, 0.190211, 0, -1, 0, 0.561803, 0.309789, + 0.0772542, 0.5, 0.237764, 0, 1, 0, 0.577254, 0.262236, + 0.202254, 0.5, 0.146946, 0, 1, 0, 0.702254, 0.353054, + 0.161803, 0.5, 0.117557, 0, 1, 0, 0.661803, 0.382443, + 0.0618034, 0.5, 0.190211, 0, 1, 0, 0.561803, 0.309789, + 0.0772542, 0.5, 0.237764, 0, 1, 0, 0.577254, 0.262236, + 0.161803, 0.5, 0.117557, 0, 1, 0, 0.661803, 0.382443, + 0.154508, 0, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.5, + 0.404509, 0, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.5, + 0.404509, 0.1, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.4, + 0.154508, 0.1, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.4, + 0.154508, 0, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.5, + 0.404509, 0.1, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.4, + 0.202254, -0.5, 0.146946, 0, -1, 0, 0.702254, 0.353054, + 0.242705, -0.5, 0.176336, 0, -1, 0, 0.742705, 0.323664, + 0.0927051, -0.5, 0.285317, 0, -1, 0, 0.592705, 0.214683, + 0.202254, -0.5, 0.146946, 0, -1, 0, 0.702254, 0.353054, + 0.0927051, -0.5, 0.285317, 0, -1, 0, 0.592705, 0.214683, + 0.0772542, -0.5, 0.237764, 0, -1, 0, 0.577254, 0.262236, + 0.0927051, 0.5, 0.285317, 0, 1, 0, 0.592705, 0.214683, + 0.242705, 0.5, 0.176336, 0, 1, 0, 0.742705, 0.323664, + 0.202254, 0.5, 0.146946, 0, 1, 0, 0.702254, 0.353054, + 0.0772542, 0.5, 0.237764, 0, 1, 0, 0.577254, 0.262236, + 0.0927051, 0.5, 0.285317, 0, 1, 0, 0.592705, 0.214683, + 0.202254, 0.5, 0.146946, 0, 1, 0, 0.702254, 0.353054, + 0.154508, -0.1, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.6, + 0.404509, -0.1, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.6, + 0.404509, 0, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.5, + 0.154508, 0, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.5, + 0.154508, -0.1, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.6, + 0.404509, 0, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.5, + 0.242705, -0.5, 0.176336, 0, -1, 0, 0.742705, 0.323664, + 0.283156, -0.5, 0.205725, 0, -1, 0, 0.783156, 0.294275, + 0.108156, -0.5, 0.33287, 0, -1, 0, 0.608156, 0.16713, + 0.242705, -0.5, 0.176336, 0, -1, 0, 0.742705, 0.323664, + 0.108156, -0.5, 0.33287, 0, -1, 0, 0.608156, 0.16713, + 0.0927051, -0.5, 0.285317, 0, -1, 0, 0.592705, 0.214683, + 0.108156, 0.5, 0.33287, 0, 1, 0, 0.608156, 0.16713, + 0.283156, 0.5, 0.205725, 0, 1, 0, 0.783156, 0.294275, + 0.242705, 0.5, 0.176336, 0, 1, 0, 0.742705, 0.323664, + 0.0927051, 0.5, 0.285317, 0, 1, 0, 0.592705, 0.214683, + 0.108156, 0.5, 0.33287, 0, 1, 0, 0.608156, 0.16713, + 0.242705, 0.5, 0.176336, 0, 1, 0, 0.742705, 0.323664, + 0.154508, -0.2, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.7, + 0.404509, -0.2, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.7, + 0.404509, -0.1, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.6, + 0.154508, -0.1, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.6, + 0.154508, -0.2, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.7, + 0.404509, -0.1, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.6, + 0.283156, -0.5, 0.205725, 0, -1, 0, 0.783156, 0.294275, + 0.323607, -0.5, 0.235114, 0, -1, 0, 0.823607, 0.264886, + 0.123607, -0.5, 0.380423, 0, -1, 0, 0.623607, 0.119577, + 0.283156, -0.5, 0.205725, 0, -1, 0, 0.783156, 0.294275, + 0.123607, -0.5, 0.380423, 0, -1, 0, 0.623607, 0.119577, + 0.108156, -0.5, 0.33287, 0, -1, 0, 0.608156, 0.16713, + 0.123607, 0.5, 0.380423, 0, 1, 0, 0.623607, 0.119577, + 0.323607, 0.5, 0.235114, 0, 1, 0, 0.823607, 0.264886, + 0.283156, 0.5, 0.205725, 0, 1, 0, 0.783156, 0.294275, + 0.108156, 0.5, 0.33287, 0, 1, 0, 0.608156, 0.16713, + 0.123607, 0.5, 0.380423, 0, 1, 0, 0.623607, 0.119577, + 0.283156, 0.5, 0.205725, 0, 1, 0, 0.783156, 0.294275, + 0.154508, -0.3, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.8, + 0.404509, -0.3, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.8, + 0.404509, -0.2, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.7, + 0.154508, -0.2, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.7, + 0.154508, -0.3, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.8, + 0.404509, -0.2, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.7, + 0.323607, -0.5, 0.235114, 0, -1, 0, 0.823607, 0.264886, + 0.364058, -0.5, 0.264503, 0, -1, 0, 0.864058, 0.235497, + 0.139058, -0.5, 0.427975, 0, -1, 0, 0.639058, 0.0720246, + 0.323607, -0.5, 0.235114, 0, -1, 0, 0.823607, 0.264886, + 0.139058, -0.5, 0.427975, 0, -1, 0, 0.639058, 0.0720246, + 0.123607, -0.5, 0.380423, 0, -1, 0, 0.623607, 0.119577, + 0.139058, 0.5, 0.427975, 0, 1, 0, 0.639058, 0.0720246, + 0.364058, 0.5, 0.264503, 0, 1, 0, 0.864058, 0.235497, + 0.323607, 0.5, 0.235114, 0, 1, 0, 0.823607, 0.264886, + 0.123607, 0.5, 0.380423, 0, 1, 0, 0.623607, 0.119577, + 0.139058, 0.5, 0.427975, 0, 1, 0, 0.639058, 0.0720246, + 0.323607, 0.5, 0.235114, 0, 1, 0, 0.823607, 0.264886, + 0.154508, -0.4, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.9, + 0.404509, -0.4, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.9, + 0.404509, -0.3, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.8, + 0.154508, -0.3, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.8, + 0.154508, -0.4, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.9, + 0.404509, -0.3, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.8, + 0.364058, -0.5, 0.264503, 0, -1, 0, 0.864058, 0.235497, + 0.404509, -0.5, 0.293893, 0, -1, 0, 0.904508, 0.206107, + 0.154508, -0.5, 0.475528, 0, -1, 0, 0.654508, 0.0244717, + 0.364058, -0.5, 0.264503, 0, -1, 0, 0.864058, 0.235497, + 0.154508, -0.5, 0.475528, 0, -1, 0, 0.654508, 0.0244717, + 0.139058, -0.5, 0.427975, 0, -1, 0, 0.639058, 0.0720246, + 0.154508, 0.5, 0.475528, 0, 1, 0, 0.654508, 0.0244717, + 0.404509, 0.5, 0.293893, 0, 1, 0, 0.904508, 0.206107, + 0.364058, 0.5, 0.264503, 0, 1, 0, 0.864058, 0.235497, + 0.139058, 0.5, 0.427975, 0, 1, 0, 0.639058, 0.0720246, + 0.154508, 0.5, 0.475528, 0, 1, 0, 0.654508, 0.0244717, + 0.364058, 0.5, 0.264503, 0, 1, 0, 0.864058, 0.235497, + 0.154508, -0.5, 0.475528, 0.309017, 0, 0.951057, 0.2, 1, + 0.404509, -0.5, 0.293893, 0.809017, 0, 0.587785, 0.1, 1, + 0.404509, -0.4, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.9, + 0.154508, -0.4, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.9, + 0.154508, -0.5, 0.475528, 0.309017, 0, 0.951057, 0.2, 1, + 0.404509, -0.4, 0.293893, 0.809017, 0, 0.587785, 0.1, 0.9, + 0, -0.5, 0, 0, -1, 0, 0.5, 0.5, + 0.0154508, -0.5, 0.0475528, 0, -1, 0, 0.515451, 0.452447, + -0.0154509, -0.5, 0.0475528, 0, -1, 0, 0.484549, 0.452447, + -0.0154509, 0.5, 0.0475528, 0, 1, 0, 0.484549, 0.452447, + 0.0154508, 0.5, 0.0475528, 0, 1, 0, 0.515451, 0.452447, + 0, 0.5, 0, 0, 1, 0, 0.5, 0.5, + -0.154509, 0.4, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.1, + 0.154508, 0.4, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.1, + 0.154508, 0.5, 0.475528, 0.309017, 0, 0.951057, 0.2, 0, + -0.154509, 0.5, 0.475528, -0.309017, 0, 0.951057, 0.3, 0, + -0.154509, 0.4, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.1, + 0.154508, 0.5, 0.475528, 0.309017, 0, 0.951057, 0.2, 0, + 0.0154508, -0.5, 0.0475528, 0, -1, 0, 0.515451, 0.452447, + 0.0309017, -0.5, 0.0951057, 0, -1, 0, 0.530902, 0.404894, + -0.0309017, -0.5, 0.0951056, 0, -1, 0, 0.469098, 0.404894, + 0.0154508, -0.5, 0.0475528, 0, -1, 0, 0.515451, 0.452447, + -0.0309017, -0.5, 0.0951056, 0, -1, 0, 0.469098, 0.404894, + -0.0154509, -0.5, 0.0475528, 0, -1, 0, 0.484549, 0.452447, + -0.0309017, 0.5, 0.0951056, 0, 1, 0, 0.469098, 0.404894, + 0.0309017, 0.5, 0.0951057, 0, 1, 0, 0.530902, 0.404894, + 0.0154508, 0.5, 0.0475528, 0, 1, 0, 0.515451, 0.452447, + -0.0154509, 0.5, 0.0475528, 0, 1, 0, 0.484549, 0.452447, + -0.0309017, 0.5, 0.0951056, 0, 1, 0, 0.469098, 0.404894, + 0.0154508, 0.5, 0.0475528, 0, 1, 0, 0.515451, 0.452447, + -0.154509, 0.3, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.2, + 0.154508, 0.3, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.2, + 0.154508, 0.4, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.1, + -0.154509, 0.4, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.1, + -0.154509, 0.3, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.2, + 0.154508, 0.4, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.1, + 0.0309017, -0.5, 0.0951057, 0, -1, 0, 0.530902, 0.404894, + 0.0463525, -0.5, 0.142658, 0, -1, 0, 0.546353, 0.357342, + -0.0463526, -0.5, 0.142658, 0, -1, 0, 0.453647, 0.357342, + 0.0309017, -0.5, 0.0951057, 0, -1, 0, 0.530902, 0.404894, + -0.0463526, -0.5, 0.142658, 0, -1, 0, 0.453647, 0.357342, + -0.0309017, -0.5, 0.0951056, 0, -1, 0, 0.469098, 0.404894, + -0.0463526, 0.5, 0.142658, 0, 1, 0, 0.453647, 0.357342, + 0.0463525, 0.5, 0.142658, 0, 1, 0, 0.546353, 0.357342, + 0.0309017, 0.5, 0.0951057, 0, 1, 0, 0.530902, 0.404894, + -0.0309017, 0.5, 0.0951056, 0, 1, 0, 0.469098, 0.404894, + -0.0463526, 0.5, 0.142658, 0, 1, 0, 0.453647, 0.357342, + 0.0309017, 0.5, 0.0951057, 0, 1, 0, 0.530902, 0.404894, + -0.154509, 0.2, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.3, + 0.154508, 0.2, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.3, + 0.154508, 0.3, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.2, + -0.154509, 0.3, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.2, + -0.154509, 0.2, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.3, + 0.154508, 0.3, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.2, + 0.0463525, -0.5, 0.142658, 0, -1, 0, 0.546353, 0.357342, + 0.0618034, -0.5, 0.190211, 0, -1, 0, 0.561803, 0.309789, + -0.0618034, -0.5, 0.190211, 0, -1, 0, 0.438197, 0.309789, + 0.0463525, -0.5, 0.142658, 0, -1, 0, 0.546353, 0.357342, + -0.0618034, -0.5, 0.190211, 0, -1, 0, 0.438197, 0.309789, + -0.0463526, -0.5, 0.142658, 0, -1, 0, 0.453647, 0.357342, + -0.0618034, 0.5, 0.190211, 0, 1, 0, 0.438197, 0.309789, + 0.0618034, 0.5, 0.190211, 0, 1, 0, 0.561803, 0.309789, + 0.0463525, 0.5, 0.142658, 0, 1, 0, 0.546353, 0.357342, + -0.0463526, 0.5, 0.142658, 0, 1, 0, 0.453647, 0.357342, + -0.0618034, 0.5, 0.190211, 0, 1, 0, 0.438197, 0.309789, + 0.0463525, 0.5, 0.142658, 0, 1, 0, 0.546353, 0.357342, + -0.154509, 0.1, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.4, + 0.154508, 0.1, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.4, + 0.154508, 0.2, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.3, + -0.154509, 0.2, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.3, + -0.154509, 0.1, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.4, + 0.154508, 0.2, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.3, + 0.0618034, -0.5, 0.190211, 0, -1, 0, 0.561803, 0.309789, + 0.0772542, -0.5, 0.237764, 0, -1, 0, 0.577254, 0.262236, + -0.0772543, -0.5, 0.237764, 0, -1, 0, 0.422746, 0.262236, + 0.0618034, -0.5, 0.190211, 0, -1, 0, 0.561803, 0.309789, + -0.0772543, -0.5, 0.237764, 0, -1, 0, 0.422746, 0.262236, + -0.0618034, -0.5, 0.190211, 0, -1, 0, 0.438197, 0.309789, + -0.0772543, 0.5, 0.237764, 0, 1, 0, 0.422746, 0.262236, + 0.0772542, 0.5, 0.237764, 0, 1, 0, 0.577254, 0.262236, + 0.0618034, 0.5, 0.190211, 0, 1, 0, 0.561803, 0.309789, + -0.0618034, 0.5, 0.190211, 0, 1, 0, 0.438197, 0.309789, + -0.0772543, 0.5, 0.237764, 0, 1, 0, 0.422746, 0.262236, + 0.0618034, 0.5, 0.190211, 0, 1, 0, 0.561803, 0.309789, + -0.154509, 0, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.5, + 0.154508, 0, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.5, + 0.154508, 0.1, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.4, + -0.154509, 0.1, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.4, + -0.154509, 0, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.5, + 0.154508, 0.1, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.4, + 0.0772542, -0.5, 0.237764, 0, -1, 0, 0.577254, 0.262236, + 0.0927051, -0.5, 0.285317, 0, -1, 0, 0.592705, 0.214683, + -0.0927051, -0.5, 0.285317, 0, -1, 0, 0.407295, 0.214683, + 0.0772542, -0.5, 0.237764, 0, -1, 0, 0.577254, 0.262236, + -0.0927051, -0.5, 0.285317, 0, -1, 0, 0.407295, 0.214683, + -0.0772543, -0.5, 0.237764, 0, -1, 0, 0.422746, 0.262236, + -0.0927051, 0.5, 0.285317, 0, 1, 0, 0.407295, 0.214683, + 0.0927051, 0.5, 0.285317, 0, 1, 0, 0.592705, 0.214683, + 0.0772542, 0.5, 0.237764, 0, 1, 0, 0.577254, 0.262236, + -0.0772543, 0.5, 0.237764, 0, 1, 0, 0.422746, 0.262236, + -0.0927051, 0.5, 0.285317, 0, 1, 0, 0.407295, 0.214683, + 0.0772542, 0.5, 0.237764, 0, 1, 0, 0.577254, 0.262236, + -0.154509, -0.1, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.6, + 0.154508, -0.1, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.6, + 0.154508, 0, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.5, + -0.154509, 0, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.5, + -0.154509, -0.1, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.6, + 0.154508, 0, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.5, + 0.0927051, -0.5, 0.285317, 0, -1, 0, 0.592705, 0.214683, + 0.108156, -0.5, 0.33287, 0, -1, 0, 0.608156, 0.16713, + -0.108156, -0.5, 0.33287, 0, -1, 0, 0.391844, 0.16713, + 0.0927051, -0.5, 0.285317, 0, -1, 0, 0.592705, 0.214683, + -0.108156, -0.5, 0.33287, 0, -1, 0, 0.391844, 0.16713, + -0.0927051, -0.5, 0.285317, 0, -1, 0, 0.407295, 0.214683, + -0.108156, 0.5, 0.33287, 0, 1, 0, 0.391844, 0.16713, + 0.108156, 0.5, 0.33287, 0, 1, 0, 0.608156, 0.16713, + 0.0927051, 0.5, 0.285317, 0, 1, 0, 0.592705, 0.214683, + -0.0927051, 0.5, 0.285317, 0, 1, 0, 0.407295, 0.214683, + -0.108156, 0.5, 0.33287, 0, 1, 0, 0.391844, 0.16713, + 0.0927051, 0.5, 0.285317, 0, 1, 0, 0.592705, 0.214683, + -0.154509, -0.2, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.7, + 0.154508, -0.2, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.7, + 0.154508, -0.1, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.6, + -0.154509, -0.1, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.6, + -0.154509, -0.2, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.7, + 0.154508, -0.1, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.6, + 0.108156, -0.5, 0.33287, 0, -1, 0, 0.608156, 0.16713, + 0.123607, -0.5, 0.380423, 0, -1, 0, 0.623607, 0.119577, + -0.123607, -0.5, 0.380423, 0, -1, 0, 0.376393, 0.119577, + 0.108156, -0.5, 0.33287, 0, -1, 0, 0.608156, 0.16713, + -0.123607, -0.5, 0.380423, 0, -1, 0, 0.376393, 0.119577, + -0.108156, -0.5, 0.33287, 0, -1, 0, 0.391844, 0.16713, + -0.123607, 0.5, 0.380423, 0, 1, 0, 0.376393, 0.119577, + 0.123607, 0.5, 0.380423, 0, 1, 0, 0.623607, 0.119577, + 0.108156, 0.5, 0.33287, 0, 1, 0, 0.608156, 0.16713, + -0.108156, 0.5, 0.33287, 0, 1, 0, 0.391844, 0.16713, + -0.123607, 0.5, 0.380423, 0, 1, 0, 0.376393, 0.119577, + 0.108156, 0.5, 0.33287, 0, 1, 0, 0.608156, 0.16713, + -0.154509, -0.3, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.8, + 0.154508, -0.3, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.8, + 0.154508, -0.2, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.7, + -0.154509, -0.2, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.7, + -0.154509, -0.3, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.8, + 0.154508, -0.2, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.7, + 0.123607, -0.5, 0.380423, 0, -1, 0, 0.623607, 0.119577, + 0.139058, -0.5, 0.427975, 0, -1, 0, 0.639058, 0.0720246, + -0.139058, -0.5, 0.427975, 0, -1, 0, 0.360942, 0.0720246, + 0.123607, -0.5, 0.380423, 0, -1, 0, 0.623607, 0.119577, + -0.139058, -0.5, 0.427975, 0, -1, 0, 0.360942, 0.0720246, + -0.123607, -0.5, 0.380423, 0, -1, 0, 0.376393, 0.119577, + -0.139058, 0.5, 0.427975, 0, 1, 0, 0.360942, 0.0720246, + 0.139058, 0.5, 0.427975, 0, 1, 0, 0.639058, 0.0720246, + 0.123607, 0.5, 0.380423, 0, 1, 0, 0.623607, 0.119577, + -0.123607, 0.5, 0.380423, 0, 1, 0, 0.376393, 0.119577, + -0.139058, 0.5, 0.427975, 0, 1, 0, 0.360942, 0.0720246, + 0.123607, 0.5, 0.380423, 0, 1, 0, 0.623607, 0.119577, + -0.154509, -0.4, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.9, + 0.154508, -0.4, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.9, + 0.154508, -0.3, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.8, + -0.154509, -0.3, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.8, + -0.154509, -0.4, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.9, + 0.154508, -0.3, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.8, + 0.139058, -0.5, 0.427975, 0, -1, 0, 0.639058, 0.0720246, + 0.154508, -0.5, 0.475528, 0, -1, 0, 0.654508, 0.0244717, + -0.154509, -0.5, 0.475528, 0, -1, 0, 0.345491, 0.0244718, + 0.139058, -0.5, 0.427975, 0, -1, 0, 0.639058, 0.0720246, + -0.154509, -0.5, 0.475528, 0, -1, 0, 0.345491, 0.0244718, + -0.139058, -0.5, 0.427975, 0, -1, 0, 0.360942, 0.0720246, + -0.154509, 0.5, 0.475528, 0, 1, 0, 0.345491, 0.0244718, + 0.154508, 0.5, 0.475528, 0, 1, 0, 0.654508, 0.0244717, + 0.139058, 0.5, 0.427975, 0, 1, 0, 0.639058, 0.0720246, + -0.139058, 0.5, 0.427975, 0, 1, 0, 0.360942, 0.0720246, + -0.154509, 0.5, 0.475528, 0, 1, 0, 0.345491, 0.0244718, + 0.139058, 0.5, 0.427975, 0, 1, 0, 0.639058, 0.0720246, + -0.154509, -0.5, 0.475528, -0.309017, 0, 0.951057, 0.3, 1, + 0.154508, -0.5, 0.475528, 0.309017, 0, 0.951057, 0.2, 1, + 0.154508, -0.4, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.9, + -0.154509, -0.4, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.9, + -0.154509, -0.5, 0.475528, -0.309017, 0, 0.951057, 0.3, 1, + 0.154508, -0.4, 0.475528, 0.309017, 0, 0.951057, 0.2, 0.9, + -0, -0.5, 0, 0, -1, 0, 0.5, 0.5, + -0.0154509, -0.5, 0.0475528, 0, -1, 0, 0.484549, 0.452447, + -0.0404509, -0.5, 0.0293893, 0, -1, 0, 0.459549, 0.470611, + -0.0404509, 0.5, 0.0293893, 0, 1, 0, 0.459549, 0.470611, + -0.0154509, 0.5, 0.0475528, 0, 1, 0, 0.484549, 0.452447, + -0, 0.5, 0, 0, 1, 0, 0.5, 0.5, + -0.404509, 0.4, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.1, + -0.154509, 0.4, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.1, + -0.154509, 0.5, 0.475528, -0.309017, 0, 0.951057, 0.3, 0, + -0.404509, 0.5, 0.293893, -0.809017, 0, 0.587785, 0.4, 0, + -0.404509, 0.4, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.1, + -0.154509, 0.5, 0.475528, -0.309017, 0, 0.951057, 0.3, 0, + -0.0154509, -0.5, 0.0475528, 0, -1, 0, 0.484549, 0.452447, + -0.0309017, -0.5, 0.0951056, 0, -1, 0, 0.469098, 0.404894, + -0.0809017, -0.5, 0.0587785, 0, -1, 0, 0.419098, 0.441221, + -0.0154509, -0.5, 0.0475528, 0, -1, 0, 0.484549, 0.452447, + -0.0809017, -0.5, 0.0587785, 0, -1, 0, 0.419098, 0.441221, + -0.0404509, -0.5, 0.0293893, 0, -1, 0, 0.459549, 0.470611, + -0.0809017, 0.5, 0.0587785, 0, 1, 0, 0.419098, 0.441221, + -0.0309017, 0.5, 0.0951056, 0, 1, 0, 0.469098, 0.404894, + -0.0154509, 0.5, 0.0475528, 0, 1, 0, 0.484549, 0.452447, + -0.0404509, 0.5, 0.0293893, 0, 1, 0, 0.459549, 0.470611, + -0.0809017, 0.5, 0.0587785, 0, 1, 0, 0.419098, 0.441221, + -0.0154509, 0.5, 0.0475528, 0, 1, 0, 0.484549, 0.452447, + -0.404509, 0.3, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.2, + -0.154509, 0.3, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.2, + -0.154509, 0.4, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.1, + -0.404509, 0.4, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.1, + -0.404509, 0.3, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.2, + -0.154509, 0.4, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.1, + -0.0309017, -0.5, 0.0951056, 0, -1, 0, 0.469098, 0.404894, + -0.0463526, -0.5, 0.142658, 0, -1, 0, 0.453647, 0.357342, + -0.121353, -0.5, 0.0881678, 0, -1, 0, 0.378647, 0.411832, + -0.0309017, -0.5, 0.0951056, 0, -1, 0, 0.469098, 0.404894, + -0.121353, -0.5, 0.0881678, 0, -1, 0, 0.378647, 0.411832, + -0.0809017, -0.5, 0.0587785, 0, -1, 0, 0.419098, 0.441221, + -0.121353, 0.5, 0.0881678, 0, 1, 0, 0.378647, 0.411832, + -0.0463526, 0.5, 0.142658, 0, 1, 0, 0.453647, 0.357342, + -0.0309017, 0.5, 0.0951056, 0, 1, 0, 0.469098, 0.404894, + -0.0809017, 0.5, 0.0587785, 0, 1, 0, 0.419098, 0.441221, + -0.121353, 0.5, 0.0881678, 0, 1, 0, 0.378647, 0.411832, + -0.0309017, 0.5, 0.0951056, 0, 1, 0, 0.469098, 0.404894, + -0.404509, 0.2, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.3, + -0.154509, 0.2, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.3, + -0.154509, 0.3, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.2, + -0.404509, 0.3, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.2, + -0.404509, 0.2, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.3, + -0.154509, 0.3, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.2, + -0.0463526, -0.5, 0.142658, 0, -1, 0, 0.453647, 0.357342, + -0.0618034, -0.5, 0.190211, 0, -1, 0, 0.438197, 0.309789, + -0.161803, -0.5, 0.117557, 0, -1, 0, 0.338197, 0.382443, + -0.0463526, -0.5, 0.142658, 0, -1, 0, 0.453647, 0.357342, + -0.161803, -0.5, 0.117557, 0, -1, 0, 0.338197, 0.382443, + -0.121353, -0.5, 0.0881678, 0, -1, 0, 0.378647, 0.411832, + -0.161803, 0.5, 0.117557, 0, 1, 0, 0.338197, 0.382443, + -0.0618034, 0.5, 0.190211, 0, 1, 0, 0.438197, 0.309789, + -0.0463526, 0.5, 0.142658, 0, 1, 0, 0.453647, 0.357342, + -0.121353, 0.5, 0.0881678, 0, 1, 0, 0.378647, 0.411832, + -0.161803, 0.5, 0.117557, 0, 1, 0, 0.338197, 0.382443, + -0.0463526, 0.5, 0.142658, 0, 1, 0, 0.453647, 0.357342, + -0.404509, 0.1, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.4, + -0.154509, 0.1, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.4, + -0.154509, 0.2, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.3, + -0.404509, 0.2, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.3, + -0.404509, 0.1, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.4, + -0.154509, 0.2, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.3, + -0.0618034, -0.5, 0.190211, 0, -1, 0, 0.438197, 0.309789, + -0.0772543, -0.5, 0.237764, 0, -1, 0, 0.422746, 0.262236, + -0.202254, -0.5, 0.146946, 0, -1, 0, 0.297746, 0.353054, + -0.0618034, -0.5, 0.190211, 0, -1, 0, 0.438197, 0.309789, + -0.202254, -0.5, 0.146946, 0, -1, 0, 0.297746, 0.353054, + -0.161803, -0.5, 0.117557, 0, -1, 0, 0.338197, 0.382443, + -0.202254, 0.5, 0.146946, 0, 1, 0, 0.297746, 0.353054, + -0.0772543, 0.5, 0.237764, 0, 1, 0, 0.422746, 0.262236, + -0.0618034, 0.5, 0.190211, 0, 1, 0, 0.438197, 0.309789, + -0.161803, 0.5, 0.117557, 0, 1, 0, 0.338197, 0.382443, + -0.202254, 0.5, 0.146946, 0, 1, 0, 0.297746, 0.353054, + -0.0618034, 0.5, 0.190211, 0, 1, 0, 0.438197, 0.309789, + -0.404509, 0, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.5, + -0.154509, 0, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.5, + -0.154509, 0.1, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.4, + -0.404509, 0.1, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.4, + -0.404509, 0, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.5, + -0.154509, 0.1, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.4, + -0.0772543, -0.5, 0.237764, 0, -1, 0, 0.422746, 0.262236, + -0.0927051, -0.5, 0.285317, 0, -1, 0, 0.407295, 0.214683, + -0.242705, -0.5, 0.176336, 0, -1, 0, 0.257295, 0.323664, + -0.0772543, -0.5, 0.237764, 0, -1, 0, 0.422746, 0.262236, + -0.242705, -0.5, 0.176336, 0, -1, 0, 0.257295, 0.323664, + -0.202254, -0.5, 0.146946, 0, -1, 0, 0.297746, 0.353054, + -0.242705, 0.5, 0.176336, 0, 1, 0, 0.257295, 0.323664, + -0.0927051, 0.5, 0.285317, 0, 1, 0, 0.407295, 0.214683, + -0.0772543, 0.5, 0.237764, 0, 1, 0, 0.422746, 0.262236, + -0.202254, 0.5, 0.146946, 0, 1, 0, 0.297746, 0.353054, + -0.242705, 0.5, 0.176336, 0, 1, 0, 0.257295, 0.323664, + -0.0772543, 0.5, 0.237764, 0, 1, 0, 0.422746, 0.262236, + -0.404509, -0.1, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.6, + -0.154509, -0.1, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.6, + -0.154509, 0, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.5, + -0.404509, 0, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.5, + -0.404509, -0.1, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.6, + -0.154509, 0, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.5, + -0.0927051, -0.5, 0.285317, 0, -1, 0, 0.407295, 0.214683, + -0.108156, -0.5, 0.33287, 0, -1, 0, 0.391844, 0.16713, + -0.283156, -0.5, 0.205725, 0, -1, 0, 0.216844, 0.294275, + -0.0927051, -0.5, 0.285317, 0, -1, 0, 0.407295, 0.214683, + -0.283156, -0.5, 0.205725, 0, -1, 0, 0.216844, 0.294275, + -0.242705, -0.5, 0.176336, 0, -1, 0, 0.257295, 0.323664, + -0.283156, 0.5, 0.205725, 0, 1, 0, 0.216844, 0.294275, + -0.108156, 0.5, 0.33287, 0, 1, 0, 0.391844, 0.16713, + -0.0927051, 0.5, 0.285317, 0, 1, 0, 0.407295, 0.214683, + -0.242705, 0.5, 0.176336, 0, 1, 0, 0.257295, 0.323664, + -0.283156, 0.5, 0.205725, 0, 1, 0, 0.216844, 0.294275, + -0.0927051, 0.5, 0.285317, 0, 1, 0, 0.407295, 0.214683, + -0.404509, -0.2, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.7, + -0.154509, -0.2, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.7, + -0.154509, -0.1, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.6, + -0.404509, -0.1, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.6, + -0.404509, -0.2, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.7, + -0.154509, -0.1, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.6, + -0.108156, -0.5, 0.33287, 0, -1, 0, 0.391844, 0.16713, + -0.123607, -0.5, 0.380423, 0, -1, 0, 0.376393, 0.119577, + -0.323607, -0.5, 0.235114, 0, -1, 0, 0.176393, 0.264886, + -0.108156, -0.5, 0.33287, 0, -1, 0, 0.391844, 0.16713, + -0.323607, -0.5, 0.235114, 0, -1, 0, 0.176393, 0.264886, + -0.283156, -0.5, 0.205725, 0, -1, 0, 0.216844, 0.294275, + -0.323607, 0.5, 0.235114, 0, 1, 0, 0.176393, 0.264886, + -0.123607, 0.5, 0.380423, 0, 1, 0, 0.376393, 0.119577, + -0.108156, 0.5, 0.33287, 0, 1, 0, 0.391844, 0.16713, + -0.283156, 0.5, 0.205725, 0, 1, 0, 0.216844, 0.294275, + -0.323607, 0.5, 0.235114, 0, 1, 0, 0.176393, 0.264886, + -0.108156, 0.5, 0.33287, 0, 1, 0, 0.391844, 0.16713, + -0.404509, -0.3, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.8, + -0.154509, -0.3, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.8, + -0.154509, -0.2, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.7, + -0.404509, -0.2, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.7, + -0.404509, -0.3, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.8, + -0.154509, -0.2, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.7, + -0.123607, -0.5, 0.380423, 0, -1, 0, 0.376393, 0.119577, + -0.139058, -0.5, 0.427975, 0, -1, 0, 0.360942, 0.0720246, + -0.364058, -0.5, 0.264503, 0, -1, 0, 0.135942, 0.235497, + -0.123607, -0.5, 0.380423, 0, -1, 0, 0.376393, 0.119577, + -0.364058, -0.5, 0.264503, 0, -1, 0, 0.135942, 0.235497, + -0.323607, -0.5, 0.235114, 0, -1, 0, 0.176393, 0.264886, + -0.364058, 0.5, 0.264503, 0, 1, 0, 0.135942, 0.235497, + -0.139058, 0.5, 0.427975, 0, 1, 0, 0.360942, 0.0720246, + -0.123607, 0.5, 0.380423, 0, 1, 0, 0.376393, 0.119577, + -0.323607, 0.5, 0.235114, 0, 1, 0, 0.176393, 0.264886, + -0.364058, 0.5, 0.264503, 0, 1, 0, 0.135942, 0.235497, + -0.123607, 0.5, 0.380423, 0, 1, 0, 0.376393, 0.119577, + -0.404509, -0.4, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.9, + -0.154509, -0.4, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.9, + -0.154509, -0.3, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.8, + -0.404509, -0.3, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.8, + -0.404509, -0.4, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.9, + -0.154509, -0.3, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.8, + -0.139058, -0.5, 0.427975, 0, -1, 0, 0.360942, 0.0720246, + -0.154509, -0.5, 0.475528, 0, -1, 0, 0.345491, 0.0244718, + -0.404509, -0.5, 0.293893, 0, -1, 0, 0.0954915, 0.206107, + -0.139058, -0.5, 0.427975, 0, -1, 0, 0.360942, 0.0720246, + -0.404509, -0.5, 0.293893, 0, -1, 0, 0.0954915, 0.206107, + -0.364058, -0.5, 0.264503, 0, -1, 0, 0.135942, 0.235497, + -0.404509, 0.5, 0.293893, 0, 1, 0, 0.0954915, 0.206107, + -0.154509, 0.5, 0.475528, 0, 1, 0, 0.345491, 0.0244718, + -0.139058, 0.5, 0.427975, 0, 1, 0, 0.360942, 0.0720246, + -0.364058, 0.5, 0.264503, 0, 1, 0, 0.135942, 0.235497, + -0.404509, 0.5, 0.293893, 0, 1, 0, 0.0954915, 0.206107, + -0.139058, 0.5, 0.427975, 0, 1, 0, 0.360942, 0.0720246, + -0.404509, -0.5, 0.293893, -0.809017, 0, 0.587785, 0.4, 1, + -0.154509, -0.5, 0.475528, -0.309017, 0, 0.951057, 0.3, 1, + -0.154509, -0.4, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.9, + -0.404509, -0.4, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.9, + -0.404509, -0.5, 0.293893, -0.809017, 0, 0.587785, 0.4, 1, + -0.154509, -0.4, 0.475528, -0.309017, 0, 0.951057, 0.3, 0.9, + -0, -0.5, 0, 0, -1, 0, 0.5, 0.5, + -0.0404509, -0.5, 0.0293893, 0, -1, 0, 0.459549, 0.470611, + -0.05, -0.5, -4.37114e-09, 0, -1, 0, 0.45, 0.5, + -0.05, 0.5, -4.37114e-09, 0, 1, 0, 0.45, 0.5, + -0.0404509, 0.5, 0.0293893, 0, 1, 0, 0.459549, 0.470611, + -0, 0.5, 0, 0, 1, 0, 0.5, 0.5, + -0.5, 0.4, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.1, + -0.404509, 0.4, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.1, + -0.404509, 0.5, 0.293893, -0.809017, 0, 0.587785, 0.4, 0, + -0.5, 0.5, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0, + -0.5, 0.4, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.1, + -0.404509, 0.5, 0.293893, -0.809017, 0, 0.587785, 0.4, 0, + -0.0404509, -0.5, 0.0293893, 0, -1, 0, 0.459549, 0.470611, + -0.0809017, -0.5, 0.0587785, 0, -1, 0, 0.419098, 0.441221, + -0.1, -0.5, -8.74228e-09, 0, -1, 0, 0.4, 0.5, + -0.0404509, -0.5, 0.0293893, 0, -1, 0, 0.459549, 0.470611, + -0.1, -0.5, -8.74228e-09, 0, -1, 0, 0.4, 0.5, + -0.05, -0.5, -4.37114e-09, 0, -1, 0, 0.45, 0.5, + -0.1, 0.5, -8.74228e-09, 0, 1, 0, 0.4, 0.5, + -0.0809017, 0.5, 0.0587785, 0, 1, 0, 0.419098, 0.441221, + -0.0404509, 0.5, 0.0293893, 0, 1, 0, 0.459549, 0.470611, + -0.05, 0.5, -4.37114e-09, 0, 1, 0, 0.45, 0.5, + -0.1, 0.5, -8.74228e-09, 0, 1, 0, 0.4, 0.5, + -0.0404509, 0.5, 0.0293893, 0, 1, 0, 0.459549, 0.470611, + -0.5, 0.3, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.2, + -0.404509, 0.3, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.2, + -0.404509, 0.4, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.1, + -0.5, 0.4, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.1, + -0.5, 0.3, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.2, + -0.404509, 0.4, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.1, + -0.0809017, -0.5, 0.0587785, 0, -1, 0, 0.419098, 0.441221, + -0.121353, -0.5, 0.0881678, 0, -1, 0, 0.378647, 0.411832, + -0.15, -0.5, -1.31134e-08, 0, -1, 0, 0.35, 0.5, + -0.0809017, -0.5, 0.0587785, 0, -1, 0, 0.419098, 0.441221, + -0.15, -0.5, -1.31134e-08, 0, -1, 0, 0.35, 0.5, + -0.1, -0.5, -8.74228e-09, 0, -1, 0, 0.4, 0.5, + -0.15, 0.5, -1.31134e-08, 0, 1, 0, 0.35, 0.5, + -0.121353, 0.5, 0.0881678, 0, 1, 0, 0.378647, 0.411832, + -0.0809017, 0.5, 0.0587785, 0, 1, 0, 0.419098, 0.441221, + -0.1, 0.5, -8.74228e-09, 0, 1, 0, 0.4, 0.5, + -0.15, 0.5, -1.31134e-08, 0, 1, 0, 0.35, 0.5, + -0.0809017, 0.5, 0.0587785, 0, 1, 0, 0.419098, 0.441221, + -0.5, 0.2, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.3, + -0.404509, 0.2, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.3, + -0.404509, 0.3, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.2, + -0.5, 0.3, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.2, + -0.5, 0.2, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.3, + -0.404509, 0.3, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.2, + -0.121353, -0.5, 0.0881678, 0, -1, 0, 0.378647, 0.411832, + -0.161803, -0.5, 0.117557, 0, -1, 0, 0.338197, 0.382443, + -0.2, -0.5, -1.74846e-08, 0, -1, 0, 0.3, 0.5, + -0.121353, -0.5, 0.0881678, 0, -1, 0, 0.378647, 0.411832, + -0.2, -0.5, -1.74846e-08, 0, -1, 0, 0.3, 0.5, + -0.15, -0.5, -1.31134e-08, 0, -1, 0, 0.35, 0.5, + -0.2, 0.5, -1.74846e-08, 0, 1, 0, 0.3, 0.5, + -0.161803, 0.5, 0.117557, 0, 1, 0, 0.338197, 0.382443, + -0.121353, 0.5, 0.0881678, 0, 1, 0, 0.378647, 0.411832, + -0.15, 0.5, -1.31134e-08, 0, 1, 0, 0.35, 0.5, + -0.2, 0.5, -1.74846e-08, 0, 1, 0, 0.3, 0.5, + -0.121353, 0.5, 0.0881678, 0, 1, 0, 0.378647, 0.411832, + -0.5, 0.1, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.4, + -0.404509, 0.1, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.4, + -0.404509, 0.2, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.3, + -0.5, 0.2, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.3, + -0.5, 0.1, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.4, + -0.404509, 0.2, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.3, + -0.161803, -0.5, 0.117557, 0, -1, 0, 0.338197, 0.382443, + -0.202254, -0.5, 0.146946, 0, -1, 0, 0.297746, 0.353054, + -0.25, -0.5, -2.18557e-08, 0, -1, 0, 0.25, 0.5, + -0.161803, -0.5, 0.117557, 0, -1, 0, 0.338197, 0.382443, + -0.25, -0.5, -2.18557e-08, 0, -1, 0, 0.25, 0.5, + -0.2, -0.5, -1.74846e-08, 0, -1, 0, 0.3, 0.5, + -0.25, 0.5, -2.18557e-08, 0, 1, 0, 0.25, 0.5, + -0.202254, 0.5, 0.146946, 0, 1, 0, 0.297746, 0.353054, + -0.161803, 0.5, 0.117557, 0, 1, 0, 0.338197, 0.382443, + -0.2, 0.5, -1.74846e-08, 0, 1, 0, 0.3, 0.5, + -0.25, 0.5, -2.18557e-08, 0, 1, 0, 0.25, 0.5, + -0.161803, 0.5, 0.117557, 0, 1, 0, 0.338197, 0.382443, + -0.5, 0, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.5, + -0.404509, 0, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.5, + -0.404509, 0.1, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.4, + -0.5, 0.1, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.4, + -0.5, 0, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.5, + -0.404509, 0.1, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.4, + -0.202254, -0.5, 0.146946, 0, -1, 0, 0.297746, 0.353054, + -0.242705, -0.5, 0.176336, 0, -1, 0, 0.257295, 0.323664, + -0.3, -0.5, -2.62268e-08, 0, -1, 0, 0.2, 0.5, + -0.202254, -0.5, 0.146946, 0, -1, 0, 0.297746, 0.353054, + -0.3, -0.5, -2.62268e-08, 0, -1, 0, 0.2, 0.5, + -0.25, -0.5, -2.18557e-08, 0, -1, 0, 0.25, 0.5, + -0.3, 0.5, -2.62268e-08, 0, 1, 0, 0.2, 0.5, + -0.242705, 0.5, 0.176336, 0, 1, 0, 0.257295, 0.323664, + -0.202254, 0.5, 0.146946, 0, 1, 0, 0.297746, 0.353054, + -0.25, 0.5, -2.18557e-08, 0, 1, 0, 0.25, 0.5, + -0.3, 0.5, -2.62268e-08, 0, 1, 0, 0.2, 0.5, + -0.202254, 0.5, 0.146946, 0, 1, 0, 0.297746, 0.353054, + -0.5, -0.1, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.6, + -0.404509, -0.1, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.6, + -0.404509, 0, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.5, + -0.5, 0, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.5, + -0.5, -0.1, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.6, + -0.404509, 0, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.5, + -0.242705, -0.5, 0.176336, 0, -1, 0, 0.257295, 0.323664, + -0.283156, -0.5, 0.205725, 0, -1, 0, 0.216844, 0.294275, + -0.35, -0.5, -3.0598e-08, 0, -1, 0, 0.15, 0.5, + -0.242705, -0.5, 0.176336, 0, -1, 0, 0.257295, 0.323664, + -0.35, -0.5, -3.0598e-08, 0, -1, 0, 0.15, 0.5, + -0.3, -0.5, -2.62268e-08, 0, -1, 0, 0.2, 0.5, + -0.35, 0.5, -3.0598e-08, 0, 1, 0, 0.15, 0.5, + -0.283156, 0.5, 0.205725, 0, 1, 0, 0.216844, 0.294275, + -0.242705, 0.5, 0.176336, 0, 1, 0, 0.257295, 0.323664, + -0.3, 0.5, -2.62268e-08, 0, 1, 0, 0.2, 0.5, + -0.35, 0.5, -3.0598e-08, 0, 1, 0, 0.15, 0.5, + -0.242705, 0.5, 0.176336, 0, 1, 0, 0.257295, 0.323664, + -0.5, -0.2, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.7, + -0.404509, -0.2, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.7, + -0.404509, -0.1, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.6, + -0.5, -0.1, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.6, + -0.5, -0.2, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.7, + -0.404509, -0.1, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.6, + -0.283156, -0.5, 0.205725, 0, -1, 0, 0.216844, 0.294275, + -0.323607, -0.5, 0.235114, 0, -1, 0, 0.176393, 0.264886, + -0.4, -0.5, -3.49691e-08, 0, -1, 0, 0.1, 0.5, + -0.283156, -0.5, 0.205725, 0, -1, 0, 0.216844, 0.294275, + -0.4, -0.5, -3.49691e-08, 0, -1, 0, 0.1, 0.5, + -0.35, -0.5, -3.0598e-08, 0, -1, 0, 0.15, 0.5, + -0.4, 0.5, -3.49691e-08, 0, 1, 0, 0.1, 0.5, + -0.323607, 0.5, 0.235114, 0, 1, 0, 0.176393, 0.264886, + -0.283156, 0.5, 0.205725, 0, 1, 0, 0.216844, 0.294275, + -0.35, 0.5, -3.0598e-08, 0, 1, 0, 0.15, 0.5, + -0.4, 0.5, -3.49691e-08, 0, 1, 0, 0.1, 0.5, + -0.283156, 0.5, 0.205725, 0, 1, 0, 0.216844, 0.294275, + -0.5, -0.3, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.8, + -0.404509, -0.3, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.8, + -0.404509, -0.2, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.7, + -0.5, -0.2, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.7, + -0.5, -0.3, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.8, + -0.404509, -0.2, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.7, + -0.323607, -0.5, 0.235114, 0, -1, 0, 0.176393, 0.264886, + -0.364058, -0.5, 0.264503, 0, -1, 0, 0.135942, 0.235497, + -0.45, -0.5, -3.93403e-08, 0, -1, 0, 0.05, 0.5, + -0.323607, -0.5, 0.235114, 0, -1, 0, 0.176393, 0.264886, + -0.45, -0.5, -3.93403e-08, 0, -1, 0, 0.05, 0.5, + -0.4, -0.5, -3.49691e-08, 0, -1, 0, 0.1, 0.5, + -0.45, 0.5, -3.93403e-08, 0, 1, 0, 0.05, 0.5, + -0.364058, 0.5, 0.264503, 0, 1, 0, 0.135942, 0.235497, + -0.323607, 0.5, 0.235114, 0, 1, 0, 0.176393, 0.264886, + -0.4, 0.5, -3.49691e-08, 0, 1, 0, 0.1, 0.5, + -0.45, 0.5, -3.93403e-08, 0, 1, 0, 0.05, 0.5, + -0.323607, 0.5, 0.235114, 0, 1, 0, 0.176393, 0.264886, + -0.5, -0.4, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.9, + -0.404509, -0.4, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.9, + -0.404509, -0.3, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.8, + -0.5, -0.3, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.8, + -0.5, -0.4, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.9, + -0.404509, -0.3, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.8, + -0.364058, -0.5, 0.264503, 0, -1, 0, 0.135942, 0.235497, + -0.404509, -0.5, 0.293893, 0, -1, 0, 0.0954915, 0.206107, + -0.5, -0.5, -4.37114e-08, 0, -1, 0, 0, 0.5, + -0.364058, -0.5, 0.264503, 0, -1, 0, 0.135942, 0.235497, + -0.5, -0.5, -4.37114e-08, 0, -1, 0, 0, 0.5, + -0.45, -0.5, -3.93403e-08, 0, -1, 0, 0.05, 0.5, + -0.5, 0.5, -4.37114e-08, 0, 1, 0, 0, 0.5, + -0.404509, 0.5, 0.293893, 0, 1, 0, 0.0954915, 0.206107, + -0.364058, 0.5, 0.264503, 0, 1, 0, 0.135942, 0.235497, + -0.45, 0.5, -3.93403e-08, 0, 1, 0, 0.05, 0.5, + -0.5, 0.5, -4.37114e-08, 0, 1, 0, 0, 0.5, + -0.364058, 0.5, 0.264503, 0, 1, 0, 0.135942, 0.235497, + -0.5, -0.5, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 1, + -0.404509, -0.5, 0.293893, -0.809017, 0, 0.587785, 0.4, 1, + -0.404509, -0.4, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.9, + -0.5, -0.4, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.9, + -0.5, -0.5, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 1, + -0.404509, -0.4, 0.293893, -0.809017, 0, 0.587785, 0.4, 0.9, + -0, -0.5, -0, 0, -1, 0, 0.5, 0.5, + -0.05, -0.5, -4.37114e-09, 0, -1, 0, 0.45, 0.5, + -0.0404508, -0.5, -0.0293893, 0, -1, 0, 0.459549, 0.529389, + -0.0404508, 0.5, -0.0293893, 0, 1, 0, 0.459549, 0.529389, + -0.05, 0.5, -4.37114e-09, 0, 1, 0, 0.45, 0.5, + -0, 0.5, -0, 0, 1, 0, 0.5, 0.5, + -0.404508, 0.4, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.1, + -0.5, 0.4, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.1, + -0.5, 0.5, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0, + -0.404508, 0.5, -0.293893, -0.809017, 0, -0.587785, 0.6, 0, + -0.404508, 0.4, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.1, + -0.5, 0.5, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0, + -0.05, -0.5, -4.37114e-09, 0, -1, 0, 0.45, 0.5, + -0.1, -0.5, -8.74228e-09, 0, -1, 0, 0.4, 0.5, + -0.0809017, -0.5, -0.0587785, 0, -1, 0, 0.419098, 0.558779, + -0.05, -0.5, -4.37114e-09, 0, -1, 0, 0.45, 0.5, + -0.0809017, -0.5, -0.0587785, 0, -1, 0, 0.419098, 0.558779, + -0.0404508, -0.5, -0.0293893, 0, -1, 0, 0.459549, 0.529389, + -0.0809017, 0.5, -0.0587785, 0, 1, 0, 0.419098, 0.558779, + -0.1, 0.5, -8.74228e-09, 0, 1, 0, 0.4, 0.5, + -0.05, 0.5, -4.37114e-09, 0, 1, 0, 0.45, 0.5, + -0.0404508, 0.5, -0.0293893, 0, 1, 0, 0.459549, 0.529389, + -0.0809017, 0.5, -0.0587785, 0, 1, 0, 0.419098, 0.558779, + -0.05, 0.5, -4.37114e-09, 0, 1, 0, 0.45, 0.5, + -0.404508, 0.3, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.2, + -0.5, 0.3, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.2, + -0.5, 0.4, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.1, + -0.404508, 0.4, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.1, + -0.404508, 0.3, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.2, + -0.5, 0.4, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.1, + -0.1, -0.5, -8.74228e-09, 0, -1, 0, 0.4, 0.5, + -0.15, -0.5, -1.31134e-08, 0, -1, 0, 0.35, 0.5, + -0.121353, -0.5, -0.0881678, 0, -1, 0, 0.378647, 0.588168, + -0.1, -0.5, -8.74228e-09, 0, -1, 0, 0.4, 0.5, + -0.121353, -0.5, -0.0881678, 0, -1, 0, 0.378647, 0.588168, + -0.0809017, -0.5, -0.0587785, 0, -1, 0, 0.419098, 0.558779, + -0.121353, 0.5, -0.0881678, 0, 1, 0, 0.378647, 0.588168, + -0.15, 0.5, -1.31134e-08, 0, 1, 0, 0.35, 0.5, + -0.1, 0.5, -8.74228e-09, 0, 1, 0, 0.4, 0.5, + -0.0809017, 0.5, -0.0587785, 0, 1, 0, 0.419098, 0.558779, + -0.121353, 0.5, -0.0881678, 0, 1, 0, 0.378647, 0.588168, + -0.1, 0.5, -8.74228e-09, 0, 1, 0, 0.4, 0.5, + -0.404508, 0.2, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.3, + -0.5, 0.2, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.3, + -0.5, 0.3, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.2, + -0.404508, 0.3, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.2, + -0.404508, 0.2, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.3, + -0.5, 0.3, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.2, + -0.15, -0.5, -1.31134e-08, 0, -1, 0, 0.35, 0.5, + -0.2, -0.5, -1.74846e-08, 0, -1, 0, 0.3, 0.5, + -0.161803, -0.5, -0.117557, 0, -1, 0, 0.338197, 0.617557, + -0.15, -0.5, -1.31134e-08, 0, -1, 0, 0.35, 0.5, + -0.161803, -0.5, -0.117557, 0, -1, 0, 0.338197, 0.617557, + -0.121353, -0.5, -0.0881678, 0, -1, 0, 0.378647, 0.588168, + -0.161803, 0.5, -0.117557, 0, 1, 0, 0.338197, 0.617557, + -0.2, 0.5, -1.74846e-08, 0, 1, 0, 0.3, 0.5, + -0.15, 0.5, -1.31134e-08, 0, 1, 0, 0.35, 0.5, + -0.121353, 0.5, -0.0881678, 0, 1, 0, 0.378647, 0.588168, + -0.161803, 0.5, -0.117557, 0, 1, 0, 0.338197, 0.617557, + -0.15, 0.5, -1.31134e-08, 0, 1, 0, 0.35, 0.5, + -0.404508, 0.1, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.4, + -0.5, 0.1, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.4, + -0.5, 0.2, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.3, + -0.404508, 0.2, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.3, + -0.404508, 0.1, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.4, + -0.5, 0.2, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.3, + -0.2, -0.5, -1.74846e-08, 0, -1, 0, 0.3, 0.5, + -0.25, -0.5, -2.18557e-08, 0, -1, 0, 0.25, 0.5, + -0.202254, -0.5, -0.146946, 0, -1, 0, 0.297746, 0.646946, + -0.2, -0.5, -1.74846e-08, 0, -1, 0, 0.3, 0.5, + -0.202254, -0.5, -0.146946, 0, -1, 0, 0.297746, 0.646946, + -0.161803, -0.5, -0.117557, 0, -1, 0, 0.338197, 0.617557, + -0.202254, 0.5, -0.146946, 0, 1, 0, 0.297746, 0.646946, + -0.25, 0.5, -2.18557e-08, 0, 1, 0, 0.25, 0.5, + -0.2, 0.5, -1.74846e-08, 0, 1, 0, 0.3, 0.5, + -0.161803, 0.5, -0.117557, 0, 1, 0, 0.338197, 0.617557, + -0.202254, 0.5, -0.146946, 0, 1, 0, 0.297746, 0.646946, + -0.2, 0.5, -1.74846e-08, 0, 1, 0, 0.3, 0.5, + -0.404508, 0, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.5, + -0.5, 0, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.5, + -0.5, 0.1, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.4, + -0.404508, 0.1, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.4, + -0.404508, 0, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.5, + -0.5, 0.1, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.4, + -0.25, -0.5, -2.18557e-08, 0, -1, 0, 0.25, 0.5, + -0.3, -0.5, -2.62268e-08, 0, -1, 0, 0.2, 0.5, + -0.242705, -0.5, -0.176336, 0, -1, 0, 0.257295, 0.676336, + -0.25, -0.5, -2.18557e-08, 0, -1, 0, 0.25, 0.5, + -0.242705, -0.5, -0.176336, 0, -1, 0, 0.257295, 0.676336, + -0.202254, -0.5, -0.146946, 0, -1, 0, 0.297746, 0.646946, + -0.242705, 0.5, -0.176336, 0, 1, 0, 0.257295, 0.676336, + -0.3, 0.5, -2.62268e-08, 0, 1, 0, 0.2, 0.5, + -0.25, 0.5, -2.18557e-08, 0, 1, 0, 0.25, 0.5, + -0.202254, 0.5, -0.146946, 0, 1, 0, 0.297746, 0.646946, + -0.242705, 0.5, -0.176336, 0, 1, 0, 0.257295, 0.676336, + -0.25, 0.5, -2.18557e-08, 0, 1, 0, 0.25, 0.5, + -0.404508, -0.1, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.6, + -0.5, -0.1, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.6, + -0.5, 0, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.5, + -0.404508, 0, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.5, + -0.404508, -0.1, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.6, + -0.5, 0, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.5, + -0.3, -0.5, -2.62268e-08, 0, -1, 0, 0.2, 0.5, + -0.35, -0.5, -3.0598e-08, 0, -1, 0, 0.15, 0.5, + -0.283156, -0.5, -0.205725, 0, -1, 0, 0.216844, 0.705725, + -0.3, -0.5, -2.62268e-08, 0, -1, 0, 0.2, 0.5, + -0.283156, -0.5, -0.205725, 0, -1, 0, 0.216844, 0.705725, + -0.242705, -0.5, -0.176336, 0, -1, 0, 0.257295, 0.676336, + -0.283156, 0.5, -0.205725, 0, 1, 0, 0.216844, 0.705725, + -0.35, 0.5, -3.0598e-08, 0, 1, 0, 0.15, 0.5, + -0.3, 0.5, -2.62268e-08, 0, 1, 0, 0.2, 0.5, + -0.242705, 0.5, -0.176336, 0, 1, 0, 0.257295, 0.676336, + -0.283156, 0.5, -0.205725, 0, 1, 0, 0.216844, 0.705725, + -0.3, 0.5, -2.62268e-08, 0, 1, 0, 0.2, 0.5, + -0.404508, -0.2, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.7, + -0.5, -0.2, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.7, + -0.5, -0.1, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.6, + -0.404508, -0.1, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.6, + -0.404508, -0.2, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.7, + -0.5, -0.1, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.6, + -0.35, -0.5, -3.0598e-08, 0, -1, 0, 0.15, 0.5, + -0.4, -0.5, -3.49691e-08, 0, -1, 0, 0.1, 0.5, + -0.323607, -0.5, -0.235114, 0, -1, 0, 0.176393, 0.735114, + -0.35, -0.5, -3.0598e-08, 0, -1, 0, 0.15, 0.5, + -0.323607, -0.5, -0.235114, 0, -1, 0, 0.176393, 0.735114, + -0.283156, -0.5, -0.205725, 0, -1, 0, 0.216844, 0.705725, + -0.323607, 0.5, -0.235114, 0, 1, 0, 0.176393, 0.735114, + -0.4, 0.5, -3.49691e-08, 0, 1, 0, 0.1, 0.5, + -0.35, 0.5, -3.0598e-08, 0, 1, 0, 0.15, 0.5, + -0.283156, 0.5, -0.205725, 0, 1, 0, 0.216844, 0.705725, + -0.323607, 0.5, -0.235114, 0, 1, 0, 0.176393, 0.735114, + -0.35, 0.5, -3.0598e-08, 0, 1, 0, 0.15, 0.5, + -0.404508, -0.3, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.8, + -0.5, -0.3, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.8, + -0.5, -0.2, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.7, + -0.404508, -0.2, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.7, + -0.404508, -0.3, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.8, + -0.5, -0.2, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.7, + -0.4, -0.5, -3.49691e-08, 0, -1, 0, 0.1, 0.5, + -0.45, -0.5, -3.93403e-08, 0, -1, 0, 0.05, 0.5, + -0.364058, -0.5, -0.264503, 0, -1, 0, 0.135942, 0.764503, + -0.4, -0.5, -3.49691e-08, 0, -1, 0, 0.1, 0.5, + -0.364058, -0.5, -0.264503, 0, -1, 0, 0.135942, 0.764503, + -0.323607, -0.5, -0.235114, 0, -1, 0, 0.176393, 0.735114, + -0.364058, 0.5, -0.264503, 0, 1, 0, 0.135942, 0.764503, + -0.45, 0.5, -3.93403e-08, 0, 1, 0, 0.05, 0.5, + -0.4, 0.5, -3.49691e-08, 0, 1, 0, 0.1, 0.5, + -0.323607, 0.5, -0.235114, 0, 1, 0, 0.176393, 0.735114, + -0.364058, 0.5, -0.264503, 0, 1, 0, 0.135942, 0.764503, + -0.4, 0.5, -3.49691e-08, 0, 1, 0, 0.1, 0.5, + -0.404508, -0.4, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.9, + -0.5, -0.4, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.9, + -0.5, -0.3, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.8, + -0.404508, -0.3, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.8, + -0.404508, -0.4, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.9, + -0.5, -0.3, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.8, + -0.45, -0.5, -3.93403e-08, 0, -1, 0, 0.05, 0.5, + -0.5, -0.5, -4.37114e-08, 0, -1, 0, 0, 0.5, + -0.404508, -0.5, -0.293893, 0, -1, 0, 0.0954915, 0.793893, + -0.45, -0.5, -3.93403e-08, 0, -1, 0, 0.05, 0.5, + -0.404508, -0.5, -0.293893, 0, -1, 0, 0.0954915, 0.793893, + -0.364058, -0.5, -0.264503, 0, -1, 0, 0.135942, 0.764503, + -0.404508, 0.5, -0.293893, 0, 1, 0, 0.0954915, 0.793893, + -0.5, 0.5, -4.37114e-08, 0, 1, 0, 0, 0.5, + -0.45, 0.5, -3.93403e-08, 0, 1, 0, 0.05, 0.5, + -0.364058, 0.5, -0.264503, 0, 1, 0, 0.135942, 0.764503, + -0.404508, 0.5, -0.293893, 0, 1, 0, 0.0954915, 0.793893, + -0.45, 0.5, -3.93403e-08, 0, 1, 0, 0.05, 0.5, + -0.404508, -0.5, -0.293893, -0.809017, 0, -0.587785, 0.6, 1, + -0.5, -0.5, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 1, + -0.5, -0.4, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.9, + -0.404508, -0.4, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.9, + -0.404508, -0.5, -0.293893, -0.809017, 0, -0.587785, 0.6, 1, + -0.5, -0.4, -4.37114e-08, -1, 0, -8.74228e-08, 0.5, 0.9, + -0, -0.5, -0, 0, -1, 0, 0.5, 0.5, + -0.0404508, -0.5, -0.0293893, 0, -1, 0, 0.459549, 0.529389, + -0.0154509, -0.5, -0.0475528, 0, -1, 0, 0.484549, 0.547553, + -0.0154509, 0.5, -0.0475528, 0, 1, 0, 0.484549, 0.547553, + -0.0404508, 0.5, -0.0293893, 0, 1, 0, 0.459549, 0.529389, + -0, 0.5, -0, 0, 1, 0, 0.5, 0.5, + -0.154509, 0.4, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.1, + -0.404508, 0.4, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.1, + -0.404508, 0.5, -0.293893, -0.809017, 0, -0.587785, 0.6, 0, + -0.154509, 0.5, -0.475528, -0.309017, 0, -0.951056, 0.7, 0, + -0.154509, 0.4, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.1, + -0.404508, 0.5, -0.293893, -0.809017, 0, -0.587785, 0.6, 0, + -0.0404508, -0.5, -0.0293893, 0, -1, 0, 0.459549, 0.529389, + -0.0809017, -0.5, -0.0587785, 0, -1, 0, 0.419098, 0.558779, + -0.0309017, -0.5, -0.0951056, 0, -1, 0, 0.469098, 0.595106, + -0.0404508, -0.5, -0.0293893, 0, -1, 0, 0.459549, 0.529389, + -0.0309017, -0.5, -0.0951056, 0, -1, 0, 0.469098, 0.595106, + -0.0154509, -0.5, -0.0475528, 0, -1, 0, 0.484549, 0.547553, + -0.0309017, 0.5, -0.0951056, 0, 1, 0, 0.469098, 0.595106, + -0.0809017, 0.5, -0.0587785, 0, 1, 0, 0.419098, 0.558779, + -0.0404508, 0.5, -0.0293893, 0, 1, 0, 0.459549, 0.529389, + -0.0154509, 0.5, -0.0475528, 0, 1, 0, 0.484549, 0.547553, + -0.0309017, 0.5, -0.0951056, 0, 1, 0, 0.469098, 0.595106, + -0.0404508, 0.5, -0.0293893, 0, 1, 0, 0.459549, 0.529389, + -0.154509, 0.3, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.2, + -0.404508, 0.3, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.2, + -0.404508, 0.4, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.1, + -0.154509, 0.4, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.1, + -0.154509, 0.3, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.2, + -0.404508, 0.4, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.1, + -0.0809017, -0.5, -0.0587785, 0, -1, 0, 0.419098, 0.558779, + -0.121353, -0.5, -0.0881678, 0, -1, 0, 0.378647, 0.588168, + -0.0463526, -0.5, -0.142658, 0, -1, 0, 0.453647, 0.642658, + -0.0809017, -0.5, -0.0587785, 0, -1, 0, 0.419098, 0.558779, + -0.0463526, -0.5, -0.142658, 0, -1, 0, 0.453647, 0.642658, + -0.0309017, -0.5, -0.0951056, 0, -1, 0, 0.469098, 0.595106, + -0.0463526, 0.5, -0.142658, 0, 1, 0, 0.453647, 0.642658, + -0.121353, 0.5, -0.0881678, 0, 1, 0, 0.378647, 0.588168, + -0.0809017, 0.5, -0.0587785, 0, 1, 0, 0.419098, 0.558779, + -0.0309017, 0.5, -0.0951056, 0, 1, 0, 0.469098, 0.595106, + -0.0463526, 0.5, -0.142658, 0, 1, 0, 0.453647, 0.642658, + -0.0809017, 0.5, -0.0587785, 0, 1, 0, 0.419098, 0.558779, + -0.154509, 0.2, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.3, + -0.404508, 0.2, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.3, + -0.404508, 0.3, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.2, + -0.154509, 0.3, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.2, + -0.154509, 0.2, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.3, + -0.404508, 0.3, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.2, + -0.121353, -0.5, -0.0881678, 0, -1, 0, 0.378647, 0.588168, + -0.161803, -0.5, -0.117557, 0, -1, 0, 0.338197, 0.617557, + -0.0618034, -0.5, -0.190211, 0, -1, 0, 0.438197, 0.690211, + -0.121353, -0.5, -0.0881678, 0, -1, 0, 0.378647, 0.588168, + -0.0618034, -0.5, -0.190211, 0, -1, 0, 0.438197, 0.690211, + -0.0463526, -0.5, -0.142658, 0, -1, 0, 0.453647, 0.642658, + -0.0618034, 0.5, -0.190211, 0, 1, 0, 0.438197, 0.690211, + -0.161803, 0.5, -0.117557, 0, 1, 0, 0.338197, 0.617557, + -0.121353, 0.5, -0.0881678, 0, 1, 0, 0.378647, 0.588168, + -0.0463526, 0.5, -0.142658, 0, 1, 0, 0.453647, 0.642658, + -0.0618034, 0.5, -0.190211, 0, 1, 0, 0.438197, 0.690211, + -0.121353, 0.5, -0.0881678, 0, 1, 0, 0.378647, 0.588168, + -0.154509, 0.1, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.4, + -0.404508, 0.1, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.4, + -0.404508, 0.2, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.3, + -0.154509, 0.2, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.3, + -0.154509, 0.1, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.4, + -0.404508, 0.2, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.3, + -0.161803, -0.5, -0.117557, 0, -1, 0, 0.338197, 0.617557, + -0.202254, -0.5, -0.146946, 0, -1, 0, 0.297746, 0.646946, + -0.0772543, -0.5, -0.237764, 0, -1, 0, 0.422746, 0.737764, + -0.161803, -0.5, -0.117557, 0, -1, 0, 0.338197, 0.617557, + -0.0772543, -0.5, -0.237764, 0, -1, 0, 0.422746, 0.737764, + -0.0618034, -0.5, -0.190211, 0, -1, 0, 0.438197, 0.690211, + -0.0772543, 0.5, -0.237764, 0, 1, 0, 0.422746, 0.737764, + -0.202254, 0.5, -0.146946, 0, 1, 0, 0.297746, 0.646946, + -0.161803, 0.5, -0.117557, 0, 1, 0, 0.338197, 0.617557, + -0.0618034, 0.5, -0.190211, 0, 1, 0, 0.438197, 0.690211, + -0.0772543, 0.5, -0.237764, 0, 1, 0, 0.422746, 0.737764, + -0.161803, 0.5, -0.117557, 0, 1, 0, 0.338197, 0.617557, + -0.154509, 0, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.5, + -0.404508, 0, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.5, + -0.404508, 0.1, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.4, + -0.154509, 0.1, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.4, + -0.154509, 0, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.5, + -0.404508, 0.1, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.4, + -0.202254, -0.5, -0.146946, 0, -1, 0, 0.297746, 0.646946, + -0.242705, -0.5, -0.176336, 0, -1, 0, 0.257295, 0.676336, + -0.0927051, -0.5, -0.285317, 0, -1, 0, 0.407295, 0.785317, + -0.202254, -0.5, -0.146946, 0, -1, 0, 0.297746, 0.646946, + -0.0927051, -0.5, -0.285317, 0, -1, 0, 0.407295, 0.785317, + -0.0772543, -0.5, -0.237764, 0, -1, 0, 0.422746, 0.737764, + -0.0927051, 0.5, -0.285317, 0, 1, 0, 0.407295, 0.785317, + -0.242705, 0.5, -0.176336, 0, 1, 0, 0.257295, 0.676336, + -0.202254, 0.5, -0.146946, 0, 1, 0, 0.297746, 0.646946, + -0.0772543, 0.5, -0.237764, 0, 1, 0, 0.422746, 0.737764, + -0.0927051, 0.5, -0.285317, 0, 1, 0, 0.407295, 0.785317, + -0.202254, 0.5, -0.146946, 0, 1, 0, 0.297746, 0.646946, + -0.154509, -0.1, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.6, + -0.404508, -0.1, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.6, + -0.404508, 0, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.5, + -0.154509, 0, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.5, + -0.154509, -0.1, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.6, + -0.404508, 0, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.5, + -0.242705, -0.5, -0.176336, 0, -1, 0, 0.257295, 0.676336, + -0.283156, -0.5, -0.205725, 0, -1, 0, 0.216844, 0.705725, + -0.108156, -0.5, -0.33287, 0, -1, 0, 0.391844, 0.83287, + -0.242705, -0.5, -0.176336, 0, -1, 0, 0.257295, 0.676336, + -0.108156, -0.5, -0.33287, 0, -1, 0, 0.391844, 0.83287, + -0.0927051, -0.5, -0.285317, 0, -1, 0, 0.407295, 0.785317, + -0.108156, 0.5, -0.33287, 0, 1, 0, 0.391844, 0.83287, + -0.283156, 0.5, -0.205725, 0, 1, 0, 0.216844, 0.705725, + -0.242705, 0.5, -0.176336, 0, 1, 0, 0.257295, 0.676336, + -0.0927051, 0.5, -0.285317, 0, 1, 0, 0.407295, 0.785317, + -0.108156, 0.5, -0.33287, 0, 1, 0, 0.391844, 0.83287, + -0.242705, 0.5, -0.176336, 0, 1, 0, 0.257295, 0.676336, + -0.154509, -0.2, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.7, + -0.404508, -0.2, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.7, + -0.404508, -0.1, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.6, + -0.154509, -0.1, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.6, + -0.154509, -0.2, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.7, + -0.404508, -0.1, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.6, + -0.283156, -0.5, -0.205725, 0, -1, 0, 0.216844, 0.705725, + -0.323607, -0.5, -0.235114, 0, -1, 0, 0.176393, 0.735114, + -0.123607, -0.5, -0.380423, 0, -1, 0, 0.376393, 0.880423, + -0.283156, -0.5, -0.205725, 0, -1, 0, 0.216844, 0.705725, + -0.123607, -0.5, -0.380423, 0, -1, 0, 0.376393, 0.880423, + -0.108156, -0.5, -0.33287, 0, -1, 0, 0.391844, 0.83287, + -0.123607, 0.5, -0.380423, 0, 1, 0, 0.376393, 0.880423, + -0.323607, 0.5, -0.235114, 0, 1, 0, 0.176393, 0.735114, + -0.283156, 0.5, -0.205725, 0, 1, 0, 0.216844, 0.705725, + -0.108156, 0.5, -0.33287, 0, 1, 0, 0.391844, 0.83287, + -0.123607, 0.5, -0.380423, 0, 1, 0, 0.376393, 0.880423, + -0.283156, 0.5, -0.205725, 0, 1, 0, 0.216844, 0.705725, + -0.154509, -0.3, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.8, + -0.404508, -0.3, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.8, + -0.404508, -0.2, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.7, + -0.154509, -0.2, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.7, + -0.154509, -0.3, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.8, + -0.404508, -0.2, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.7, + -0.323607, -0.5, -0.235114, 0, -1, 0, 0.176393, 0.735114, + -0.364058, -0.5, -0.264503, 0, -1, 0, 0.135942, 0.764503, + -0.139058, -0.5, -0.427975, 0, -1, 0, 0.360942, 0.927975, + -0.323607, -0.5, -0.235114, 0, -1, 0, 0.176393, 0.735114, + -0.139058, -0.5, -0.427975, 0, -1, 0, 0.360942, 0.927975, + -0.123607, -0.5, -0.380423, 0, -1, 0, 0.376393, 0.880423, + -0.139058, 0.5, -0.427975, 0, 1, 0, 0.360942, 0.927975, + -0.364058, 0.5, -0.264503, 0, 1, 0, 0.135942, 0.764503, + -0.323607, 0.5, -0.235114, 0, 1, 0, 0.176393, 0.735114, + -0.123607, 0.5, -0.380423, 0, 1, 0, 0.376393, 0.880423, + -0.139058, 0.5, -0.427975, 0, 1, 0, 0.360942, 0.927975, + -0.323607, 0.5, -0.235114, 0, 1, 0, 0.176393, 0.735114, + -0.154509, -0.4, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.9, + -0.404508, -0.4, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.9, + -0.404508, -0.3, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.8, + -0.154509, -0.3, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.8, + -0.154509, -0.4, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.9, + -0.404508, -0.3, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.8, + -0.364058, -0.5, -0.264503, 0, -1, 0, 0.135942, 0.764503, + -0.404508, -0.5, -0.293893, 0, -1, 0, 0.0954915, 0.793893, + -0.154509, -0.5, -0.475528, 0, -1, 0, 0.345491, 0.975528, + -0.364058, -0.5, -0.264503, 0, -1, 0, 0.135942, 0.764503, + -0.154509, -0.5, -0.475528, 0, -1, 0, 0.345491, 0.975528, + -0.139058, -0.5, -0.427975, 0, -1, 0, 0.360942, 0.927975, + -0.154509, 0.5, -0.475528, 0, 1, 0, 0.345491, 0.975528, + -0.404508, 0.5, -0.293893, 0, 1, 0, 0.0954915, 0.793893, + -0.364058, 0.5, -0.264503, 0, 1, 0, 0.135942, 0.764503, + -0.139058, 0.5, -0.427975, 0, 1, 0, 0.360942, 0.927975, + -0.154509, 0.5, -0.475528, 0, 1, 0, 0.345491, 0.975528, + -0.364058, 0.5, -0.264503, 0, 1, 0, 0.135942, 0.764503, + -0.154509, -0.5, -0.475528, -0.309017, 0, -0.951056, 0.7, 1, + -0.404508, -0.5, -0.293893, -0.809017, 0, -0.587785, 0.6, 1, + -0.404508, -0.4, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.9, + -0.154509, -0.4, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.9, + -0.154509, -0.5, -0.475528, -0.309017, 0, -0.951056, 0.7, 1, + -0.404508, -0.4, -0.293893, -0.809017, 0, -0.587785, 0.6, 0.9, + -0, -0.5, -0, 0, -1, 0, 0.5, 0.5, + -0.0154509, -0.5, -0.0475528, 0, -1, 0, 0.484549, 0.547553, + 0.0154509, -0.5, -0.0475528, 0, -1, 0, 0.515451, 0.547553, + 0.0154509, 0.5, -0.0475528, 0, 1, 0, 0.515451, 0.547553, + -0.0154509, 0.5, -0.0475528, 0, 1, 0, 0.484549, 0.547553, + -0, 0.5, -0, 0, 1, 0, 0.5, 0.5, + 0.154509, 0.4, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.1, + -0.154509, 0.4, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.1, + -0.154509, 0.5, -0.475528, -0.309017, 0, -0.951056, 0.7, 0, + 0.154509, 0.5, -0.475528, 0.309017, 0, -0.951056, 0.8, 0, + 0.154509, 0.4, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.1, + -0.154509, 0.5, -0.475528, -0.309017, 0, -0.951056, 0.7, 0, + -0.0154509, -0.5, -0.0475528, 0, -1, 0, 0.484549, 0.547553, + -0.0309017, -0.5, -0.0951056, 0, -1, 0, 0.469098, 0.595106, + 0.0309017, -0.5, -0.0951056, 0, -1, 0, 0.530902, 0.595106, + -0.0154509, -0.5, -0.0475528, 0, -1, 0, 0.484549, 0.547553, + 0.0309017, -0.5, -0.0951056, 0, -1, 0, 0.530902, 0.595106, + 0.0154509, -0.5, -0.0475528, 0, -1, 0, 0.515451, 0.547553, + 0.0309017, 0.5, -0.0951056, 0, 1, 0, 0.530902, 0.595106, + -0.0309017, 0.5, -0.0951056, 0, 1, 0, 0.469098, 0.595106, + -0.0154509, 0.5, -0.0475528, 0, 1, 0, 0.484549, 0.547553, + 0.0154509, 0.5, -0.0475528, 0, 1, 0, 0.515451, 0.547553, + 0.0309017, 0.5, -0.0951056, 0, 1, 0, 0.530902, 0.595106, + -0.0154509, 0.5, -0.0475528, 0, 1, 0, 0.484549, 0.547553, + 0.154509, 0.3, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.2, + -0.154509, 0.3, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.2, + -0.154509, 0.4, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.1, + 0.154509, 0.4, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.1, + 0.154509, 0.3, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.2, + -0.154509, 0.4, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.1, + -0.0309017, -0.5, -0.0951056, 0, -1, 0, 0.469098, 0.595106, + -0.0463526, -0.5, -0.142658, 0, -1, 0, 0.453647, 0.642658, + 0.0463526, -0.5, -0.142658, 0, -1, 0, 0.546353, 0.642658, + -0.0309017, -0.5, -0.0951056, 0, -1, 0, 0.469098, 0.595106, + 0.0463526, -0.5, -0.142658, 0, -1, 0, 0.546353, 0.642658, + 0.0309017, -0.5, -0.0951056, 0, -1, 0, 0.530902, 0.595106, + 0.0463526, 0.5, -0.142658, 0, 1, 0, 0.546353, 0.642658, + -0.0463526, 0.5, -0.142658, 0, 1, 0, 0.453647, 0.642658, + -0.0309017, 0.5, -0.0951056, 0, 1, 0, 0.469098, 0.595106, + 0.0309017, 0.5, -0.0951056, 0, 1, 0, 0.530902, 0.595106, + 0.0463526, 0.5, -0.142658, 0, 1, 0, 0.546353, 0.642658, + -0.0309017, 0.5, -0.0951056, 0, 1, 0, 0.469098, 0.595106, + 0.154509, 0.2, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.3, + -0.154509, 0.2, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.3, + -0.154509, 0.3, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.2, + 0.154509, 0.3, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.2, + 0.154509, 0.2, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.3, + -0.154509, 0.3, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.2, + -0.0463526, -0.5, -0.142658, 0, -1, 0, 0.453647, 0.642658, + -0.0618034, -0.5, -0.190211, 0, -1, 0, 0.438197, 0.690211, + 0.0618034, -0.5, -0.190211, 0, -1, 0, 0.561803, 0.690211, + -0.0463526, -0.5, -0.142658, 0, -1, 0, 0.453647, 0.642658, + 0.0618034, -0.5, -0.190211, 0, -1, 0, 0.561803, 0.690211, + 0.0463526, -0.5, -0.142658, 0, -1, 0, 0.546353, 0.642658, + 0.0618034, 0.5, -0.190211, 0, 1, 0, 0.561803, 0.690211, + -0.0618034, 0.5, -0.190211, 0, 1, 0, 0.438197, 0.690211, + -0.0463526, 0.5, -0.142658, 0, 1, 0, 0.453647, 0.642658, + 0.0463526, 0.5, -0.142658, 0, 1, 0, 0.546353, 0.642658, + 0.0618034, 0.5, -0.190211, 0, 1, 0, 0.561803, 0.690211, + -0.0463526, 0.5, -0.142658, 0, 1, 0, 0.453647, 0.642658, + 0.154509, 0.1, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.4, + -0.154509, 0.1, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.4, + -0.154509, 0.2, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.3, + 0.154509, 0.2, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.3, + 0.154509, 0.1, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.4, + -0.154509, 0.2, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.3, + -0.0618034, -0.5, -0.190211, 0, -1, 0, 0.438197, 0.690211, + -0.0772543, -0.5, -0.237764, 0, -1, 0, 0.422746, 0.737764, + 0.0772543, -0.5, -0.237764, 0, -1, 0, 0.577254, 0.737764, + -0.0618034, -0.5, -0.190211, 0, -1, 0, 0.438197, 0.690211, + 0.0772543, -0.5, -0.237764, 0, -1, 0, 0.577254, 0.737764, + 0.0618034, -0.5, -0.190211, 0, -1, 0, 0.561803, 0.690211, + 0.0772543, 0.5, -0.237764, 0, 1, 0, 0.577254, 0.737764, + -0.0772543, 0.5, -0.237764, 0, 1, 0, 0.422746, 0.737764, + -0.0618034, 0.5, -0.190211, 0, 1, 0, 0.438197, 0.690211, + 0.0618034, 0.5, -0.190211, 0, 1, 0, 0.561803, 0.690211, + 0.0772543, 0.5, -0.237764, 0, 1, 0, 0.577254, 0.737764, + -0.0618034, 0.5, -0.190211, 0, 1, 0, 0.438197, 0.690211, + 0.154509, 0, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.5, + -0.154509, 0, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.5, + -0.154509, 0.1, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.4, + 0.154509, 0.1, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.4, + 0.154509, 0, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.5, + -0.154509, 0.1, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.4, + -0.0772543, -0.5, -0.237764, 0, -1, 0, 0.422746, 0.737764, + -0.0927051, -0.5, -0.285317, 0, -1, 0, 0.407295, 0.785317, + 0.0927051, -0.5, -0.285317, 0, -1, 0, 0.592705, 0.785317, + -0.0772543, -0.5, -0.237764, 0, -1, 0, 0.422746, 0.737764, + 0.0927051, -0.5, -0.285317, 0, -1, 0, 0.592705, 0.785317, + 0.0772543, -0.5, -0.237764, 0, -1, 0, 0.577254, 0.737764, + 0.0927051, 0.5, -0.285317, 0, 1, 0, 0.592705, 0.785317, + -0.0927051, 0.5, -0.285317, 0, 1, 0, 0.407295, 0.785317, + -0.0772543, 0.5, -0.237764, 0, 1, 0, 0.422746, 0.737764, + 0.0772543, 0.5, -0.237764, 0, 1, 0, 0.577254, 0.737764, + 0.0927051, 0.5, -0.285317, 0, 1, 0, 0.592705, 0.785317, + -0.0772543, 0.5, -0.237764, 0, 1, 0, 0.422746, 0.737764, + 0.154509, -0.1, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.6, + -0.154509, -0.1, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.6, + -0.154509, 0, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.5, + 0.154509, 0, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.5, + 0.154509, -0.1, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.6, + -0.154509, 0, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.5, + -0.0927051, -0.5, -0.285317, 0, -1, 0, 0.407295, 0.785317, + -0.108156, -0.5, -0.33287, 0, -1, 0, 0.391844, 0.83287, + 0.108156, -0.5, -0.33287, 0, -1, 0, 0.608156, 0.83287, + -0.0927051, -0.5, -0.285317, 0, -1, 0, 0.407295, 0.785317, + 0.108156, -0.5, -0.33287, 0, -1, 0, 0.608156, 0.83287, + 0.0927051, -0.5, -0.285317, 0, -1, 0, 0.592705, 0.785317, + 0.108156, 0.5, -0.33287, 0, 1, 0, 0.608156, 0.83287, + -0.108156, 0.5, -0.33287, 0, 1, 0, 0.391844, 0.83287, + -0.0927051, 0.5, -0.285317, 0, 1, 0, 0.407295, 0.785317, + 0.0927051, 0.5, -0.285317, 0, 1, 0, 0.592705, 0.785317, + 0.108156, 0.5, -0.33287, 0, 1, 0, 0.608156, 0.83287, + -0.0927051, 0.5, -0.285317, 0, 1, 0, 0.407295, 0.785317, + 0.154509, -0.2, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.7, + -0.154509, -0.2, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.7, + -0.154509, -0.1, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.6, + 0.154509, -0.1, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.6, + 0.154509, -0.2, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.7, + -0.154509, -0.1, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.6, + -0.108156, -0.5, -0.33287, 0, -1, 0, 0.391844, 0.83287, + -0.123607, -0.5, -0.380423, 0, -1, 0, 0.376393, 0.880423, + 0.123607, -0.5, -0.380423, 0, -1, 0, 0.623607, 0.880423, + -0.108156, -0.5, -0.33287, 0, -1, 0, 0.391844, 0.83287, + 0.123607, -0.5, -0.380423, 0, -1, 0, 0.623607, 0.880423, + 0.108156, -0.5, -0.33287, 0, -1, 0, 0.608156, 0.83287, + 0.123607, 0.5, -0.380423, 0, 1, 0, 0.623607, 0.880423, + -0.123607, 0.5, -0.380423, 0, 1, 0, 0.376393, 0.880423, + -0.108156, 0.5, -0.33287, 0, 1, 0, 0.391844, 0.83287, + 0.108156, 0.5, -0.33287, 0, 1, 0, 0.608156, 0.83287, + 0.123607, 0.5, -0.380423, 0, 1, 0, 0.623607, 0.880423, + -0.108156, 0.5, -0.33287, 0, 1, 0, 0.391844, 0.83287, + 0.154509, -0.3, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.8, + -0.154509, -0.3, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.8, + -0.154509, -0.2, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.7, + 0.154509, -0.2, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.7, + 0.154509, -0.3, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.8, + -0.154509, -0.2, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.7, + -0.123607, -0.5, -0.380423, 0, -1, 0, 0.376393, 0.880423, + -0.139058, -0.5, -0.427975, 0, -1, 0, 0.360942, 0.927975, + 0.139058, -0.5, -0.427975, 0, -1, 0, 0.639058, 0.927975, + -0.123607, -0.5, -0.380423, 0, -1, 0, 0.376393, 0.880423, + 0.139058, -0.5, -0.427975, 0, -1, 0, 0.639058, 0.927975, + 0.123607, -0.5, -0.380423, 0, -1, 0, 0.623607, 0.880423, + 0.139058, 0.5, -0.427975, 0, 1, 0, 0.639058, 0.927975, + -0.139058, 0.5, -0.427975, 0, 1, 0, 0.360942, 0.927975, + -0.123607, 0.5, -0.380423, 0, 1, 0, 0.376393, 0.880423, + 0.123607, 0.5, -0.380423, 0, 1, 0, 0.623607, 0.880423, + 0.139058, 0.5, -0.427975, 0, 1, 0, 0.639058, 0.927975, + -0.123607, 0.5, -0.380423, 0, 1, 0, 0.376393, 0.880423, + 0.154509, -0.4, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.9, + -0.154509, -0.4, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.9, + -0.154509, -0.3, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.8, + 0.154509, -0.3, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.8, + 0.154509, -0.4, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.9, + -0.154509, -0.3, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.8, + -0.139058, -0.5, -0.427975, 0, -1, 0, 0.360942, 0.927975, + -0.154509, -0.5, -0.475528, 0, -1, 0, 0.345491, 0.975528, + 0.154509, -0.5, -0.475528, 0, -1, 0, 0.654509, 0.975528, + -0.139058, -0.5, -0.427975, 0, -1, 0, 0.360942, 0.927975, + 0.154509, -0.5, -0.475528, 0, -1, 0, 0.654509, 0.975528, + 0.139058, -0.5, -0.427975, 0, -1, 0, 0.639058, 0.927975, + 0.154509, 0.5, -0.475528, 0, 1, 0, 0.654509, 0.975528, + -0.154509, 0.5, -0.475528, 0, 1, 0, 0.345491, 0.975528, + -0.139058, 0.5, -0.427975, 0, 1, 0, 0.360942, 0.927975, + 0.139058, 0.5, -0.427975, 0, 1, 0, 0.639058, 0.927975, + 0.154509, 0.5, -0.475528, 0, 1, 0, 0.654509, 0.975528, + -0.139058, 0.5, -0.427975, 0, 1, 0, 0.360942, 0.927975, + 0.154509, -0.5, -0.475528, 0.309017, 0, -0.951056, 0.8, 1, + -0.154509, -0.5, -0.475528, -0.309017, 0, -0.951056, 0.7, 1, + -0.154509, -0.4, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.9, + 0.154509, -0.4, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.9, + 0.154509, -0.5, -0.475528, 0.309017, 0, -0.951056, 0.8, 1, + -0.154509, -0.4, -0.475528, -0.309017, 0, -0.951056, 0.7, 0.9, + 0, -0.5, -0, 0, -1, 0, 0.5, 0.5, + 0.0154509, -0.5, -0.0475528, 0, -1, 0, 0.515451, 0.547553, + 0.0404509, -0.5, -0.0293892, 0, -1, 0, 0.540451, 0.529389, + 0.0404509, 0.5, -0.0293892, 0, 1, 0, 0.540451, 0.529389, + 0.0154509, 0.5, -0.0475528, 0, 1, 0, 0.515451, 0.547553, + 0, 0.5, -0, 0, 1, 0, 0.5, 0.5, + 0.404509, 0.4, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.1, + 0.154509, 0.4, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.1, + 0.154509, 0.5, -0.475528, 0.309017, 0, -0.951056, 0.8, 0, + 0.404509, 0.5, -0.293892, 0.809017, 0, -0.587785, 0.9, 0, + 0.404509, 0.4, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.1, + 0.154509, 0.5, -0.475528, 0.309017, 0, -0.951056, 0.8, 0, + 0.0154509, -0.5, -0.0475528, 0, -1, 0, 0.515451, 0.547553, + 0.0309017, -0.5, -0.0951056, 0, -1, 0, 0.530902, 0.595106, + 0.0809017, -0.5, -0.0587785, 0, -1, 0, 0.580902, 0.558779, + 0.0154509, -0.5, -0.0475528, 0, -1, 0, 0.515451, 0.547553, + 0.0809017, -0.5, -0.0587785, 0, -1, 0, 0.580902, 0.558779, + 0.0404509, -0.5, -0.0293892, 0, -1, 0, 0.540451, 0.529389, + 0.0809017, 0.5, -0.0587785, 0, 1, 0, 0.580902, 0.558779, + 0.0309017, 0.5, -0.0951056, 0, 1, 0, 0.530902, 0.595106, + 0.0154509, 0.5, -0.0475528, 0, 1, 0, 0.515451, 0.547553, + 0.0404509, 0.5, -0.0293892, 0, 1, 0, 0.540451, 0.529389, + 0.0809017, 0.5, -0.0587785, 0, 1, 0, 0.580902, 0.558779, + 0.0154509, 0.5, -0.0475528, 0, 1, 0, 0.515451, 0.547553, + 0.404509, 0.3, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.2, + 0.154509, 0.3, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.2, + 0.154509, 0.4, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.1, + 0.404509, 0.4, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.1, + 0.404509, 0.3, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.2, + 0.154509, 0.4, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.1, + 0.0309017, -0.5, -0.0951056, 0, -1, 0, 0.530902, 0.595106, + 0.0463526, -0.5, -0.142658, 0, -1, 0, 0.546353, 0.642658, + 0.121353, -0.5, -0.0881677, 0, -1, 0, 0.621353, 0.588168, + 0.0309017, -0.5, -0.0951056, 0, -1, 0, 0.530902, 0.595106, + 0.121353, -0.5, -0.0881677, 0, -1, 0, 0.621353, 0.588168, + 0.0809017, -0.5, -0.0587785, 0, -1, 0, 0.580902, 0.558779, + 0.121353, 0.5, -0.0881677, 0, 1, 0, 0.621353, 0.588168, + 0.0463526, 0.5, -0.142658, 0, 1, 0, 0.546353, 0.642658, + 0.0309017, 0.5, -0.0951056, 0, 1, 0, 0.530902, 0.595106, + 0.0809017, 0.5, -0.0587785, 0, 1, 0, 0.580902, 0.558779, + 0.121353, 0.5, -0.0881677, 0, 1, 0, 0.621353, 0.588168, + 0.0309017, 0.5, -0.0951056, 0, 1, 0, 0.530902, 0.595106, + 0.404509, 0.2, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.3, + 0.154509, 0.2, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.3, + 0.154509, 0.3, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.2, + 0.404509, 0.3, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.2, + 0.404509, 0.2, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.3, + 0.154509, 0.3, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.2, + 0.0463526, -0.5, -0.142658, 0, -1, 0, 0.546353, 0.642658, + 0.0618034, -0.5, -0.190211, 0, -1, 0, 0.561803, 0.690211, + 0.161803, -0.5, -0.117557, 0, -1, 0, 0.661803, 0.617557, + 0.0463526, -0.5, -0.142658, 0, -1, 0, 0.546353, 0.642658, + 0.161803, -0.5, -0.117557, 0, -1, 0, 0.661803, 0.617557, + 0.121353, -0.5, -0.0881677, 0, -1, 0, 0.621353, 0.588168, + 0.161803, 0.5, -0.117557, 0, 1, 0, 0.661803, 0.617557, + 0.0618034, 0.5, -0.190211, 0, 1, 0, 0.561803, 0.690211, + 0.0463526, 0.5, -0.142658, 0, 1, 0, 0.546353, 0.642658, + 0.121353, 0.5, -0.0881677, 0, 1, 0, 0.621353, 0.588168, + 0.161803, 0.5, -0.117557, 0, 1, 0, 0.661803, 0.617557, + 0.0463526, 0.5, -0.142658, 0, 1, 0, 0.546353, 0.642658, + 0.404509, 0.1, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.4, + 0.154509, 0.1, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.4, + 0.154509, 0.2, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.3, + 0.404509, 0.2, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.3, + 0.404509, 0.1, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.4, + 0.154509, 0.2, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.3, + 0.0618034, -0.5, -0.190211, 0, -1, 0, 0.561803, 0.690211, + 0.0772543, -0.5, -0.237764, 0, -1, 0, 0.577254, 0.737764, + 0.202254, -0.5, -0.146946, 0, -1, 0, 0.702254, 0.646946, + 0.0618034, -0.5, -0.190211, 0, -1, 0, 0.561803, 0.690211, + 0.202254, -0.5, -0.146946, 0, -1, 0, 0.702254, 0.646946, + 0.161803, -0.5, -0.117557, 0, -1, 0, 0.661803, 0.617557, + 0.202254, 0.5, -0.146946, 0, 1, 0, 0.702254, 0.646946, + 0.0772543, 0.5, -0.237764, 0, 1, 0, 0.577254, 0.737764, + 0.0618034, 0.5, -0.190211, 0, 1, 0, 0.561803, 0.690211, + 0.161803, 0.5, -0.117557, 0, 1, 0, 0.661803, 0.617557, + 0.202254, 0.5, -0.146946, 0, 1, 0, 0.702254, 0.646946, + 0.0618034, 0.5, -0.190211, 0, 1, 0, 0.561803, 0.690211, + 0.404509, 0, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.5, + 0.154509, 0, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.5, + 0.154509, 0.1, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.4, + 0.404509, 0.1, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.4, + 0.404509, 0, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.5, + 0.154509, 0.1, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.4, + 0.0772543, -0.5, -0.237764, 0, -1, 0, 0.577254, 0.737764, + 0.0927051, -0.5, -0.285317, 0, -1, 0, 0.592705, 0.785317, + 0.242705, -0.5, -0.176335, 0, -1, 0, 0.742705, 0.676335, + 0.0772543, -0.5, -0.237764, 0, -1, 0, 0.577254, 0.737764, + 0.242705, -0.5, -0.176335, 0, -1, 0, 0.742705, 0.676335, + 0.202254, -0.5, -0.146946, 0, -1, 0, 0.702254, 0.646946, + 0.242705, 0.5, -0.176335, 0, 1, 0, 0.742705, 0.676335, + 0.0927051, 0.5, -0.285317, 0, 1, 0, 0.592705, 0.785317, + 0.0772543, 0.5, -0.237764, 0, 1, 0, 0.577254, 0.737764, + 0.202254, 0.5, -0.146946, 0, 1, 0, 0.702254, 0.646946, + 0.242705, 0.5, -0.176335, 0, 1, 0, 0.742705, 0.676335, + 0.0772543, 0.5, -0.237764, 0, 1, 0, 0.577254, 0.737764, + 0.404509, -0.1, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.6, + 0.154509, -0.1, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.6, + 0.154509, 0, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.5, + 0.404509, 0, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.5, + 0.404509, -0.1, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.6, + 0.154509, 0, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.5, + 0.0927051, -0.5, -0.285317, 0, -1, 0, 0.592705, 0.785317, + 0.108156, -0.5, -0.33287, 0, -1, 0, 0.608156, 0.83287, + 0.283156, -0.5, -0.205725, 0, -1, 0, 0.783156, 0.705725, + 0.0927051, -0.5, -0.285317, 0, -1, 0, 0.592705, 0.785317, + 0.283156, -0.5, -0.205725, 0, -1, 0, 0.783156, 0.705725, + 0.242705, -0.5, -0.176335, 0, -1, 0, 0.742705, 0.676335, + 0.283156, 0.5, -0.205725, 0, 1, 0, 0.783156, 0.705725, + 0.108156, 0.5, -0.33287, 0, 1, 0, 0.608156, 0.83287, + 0.0927051, 0.5, -0.285317, 0, 1, 0, 0.592705, 0.785317, + 0.242705, 0.5, -0.176335, 0, 1, 0, 0.742705, 0.676335, + 0.283156, 0.5, -0.205725, 0, 1, 0, 0.783156, 0.705725, + 0.0927051, 0.5, -0.285317, 0, 1, 0, 0.592705, 0.785317, + 0.404509, -0.2, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.7, + 0.154509, -0.2, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.7, + 0.154509, -0.1, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.6, + 0.404509, -0.1, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.6, + 0.404509, -0.2, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.7, + 0.154509, -0.1, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.6, + 0.108156, -0.5, -0.33287, 0, -1, 0, 0.608156, 0.83287, + 0.123607, -0.5, -0.380423, 0, -1, 0, 0.623607, 0.880423, + 0.323607, -0.5, -0.235114, 0, -1, 0, 0.823607, 0.735114, + 0.108156, -0.5, -0.33287, 0, -1, 0, 0.608156, 0.83287, + 0.323607, -0.5, -0.235114, 0, -1, 0, 0.823607, 0.735114, + 0.283156, -0.5, -0.205725, 0, -1, 0, 0.783156, 0.705725, + 0.323607, 0.5, -0.235114, 0, 1, 0, 0.823607, 0.735114, + 0.123607, 0.5, -0.380423, 0, 1, 0, 0.623607, 0.880423, + 0.108156, 0.5, -0.33287, 0, 1, 0, 0.608156, 0.83287, + 0.283156, 0.5, -0.205725, 0, 1, 0, 0.783156, 0.705725, + 0.323607, 0.5, -0.235114, 0, 1, 0, 0.823607, 0.735114, + 0.108156, 0.5, -0.33287, 0, 1, 0, 0.608156, 0.83287, + 0.404509, -0.3, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.8, + 0.154509, -0.3, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.8, + 0.154509, -0.2, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.7, + 0.404509, -0.2, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.7, + 0.404509, -0.3, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.8, + 0.154509, -0.2, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.7, + 0.123607, -0.5, -0.380423, 0, -1, 0, 0.623607, 0.880423, + 0.139058, -0.5, -0.427975, 0, -1, 0, 0.639058, 0.927975, + 0.364058, -0.5, -0.264503, 0, -1, 0, 0.864058, 0.764503, + 0.123607, -0.5, -0.380423, 0, -1, 0, 0.623607, 0.880423, + 0.364058, -0.5, -0.264503, 0, -1, 0, 0.864058, 0.764503, + 0.323607, -0.5, -0.235114, 0, -1, 0, 0.823607, 0.735114, + 0.364058, 0.5, -0.264503, 0, 1, 0, 0.864058, 0.764503, + 0.139058, 0.5, -0.427975, 0, 1, 0, 0.639058, 0.927975, + 0.123607, 0.5, -0.380423, 0, 1, 0, 0.623607, 0.880423, + 0.323607, 0.5, -0.235114, 0, 1, 0, 0.823607, 0.735114, + 0.364058, 0.5, -0.264503, 0, 1, 0, 0.864058, 0.764503, + 0.123607, 0.5, -0.380423, 0, 1, 0, 0.623607, 0.880423, + 0.404509, -0.4, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.9, + 0.154509, -0.4, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.9, + 0.154509, -0.3, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.8, + 0.404509, -0.3, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.8, + 0.404509, -0.4, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.9, + 0.154509, -0.3, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.8, + 0.139058, -0.5, -0.427975, 0, -1, 0, 0.639058, 0.927975, + 0.154509, -0.5, -0.475528, 0, -1, 0, 0.654509, 0.975528, + 0.404509, -0.5, -0.293892, 0, -1, 0, 0.904509, 0.793893, + 0.139058, -0.5, -0.427975, 0, -1, 0, 0.639058, 0.927975, + 0.404509, -0.5, -0.293892, 0, -1, 0, 0.904509, 0.793893, + 0.364058, -0.5, -0.264503, 0, -1, 0, 0.864058, 0.764503, + 0.404509, 0.5, -0.293892, 0, 1, 0, 0.904509, 0.793893, + 0.154509, 0.5, -0.475528, 0, 1, 0, 0.654509, 0.975528, + 0.139058, 0.5, -0.427975, 0, 1, 0, 0.639058, 0.927975, + 0.364058, 0.5, -0.264503, 0, 1, 0, 0.864058, 0.764503, + 0.404509, 0.5, -0.293892, 0, 1, 0, 0.904509, 0.793893, + 0.139058, 0.5, -0.427975, 0, 1, 0, 0.639058, 0.927975, + 0.404509, -0.5, -0.293892, 0.809017, 0, -0.587785, 0.9, 1, + 0.154509, -0.5, -0.475528, 0.309017, 0, -0.951056, 0.8, 1, + 0.154509, -0.4, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.9, + 0.404509, -0.4, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.9, + 0.404509, -0.5, -0.293892, 0.809017, 0, -0.587785, 0.9, 1, + 0.154509, -0.4, -0.475528, 0.309017, 0, -0.951056, 0.8, 0.9, + 0, -0.5, -0, 0, -1, 0, 0.5, 0.5, + 0.0404509, -0.5, -0.0293892, 0, -1, 0, 0.540451, 0.529389, + 0.05, -0.5, 8.74228e-09, 0, -1, 0, 0.55, 0.5, + 0.05, 0.5, 8.74228e-09, 0, 1, 0, 0.55, 0.5, + 0.0404509, 0.5, -0.0293892, 0, 1, 0, 0.540451, 0.529389, + 0, 0.5, -0, 0, 1, 0, 0.5, 0.5, + 0.5, 0.4, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.1, + 0.404509, 0.4, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.1, + 0.404509, 0.5, -0.293892, 0.809017, 0, -0.587785, 0.9, 0, + 0.5, 0.5, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0, + 0.5, 0.4, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.1, + 0.404509, 0.5, -0.293892, 0.809017, 0, -0.587785, 0.9, 0, + 0.0404509, -0.5, -0.0293892, 0, -1, 0, 0.540451, 0.529389, + 0.0809017, -0.5, -0.0587785, 0, -1, 0, 0.580902, 0.558779, + 0.1, -0.5, 1.74846e-08, 0, -1, 0, 0.6, 0.5, + 0.0404509, -0.5, -0.0293892, 0, -1, 0, 0.540451, 0.529389, + 0.1, -0.5, 1.74846e-08, 0, -1, 0, 0.6, 0.5, + 0.05, -0.5, 8.74228e-09, 0, -1, 0, 0.55, 0.5, + 0.1, 0.5, 1.74846e-08, 0, 1, 0, 0.6, 0.5, + 0.0809017, 0.5, -0.0587785, 0, 1, 0, 0.580902, 0.558779, + 0.0404509, 0.5, -0.0293892, 0, 1, 0, 0.540451, 0.529389, + 0.05, 0.5, 8.74228e-09, 0, 1, 0, 0.55, 0.5, + 0.1, 0.5, 1.74846e-08, 0, 1, 0, 0.6, 0.5, + 0.0404509, 0.5, -0.0293892, 0, 1, 0, 0.540451, 0.529389, + 0.5, 0.3, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.2, + 0.404509, 0.3, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.2, + 0.404509, 0.4, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.1, + 0.5, 0.4, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.1, + 0.5, 0.3, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.2, + 0.404509, 0.4, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.1, + 0.0809017, -0.5, -0.0587785, 0, -1, 0, 0.580902, 0.558779, + 0.121353, -0.5, -0.0881677, 0, -1, 0, 0.621353, 0.588168, + 0.15, -0.5, 2.62268e-08, 0, -1, 0, 0.65, 0.5, + 0.0809017, -0.5, -0.0587785, 0, -1, 0, 0.580902, 0.558779, + 0.15, -0.5, 2.62268e-08, 0, -1, 0, 0.65, 0.5, + 0.1, -0.5, 1.74846e-08, 0, -1, 0, 0.6, 0.5, + 0.15, 0.5, 2.62268e-08, 0, 1, 0, 0.65, 0.5, + 0.121353, 0.5, -0.0881677, 0, 1, 0, 0.621353, 0.588168, + 0.0809017, 0.5, -0.0587785, 0, 1, 0, 0.580902, 0.558779, + 0.1, 0.5, 1.74846e-08, 0, 1, 0, 0.6, 0.5, + 0.15, 0.5, 2.62268e-08, 0, 1, 0, 0.65, 0.5, + 0.0809017, 0.5, -0.0587785, 0, 1, 0, 0.580902, 0.558779, + 0.5, 0.2, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.3, + 0.404509, 0.2, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.3, + 0.404509, 0.3, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.2, + 0.5, 0.3, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.2, + 0.5, 0.2, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.3, + 0.404509, 0.3, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.2, + 0.121353, -0.5, -0.0881677, 0, -1, 0, 0.621353, 0.588168, + 0.161803, -0.5, -0.117557, 0, -1, 0, 0.661803, 0.617557, + 0.2, -0.5, 3.49691e-08, 0, -1, 0, 0.7, 0.5, + 0.121353, -0.5, -0.0881677, 0, -1, 0, 0.621353, 0.588168, + 0.2, -0.5, 3.49691e-08, 0, -1, 0, 0.7, 0.5, + 0.15, -0.5, 2.62268e-08, 0, -1, 0, 0.65, 0.5, + 0.2, 0.5, 3.49691e-08, 0, 1, 0, 0.7, 0.5, + 0.161803, 0.5, -0.117557, 0, 1, 0, 0.661803, 0.617557, + 0.121353, 0.5, -0.0881677, 0, 1, 0, 0.621353, 0.588168, + 0.15, 0.5, 2.62268e-08, 0, 1, 0, 0.65, 0.5, + 0.2, 0.5, 3.49691e-08, 0, 1, 0, 0.7, 0.5, + 0.121353, 0.5, -0.0881677, 0, 1, 0, 0.621353, 0.588168, + 0.5, 0.1, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.4, + 0.404509, 0.1, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.4, + 0.404509, 0.2, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.3, + 0.5, 0.2, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.3, + 0.5, 0.1, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.4, + 0.404509, 0.2, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.3, + 0.161803, -0.5, -0.117557, 0, -1, 0, 0.661803, 0.617557, + 0.202254, -0.5, -0.146946, 0, -1, 0, 0.702254, 0.646946, + 0.25, -0.5, 4.37114e-08, 0, -1, 0, 0.75, 0.5, + 0.161803, -0.5, -0.117557, 0, -1, 0, 0.661803, 0.617557, + 0.25, -0.5, 4.37114e-08, 0, -1, 0, 0.75, 0.5, + 0.2, -0.5, 3.49691e-08, 0, -1, 0, 0.7, 0.5, + 0.25, 0.5, 4.37114e-08, 0, 1, 0, 0.75, 0.5, + 0.202254, 0.5, -0.146946, 0, 1, 0, 0.702254, 0.646946, + 0.161803, 0.5, -0.117557, 0, 1, 0, 0.661803, 0.617557, + 0.2, 0.5, 3.49691e-08, 0, 1, 0, 0.7, 0.5, + 0.25, 0.5, 4.37114e-08, 0, 1, 0, 0.75, 0.5, + 0.161803, 0.5, -0.117557, 0, 1, 0, 0.661803, 0.617557, + 0.5, 0, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.5, + 0.404509, 0, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.5, + 0.404509, 0.1, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.4, + 0.5, 0.1, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.4, + 0.5, 0, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.5, + 0.404509, 0.1, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.4, + 0.202254, -0.5, -0.146946, 0, -1, 0, 0.702254, 0.646946, + 0.242705, -0.5, -0.176335, 0, -1, 0, 0.742705, 0.676335, + 0.3, -0.5, 5.24537e-08, 0, -1, 0, 0.8, 0.5, + 0.202254, -0.5, -0.146946, 0, -1, 0, 0.702254, 0.646946, + 0.3, -0.5, 5.24537e-08, 0, -1, 0, 0.8, 0.5, + 0.25, -0.5, 4.37114e-08, 0, -1, 0, 0.75, 0.5, + 0.3, 0.5, 5.24537e-08, 0, 1, 0, 0.8, 0.5, + 0.242705, 0.5, -0.176335, 0, 1, 0, 0.742705, 0.676335, + 0.202254, 0.5, -0.146946, 0, 1, 0, 0.702254, 0.646946, + 0.25, 0.5, 4.37114e-08, 0, 1, 0, 0.75, 0.5, + 0.3, 0.5, 5.24537e-08, 0, 1, 0, 0.8, 0.5, + 0.202254, 0.5, -0.146946, 0, 1, 0, 0.702254, 0.646946, + 0.5, -0.1, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.6, + 0.404509, -0.1, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.6, + 0.404509, 0, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.5, + 0.5, 0, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.5, + 0.5, -0.1, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.6, + 0.404509, 0, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.5, + 0.242705, -0.5, -0.176335, 0, -1, 0, 0.742705, 0.676335, + 0.283156, -0.5, -0.205725, 0, -1, 0, 0.783156, 0.705725, + 0.35, -0.5, 6.11959e-08, 0, -1, 0, 0.85, 0.5, + 0.242705, -0.5, -0.176335, 0, -1, 0, 0.742705, 0.676335, + 0.35, -0.5, 6.11959e-08, 0, -1, 0, 0.85, 0.5, + 0.3, -0.5, 5.24537e-08, 0, -1, 0, 0.8, 0.5, + 0.35, 0.5, 6.11959e-08, 0, 1, 0, 0.85, 0.5, + 0.283156, 0.5, -0.205725, 0, 1, 0, 0.783156, 0.705725, + 0.242705, 0.5, -0.176335, 0, 1, 0, 0.742705, 0.676335, + 0.3, 0.5, 5.24537e-08, 0, 1, 0, 0.8, 0.5, + 0.35, 0.5, 6.11959e-08, 0, 1, 0, 0.85, 0.5, + 0.242705, 0.5, -0.176335, 0, 1, 0, 0.742705, 0.676335, + 0.5, -0.2, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.7, + 0.404509, -0.2, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.7, + 0.404509, -0.1, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.6, + 0.5, -0.1, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.6, + 0.5, -0.2, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.7, + 0.404509, -0.1, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.6, + 0.283156, -0.5, -0.205725, 0, -1, 0, 0.783156, 0.705725, + 0.323607, -0.5, -0.235114, 0, -1, 0, 0.823607, 0.735114, + 0.4, -0.5, 6.99382e-08, 0, -1, 0, 0.9, 0.5, + 0.283156, -0.5, -0.205725, 0, -1, 0, 0.783156, 0.705725, + 0.4, -0.5, 6.99382e-08, 0, -1, 0, 0.9, 0.5, + 0.35, -0.5, 6.11959e-08, 0, -1, 0, 0.85, 0.5, + 0.4, 0.5, 6.99382e-08, 0, 1, 0, 0.9, 0.5, + 0.323607, 0.5, -0.235114, 0, 1, 0, 0.823607, 0.735114, + 0.283156, 0.5, -0.205725, 0, 1, 0, 0.783156, 0.705725, + 0.35, 0.5, 6.11959e-08, 0, 1, 0, 0.85, 0.5, + 0.4, 0.5, 6.99382e-08, 0, 1, 0, 0.9, 0.5, + 0.283156, 0.5, -0.205725, 0, 1, 0, 0.783156, 0.705725, + 0.5, -0.3, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.8, + 0.404509, -0.3, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.8, + 0.404509, -0.2, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.7, + 0.5, -0.2, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.7, + 0.5, -0.3, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.8, + 0.404509, -0.2, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.7, + 0.323607, -0.5, -0.235114, 0, -1, 0, 0.823607, 0.735114, + 0.364058, -0.5, -0.264503, 0, -1, 0, 0.864058, 0.764503, + 0.45, -0.5, 7.86805e-08, 0, -1, 0, 0.95, 0.5, + 0.323607, -0.5, -0.235114, 0, -1, 0, 0.823607, 0.735114, + 0.45, -0.5, 7.86805e-08, 0, -1, 0, 0.95, 0.5, + 0.4, -0.5, 6.99382e-08, 0, -1, 0, 0.9, 0.5, + 0.45, 0.5, 7.86805e-08, 0, 1, 0, 0.95, 0.5, + 0.364058, 0.5, -0.264503, 0, 1, 0, 0.864058, 0.764503, + 0.323607, 0.5, -0.235114, 0, 1, 0, 0.823607, 0.735114, + 0.4, 0.5, 6.99382e-08, 0, 1, 0, 0.9, 0.5, + 0.45, 0.5, 7.86805e-08, 0, 1, 0, 0.95, 0.5, + 0.323607, 0.5, -0.235114, 0, 1, 0, 0.823607, 0.735114, + 0.5, -0.4, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.9, + 0.404509, -0.4, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.9, + 0.404509, -0.3, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.8, + 0.5, -0.3, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.8, + 0.5, -0.4, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.9, + 0.404509, -0.3, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.8, + 0.364058, -0.5, -0.264503, 0, -1, 0, 0.864058, 0.764503, + 0.404509, -0.5, -0.293892, 0, -1, 0, 0.904509, 0.793893, + 0.5, -0.5, 8.74228e-08, 0, -1, 0, 1, 0.5, + 0.364058, -0.5, -0.264503, 0, -1, 0, 0.864058, 0.764503, + 0.5, -0.5, 8.74228e-08, 0, -1, 0, 1, 0.5, + 0.45, -0.5, 7.86805e-08, 0, -1, 0, 0.95, 0.5, + 0.5, 0.5, 8.74228e-08, 0, 1, 0, 1, 0.5, + 0.404509, 0.5, -0.293892, 0, 1, 0, 0.904509, 0.793893, + 0.364058, 0.5, -0.264503, 0, 1, 0, 0.864058, 0.764503, + 0.45, 0.5, 7.86805e-08, 0, 1, 0, 0.95, 0.5, + 0.5, 0.5, 8.74228e-08, 0, 1, 0, 1, 0.5, + 0.364058, 0.5, -0.264503, 0, 1, 0, 0.864058, 0.764503, + 0.5, -0.5, 8.74228e-08, 1, 0, 1.74846e-07, 1, 1, + 0.404509, -0.5, -0.293892, 0.809017, 0, -0.587785, 0.9, 1, + 0.404509, -0.4, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.9, + 0.5, -0.4, 8.74228e-08, 1, 0, 1.74846e-07, 1, 0.9, + 0.5, -0.5, 8.74228e-08, 1, 0, 1.74846e-07, 1, 1, + 0.404509, -0.4, -0.293892, 0.809017, 0, -0.587785, 0.9, 0.9 +}; + +std::vector<GLfloat> coneVertexBufferData = { + 0.0404509, 0.4, 0.0293893, 0.723607, 0.447214, 0.525731, 0.9, 0.9, + 0.05, 0.4, 0, 0.894427, 0.447214, 0, 1, 0.9, + 0, 0.5, 0, 0.84181, 0.465341, 0.273521, 1, 1, + 0, -0.5, 0, 0, -1, 0, -0.5, -0.5, + 0.05, -0.5, 0, 0, -1, 0, -0.45, -0.5, + 0.0404509, -0.5, 0.0293893, 0, -1, 0, -0.459549, -0.470611, + 0.0809017, 0.3, 0.0587785, 0.723607, 0.447214, 0.525731, 0.9, 0.8, + 0.1, 0.3, 0, 0.894427, 0.447214, 0, 1, 0.8, + 0.05, 0.4, 0, 0.894427, 0.447214, 0, 1, 0.9, + 0.0404509, 0.4, 0.0293893, 0.723607, 0.447214, 0.525731, 0.9, 0.9, + 0.0809017, 0.3, 0.0587785, 0.723607, 0.447214, 0.525731, 0.9, 0.8, + 0.05, 0.4, 0, 0.894427, 0.447214, 0, 1, 0.9, + 0.05, -0.5, 0, 0, -1, 0, -0.45, -0.5, + 0.1, -0.5, 0, 0, -1, 0, -0.4, -0.5, + 0.0809017, -0.5, 0.0587785, 0, -1, 0, -0.419098, -0.441221, + 0.05, -0.5, 0, 0, -1, 0, -0.45, -0.5, + 0.0809017, -0.5, 0.0587785, 0, -1, 0, -0.419098, -0.441221, + 0.0404509, -0.5, 0.0293893, 0, -1, 0, -0.459549, -0.470611, + 0.121353, 0.2, 0.0881678, 0.723607, 0.447214, 0.525731, 0.9, 0.7, + 0.15, 0.2, 0, 0.894427, 0.447214, 0, 1, 0.7, + 0.1, 0.3, 0, 0.894427, 0.447214, 0, 1, 0.8, + 0.0809017, 0.3, 0.0587785, 0.723607, 0.447214, 0.525731, 0.9, 0.8, + 0.121353, 0.2, 0.0881678, 0.723607, 0.447214, 0.525731, 0.9, 0.7, + 0.1, 0.3, 0, 0.894427, 0.447214, 0, 1, 0.8, + 0.1, -0.5, 0, 0, -1, 0, -0.4, -0.5, + 0.15, -0.5, 0, 0, -1, 0, -0.35, -0.5, + 0.121353, -0.5, 0.0881678, 0, -1, 0, -0.378647, -0.411832, + 0.1, -0.5, 0, 0, -1, 0, -0.4, -0.5, + 0.121353, -0.5, 0.0881678, 0, -1, 0, -0.378647, -0.411832, + 0.0809017, -0.5, 0.0587785, 0, -1, 0, -0.419098, -0.441221, + 0.161803, 0.1, 0.117557, 0.723607, 0.447214, 0.525731, 0.9, 0.6, + 0.2, 0.1, 0, 0.894427, 0.447214, 0, 1, 0.6, + 0.15, 0.2, 0, 0.894427, 0.447214, 0, 1, 0.7, + 0.121353, 0.2, 0.0881678, 0.723607, 0.447214, 0.525731, 0.9, 0.7, + 0.161803, 0.1, 0.117557, 0.723607, 0.447214, 0.525731, 0.9, 0.6, + 0.15, 0.2, 0, 0.894427, 0.447214, 0, 1, 0.7, + 0.15, -0.5, 0, 0, -1, 0, -0.35, -0.5, + 0.2, -0.5, 0, 0, -1, 0, -0.3, -0.5, + 0.161803, -0.5, 0.117557, 0, -1, 0, -0.338197, -0.382443, + 0.15, -0.5, 0, 0, -1, 0, -0.35, -0.5, + 0.161803, -0.5, 0.117557, 0, -1, 0, -0.338197, -0.382443, + 0.121353, -0.5, 0.0881678, 0, -1, 0, -0.378647, -0.411832, + 0.202254, 0, 0.146946, 0.723607, 0.447214, 0.525731, 0.9, 0.5, + 0.25, 0, 0, 0.894427, 0.447214, 0, 1, 0.5, + 0.2, 0.1, 0, 0.894427, 0.447214, 0, 1, 0.6, + 0.161803, 0.1, 0.117557, 0.723607, 0.447214, 0.525731, 0.9, 0.6, + 0.202254, 0, 0.146946, 0.723607, 0.447214, 0.525731, 0.9, 0.5, + 0.2, 0.1, 0, 0.894427, 0.447214, 0, 1, 0.6, + 0.2, -0.5, 0, 0, -1, 0, -0.3, -0.5, + 0.25, -0.5, 0, 0, -1, 0, -0.25, -0.5, + 0.202254, -0.5, 0.146946, 0, -1, 0, -0.297746, -0.353054, + 0.2, -0.5, 0, 0, -1, 0, -0.3, -0.5, + 0.202254, -0.5, 0.146946, 0, -1, 0, -0.297746, -0.353054, + 0.161803, -0.5, 0.117557, 0, -1, 0, -0.338197, -0.382443, + 0.242705, -0.1, 0.176336, 0.723607, 0.447214, 0.525731, 0.9, 0.4, + 0.3, -0.1, 0, 0.894427, 0.447214, 0, 1, 0.4, + 0.25, 0, 0, 0.894427, 0.447214, 0, 1, 0.5, + 0.202254, 0, 0.146946, 0.723607, 0.447214, 0.525731, 0.9, 0.5, + 0.242705, -0.1, 0.176336, 0.723607, 0.447214, 0.525731, 0.9, 0.4, + 0.25, 0, 0, 0.894427, 0.447214, 0, 1, 0.5, + 0.25, -0.5, 0, 0, -1, 0, -0.25, -0.5, + 0.3, -0.5, 0, 0, -1, 0, -0.2, -0.5, + 0.242705, -0.5, 0.176336, 0, -1, 0, -0.257295, -0.323664, + 0.25, -0.5, 0, 0, -1, 0, -0.25, -0.5, + 0.242705, -0.5, 0.176336, 0, -1, 0, -0.257295, -0.323664, + 0.202254, -0.5, 0.146946, 0, -1, 0, -0.297746, -0.353054, + 0.283156, -0.2, 0.205725, 0.723607, 0.447214, 0.525731, 0.9, 0.3, + 0.35, -0.2, 0, 0.894427, 0.447214, 0, 1, 0.3, + 0.3, -0.1, 0, 0.894427, 0.447214, 0, 1, 0.4, + 0.242705, -0.1, 0.176336, 0.723607, 0.447214, 0.525731, 0.9, 0.4, + 0.283156, -0.2, 0.205725, 0.723607, 0.447214, 0.525731, 0.9, 0.3, + 0.3, -0.1, 0, 0.894427, 0.447214, 0, 1, 0.4, + 0.3, -0.5, 0, 0, -1, 0, -0.2, -0.5, + 0.35, -0.5, 0, 0, -1, 0, -0.15, -0.5, + 0.283156, -0.5, 0.205725, 0, -1, 0, -0.216844, -0.294275, + 0.3, -0.5, 0, 0, -1, 0, -0.2, -0.5, + 0.283156, -0.5, 0.205725, 0, -1, 0, -0.216844, -0.294275, + 0.242705, -0.5, 0.176336, 0, -1, 0, -0.257295, -0.323664, + 0.323607, -0.3, 0.235114, 0.723607, 0.447214, 0.525731, 0.9, 0.2, + 0.4, -0.3, 0, 0.894427, 0.447214, 0, 1, 0.2, + 0.35, -0.2, 0, 0.894427, 0.447214, 0, 1, 0.3, + 0.283156, -0.2, 0.205725, 0.723607, 0.447214, 0.525731, 0.9, 0.3, + 0.323607, -0.3, 0.235114, 0.723607, 0.447214, 0.525731, 0.9, 0.2, + 0.35, -0.2, 0, 0.894427, 0.447214, 0, 1, 0.3, + 0.35, -0.5, 0, 0, -1, 0, -0.15, -0.5, + 0.4, -0.5, 0, 0, -1, 0, -0.1, -0.5, + 0.323607, -0.5, 0.235114, 0, -1, 0, -0.176393, -0.264886, + 0.35, -0.5, 0, 0, -1, 0, -0.15, -0.5, + 0.323607, -0.5, 0.235114, 0, -1, 0, -0.176393, -0.264886, + 0.283156, -0.5, 0.205725, 0, -1, 0, -0.216844, -0.294275, + 0.364058, -0.4, 0.264503, 0.723607, 0.447214, 0.525731, 0.9, 0.1, + 0.45, -0.4, 0, 0.894427, 0.447214, 0, 1, 0.1, + 0.4, -0.3, 0, 0.894427, 0.447214, 0, 1, 0.2, + 0.323607, -0.3, 0.235114, 0.723607, 0.447214, 0.525731, 0.9, 0.2, + 0.364058, -0.4, 0.264503, 0.723607, 0.447214, 0.525731, 0.9, 0.1, + 0.4, -0.3, 0, 0.894427, 0.447214, 0, 1, 0.2, + 0.4, -0.5, 0, 0, -1, 0, -0.1, -0.5, + 0.45, -0.5, 0, 0, -1, 0, -0.05, -0.5, + 0.364058, -0.5, 0.264503, 0, -1, 0, -0.135942, -0.235497, + 0.4, -0.5, 0, 0, -1, 0, -0.1, -0.5, + 0.364058, -0.5, 0.264503, 0, -1, 0, -0.135942, -0.235497, + 0.323607, -0.5, 0.235114, 0, -1, 0, -0.176393, -0.264886, + 0.404509, -0.5, 0.293893, 0.723607, 0.447214, 0.525731, 0.9, 0, + 0.5, -0.5, 0, 0.894427, 0.447214, 0, 1, 0, + 0.45, -0.4, 0, 0.894427, 0.447214, 0, 1, 0.1, + 0.364058, -0.4, 0.264503, 0.723607, 0.447214, 0.525731, 0.9, 0.1, + 0.404509, -0.5, 0.293893, 0.723607, 0.447214, 0.525731, 0.9, 0, + 0.45, -0.4, 0, 0.894427, 0.447214, 0, 1, 0.1, + 0.45, -0.5, 0, 0, -1, 0, -0.05, -0.5, + 0.5, -0.5, 0, 0, -1, 0, 0, -0.5, + 0.404509, -0.5, 0.293893, 0, -1, 0, -0.0954915, -0.206107, + 0.45, -0.5, 0, 0, -1, 0, -0.05, -0.5, + 0.404509, -0.5, 0.293893, 0, -1, 0, -0.0954915, -0.206107, + 0.364058, -0.5, 0.264503, 0, -1, 0, -0.135942, -0.235497, + 0.0154508, 0.4, 0.0475528, 0.276393, 0.447214, 0.850651, 0.8, 0.9, + 0.0404509, 0.4, 0.0293893, 0.723607, 0.447214, 0.525731, 0.9, 0.9, + 0, 0.5, 0, 0.520267, 0.465341, 0.716086, 0.9, 1, + 0, -0.5, 0, 0, -1, 0, -0.5, -0.5, + 0.0404509, -0.5, 0.0293893, 0, -1, 0, -0.459549, -0.470611, + 0.0154508, -0.5, 0.0475528, 0, -1, 0, -0.484549, -0.452447, + 0.0309017, 0.3, 0.0951057, 0.276393, 0.447214, 0.850651, 0.8, 0.8, + 0.0809017, 0.3, 0.0587785, 0.723607, 0.447214, 0.525731, 0.9, 0.8, + 0.0404509, 0.4, 0.0293893, 0.723607, 0.447214, 0.525731, 0.9, 0.9, + 0.0154508, 0.4, 0.0475528, 0.276393, 0.447214, 0.850651, 0.8, 0.9, + 0.0309017, 0.3, 0.0951057, 0.276393, 0.447214, 0.850651, 0.8, 0.8, + 0.0404509, 0.4, 0.0293893, 0.723607, 0.447214, 0.525731, 0.9, 0.9, + 0.0404509, -0.5, 0.0293893, 0, -1, 0, -0.459549, -0.470611, + 0.0809017, -0.5, 0.0587785, 0, -1, 0, -0.419098, -0.441221, + 0.0309017, -0.5, 0.0951057, 0, -1, 0, -0.469098, -0.404894, + 0.0404509, -0.5, 0.0293893, 0, -1, 0, -0.459549, -0.470611, + 0.0309017, -0.5, 0.0951057, 0, -1, 0, -0.469098, -0.404894, + 0.0154508, -0.5, 0.0475528, 0, -1, 0, -0.484549, -0.452447, + 0.0463525, 0.2, 0.142658, 0.276393, 0.447214, 0.850651, 0.8, 0.7, + 0.121353, 0.2, 0.0881678, 0.723607, 0.447214, 0.525731, 0.9, 0.7, + 0.0809017, 0.3, 0.0587785, 0.723607, 0.447214, 0.525731, 0.9, 0.8, + 0.0309017, 0.3, 0.0951057, 0.276393, 0.447214, 0.850651, 0.8, 0.8, + 0.0463525, 0.2, 0.142658, 0.276393, 0.447214, 0.850651, 0.8, 0.7, + 0.0809017, 0.3, 0.0587785, 0.723607, 0.447214, 0.525731, 0.9, 0.8, + 0.0809017, -0.5, 0.0587785, 0, -1, 0, -0.419098, -0.441221, + 0.121353, -0.5, 0.0881678, 0, -1, 0, -0.378647, -0.411832, + 0.0463525, -0.5, 0.142658, 0, -1, 0, -0.453647, -0.357342, + 0.0809017, -0.5, 0.0587785, 0, -1, 0, -0.419098, -0.441221, + 0.0463525, -0.5, 0.142658, 0, -1, 0, -0.453647, -0.357342, + 0.0309017, -0.5, 0.0951057, 0, -1, 0, -0.469098, -0.404894, + 0.0618034, 0.1, 0.190211, 0.276393, 0.447214, 0.850651, 0.8, 0.6, + 0.161803, 0.1, 0.117557, 0.723607, 0.447214, 0.525731, 0.9, 0.6, + 0.121353, 0.2, 0.0881678, 0.723607, 0.447214, 0.525731, 0.9, 0.7, + 0.0463525, 0.2, 0.142658, 0.276393, 0.447214, 0.850651, 0.8, 0.7, + 0.0618034, 0.1, 0.190211, 0.276393, 0.447214, 0.850651, 0.8, 0.6, + 0.121353, 0.2, 0.0881678, 0.723607, 0.447214, 0.525731, 0.9, 0.7, + 0.121353, -0.5, 0.0881678, 0, -1, 0, -0.378647, -0.411832, + 0.161803, -0.5, 0.117557, 0, -1, 0, -0.338197, -0.382443, + 0.0618034, -0.5, 0.190211, 0, -1, 0, -0.438197, -0.309789, + 0.121353, -0.5, 0.0881678, 0, -1, 0, -0.378647, -0.411832, + 0.0618034, -0.5, 0.190211, 0, -1, 0, -0.438197, -0.309789, + 0.0463525, -0.5, 0.142658, 0, -1, 0, -0.453647, -0.357342, + 0.0772542, 0, 0.237764, 0.276393, 0.447214, 0.850651, 0.8, 0.5, + 0.202254, 0, 0.146946, 0.723607, 0.447214, 0.525731, 0.9, 0.5, + 0.161803, 0.1, 0.117557, 0.723607, 0.447214, 0.525731, 0.9, 0.6, + 0.0618034, 0.1, 0.190211, 0.276393, 0.447214, 0.850651, 0.8, 0.6, + 0.0772542, 0, 0.237764, 0.276393, 0.447214, 0.850651, 0.8, 0.5, + 0.161803, 0.1, 0.117557, 0.723607, 0.447214, 0.525731, 0.9, 0.6, + 0.161803, -0.5, 0.117557, 0, -1, 0, -0.338197, -0.382443, + 0.202254, -0.5, 0.146946, 0, -1, 0, -0.297746, -0.353054, + 0.0772542, -0.5, 0.237764, 0, -1, 0, -0.422746, -0.262236, + 0.161803, -0.5, 0.117557, 0, -1, 0, -0.338197, -0.382443, + 0.0772542, -0.5, 0.237764, 0, -1, 0, -0.422746, -0.262236, + 0.0618034, -0.5, 0.190211, 0, -1, 0, -0.438197, -0.309789, + 0.0927051, -0.1, 0.285317, 0.276393, 0.447214, 0.850651, 0.8, 0.4, + 0.242705, -0.1, 0.176336, 0.723607, 0.447214, 0.525731, 0.9, 0.4, + 0.202254, 0, 0.146946, 0.723607, 0.447214, 0.525731, 0.9, 0.5, + 0.0772542, 0, 0.237764, 0.276393, 0.447214, 0.850651, 0.8, 0.5, + 0.0927051, -0.1, 0.285317, 0.276393, 0.447214, 0.850651, 0.8, 0.4, + 0.202254, 0, 0.146946, 0.723607, 0.447214, 0.525731, 0.9, 0.5, + 0.202254, -0.5, 0.146946, 0, -1, 0, -0.297746, -0.353054, + 0.242705, -0.5, 0.176336, 0, -1, 0, -0.257295, -0.323664, + 0.0927051, -0.5, 0.285317, 0, -1, 0, -0.407295, -0.214683, + 0.202254, -0.5, 0.146946, 0, -1, 0, -0.297746, -0.353054, + 0.0927051, -0.5, 0.285317, 0, -1, 0, -0.407295, -0.214683, + 0.0772542, -0.5, 0.237764, 0, -1, 0, -0.422746, -0.262236, + 0.108156, -0.2, 0.33287, 0.276393, 0.447214, 0.850651, 0.8, 0.3, + 0.283156, -0.2, 0.205725, 0.723607, 0.447214, 0.525731, 0.9, 0.3, + 0.242705, -0.1, 0.176336, 0.723607, 0.447214, 0.525731, 0.9, 0.4, + 0.0927051, -0.1, 0.285317, 0.276393, 0.447214, 0.850651, 0.8, 0.4, + 0.108156, -0.2, 0.33287, 0.276393, 0.447214, 0.850651, 0.8, 0.3, + 0.242705, -0.1, 0.176336, 0.723607, 0.447214, 0.525731, 0.9, 0.4, + 0.242705, -0.5, 0.176336, 0, -1, 0, -0.257295, -0.323664, + 0.283156, -0.5, 0.205725, 0, -1, 0, -0.216844, -0.294275, + 0.108156, -0.5, 0.33287, 0, -1, 0, -0.391844, -0.16713, + 0.242705, -0.5, 0.176336, 0, -1, 0, -0.257295, -0.323664, + 0.108156, -0.5, 0.33287, 0, -1, 0, -0.391844, -0.16713, + 0.0927051, -0.5, 0.285317, 0, -1, 0, -0.407295, -0.214683, + 0.123607, -0.3, 0.380423, 0.276393, 0.447214, 0.850651, 0.8, 0.2, + 0.323607, -0.3, 0.235114, 0.723607, 0.447214, 0.525731, 0.9, 0.2, + 0.283156, -0.2, 0.205725, 0.723607, 0.447214, 0.525731, 0.9, 0.3, + 0.108156, -0.2, 0.33287, 0.276393, 0.447214, 0.850651, 0.8, 0.3, + 0.123607, -0.3, 0.380423, 0.276393, 0.447214, 0.850651, 0.8, 0.2, + 0.283156, -0.2, 0.205725, 0.723607, 0.447214, 0.525731, 0.9, 0.3, + 0.283156, -0.5, 0.205725, 0, -1, 0, -0.216844, -0.294275, + 0.323607, -0.5, 0.235114, 0, -1, 0, -0.176393, -0.264886, + 0.123607, -0.5, 0.380423, 0, -1, 0, -0.376393, -0.119577, + 0.283156, -0.5, 0.205725, 0, -1, 0, -0.216844, -0.294275, + 0.123607, -0.5, 0.380423, 0, -1, 0, -0.376393, -0.119577, + 0.108156, -0.5, 0.33287, 0, -1, 0, -0.391844, -0.16713, + 0.139058, -0.4, 0.427975, 0.276393, 0.447214, 0.850651, 0.8, 0.1, + 0.364058, -0.4, 0.264503, 0.723607, 0.447214, 0.525731, 0.9, 0.1, + 0.323607, -0.3, 0.235114, 0.723607, 0.447214, 0.525731, 0.9, 0.2, + 0.123607, -0.3, 0.380423, 0.276393, 0.447214, 0.850651, 0.8, 0.2, + 0.139058, -0.4, 0.427975, 0.276393, 0.447214, 0.850651, 0.8, 0.1, + 0.323607, -0.3, 0.235114, 0.723607, 0.447214, 0.525731, 0.9, 0.2, + 0.323607, -0.5, 0.235114, 0, -1, 0, -0.176393, -0.264886, + 0.364058, -0.5, 0.264503, 0, -1, 0, -0.135942, -0.235497, + 0.139058, -0.5, 0.427975, 0, -1, 0, -0.360942, -0.0720246, + 0.323607, -0.5, 0.235114, 0, -1, 0, -0.176393, -0.264886, + 0.139058, -0.5, 0.427975, 0, -1, 0, -0.360942, -0.0720246, + 0.123607, -0.5, 0.380423, 0, -1, 0, -0.376393, -0.119577, + 0.154508, -0.5, 0.475528, 0.276393, 0.447214, 0.850651, 0.8, 0, + 0.404509, -0.5, 0.293893, 0.723607, 0.447214, 0.525731, 0.9, 0, + 0.364058, -0.4, 0.264503, 0.723607, 0.447214, 0.525731, 0.9, 0.1, + 0.139058, -0.4, 0.427975, 0.276393, 0.447214, 0.850651, 0.8, 0.1, + 0.154508, -0.5, 0.475528, 0.276393, 0.447214, 0.850651, 0.8, 0, + 0.364058, -0.4, 0.264503, 0.723607, 0.447214, 0.525731, 0.9, 0.1, + 0.364058, -0.5, 0.264503, 0, -1, 0, -0.135942, -0.235497, + 0.404509, -0.5, 0.293893, 0, -1, 0, -0.0954915, -0.206107, + 0.154508, -0.5, 0.475528, 0, -1, 0, -0.345492, -0.0244717, + 0.364058, -0.5, 0.264503, 0, -1, 0, -0.135942, -0.235497, + 0.154508, -0.5, 0.475528, 0, -1, 0, -0.345492, -0.0244717, + 0.139058, -0.5, 0.427975, 0, -1, 0, -0.360942, -0.0720246, + -0.0154509, 0.4, 0.0475528, -0.276393, 0.447214, 0.850651, 0.7, 0.9, + 0.0154508, 0.4, 0.0475528, 0.276393, 0.447214, 0.850651, 0.8, 0.9, + 0, 0.5, 0, -3.10103e-08, 0.465341, 0.885131, 0.8, 1, + 0, -0.5, 0, 0, -1, 0, -0.5, -0.5, + 0.0154508, -0.5, 0.0475528, 0, -1, 0, -0.484549, -0.452447, + -0.0154509, -0.5, 0.0475528, 0, -1, 0, -0.515451, -0.452447, + -0.0309017, 0.3, 0.0951056, -0.276393, 0.447214, 0.850651, 0.7, 0.8, + 0.0309017, 0.3, 0.0951057, 0.276393, 0.447214, 0.850651, 0.8, 0.8, + 0.0154508, 0.4, 0.0475528, 0.276393, 0.447214, 0.850651, 0.8, 0.9, + -0.0154509, 0.4, 0.0475528, -0.276393, 0.447214, 0.850651, 0.7, 0.9, + -0.0309017, 0.3, 0.0951056, -0.276393, 0.447214, 0.850651, 0.7, 0.8, + 0.0154508, 0.4, 0.0475528, 0.276393, 0.447214, 0.850651, 0.8, 0.9, + 0.0154508, -0.5, 0.0475528, 0, -1, 0, -0.484549, -0.452447, + 0.0309017, -0.5, 0.0951057, 0, -1, 0, -0.469098, -0.404894, + -0.0309017, -0.5, 0.0951056, 0, -1, 0, -0.530902, -0.404894, + 0.0154508, -0.5, 0.0475528, 0, -1, 0, -0.484549, -0.452447, + -0.0309017, -0.5, 0.0951056, 0, -1, 0, -0.530902, -0.404894, + -0.0154509, -0.5, 0.0475528, 0, -1, 0, -0.515451, -0.452447, + -0.0463526, 0.2, 0.142658, -0.276393, 0.447214, 0.850651, 0.7, 0.7, + 0.0463525, 0.2, 0.142658, 0.276393, 0.447214, 0.850651, 0.8, 0.7, + 0.0309017, 0.3, 0.0951057, 0.276393, 0.447214, 0.850651, 0.8, 0.8, + -0.0309017, 0.3, 0.0951056, -0.276393, 0.447214, 0.850651, 0.7, 0.8, + -0.0463526, 0.2, 0.142658, -0.276393, 0.447214, 0.850651, 0.7, 0.7, + 0.0309017, 0.3, 0.0951057, 0.276393, 0.447214, 0.850651, 0.8, 0.8, + 0.0309017, -0.5, 0.0951057, 0, -1, 0, -0.469098, -0.404894, + 0.0463525, -0.5, 0.142658, 0, -1, 0, -0.453647, -0.357342, + -0.0463526, -0.5, 0.142658, 0, -1, 0, -0.546353, -0.357342, + 0.0309017, -0.5, 0.0951057, 0, -1, 0, -0.469098, -0.404894, + -0.0463526, -0.5, 0.142658, 0, -1, 0, -0.546353, -0.357342, + -0.0309017, -0.5, 0.0951056, 0, -1, 0, -0.530902, -0.404894, + -0.0618034, 0.1, 0.190211, -0.276393, 0.447214, 0.850651, 0.7, 0.6, + 0.0618034, 0.1, 0.190211, 0.276393, 0.447214, 0.850651, 0.8, 0.6, + 0.0463525, 0.2, 0.142658, 0.276393, 0.447214, 0.850651, 0.8, 0.7, + -0.0463526, 0.2, 0.142658, -0.276393, 0.447214, 0.850651, 0.7, 0.7, + -0.0618034, 0.1, 0.190211, -0.276393, 0.447214, 0.850651, 0.7, 0.6, + 0.0463525, 0.2, 0.142658, 0.276393, 0.447214, 0.850651, 0.8, 0.7, + 0.0463525, -0.5, 0.142658, 0, -1, 0, -0.453647, -0.357342, + 0.0618034, -0.5, 0.190211, 0, -1, 0, -0.438197, -0.309789, + -0.0618034, -0.5, 0.190211, 0, -1, 0, -0.561803, -0.309789, + 0.0463525, -0.5, 0.142658, 0, -1, 0, -0.453647, -0.357342, + -0.0618034, -0.5, 0.190211, 0, -1, 0, -0.561803, -0.309789, + -0.0463526, -0.5, 0.142658, 0, -1, 0, -0.546353, -0.357342, + -0.0772543, 0, 0.237764, -0.276393, 0.447214, 0.850651, 0.7, 0.5, + 0.0772542, 0, 0.237764, 0.276393, 0.447214, 0.850651, 0.8, 0.5, + 0.0618034, 0.1, 0.190211, 0.276393, 0.447214, 0.850651, 0.8, 0.6, + -0.0618034, 0.1, 0.190211, -0.276393, 0.447214, 0.850651, 0.7, 0.6, + -0.0772543, 0, 0.237764, -0.276393, 0.447214, 0.850651, 0.7, 0.5, + 0.0618034, 0.1, 0.190211, 0.276393, 0.447214, 0.850651, 0.8, 0.6, + 0.0618034, -0.5, 0.190211, 0, -1, 0, -0.438197, -0.309789, + 0.0772542, -0.5, 0.237764, 0, -1, 0, -0.422746, -0.262236, + -0.0772543, -0.5, 0.237764, 0, -1, 0, -0.577254, -0.262236, + 0.0618034, -0.5, 0.190211, 0, -1, 0, -0.438197, -0.309789, + -0.0772543, -0.5, 0.237764, 0, -1, 0, -0.577254, -0.262236, + -0.0618034, -0.5, 0.190211, 0, -1, 0, -0.561803, -0.309789, + -0.0927051, -0.1, 0.285317, -0.276393, 0.447214, 0.850651, 0.7, 0.4, + 0.0927051, -0.1, 0.285317, 0.276393, 0.447214, 0.850651, 0.8, 0.4, + 0.0772542, 0, 0.237764, 0.276393, 0.447214, 0.850651, 0.8, 0.5, + -0.0772543, 0, 0.237764, -0.276393, 0.447214, 0.850651, 0.7, 0.5, + -0.0927051, -0.1, 0.285317, -0.276393, 0.447214, 0.850651, 0.7, 0.4, + 0.0772542, 0, 0.237764, 0.276393, 0.447214, 0.850651, 0.8, 0.5, + 0.0772542, -0.5, 0.237764, 0, -1, 0, -0.422746, -0.262236, + 0.0927051, -0.5, 0.285317, 0, -1, 0, -0.407295, -0.214683, + -0.0927051, -0.5, 0.285317, 0, -1, 0, -0.592705, -0.214683, + 0.0772542, -0.5, 0.237764, 0, -1, 0, -0.422746, -0.262236, + -0.0927051, -0.5, 0.285317, 0, -1, 0, -0.592705, -0.214683, + -0.0772543, -0.5, 0.237764, 0, -1, 0, -0.577254, -0.262236, + -0.108156, -0.2, 0.33287, -0.276393, 0.447214, 0.850651, 0.7, 0.3, + 0.108156, -0.2, 0.33287, 0.276393, 0.447214, 0.850651, 0.8, 0.3, + 0.0927051, -0.1, 0.285317, 0.276393, 0.447214, 0.850651, 0.8, 0.4, + -0.0927051, -0.1, 0.285317, -0.276393, 0.447214, 0.850651, 0.7, 0.4, + -0.108156, -0.2, 0.33287, -0.276393, 0.447214, 0.850651, 0.7, 0.3, + 0.0927051, -0.1, 0.285317, 0.276393, 0.447214, 0.850651, 0.8, 0.4, + 0.0927051, -0.5, 0.285317, 0, -1, 0, -0.407295, -0.214683, + 0.108156, -0.5, 0.33287, 0, -1, 0, -0.391844, -0.16713, + -0.108156, -0.5, 0.33287, 0, -1, 0, -0.608156, -0.16713, + 0.0927051, -0.5, 0.285317, 0, -1, 0, -0.407295, -0.214683, + -0.108156, -0.5, 0.33287, 0, -1, 0, -0.608156, -0.16713, + -0.0927051, -0.5, 0.285317, 0, -1, 0, -0.592705, -0.214683, + -0.123607, -0.3, 0.380423, -0.276393, 0.447214, 0.850651, 0.7, 0.2, + 0.123607, -0.3, 0.380423, 0.276393, 0.447214, 0.850651, 0.8, 0.2, + 0.108156, -0.2, 0.33287, 0.276393, 0.447214, 0.850651, 0.8, 0.3, + -0.108156, -0.2, 0.33287, -0.276393, 0.447214, 0.850651, 0.7, 0.3, + -0.123607, -0.3, 0.380423, -0.276393, 0.447214, 0.850651, 0.7, 0.2, + 0.108156, -0.2, 0.33287, 0.276393, 0.447214, 0.850651, 0.8, 0.3, + 0.108156, -0.5, 0.33287, 0, -1, 0, -0.391844, -0.16713, + 0.123607, -0.5, 0.380423, 0, -1, 0, -0.376393, -0.119577, + -0.123607, -0.5, 0.380423, 0, -1, 0, -0.623607, -0.119577, + 0.108156, -0.5, 0.33287, 0, -1, 0, -0.391844, -0.16713, + -0.123607, -0.5, 0.380423, 0, -1, 0, -0.623607, -0.119577, + -0.108156, -0.5, 0.33287, 0, -1, 0, -0.608156, -0.16713, + -0.139058, -0.4, 0.427975, -0.276393, 0.447214, 0.850651, 0.7, 0.1, + 0.139058, -0.4, 0.427975, 0.276393, 0.447214, 0.850651, 0.8, 0.1, + 0.123607, -0.3, 0.380423, 0.276393, 0.447214, 0.850651, 0.8, 0.2, + -0.123607, -0.3, 0.380423, -0.276393, 0.447214, 0.850651, 0.7, 0.2, + -0.139058, -0.4, 0.427975, -0.276393, 0.447214, 0.850651, 0.7, 0.1, + 0.123607, -0.3, 0.380423, 0.276393, 0.447214, 0.850651, 0.8, 0.2, + 0.123607, -0.5, 0.380423, 0, -1, 0, -0.376393, -0.119577, + 0.139058, -0.5, 0.427975, 0, -1, 0, -0.360942, -0.0720246, + -0.139058, -0.5, 0.427975, 0, -1, 0, -0.639058, -0.0720246, + 0.123607, -0.5, 0.380423, 0, -1, 0, -0.376393, -0.119577, + -0.139058, -0.5, 0.427975, 0, -1, 0, -0.639058, -0.0720246, + -0.123607, -0.5, 0.380423, 0, -1, 0, -0.623607, -0.119577, + -0.154509, -0.5, 0.475528, -0.276393, 0.447214, 0.850651, 0.7, 0, + 0.154508, -0.5, 0.475528, 0.276393, 0.447214, 0.850651, 0.8, 0, + 0.139058, -0.4, 0.427975, 0.276393, 0.447214, 0.850651, 0.8, 0.1, + -0.139058, -0.4, 0.427975, -0.276393, 0.447214, 0.850651, 0.7, 0.1, + -0.154509, -0.5, 0.475528, -0.276393, 0.447214, 0.850651, 0.7, 0, + 0.139058, -0.4, 0.427975, 0.276393, 0.447214, 0.850651, 0.8, 0.1, + 0.139058, -0.5, 0.427975, 0, -1, 0, -0.360942, -0.0720246, + 0.154508, -0.5, 0.475528, 0, -1, 0, -0.345492, -0.0244717, + -0.154509, -0.5, 0.475528, 0, -1, 0, -0.654509, -0.0244718, + 0.139058, -0.5, 0.427975, 0, -1, 0, -0.360942, -0.0720246, + -0.154509, -0.5, 0.475528, 0, -1, 0, -0.654509, -0.0244718, + -0.139058, -0.5, 0.427975, 0, -1, 0, -0.639058, -0.0720246, + -0.0404509, 0.4, 0.0293893, -0.723607, 0.447214, 0.525731, 0.6, 0.9, + -0.0154509, 0.4, 0.0475528, -0.276393, 0.447214, 0.850651, 0.7, 0.9, + -0, 0.5, 0, -0.520267, 0.465341, 0.716086, 0.7, 1, + -0, -0.5, 0, 0, -1, 0, -0.5, -0.5, + -0.0154509, -0.5, 0.0475528, 0, -1, 0, -0.515451, -0.452447, + -0.0404509, -0.5, 0.0293893, 0, -1, 0, -0.540451, -0.470611, + -0.0809017, 0.3, 0.0587785, -0.723607, 0.447214, 0.525731, 0.6, 0.8, + -0.0309017, 0.3, 0.0951056, -0.276393, 0.447214, 0.850651, 0.7, 0.8, + -0.0154509, 0.4, 0.0475528, -0.276393, 0.447214, 0.850651, 0.7, 0.9, + -0.0404509, 0.4, 0.0293893, -0.723607, 0.447214, 0.525731, 0.6, 0.9, + -0.0809017, 0.3, 0.0587785, -0.723607, 0.447214, 0.525731, 0.6, 0.8, + -0.0154509, 0.4, 0.0475528, -0.276393, 0.447214, 0.850651, 0.7, 0.9, + -0.0154509, -0.5, 0.0475528, 0, -1, 0, -0.515451, -0.452447, + -0.0309017, -0.5, 0.0951056, 0, -1, 0, -0.530902, -0.404894, + -0.0809017, -0.5, 0.0587785, 0, -1, 0, -0.580902, -0.441221, + -0.0154509, -0.5, 0.0475528, 0, -1, 0, -0.515451, -0.452447, + -0.0809017, -0.5, 0.0587785, 0, -1, 0, -0.580902, -0.441221, + -0.0404509, -0.5, 0.0293893, 0, -1, 0, -0.540451, -0.470611, + -0.121353, 0.2, 0.0881678, -0.723607, 0.447214, 0.525731, 0.6, 0.7, + -0.0463526, 0.2, 0.142658, -0.276393, 0.447214, 0.850651, 0.7, 0.7, + -0.0309017, 0.3, 0.0951056, -0.276393, 0.447214, 0.850651, 0.7, 0.8, + -0.0809017, 0.3, 0.0587785, -0.723607, 0.447214, 0.525731, 0.6, 0.8, + -0.121353, 0.2, 0.0881678, -0.723607, 0.447214, 0.525731, 0.6, 0.7, + -0.0309017, 0.3, 0.0951056, -0.276393, 0.447214, 0.850651, 0.7, 0.8, + -0.0309017, -0.5, 0.0951056, 0, -1, 0, -0.530902, -0.404894, + -0.0463526, -0.5, 0.142658, 0, -1, 0, -0.546353, -0.357342, + -0.121353, -0.5, 0.0881678, 0, -1, 0, -0.621353, -0.411832, + -0.0309017, -0.5, 0.0951056, 0, -1, 0, -0.530902, -0.404894, + -0.121353, -0.5, 0.0881678, 0, -1, 0, -0.621353, -0.411832, + -0.0809017, -0.5, 0.0587785, 0, -1, 0, -0.580902, -0.441221, + -0.161803, 0.1, 0.117557, -0.723607, 0.447214, 0.525731, 0.6, 0.6, + -0.0618034, 0.1, 0.190211, -0.276393, 0.447214, 0.850651, 0.7, 0.6, + -0.0463526, 0.2, 0.142658, -0.276393, 0.447214, 0.850651, 0.7, 0.7, + -0.121353, 0.2, 0.0881678, -0.723607, 0.447214, 0.525731, 0.6, 0.7, + -0.161803, 0.1, 0.117557, -0.723607, 0.447214, 0.525731, 0.6, 0.6, + -0.0463526, 0.2, 0.142658, -0.276393, 0.447214, 0.850651, 0.7, 0.7, + -0.0463526, -0.5, 0.142658, 0, -1, 0, -0.546353, -0.357342, + -0.0618034, -0.5, 0.190211, 0, -1, 0, -0.561803, -0.309789, + -0.161803, -0.5, 0.117557, 0, -1, 0, -0.661803, -0.382443, + -0.0463526, -0.5, 0.142658, 0, -1, 0, -0.546353, -0.357342, + -0.161803, -0.5, 0.117557, 0, -1, 0, -0.661803, -0.382443, + -0.121353, -0.5, 0.0881678, 0, -1, 0, -0.621353, -0.411832, + -0.202254, 0, 0.146946, -0.723607, 0.447214, 0.525731, 0.6, 0.5, + -0.0772543, 0, 0.237764, -0.276393, 0.447214, 0.850651, 0.7, 0.5, + -0.0618034, 0.1, 0.190211, -0.276393, 0.447214, 0.850651, 0.7, 0.6, + -0.161803, 0.1, 0.117557, -0.723607, 0.447214, 0.525731, 0.6, 0.6, + -0.202254, 0, 0.146946, -0.723607, 0.447214, 0.525731, 0.6, 0.5, + -0.0618034, 0.1, 0.190211, -0.276393, 0.447214, 0.850651, 0.7, 0.6, + -0.0618034, -0.5, 0.190211, 0, -1, 0, -0.561803, -0.309789, + -0.0772543, -0.5, 0.237764, 0, -1, 0, -0.577254, -0.262236, + -0.202254, -0.5, 0.146946, 0, -1, 0, -0.702254, -0.353054, + -0.0618034, -0.5, 0.190211, 0, -1, 0, -0.561803, -0.309789, + -0.202254, -0.5, 0.146946, 0, -1, 0, -0.702254, -0.353054, + -0.161803, -0.5, 0.117557, 0, -1, 0, -0.661803, -0.382443, + -0.242705, -0.1, 0.176336, -0.723607, 0.447214, 0.525731, 0.6, 0.4, + -0.0927051, -0.1, 0.285317, -0.276393, 0.447214, 0.850651, 0.7, 0.4, + -0.0772543, 0, 0.237764, -0.276393, 0.447214, 0.850651, 0.7, 0.5, + -0.202254, 0, 0.146946, -0.723607, 0.447214, 0.525731, 0.6, 0.5, + -0.242705, -0.1, 0.176336, -0.723607, 0.447214, 0.525731, 0.6, 0.4, + -0.0772543, 0, 0.237764, -0.276393, 0.447214, 0.850651, 0.7, 0.5, + -0.0772543, -0.5, 0.237764, 0, -1, 0, -0.577254, -0.262236, + -0.0927051, -0.5, 0.285317, 0, -1, 0, -0.592705, -0.214683, + -0.242705, -0.5, 0.176336, 0, -1, 0, -0.742705, -0.323664, + -0.0772543, -0.5, 0.237764, 0, -1, 0, -0.577254, -0.262236, + -0.242705, -0.5, 0.176336, 0, -1, 0, -0.742705, -0.323664, + -0.202254, -0.5, 0.146946, 0, -1, 0, -0.702254, -0.353054, + -0.283156, -0.2, 0.205725, -0.723607, 0.447214, 0.525731, 0.6, 0.3, + -0.108156, -0.2, 0.33287, -0.276393, 0.447214, 0.850651, 0.7, 0.3, + -0.0927051, -0.1, 0.285317, -0.276393, 0.447214, 0.850651, 0.7, 0.4, + -0.242705, -0.1, 0.176336, -0.723607, 0.447214, 0.525731, 0.6, 0.4, + -0.283156, -0.2, 0.205725, -0.723607, 0.447214, 0.525731, 0.6, 0.3, + -0.0927051, -0.1, 0.285317, -0.276393, 0.447214, 0.850651, 0.7, 0.4, + -0.0927051, -0.5, 0.285317, 0, -1, 0, -0.592705, -0.214683, + -0.108156, -0.5, 0.33287, 0, -1, 0, -0.608156, -0.16713, + -0.283156, -0.5, 0.205725, 0, -1, 0, -0.783156, -0.294275, + -0.0927051, -0.5, 0.285317, 0, -1, 0, -0.592705, -0.214683, + -0.283156, -0.5, 0.205725, 0, -1, 0, -0.783156, -0.294275, + -0.242705, -0.5, 0.176336, 0, -1, 0, -0.742705, -0.323664, + -0.323607, -0.3, 0.235114, -0.723607, 0.447214, 0.525731, 0.6, 0.2, + -0.123607, -0.3, 0.380423, -0.276393, 0.447214, 0.850651, 0.7, 0.2, + -0.108156, -0.2, 0.33287, -0.276393, 0.447214, 0.850651, 0.7, 0.3, + -0.283156, -0.2, 0.205725, -0.723607, 0.447214, 0.525731, 0.6, 0.3, + -0.323607, -0.3, 0.235114, -0.723607, 0.447214, 0.525731, 0.6, 0.2, + -0.108156, -0.2, 0.33287, -0.276393, 0.447214, 0.850651, 0.7, 0.3, + -0.108156, -0.5, 0.33287, 0, -1, 0, -0.608156, -0.16713, + -0.123607, -0.5, 0.380423, 0, -1, 0, -0.623607, -0.119577, + -0.323607, -0.5, 0.235114, 0, -1, 0, -0.823607, -0.264886, + -0.108156, -0.5, 0.33287, 0, -1, 0, -0.608156, -0.16713, + -0.323607, -0.5, 0.235114, 0, -1, 0, -0.823607, -0.264886, + -0.283156, -0.5, 0.205725, 0, -1, 0, -0.783156, -0.294275, + -0.364058, -0.4, 0.264503, -0.723607, 0.447214, 0.525731, 0.6, 0.1, + -0.139058, -0.4, 0.427975, -0.276393, 0.447214, 0.850651, 0.7, 0.1, + -0.123607, -0.3, 0.380423, -0.276393, 0.447214, 0.850651, 0.7, 0.2, + -0.323607, -0.3, 0.235114, -0.723607, 0.447214, 0.525731, 0.6, 0.2, + -0.364058, -0.4, 0.264503, -0.723607, 0.447214, 0.525731, 0.6, 0.1, + -0.123607, -0.3, 0.380423, -0.276393, 0.447214, 0.850651, 0.7, 0.2, + -0.123607, -0.5, 0.380423, 0, -1, 0, -0.623607, -0.119577, + -0.139058, -0.5, 0.427975, 0, -1, 0, -0.639058, -0.0720246, + -0.364058, -0.5, 0.264503, 0, -1, 0, -0.864058, -0.235497, + -0.123607, -0.5, 0.380423, 0, -1, 0, -0.623607, -0.119577, + -0.364058, -0.5, 0.264503, 0, -1, 0, -0.864058, -0.235497, + -0.323607, -0.5, 0.235114, 0, -1, 0, -0.823607, -0.264886, + -0.404509, -0.5, 0.293893, -0.723607, 0.447214, 0.525731, 0.6, 0, + -0.154509, -0.5, 0.475528, -0.276393, 0.447214, 0.850651, 0.7, 0, + -0.139058, -0.4, 0.427975, -0.276393, 0.447214, 0.850651, 0.7, 0.1, + -0.364058, -0.4, 0.264503, -0.723607, 0.447214, 0.525731, 0.6, 0.1, + -0.404509, -0.5, 0.293893, -0.723607, 0.447214, 0.525731, 0.6, 0, + -0.139058, -0.4, 0.427975, -0.276393, 0.447214, 0.850651, 0.7, 0.1, + -0.139058, -0.5, 0.427975, 0, -1, 0, -0.639058, -0.0720246, + -0.154509, -0.5, 0.475528, 0, -1, 0, -0.654509, -0.0244718, + -0.404509, -0.5, 0.293893, 0, -1, 0, -0.904509, -0.206107, + -0.139058, -0.5, 0.427975, 0, -1, 0, -0.639058, -0.0720246, + -0.404509, -0.5, 0.293893, 0, -1, 0, -0.904509, -0.206107, + -0.364058, -0.5, 0.264503, 0, -1, 0, -0.864058, -0.235497, + -0.05, 0.4, -4.37114e-09, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.9, + -0.0404509, 0.4, 0.0293893, -0.723607, 0.447214, 0.525731, 0.6, 0.9, + -0, 0.5, 0, -0.84181, 0.465341, 0.273521, 0.6, 1, + -0, -0.5, 0, 0, -1, 0, -0.5, -0.5, + -0.0404509, -0.5, 0.0293893, 0, -1, 0, -0.540451, -0.470611, + -0.05, -0.5, -4.37114e-09, 0, -1, 0, -0.55, -0.5, + -0.1, 0.3, -8.74228e-09, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.8, + -0.0809017, 0.3, 0.0587785, -0.723607, 0.447214, 0.525731, 0.6, 0.8, + -0.0404509, 0.4, 0.0293893, -0.723607, 0.447214, 0.525731, 0.6, 0.9, + -0.05, 0.4, -4.37114e-09, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.9, + -0.1, 0.3, -8.74228e-09, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.8, + -0.0404509, 0.4, 0.0293893, -0.723607, 0.447214, 0.525731, 0.6, 0.9, + -0.0404509, -0.5, 0.0293893, 0, -1, 0, -0.540451, -0.470611, + -0.0809017, -0.5, 0.0587785, 0, -1, 0, -0.580902, -0.441221, + -0.1, -0.5, -8.74228e-09, 0, -1, 0, -0.6, -0.5, + -0.0404509, -0.5, 0.0293893, 0, -1, 0, -0.540451, -0.470611, + -0.1, -0.5, -8.74228e-09, 0, -1, 0, -0.6, -0.5, + -0.05, -0.5, -4.37114e-09, 0, -1, 0, -0.55, -0.5, + -0.15, 0.2, -1.31134e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.7, + -0.121353, 0.2, 0.0881678, -0.723607, 0.447214, 0.525731, 0.6, 0.7, + -0.0809017, 0.3, 0.0587785, -0.723607, 0.447214, 0.525731, 0.6, 0.8, + -0.1, 0.3, -8.74228e-09, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.8, + -0.15, 0.2, -1.31134e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.7, + -0.0809017, 0.3, 0.0587785, -0.723607, 0.447214, 0.525731, 0.6, 0.8, + -0.0809017, -0.5, 0.0587785, 0, -1, 0, -0.580902, -0.441221, + -0.121353, -0.5, 0.0881678, 0, -1, 0, -0.621353, -0.411832, + -0.15, -0.5, -1.31134e-08, 0, -1, 0, -0.65, -0.5, + -0.0809017, -0.5, 0.0587785, 0, -1, 0, -0.580902, -0.441221, + -0.15, -0.5, -1.31134e-08, 0, -1, 0, -0.65, -0.5, + -0.1, -0.5, -8.74228e-09, 0, -1, 0, -0.6, -0.5, + -0.2, 0.1, -1.74846e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.6, + -0.161803, 0.1, 0.117557, -0.723607, 0.447214, 0.525731, 0.6, 0.6, + -0.121353, 0.2, 0.0881678, -0.723607, 0.447214, 0.525731, 0.6, 0.7, + -0.15, 0.2, -1.31134e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.7, + -0.2, 0.1, -1.74846e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.6, + -0.121353, 0.2, 0.0881678, -0.723607, 0.447214, 0.525731, 0.6, 0.7, + -0.121353, -0.5, 0.0881678, 0, -1, 0, -0.621353, -0.411832, + -0.161803, -0.5, 0.117557, 0, -1, 0, -0.661803, -0.382443, + -0.2, -0.5, -1.74846e-08, 0, -1, 0, -0.7, -0.5, + -0.121353, -0.5, 0.0881678, 0, -1, 0, -0.621353, -0.411832, + -0.2, -0.5, -1.74846e-08, 0, -1, 0, -0.7, -0.5, + -0.15, -0.5, -1.31134e-08, 0, -1, 0, -0.65, -0.5, + -0.25, 0, -2.18557e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.5, + -0.202254, 0, 0.146946, -0.723607, 0.447214, 0.525731, 0.6, 0.5, + -0.161803, 0.1, 0.117557, -0.723607, 0.447214, 0.525731, 0.6, 0.6, + -0.2, 0.1, -1.74846e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.6, + -0.25, 0, -2.18557e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.5, + -0.161803, 0.1, 0.117557, -0.723607, 0.447214, 0.525731, 0.6, 0.6, + -0.161803, -0.5, 0.117557, 0, -1, 0, -0.661803, -0.382443, + -0.202254, -0.5, 0.146946, 0, -1, 0, -0.702254, -0.353054, + -0.25, -0.5, -2.18557e-08, 0, -1, 0, -0.75, -0.5, + -0.161803, -0.5, 0.117557, 0, -1, 0, -0.661803, -0.382443, + -0.25, -0.5, -2.18557e-08, 0, -1, 0, -0.75, -0.5, + -0.2, -0.5, -1.74846e-08, 0, -1, 0, -0.7, -0.5, + -0.3, -0.1, -2.62268e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.4, + -0.242705, -0.1, 0.176336, -0.723607, 0.447214, 0.525731, 0.6, 0.4, + -0.202254, 0, 0.146946, -0.723607, 0.447214, 0.525731, 0.6, 0.5, + -0.25, 0, -2.18557e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.5, + -0.3, -0.1, -2.62268e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.4, + -0.202254, 0, 0.146946, -0.723607, 0.447214, 0.525731, 0.6, 0.5, + -0.202254, -0.5, 0.146946, 0, -1, 0, -0.702254, -0.353054, + -0.242705, -0.5, 0.176336, 0, -1, 0, -0.742705, -0.323664, + -0.3, -0.5, -2.62268e-08, 0, -1, 0, -0.8, -0.5, + -0.202254, -0.5, 0.146946, 0, -1, 0, -0.702254, -0.353054, + -0.3, -0.5, -2.62268e-08, 0, -1, 0, -0.8, -0.5, + -0.25, -0.5, -2.18557e-08, 0, -1, 0, -0.75, -0.5, + -0.35, -0.2, -3.0598e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.3, + -0.283156, -0.2, 0.205725, -0.723607, 0.447214, 0.525731, 0.6, 0.3, + -0.242705, -0.1, 0.176336, -0.723607, 0.447214, 0.525731, 0.6, 0.4, + -0.3, -0.1, -2.62268e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.4, + -0.35, -0.2, -3.0598e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.3, + -0.242705, -0.1, 0.176336, -0.723607, 0.447214, 0.525731, 0.6, 0.4, + -0.242705, -0.5, 0.176336, 0, -1, 0, -0.742705, -0.323664, + -0.283156, -0.5, 0.205725, 0, -1, 0, -0.783156, -0.294275, + -0.35, -0.5, -3.0598e-08, 0, -1, 0, -0.85, -0.5, + -0.242705, -0.5, 0.176336, 0, -1, 0, -0.742705, -0.323664, + -0.35, -0.5, -3.0598e-08, 0, -1, 0, -0.85, -0.5, + -0.3, -0.5, -2.62268e-08, 0, -1, 0, -0.8, -0.5, + -0.4, -0.3, -3.49691e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.2, + -0.323607, -0.3, 0.235114, -0.723607, 0.447214, 0.525731, 0.6, 0.2, + -0.283156, -0.2, 0.205725, -0.723607, 0.447214, 0.525731, 0.6, 0.3, + -0.35, -0.2, -3.0598e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.3, + -0.4, -0.3, -3.49691e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.2, + -0.283156, -0.2, 0.205725, -0.723607, 0.447214, 0.525731, 0.6, 0.3, + -0.283156, -0.5, 0.205725, 0, -1, 0, -0.783156, -0.294275, + -0.323607, -0.5, 0.235114, 0, -1, 0, -0.823607, -0.264886, + -0.4, -0.5, -3.49691e-08, 0, -1, 0, -0.9, -0.5, + -0.283156, -0.5, 0.205725, 0, -1, 0, -0.783156, -0.294275, + -0.4, -0.5, -3.49691e-08, 0, -1, 0, -0.9, -0.5, + -0.35, -0.5, -3.0598e-08, 0, -1, 0, -0.85, -0.5, + -0.45, -0.4, -3.93403e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.1, + -0.364058, -0.4, 0.264503, -0.723607, 0.447214, 0.525731, 0.6, 0.1, + -0.323607, -0.3, 0.235114, -0.723607, 0.447214, 0.525731, 0.6, 0.2, + -0.4, -0.3, -3.49691e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.2, + -0.45, -0.4, -3.93403e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.1, + -0.323607, -0.3, 0.235114, -0.723607, 0.447214, 0.525731, 0.6, 0.2, + -0.323607, -0.5, 0.235114, 0, -1, 0, -0.823607, -0.264886, + -0.364058, -0.5, 0.264503, 0, -1, 0, -0.864058, -0.235497, + -0.45, -0.5, -3.93403e-08, 0, -1, 0, -0.95, -0.5, + -0.323607, -0.5, 0.235114, 0, -1, 0, -0.823607, -0.264886, + -0.45, -0.5, -3.93403e-08, 0, -1, 0, -0.95, -0.5, + -0.4, -0.5, -3.49691e-08, 0, -1, 0, -0.9, -0.5, + -0.5, -0.5, -4.37114e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0, + -0.404509, -0.5, 0.293893, -0.723607, 0.447214, 0.525731, 0.6, 0, + -0.364058, -0.4, 0.264503, -0.723607, 0.447214, 0.525731, 0.6, 0.1, + -0.45, -0.4, -3.93403e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.1, + -0.5, -0.5, -4.37114e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0, + -0.364058, -0.4, 0.264503, -0.723607, 0.447214, 0.525731, 0.6, 0.1, + -0.364058, -0.5, 0.264503, 0, -1, 0, -0.864058, -0.235497, + -0.404509, -0.5, 0.293893, 0, -1, 0, -0.904509, -0.206107, + -0.5, -0.5, -4.37114e-08, 0, -1, 0, -1, -0.5, + -0.364058, -0.5, 0.264503, 0, -1, 0, -0.864058, -0.235497, + -0.5, -0.5, -4.37114e-08, 0, -1, 0, -1, -0.5, + -0.45, -0.5, -3.93403e-08, 0, -1, 0, -0.95, -0.5, + -0.0404508, 0.4, -0.0293893, -0.723607, 0.447214, -0.525731, 0.4, 0.9, + -0.05, 0.4, -4.37114e-09, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.9, + -0, 0.5, -0, -0.84181, 0.465341, -0.273521, 0.5, 1, + -0, -0.5, -0, 0, -1, 0, -0.5, -0.5, + -0.05, -0.5, -4.37114e-09, 0, -1, 0, -0.55, -0.5, + -0.0404508, -0.5, -0.0293893, 0, -1, 0, -0.540451, -0.529389, + -0.0809017, 0.3, -0.0587785, -0.723607, 0.447214, -0.525731, 0.4, 0.8, + -0.1, 0.3, -8.74228e-09, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.8, + -0.05, 0.4, -4.37114e-09, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.9, + -0.0404508, 0.4, -0.0293893, -0.723607, 0.447214, -0.525731, 0.4, 0.9, + -0.0809017, 0.3, -0.0587785, -0.723607, 0.447214, -0.525731, 0.4, 0.8, + -0.05, 0.4, -4.37114e-09, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.9, + -0.05, -0.5, -4.37114e-09, 0, -1, 0, -0.55, -0.5, + -0.1, -0.5, -8.74228e-09, 0, -1, 0, -0.6, -0.5, + -0.0809017, -0.5, -0.0587785, 0, -1, 0, -0.580902, -0.558779, + -0.05, -0.5, -4.37114e-09, 0, -1, 0, -0.55, -0.5, + -0.0809017, -0.5, -0.0587785, 0, -1, 0, -0.580902, -0.558779, + -0.0404508, -0.5, -0.0293893, 0, -1, 0, -0.540451, -0.529389, + -0.121353, 0.2, -0.0881678, -0.723607, 0.447214, -0.525731, 0.4, 0.7, + -0.15, 0.2, -1.31134e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.7, + -0.1, 0.3, -8.74228e-09, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.8, + -0.0809017, 0.3, -0.0587785, -0.723607, 0.447214, -0.525731, 0.4, 0.8, + -0.121353, 0.2, -0.0881678, -0.723607, 0.447214, -0.525731, 0.4, 0.7, + -0.1, 0.3, -8.74228e-09, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.8, + -0.1, -0.5, -8.74228e-09, 0, -1, 0, -0.6, -0.5, + -0.15, -0.5, -1.31134e-08, 0, -1, 0, -0.65, -0.5, + -0.121353, -0.5, -0.0881678, 0, -1, 0, -0.621353, -0.588168, + -0.1, -0.5, -8.74228e-09, 0, -1, 0, -0.6, -0.5, + -0.121353, -0.5, -0.0881678, 0, -1, 0, -0.621353, -0.588168, + -0.0809017, -0.5, -0.0587785, 0, -1, 0, -0.580902, -0.558779, + -0.161803, 0.1, -0.117557, -0.723607, 0.447214, -0.525731, 0.4, 0.6, + -0.2, 0.1, -1.74846e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.6, + -0.15, 0.2, -1.31134e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.7, + -0.121353, 0.2, -0.0881678, -0.723607, 0.447214, -0.525731, 0.4, 0.7, + -0.161803, 0.1, -0.117557, -0.723607, 0.447214, -0.525731, 0.4, 0.6, + -0.15, 0.2, -1.31134e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.7, + -0.15, -0.5, -1.31134e-08, 0, -1, 0, -0.65, -0.5, + -0.2, -0.5, -1.74846e-08, 0, -1, 0, -0.7, -0.5, + -0.161803, -0.5, -0.117557, 0, -1, 0, -0.661803, -0.617557, + -0.15, -0.5, -1.31134e-08, 0, -1, 0, -0.65, -0.5, + -0.161803, -0.5, -0.117557, 0, -1, 0, -0.661803, -0.617557, + -0.121353, -0.5, -0.0881678, 0, -1, 0, -0.621353, -0.588168, + -0.202254, 0, -0.146946, -0.723607, 0.447214, -0.525731, 0.4, 0.5, + -0.25, 0, -2.18557e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.5, + -0.2, 0.1, -1.74846e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.6, + -0.161803, 0.1, -0.117557, -0.723607, 0.447214, -0.525731, 0.4, 0.6, + -0.202254, 0, -0.146946, -0.723607, 0.447214, -0.525731, 0.4, 0.5, + -0.2, 0.1, -1.74846e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.6, + -0.2, -0.5, -1.74846e-08, 0, -1, 0, -0.7, -0.5, + -0.25, -0.5, -2.18557e-08, 0, -1, 0, -0.75, -0.5, + -0.202254, -0.5, -0.146946, 0, -1, 0, -0.702254, -0.646946, + -0.2, -0.5, -1.74846e-08, 0, -1, 0, -0.7, -0.5, + -0.202254, -0.5, -0.146946, 0, -1, 0, -0.702254, -0.646946, + -0.161803, -0.5, -0.117557, 0, -1, 0, -0.661803, -0.617557, + -0.242705, -0.1, -0.176336, -0.723607, 0.447214, -0.525731, 0.4, 0.4, + -0.3, -0.1, -2.62268e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.4, + -0.25, 0, -2.18557e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.5, + -0.202254, 0, -0.146946, -0.723607, 0.447214, -0.525731, 0.4, 0.5, + -0.242705, -0.1, -0.176336, -0.723607, 0.447214, -0.525731, 0.4, 0.4, + -0.25, 0, -2.18557e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.5, + -0.25, -0.5, -2.18557e-08, 0, -1, 0, -0.75, -0.5, + -0.3, -0.5, -2.62268e-08, 0, -1, 0, -0.8, -0.5, + -0.242705, -0.5, -0.176336, 0, -1, 0, -0.742705, -0.676336, + -0.25, -0.5, -2.18557e-08, 0, -1, 0, -0.75, -0.5, + -0.242705, -0.5, -0.176336, 0, -1, 0, -0.742705, -0.676336, + -0.202254, -0.5, -0.146946, 0, -1, 0, -0.702254, -0.646946, + -0.283156, -0.2, -0.205725, -0.723607, 0.447214, -0.525731, 0.4, 0.3, + -0.35, -0.2, -3.0598e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.3, + -0.3, -0.1, -2.62268e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.4, + -0.242705, -0.1, -0.176336, -0.723607, 0.447214, -0.525731, 0.4, 0.4, + -0.283156, -0.2, -0.205725, -0.723607, 0.447214, -0.525731, 0.4, 0.3, + -0.3, -0.1, -2.62268e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.4, + -0.3, -0.5, -2.62268e-08, 0, -1, 0, -0.8, -0.5, + -0.35, -0.5, -3.0598e-08, 0, -1, 0, -0.85, -0.5, + -0.283156, -0.5, -0.205725, 0, -1, 0, -0.783156, -0.705725, + -0.3, -0.5, -2.62268e-08, 0, -1, 0, -0.8, -0.5, + -0.283156, -0.5, -0.205725, 0, -1, 0, -0.783156, -0.705725, + -0.242705, -0.5, -0.176336, 0, -1, 0, -0.742705, -0.676336, + -0.323607, -0.3, -0.235114, -0.723607, 0.447214, -0.525731, 0.4, 0.2, + -0.4, -0.3, -3.49691e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.2, + -0.35, -0.2, -3.0598e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.3, + -0.283156, -0.2, -0.205725, -0.723607, 0.447214, -0.525731, 0.4, 0.3, + -0.323607, -0.3, -0.235114, -0.723607, 0.447214, -0.525731, 0.4, 0.2, + -0.35, -0.2, -3.0598e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.3, + -0.35, -0.5, -3.0598e-08, 0, -1, 0, -0.85, -0.5, + -0.4, -0.5, -3.49691e-08, 0, -1, 0, -0.9, -0.5, + -0.323607, -0.5, -0.235114, 0, -1, 0, -0.823607, -0.735114, + -0.35, -0.5, -3.0598e-08, 0, -1, 0, -0.85, -0.5, + -0.323607, -0.5, -0.235114, 0, -1, 0, -0.823607, -0.735114, + -0.283156, -0.5, -0.205725, 0, -1, 0, -0.783156, -0.705725, + -0.364058, -0.4, -0.264503, -0.723606, 0.447214, -0.525732, 0.4, 0.1, + -0.45, -0.4, -3.93403e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.1, + -0.4, -0.3, -3.49691e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.2, + -0.323607, -0.3, -0.235114, -0.723606, 0.447214, -0.525732, 0.4, 0.2, + -0.364058, -0.4, -0.264503, -0.723606, 0.447214, -0.525732, 0.4, 0.1, + -0.4, -0.3, -3.49691e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.2, + -0.4, -0.5, -3.49691e-08, 0, -1, 0, -0.9, -0.5, + -0.45, -0.5, -3.93403e-08, 0, -1, 0, -0.95, -0.5, + -0.364058, -0.5, -0.264503, 0, -1, 0, -0.864058, -0.764503, + -0.4, -0.5, -3.49691e-08, 0, -1, 0, -0.9, -0.5, + -0.364058, -0.5, -0.264503, 0, -1, 0, -0.864058, -0.764503, + -0.323607, -0.5, -0.235114, 0, -1, 0, -0.823607, -0.735114, + -0.404508, -0.5, -0.293893, -0.723607, 0.447214, -0.525731, 0.4, 0, + -0.5, -0.5, -4.37114e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0, + -0.45, -0.4, -3.93403e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.1, + -0.364058, -0.4, -0.264503, -0.723607, 0.447214, -0.525731, 0.4, 0.1, + -0.404508, -0.5, -0.293893, -0.723607, 0.447214, -0.525731, 0.4, 0, + -0.45, -0.4, -3.93403e-08, -0.894427, 0.447214, -7.81933e-08, 0.5, 0.1, + -0.45, -0.5, -3.93403e-08, 0, -1, 0, -0.95, -0.5, + -0.5, -0.5, -4.37114e-08, 0, -1, 0, -1, -0.5, + -0.404508, -0.5, -0.293893, 0, -1, 0, -0.904508, -0.793893, + -0.45, -0.5, -3.93403e-08, 0, -1, 0, -0.95, -0.5, + -0.404508, -0.5, -0.293893, 0, -1, 0, -0.904508, -0.793893, + -0.364058, -0.5, -0.264503, 0, -1, 0, -0.864058, -0.764503, + -0.0154509, 0.4, -0.0475528, -0.276393, 0.447214, -0.850651, 0.3, 0.9, + -0.0404508, 0.4, -0.0293893, -0.723607, 0.447214, -0.525731, 0.4, 0.9, + -0, 0.5, -0, -0.520267, 0.465341, -0.716086, 0.4, 1, + -0, -0.5, -0, 0, -1, 0, -0.5, -0.5, + -0.0404508, -0.5, -0.0293893, 0, -1, 0, -0.540451, -0.529389, + -0.0154509, -0.5, -0.0475528, 0, -1, 0, -0.515451, -0.547553, + -0.0309017, 0.3, -0.0951056, -0.276393, 0.447214, -0.850651, 0.3, 0.8, + -0.0809017, 0.3, -0.0587785, -0.723607, 0.447214, -0.525731, 0.4, 0.8, + -0.0404508, 0.4, -0.0293893, -0.723607, 0.447214, -0.525731, 0.4, 0.9, + -0.0154509, 0.4, -0.0475528, -0.276393, 0.447214, -0.850651, 0.3, 0.9, + -0.0309017, 0.3, -0.0951056, -0.276393, 0.447214, -0.850651, 0.3, 0.8, + -0.0404508, 0.4, -0.0293893, -0.723607, 0.447214, -0.525731, 0.4, 0.9, + -0.0404508, -0.5, -0.0293893, 0, -1, 0, -0.540451, -0.529389, + -0.0809017, -0.5, -0.0587785, 0, -1, 0, -0.580902, -0.558779, + -0.0309017, -0.5, -0.0951056, 0, -1, 0, -0.530902, -0.595106, + -0.0404508, -0.5, -0.0293893, 0, -1, 0, -0.540451, -0.529389, + -0.0309017, -0.5, -0.0951056, 0, -1, 0, -0.530902, -0.595106, + -0.0154509, -0.5, -0.0475528, 0, -1, 0, -0.515451, -0.547553, + -0.0463526, 0.2, -0.142658, -0.276393, 0.447214, -0.850651, 0.3, 0.7, + -0.121353, 0.2, -0.0881678, -0.723607, 0.447214, -0.525731, 0.4, 0.7, + -0.0809017, 0.3, -0.0587785, -0.723607, 0.447214, -0.525731, 0.4, 0.8, + -0.0309017, 0.3, -0.0951056, -0.276393, 0.447214, -0.850651, 0.3, 0.8, + -0.0463526, 0.2, -0.142658, -0.276393, 0.447214, -0.850651, 0.3, 0.7, + -0.0809017, 0.3, -0.0587785, -0.723607, 0.447214, -0.525731, 0.4, 0.8, + -0.0809017, -0.5, -0.0587785, 0, -1, 0, -0.580902, -0.558779, + -0.121353, -0.5, -0.0881678, 0, -1, 0, -0.621353, -0.588168, + -0.0463526, -0.5, -0.142658, 0, -1, 0, -0.546353, -0.642658, + -0.0809017, -0.5, -0.0587785, 0, -1, 0, -0.580902, -0.558779, + -0.0463526, -0.5, -0.142658, 0, -1, 0, -0.546353, -0.642658, + -0.0309017, -0.5, -0.0951056, 0, -1, 0, -0.530902, -0.595106, + -0.0618034, 0.1, -0.190211, -0.276393, 0.447214, -0.850651, 0.3, 0.6, + -0.161803, 0.1, -0.117557, -0.723607, 0.447214, -0.525731, 0.4, 0.6, + -0.121353, 0.2, -0.0881678, -0.723607, 0.447214, -0.525731, 0.4, 0.7, + -0.0463526, 0.2, -0.142658, -0.276393, 0.447214, -0.850651, 0.3, 0.7, + -0.0618034, 0.1, -0.190211, -0.276393, 0.447214, -0.850651, 0.3, 0.6, + -0.121353, 0.2, -0.0881678, -0.723607, 0.447214, -0.525731, 0.4, 0.7, + -0.121353, -0.5, -0.0881678, 0, -1, 0, -0.621353, -0.588168, + -0.161803, -0.5, -0.117557, 0, -1, 0, -0.661803, -0.617557, + -0.0618034, -0.5, -0.190211, 0, -1, 0, -0.561803, -0.690211, + -0.121353, -0.5, -0.0881678, 0, -1, 0, -0.621353, -0.588168, + -0.0618034, -0.5, -0.190211, 0, -1, 0, -0.561803, -0.690211, + -0.0463526, -0.5, -0.142658, 0, -1, 0, -0.546353, -0.642658, + -0.0772543, 0, -0.237764, -0.276393, 0.447214, -0.850651, 0.3, 0.5, + -0.202254, 0, -0.146946, -0.723607, 0.447214, -0.525731, 0.4, 0.5, + -0.161803, 0.1, -0.117557, -0.723607, 0.447214, -0.525731, 0.4, 0.6, + -0.0618034, 0.1, -0.190211, -0.276393, 0.447214, -0.850651, 0.3, 0.6, + -0.0772543, 0, -0.237764, -0.276393, 0.447214, -0.850651, 0.3, 0.5, + -0.161803, 0.1, -0.117557, -0.723607, 0.447214, -0.525731, 0.4, 0.6, + -0.161803, -0.5, -0.117557, 0, -1, 0, -0.661803, -0.617557, + -0.202254, -0.5, -0.146946, 0, -1, 0, -0.702254, -0.646946, + -0.0772543, -0.5, -0.237764, 0, -1, 0, -0.577254, -0.737764, + -0.161803, -0.5, -0.117557, 0, -1, 0, -0.661803, -0.617557, + -0.0772543, -0.5, -0.237764, 0, -1, 0, -0.577254, -0.737764, + -0.0618034, -0.5, -0.190211, 0, -1, 0, -0.561803, -0.690211, + -0.0927051, -0.1, -0.285317, -0.276393, 0.447214, -0.850651, 0.3, 0.4, + -0.242705, -0.1, -0.176336, -0.723607, 0.447214, -0.525731, 0.4, 0.4, + -0.202254, 0, -0.146946, -0.723607, 0.447214, -0.525731, 0.4, 0.5, + -0.0772543, 0, -0.237764, -0.276393, 0.447214, -0.850651, 0.3, 0.5, + -0.0927051, -0.1, -0.285317, -0.276393, 0.447214, -0.850651, 0.3, 0.4, + -0.202254, 0, -0.146946, -0.723607, 0.447214, -0.525731, 0.4, 0.5, + -0.202254, -0.5, -0.146946, 0, -1, 0, -0.702254, -0.646946, + -0.242705, -0.5, -0.176336, 0, -1, 0, -0.742705, -0.676336, + -0.0927051, -0.5, -0.285317, 0, -1, 0, -0.592705, -0.785317, + -0.202254, -0.5, -0.146946, 0, -1, 0, -0.702254, -0.646946, + -0.0927051, -0.5, -0.285317, 0, -1, 0, -0.592705, -0.785317, + -0.0772543, -0.5, -0.237764, 0, -1, 0, -0.577254, -0.737764, + -0.108156, -0.2, -0.33287, -0.276393, 0.447214, -0.850651, 0.3, 0.3, + -0.283156, -0.2, -0.205725, -0.723607, 0.447214, -0.525731, 0.4, 0.3, + -0.242705, -0.1, -0.176336, -0.723607, 0.447214, -0.525731, 0.4, 0.4, + -0.0927051, -0.1, -0.285317, -0.276393, 0.447214, -0.850651, 0.3, 0.4, + -0.108156, -0.2, -0.33287, -0.276393, 0.447214, -0.850651, 0.3, 0.3, + -0.242705, -0.1, -0.176336, -0.723607, 0.447214, -0.525731, 0.4, 0.4, + -0.242705, -0.5, -0.176336, 0, -1, 0, -0.742705, -0.676336, + -0.283156, -0.5, -0.205725, 0, -1, 0, -0.783156, -0.705725, + -0.108156, -0.5, -0.33287, 0, -1, 0, -0.608156, -0.83287, + -0.242705, -0.5, -0.176336, 0, -1, 0, -0.742705, -0.676336, + -0.108156, -0.5, -0.33287, 0, -1, 0, -0.608156, -0.83287, + -0.0927051, -0.5, -0.285317, 0, -1, 0, -0.592705, -0.785317, + -0.123607, -0.3, -0.380423, -0.276393, 0.447214, -0.850651, 0.3, 0.2, + -0.323607, -0.3, -0.235114, -0.723607, 0.447214, -0.525731, 0.4, 0.2, + -0.283156, -0.2, -0.205725, -0.723607, 0.447214, -0.525731, 0.4, 0.3, + -0.108156, -0.2, -0.33287, -0.276393, 0.447214, -0.850651, 0.3, 0.3, + -0.123607, -0.3, -0.380423, -0.276393, 0.447214, -0.850651, 0.3, 0.2, + -0.283156, -0.2, -0.205725, -0.723607, 0.447214, -0.525731, 0.4, 0.3, + -0.283156, -0.5, -0.205725, 0, -1, 0, -0.783156, -0.705725, + -0.323607, -0.5, -0.235114, 0, -1, 0, -0.823607, -0.735114, + -0.123607, -0.5, -0.380423, 0, -1, 0, -0.623607, -0.880423, + -0.283156, -0.5, -0.205725, 0, -1, 0, -0.783156, -0.705725, + -0.123607, -0.5, -0.380423, 0, -1, 0, -0.623607, -0.880423, + -0.108156, -0.5, -0.33287, 0, -1, 0, -0.608156, -0.83287, + -0.139058, -0.4, -0.427975, -0.276393, 0.447214, -0.850651, 0.3, 0.1, + -0.364058, -0.4, -0.264503, -0.723606, 0.447214, -0.525732, 0.4, 0.1, + -0.323607, -0.3, -0.235114, -0.723606, 0.447214, -0.525732, 0.4, 0.2, + -0.123607, -0.3, -0.380423, -0.276393, 0.447214, -0.850651, 0.3, 0.2, + -0.139058, -0.4, -0.427975, -0.276393, 0.447214, -0.850651, 0.3, 0.1, + -0.323607, -0.3, -0.235114, -0.723606, 0.447214, -0.525732, 0.4, 0.2, + -0.323607, -0.5, -0.235114, 0, -1, 0, -0.823607, -0.735114, + -0.364058, -0.5, -0.264503, 0, -1, 0, -0.864058, -0.764503, + -0.139058, -0.5, -0.427975, 0, -1, 0, -0.639058, -0.927975, + -0.323607, -0.5, -0.235114, 0, -1, 0, -0.823607, -0.735114, + -0.139058, -0.5, -0.427975, 0, -1, 0, -0.639058, -0.927975, + -0.123607, -0.5, -0.380423, 0, -1, 0, -0.623607, -0.880423, + -0.154509, -0.5, -0.475528, -0.276393, 0.447214, -0.850651, 0.3, 0, + -0.404508, -0.5, -0.293893, -0.723607, 0.447214, -0.525731, 0.4, 0, + -0.364058, -0.4, -0.264503, -0.723607, 0.447214, -0.525731, 0.4, 0.1, + -0.139058, -0.4, -0.427975, -0.276393, 0.447214, -0.850651, 0.3, 0.1, + -0.154509, -0.5, -0.475528, -0.276393, 0.447214, -0.850651, 0.3, 0, + -0.364058, -0.4, -0.264503, -0.723607, 0.447214, -0.525731, 0.4, 0.1, + -0.364058, -0.5, -0.264503, 0, -1, 0, -0.864058, -0.764503, + -0.404508, -0.5, -0.293893, 0, -1, 0, -0.904508, -0.793893, + -0.154509, -0.5, -0.475528, 0, -1, 0, -0.654509, -0.975528, + -0.364058, -0.5, -0.264503, 0, -1, 0, -0.864058, -0.764503, + -0.154509, -0.5, -0.475528, 0, -1, 0, -0.654509, -0.975528, + -0.139058, -0.5, -0.427975, 0, -1, 0, -0.639058, -0.927975, + 0.0154509, 0.4, -0.0475528, 0.276393, 0.447214, -0.850651, 0.2, 0.9, + -0.0154509, 0.4, -0.0475528, -0.276393, 0.447214, -0.850651, 0.3, 0.9, + -0, 0.5, -0, 1.55052e-08, 0.465341, -0.885131, 0.3, 1, + -0, -0.5, -0, 0, -1, 0, -0.5, -0.5, + -0.0154509, -0.5, -0.0475528, 0, -1, 0, -0.515451, -0.547553, + 0.0154509, -0.5, -0.0475528, 0, -1, 0, -0.484549, -0.547553, + 0.0309017, 0.3, -0.0951056, 0.276393, 0.447214, -0.850651, 0.2, 0.8, + -0.0309017, 0.3, -0.0951056, -0.276393, 0.447214, -0.850651, 0.3, 0.8, + -0.0154509, 0.4, -0.0475528, -0.276393, 0.447214, -0.850651, 0.3, 0.9, + 0.0154509, 0.4, -0.0475528, 0.276393, 0.447214, -0.850651, 0.2, 0.9, + 0.0309017, 0.3, -0.0951056, 0.276393, 0.447214, -0.850651, 0.2, 0.8, + -0.0154509, 0.4, -0.0475528, -0.276393, 0.447214, -0.850651, 0.3, 0.9, + -0.0154509, -0.5, -0.0475528, 0, -1, 0, -0.515451, -0.547553, + -0.0309017, -0.5, -0.0951056, 0, -1, 0, -0.530902, -0.595106, + 0.0309017, -0.5, -0.0951056, 0, -1, 0, -0.469098, -0.595106, + -0.0154509, -0.5, -0.0475528, 0, -1, 0, -0.515451, -0.547553, + 0.0309017, -0.5, -0.0951056, 0, -1, 0, -0.469098, -0.595106, + 0.0154509, -0.5, -0.0475528, 0, -1, 0, -0.484549, -0.547553, + 0.0463526, 0.2, -0.142658, 0.276393, 0.447214, -0.850651, 0.2, 0.7, + -0.0463526, 0.2, -0.142658, -0.276393, 0.447214, -0.850651, 0.3, 0.7, + -0.0309017, 0.3, -0.0951056, -0.276393, 0.447214, -0.850651, 0.3, 0.8, + 0.0309017, 0.3, -0.0951056, 0.276393, 0.447214, -0.850651, 0.2, 0.8, + 0.0463526, 0.2, -0.142658, 0.276393, 0.447214, -0.850651, 0.2, 0.7, + -0.0309017, 0.3, -0.0951056, -0.276393, 0.447214, -0.850651, 0.3, 0.8, + -0.0309017, -0.5, -0.0951056, 0, -1, 0, -0.530902, -0.595106, + -0.0463526, -0.5, -0.142658, 0, -1, 0, -0.546353, -0.642658, + 0.0463526, -0.5, -0.142658, 0, -1, 0, -0.453647, -0.642658, + -0.0309017, -0.5, -0.0951056, 0, -1, 0, -0.530902, -0.595106, + 0.0463526, -0.5, -0.142658, 0, -1, 0, -0.453647, -0.642658, + 0.0309017, -0.5, -0.0951056, 0, -1, 0, -0.469098, -0.595106, + 0.0618034, 0.1, -0.190211, 0.276393, 0.447214, -0.850651, 0.2, 0.6, + -0.0618034, 0.1, -0.190211, -0.276393, 0.447214, -0.850651, 0.3, 0.6, + -0.0463526, 0.2, -0.142658, -0.276393, 0.447214, -0.850651, 0.3, 0.7, + 0.0463526, 0.2, -0.142658, 0.276393, 0.447214, -0.850651, 0.2, 0.7, + 0.0618034, 0.1, -0.190211, 0.276393, 0.447214, -0.850651, 0.2, 0.6, + -0.0463526, 0.2, -0.142658, -0.276393, 0.447214, -0.850651, 0.3, 0.7, + -0.0463526, -0.5, -0.142658, 0, -1, 0, -0.546353, -0.642658, + -0.0618034, -0.5, -0.190211, 0, -1, 0, -0.561803, -0.690211, + 0.0618034, -0.5, -0.190211, 0, -1, 0, -0.438197, -0.690211, + -0.0463526, -0.5, -0.142658, 0, -1, 0, -0.546353, -0.642658, + 0.0618034, -0.5, -0.190211, 0, -1, 0, -0.438197, -0.690211, + 0.0463526, -0.5, -0.142658, 0, -1, 0, -0.453647, -0.642658, + 0.0772543, 0, -0.237764, 0.276393, 0.447214, -0.850651, 0.2, 0.5, + -0.0772543, 0, -0.237764, -0.276393, 0.447214, -0.850651, 0.3, 0.5, + -0.0618034, 0.1, -0.190211, -0.276393, 0.447214, -0.850651, 0.3, 0.6, + 0.0618034, 0.1, -0.190211, 0.276393, 0.447214, -0.850651, 0.2, 0.6, + 0.0772543, 0, -0.237764, 0.276393, 0.447214, -0.850651, 0.2, 0.5, + -0.0618034, 0.1, -0.190211, -0.276393, 0.447214, -0.850651, 0.3, 0.6, + -0.0618034, -0.5, -0.190211, 0, -1, 0, -0.561803, -0.690211, + -0.0772543, -0.5, -0.237764, 0, -1, 0, -0.577254, -0.737764, + 0.0772543, -0.5, -0.237764, 0, -1, 0, -0.422746, -0.737764, + -0.0618034, -0.5, -0.190211, 0, -1, 0, -0.561803, -0.690211, + 0.0772543, -0.5, -0.237764, 0, -1, 0, -0.422746, -0.737764, + 0.0618034, -0.5, -0.190211, 0, -1, 0, -0.438197, -0.690211, + 0.0927051, -0.1, -0.285317, 0.276393, 0.447214, -0.850651, 0.2, 0.4, + -0.0927051, -0.1, -0.285317, -0.276393, 0.447214, -0.850651, 0.3, 0.4, + -0.0772543, 0, -0.237764, -0.276393, 0.447214, -0.850651, 0.3, 0.5, + 0.0772543, 0, -0.237764, 0.276393, 0.447214, -0.850651, 0.2, 0.5, + 0.0927051, -0.1, -0.285317, 0.276393, 0.447214, -0.850651, 0.2, 0.4, + -0.0772543, 0, -0.237764, -0.276393, 0.447214, -0.850651, 0.3, 0.5, + -0.0772543, -0.5, -0.237764, 0, -1, 0, -0.577254, -0.737764, + -0.0927051, -0.5, -0.285317, 0, -1, 0, -0.592705, -0.785317, + 0.0927051, -0.5, -0.285317, 0, -1, 0, -0.407295, -0.785317, + -0.0772543, -0.5, -0.237764, 0, -1, 0, -0.577254, -0.737764, + 0.0927051, -0.5, -0.285317, 0, -1, 0, -0.407295, -0.785317, + 0.0772543, -0.5, -0.237764, 0, -1, 0, -0.422746, -0.737764, + 0.108156, -0.2, -0.33287, 0.276393, 0.447214, -0.850651, 0.2, 0.3, + -0.108156, -0.2, -0.33287, -0.276393, 0.447214, -0.850651, 0.3, 0.3, + -0.0927051, -0.1, -0.285317, -0.276393, 0.447214, -0.850651, 0.3, 0.4, + 0.0927051, -0.1, -0.285317, 0.276393, 0.447214, -0.850651, 0.2, 0.4, + 0.108156, -0.2, -0.33287, 0.276393, 0.447214, -0.850651, 0.2, 0.3, + -0.0927051, -0.1, -0.285317, -0.276393, 0.447214, -0.850651, 0.3, 0.4, + -0.0927051, -0.5, -0.285317, 0, -1, 0, -0.592705, -0.785317, + -0.108156, -0.5, -0.33287, 0, -1, 0, -0.608156, -0.83287, + 0.108156, -0.5, -0.33287, 0, -1, 0, -0.391844, -0.83287, + -0.0927051, -0.5, -0.285317, 0, -1, 0, -0.592705, -0.785317, + 0.108156, -0.5, -0.33287, 0, -1, 0, -0.391844, -0.83287, + 0.0927051, -0.5, -0.285317, 0, -1, 0, -0.407295, -0.785317, + 0.123607, -0.3, -0.380423, 0.276393, 0.447214, -0.850651, 0.2, 0.2, + -0.123607, -0.3, -0.380423, -0.276393, 0.447214, -0.850651, 0.3, 0.2, + -0.108156, -0.2, -0.33287, -0.276393, 0.447214, -0.850651, 0.3, 0.3, + 0.108156, -0.2, -0.33287, 0.276393, 0.447214, -0.850651, 0.2, 0.3, + 0.123607, -0.3, -0.380423, 0.276393, 0.447214, -0.850651, 0.2, 0.2, + -0.108156, -0.2, -0.33287, -0.276393, 0.447214, -0.850651, 0.3, 0.3, + -0.108156, -0.5, -0.33287, 0, -1, 0, -0.608156, -0.83287, + -0.123607, -0.5, -0.380423, 0, -1, 0, -0.623607, -0.880423, + 0.123607, -0.5, -0.380423, 0, -1, 0, -0.376393, -0.880423, + -0.108156, -0.5, -0.33287, 0, -1, 0, -0.608156, -0.83287, + 0.123607, -0.5, -0.380423, 0, -1, 0, -0.376393, -0.880423, + 0.108156, -0.5, -0.33287, 0, -1, 0, -0.391844, -0.83287, + 0.139058, -0.4, -0.427975, 0.276393, 0.447214, -0.850651, 0.2, 0.1, + -0.139058, -0.4, -0.427975, -0.276393, 0.447214, -0.850651, 0.3, 0.1, + -0.123607, -0.3, -0.380423, -0.276393, 0.447214, -0.850651, 0.3, 0.2, + 0.123607, -0.3, -0.380423, 0.276393, 0.447214, -0.850651, 0.2, 0.2, + 0.139058, -0.4, -0.427975, 0.276393, 0.447214, -0.850651, 0.2, 0.1, + -0.123607, -0.3, -0.380423, -0.276393, 0.447214, -0.850651, 0.3, 0.2, + -0.123607, -0.5, -0.380423, 0, -1, 0, -0.623607, -0.880423, + -0.139058, -0.5, -0.427975, 0, -1, 0, -0.639058, -0.927975, + 0.139058, -0.5, -0.427975, 0, -1, 0, -0.360942, -0.927975, + -0.123607, -0.5, -0.380423, 0, -1, 0, -0.623607, -0.880423, + 0.139058, -0.5, -0.427975, 0, -1, 0, -0.360942, -0.927975, + 0.123607, -0.5, -0.380423, 0, -1, 0, -0.376393, -0.880423, + 0.154509, -0.5, -0.475528, 0.276393, 0.447214, -0.850651, 0.2, 0, + -0.154509, -0.5, -0.475528, -0.276393, 0.447214, -0.850651, 0.3, 0, + -0.139058, -0.4, -0.427975, -0.276393, 0.447214, -0.850651, 0.3, 0.1, + 0.139058, -0.4, -0.427975, 0.276393, 0.447214, -0.850651, 0.2, 0.1, + 0.154509, -0.5, -0.475528, 0.276393, 0.447214, -0.850651, 0.2, 0, + -0.139058, -0.4, -0.427975, -0.276393, 0.447214, -0.850651, 0.3, 0.1, + -0.139058, -0.5, -0.427975, 0, -1, 0, -0.639058, -0.927975, + -0.154509, -0.5, -0.475528, 0, -1, 0, -0.654509, -0.975528, + 0.154509, -0.5, -0.475528, 0, -1, 0, -0.345491, -0.975528, + -0.139058, -0.5, -0.427975, 0, -1, 0, -0.639058, -0.927975, + 0.154509, -0.5, -0.475528, 0, -1, 0, -0.345491, -0.975528, + 0.139058, -0.5, -0.427975, 0, -1, 0, -0.360942, -0.927975, + 0.0404509, 0.4, -0.0293892, 0.723607, 0.447214, -0.525731, 0.1, 0.9, + 0.0154509, 0.4, -0.0475528, 0.276393, 0.447214, -0.850651, 0.2, 0.9, + 0, 0.5, -0, 0.520267, 0.465341, -0.716086, 0.2, 1, + 0, -0.5, -0, 0, -1, 0, -0.5, -0.5, + 0.0154509, -0.5, -0.0475528, 0, -1, 0, -0.484549, -0.547553, + 0.0404509, -0.5, -0.0293892, 0, -1, 0, -0.459549, -0.529389, + 0.0809017, 0.3, -0.0587785, 0.723607, 0.447214, -0.525731, 0.1, 0.8, + 0.0309017, 0.3, -0.0951056, 0.276393, 0.447214, -0.850651, 0.2, 0.8, + 0.0154509, 0.4, -0.0475528, 0.276393, 0.447214, -0.850651, 0.2, 0.9, + 0.0404509, 0.4, -0.0293892, 0.723607, 0.447214, -0.525731, 0.1, 0.9, + 0.0809017, 0.3, -0.0587785, 0.723607, 0.447214, -0.525731, 0.1, 0.8, + 0.0154509, 0.4, -0.0475528, 0.276393, 0.447214, -0.850651, 0.2, 0.9, + 0.0154509, -0.5, -0.0475528, 0, -1, 0, -0.484549, -0.547553, + 0.0309017, -0.5, -0.0951056, 0, -1, 0, -0.469098, -0.595106, + 0.0809017, -0.5, -0.0587785, 0, -1, 0, -0.419098, -0.558779, + 0.0154509, -0.5, -0.0475528, 0, -1, 0, -0.484549, -0.547553, + 0.0809017, -0.5, -0.0587785, 0, -1, 0, -0.419098, -0.558779, + 0.0404509, -0.5, -0.0293892, 0, -1, 0, -0.459549, -0.529389, + 0.121353, 0.2, -0.0881677, 0.723607, 0.447214, -0.525731, 0.1, 0.7, + 0.0463526, 0.2, -0.142658, 0.276393, 0.447214, -0.850651, 0.2, 0.7, + 0.0309017, 0.3, -0.0951056, 0.276393, 0.447214, -0.850651, 0.2, 0.8, + 0.0809017, 0.3, -0.0587785, 0.723607, 0.447214, -0.525731, 0.1, 0.8, + 0.121353, 0.2, -0.0881677, 0.723607, 0.447214, -0.525731, 0.1, 0.7, + 0.0309017, 0.3, -0.0951056, 0.276393, 0.447214, -0.850651, 0.2, 0.8, + 0.0309017, -0.5, -0.0951056, 0, -1, 0, -0.469098, -0.595106, + 0.0463526, -0.5, -0.142658, 0, -1, 0, -0.453647, -0.642658, + 0.121353, -0.5, -0.0881677, 0, -1, 0, -0.378647, -0.588168, + 0.0309017, -0.5, -0.0951056, 0, -1, 0, -0.469098, -0.595106, + 0.121353, -0.5, -0.0881677, 0, -1, 0, -0.378647, -0.588168, + 0.0809017, -0.5, -0.0587785, 0, -1, 0, -0.419098, -0.558779, + 0.161803, 0.1, -0.117557, 0.723607, 0.447214, -0.525731, 0.1, 0.6, + 0.0618034, 0.1, -0.190211, 0.276393, 0.447214, -0.850651, 0.2, 0.6, + 0.0463526, 0.2, -0.142658, 0.276393, 0.447214, -0.850651, 0.2, 0.7, + 0.121353, 0.2, -0.0881677, 0.723607, 0.447214, -0.525731, 0.1, 0.7, + 0.161803, 0.1, -0.117557, 0.723607, 0.447214, -0.525731, 0.1, 0.6, + 0.0463526, 0.2, -0.142658, 0.276393, 0.447214, -0.850651, 0.2, 0.7, + 0.0463526, -0.5, -0.142658, 0, -1, 0, -0.453647, -0.642658, + 0.0618034, -0.5, -0.190211, 0, -1, 0, -0.438197, -0.690211, + 0.161803, -0.5, -0.117557, 0, -1, 0, -0.338197, -0.617557, + 0.0463526, -0.5, -0.142658, 0, -1, 0, -0.453647, -0.642658, + 0.161803, -0.5, -0.117557, 0, -1, 0, -0.338197, -0.617557, + 0.121353, -0.5, -0.0881677, 0, -1, 0, -0.378647, -0.588168, + 0.202254, 0, -0.146946, 0.723607, 0.447214, -0.525731, 0.1, 0.5, + 0.0772543, 0, -0.237764, 0.276393, 0.447214, -0.850651, 0.2, 0.5, + 0.0618034, 0.1, -0.190211, 0.276393, 0.447214, -0.850651, 0.2, 0.6, + 0.161803, 0.1, -0.117557, 0.723607, 0.447214, -0.525731, 0.1, 0.6, + 0.202254, 0, -0.146946, 0.723607, 0.447214, -0.525731, 0.1, 0.5, + 0.0618034, 0.1, -0.190211, 0.276393, 0.447214, -0.850651, 0.2, 0.6, + 0.0618034, -0.5, -0.190211, 0, -1, 0, -0.438197, -0.690211, + 0.0772543, -0.5, -0.237764, 0, -1, 0, -0.422746, -0.737764, + 0.202254, -0.5, -0.146946, 0, -1, 0, -0.297746, -0.646946, + 0.0618034, -0.5, -0.190211, 0, -1, 0, -0.438197, -0.690211, + 0.202254, -0.5, -0.146946, 0, -1, 0, -0.297746, -0.646946, + 0.161803, -0.5, -0.117557, 0, -1, 0, -0.338197, -0.617557, + 0.242705, -0.1, -0.176335, 0.723607, 0.447214, -0.525731, 0.1, 0.4, + 0.0927051, -0.1, -0.285317, 0.276393, 0.447214, -0.850651, 0.2, 0.4, + 0.0772543, 0, -0.237764, 0.276393, 0.447214, -0.850651, 0.2, 0.5, + 0.202254, 0, -0.146946, 0.723607, 0.447214, -0.525731, 0.1, 0.5, + 0.242705, -0.1, -0.176335, 0.723607, 0.447214, -0.525731, 0.1, 0.4, + 0.0772543, 0, -0.237764, 0.276393, 0.447214, -0.850651, 0.2, 0.5, + 0.0772543, -0.5, -0.237764, 0, -1, 0, -0.422746, -0.737764, + 0.0927051, -0.5, -0.285317, 0, -1, 0, -0.407295, -0.785317, + 0.242705, -0.5, -0.176335, 0, -1, 0, -0.257295, -0.676335, + 0.0772543, -0.5, -0.237764, 0, -1, 0, -0.422746, -0.737764, + 0.242705, -0.5, -0.176335, 0, -1, 0, -0.257295, -0.676335, + 0.202254, -0.5, -0.146946, 0, -1, 0, -0.297746, -0.646946, + 0.283156, -0.2, -0.205725, 0.723607, 0.447214, -0.525731, 0.1, 0.3, + 0.108156, -0.2, -0.33287, 0.276393, 0.447214, -0.850651, 0.2, 0.3, + 0.0927051, -0.1, -0.285317, 0.276393, 0.447214, -0.850651, 0.2, 0.4, + 0.242705, -0.1, -0.176335, 0.723607, 0.447214, -0.525731, 0.1, 0.4, + 0.283156, -0.2, -0.205725, 0.723607, 0.447214, -0.525731, 0.1, 0.3, + 0.0927051, -0.1, -0.285317, 0.276393, 0.447214, -0.850651, 0.2, 0.4, + 0.0927051, -0.5, -0.285317, 0, -1, 0, -0.407295, -0.785317, + 0.108156, -0.5, -0.33287, 0, -1, 0, -0.391844, -0.83287, + 0.283156, -0.5, -0.205725, 0, -1, 0, -0.216844, -0.705725, + 0.0927051, -0.5, -0.285317, 0, -1, 0, -0.407295, -0.785317, + 0.283156, -0.5, -0.205725, 0, -1, 0, -0.216844, -0.705725, + 0.242705, -0.5, -0.176335, 0, -1, 0, -0.257295, -0.676335, + 0.323607, -0.3, -0.235114, 0.723607, 0.447214, -0.525731, 0.1, 0.2, + 0.123607, -0.3, -0.380423, 0.276393, 0.447214, -0.850651, 0.2, 0.2, + 0.108156, -0.2, -0.33287, 0.276393, 0.447214, -0.850651, 0.2, 0.3, + 0.283156, -0.2, -0.205725, 0.723607, 0.447214, -0.525731, 0.1, 0.3, + 0.323607, -0.3, -0.235114, 0.723607, 0.447214, -0.525731, 0.1, 0.2, + 0.108156, -0.2, -0.33287, 0.276393, 0.447214, -0.850651, 0.2, 0.3, + 0.108156, -0.5, -0.33287, 0, -1, 0, -0.391844, -0.83287, + 0.123607, -0.5, -0.380423, 0, -1, 0, -0.376393, -0.880423, + 0.323607, -0.5, -0.235114, 0, -1, 0, -0.176393, -0.735114, + 0.108156, -0.5, -0.33287, 0, -1, 0, -0.391844, -0.83287, + 0.323607, -0.5, -0.235114, 0, -1, 0, -0.176393, -0.735114, + 0.283156, -0.5, -0.205725, 0, -1, 0, -0.216844, -0.705725, + 0.364058, -0.4, -0.264503, 0.723607, 0.447214, -0.525731, 0.1, 0.1, + 0.139058, -0.4, -0.427975, 0.276393, 0.447214, -0.850651, 0.2, 0.1, + 0.123607, -0.3, -0.380423, 0.276393, 0.447214, -0.850651, 0.2, 0.2, + 0.323607, -0.3, -0.235114, 0.723607, 0.447214, -0.525731, 0.1, 0.2, + 0.364058, -0.4, -0.264503, 0.723607, 0.447214, -0.525731, 0.1, 0.1, + 0.123607, -0.3, -0.380423, 0.276393, 0.447214, -0.850651, 0.2, 0.2, + 0.123607, -0.5, -0.380423, 0, -1, 0, -0.376393, -0.880423, + 0.139058, -0.5, -0.427975, 0, -1, 0, -0.360942, -0.927975, + 0.364058, -0.5, -0.264503, 0, -1, 0, -0.135942, -0.764503, + 0.123607, -0.5, -0.380423, 0, -1, 0, -0.376393, -0.880423, + 0.364058, -0.5, -0.264503, 0, -1, 0, -0.135942, -0.764503, + 0.323607, -0.5, -0.235114, 0, -1, 0, -0.176393, -0.735114, + 0.404509, -0.5, -0.293892, 0.723607, 0.447214, -0.525731, 0.1, 0, + 0.154509, -0.5, -0.475528, 0.276393, 0.447214, -0.850651, 0.2, 0, + 0.139058, -0.4, -0.427975, 0.276393, 0.447214, -0.850651, 0.2, 0.1, + 0.364058, -0.4, -0.264503, 0.723607, 0.447214, -0.525731, 0.1, 0.1, + 0.404509, -0.5, -0.293892, 0.723607, 0.447214, -0.525731, 0.1, 0, + 0.139058, -0.4, -0.427975, 0.276393, 0.447214, -0.850651, 0.2, 0.1, + 0.139058, -0.5, -0.427975, 0, -1, 0, -0.360942, -0.927975, + 0.154509, -0.5, -0.475528, 0, -1, 0, -0.345491, -0.975528, + 0.404509, -0.5, -0.293892, 0, -1, 0, -0.0954914, -0.793893, + 0.139058, -0.5, -0.427975, 0, -1, 0, -0.360942, -0.927975, + 0.404509, -0.5, -0.293892, 0, -1, 0, -0.0954914, -0.793893, + 0.364058, -0.5, -0.264503, 0, -1, 0, -0.135942, -0.764503, + 0.05, 0.4, 8.74228e-09, 0.894427, 0.447214, 1.56387e-07, 0, 0.9, + 0.0404509, 0.4, -0.0293892, 0.723607, 0.447214, -0.525731, 0.1, 0.9, + 0, 0.5, -0, 0.84181, 0.465341, -0.27352, 0.1, 1, + 0, -0.5, -0, 0, -1, 0, -0.5, -0.5, + 0.0404509, -0.5, -0.0293892, 0, -1, 0, -0.459549, -0.529389, + 0.05, -0.5, 8.74228e-09, 0, -1, 0, -0.45, -0.5, + 0.1, 0.3, 1.74846e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.8, + 0.0809017, 0.3, -0.0587785, 0.723607, 0.447214, -0.525731, 0.1, 0.8, + 0.0404509, 0.4, -0.0293892, 0.723607, 0.447214, -0.525731, 0.1, 0.9, + 0.05, 0.4, 8.74228e-09, 0.894427, 0.447214, 1.56387e-07, 0, 0.9, + 0.1, 0.3, 1.74846e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.8, + 0.0404509, 0.4, -0.0293892, 0.723607, 0.447214, -0.525731, 0.1, 0.9, + 0.0404509, -0.5, -0.0293892, 0, -1, 0, -0.459549, -0.529389, + 0.0809017, -0.5, -0.0587785, 0, -1, 0, -0.419098, -0.558779, + 0.1, -0.5, 1.74846e-08, 0, -1, 0, -0.4, -0.5, + 0.0404509, -0.5, -0.0293892, 0, -1, 0, -0.459549, -0.529389, + 0.1, -0.5, 1.74846e-08, 0, -1, 0, -0.4, -0.5, + 0.05, -0.5, 8.74228e-09, 0, -1, 0, -0.45, -0.5, + 0.15, 0.2, 2.62268e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.7, + 0.121353, 0.2, -0.0881677, 0.723607, 0.447214, -0.525731, 0.1, 0.7, + 0.0809017, 0.3, -0.0587785, 0.723607, 0.447214, -0.525731, 0.1, 0.8, + 0.1, 0.3, 1.74846e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.8, + 0.15, 0.2, 2.62268e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.7, + 0.0809017, 0.3, -0.0587785, 0.723607, 0.447214, -0.525731, 0.1, 0.8, + 0.0809017, -0.5, -0.0587785, 0, -1, 0, -0.419098, -0.558779, + 0.121353, -0.5, -0.0881677, 0, -1, 0, -0.378647, -0.588168, + 0.15, -0.5, 2.62268e-08, 0, -1, 0, -0.35, -0.5, + 0.0809017, -0.5, -0.0587785, 0, -1, 0, -0.419098, -0.558779, + 0.15, -0.5, 2.62268e-08, 0, -1, 0, -0.35, -0.5, + 0.1, -0.5, 1.74846e-08, 0, -1, 0, -0.4, -0.5, + 0.2, 0.1, 3.49691e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.6, + 0.161803, 0.1, -0.117557, 0.723607, 0.447214, -0.525731, 0.1, 0.6, + 0.121353, 0.2, -0.0881677, 0.723607, 0.447214, -0.525731, 0.1, 0.7, + 0.15, 0.2, 2.62268e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.7, + 0.2, 0.1, 3.49691e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.6, + 0.121353, 0.2, -0.0881677, 0.723607, 0.447214, -0.525731, 0.1, 0.7, + 0.121353, -0.5, -0.0881677, 0, -1, 0, -0.378647, -0.588168, + 0.161803, -0.5, -0.117557, 0, -1, 0, -0.338197, -0.617557, + 0.2, -0.5, 3.49691e-08, 0, -1, 0, -0.3, -0.5, + 0.121353, -0.5, -0.0881677, 0, -1, 0, -0.378647, -0.588168, + 0.2, -0.5, 3.49691e-08, 0, -1, 0, -0.3, -0.5, + 0.15, -0.5, 2.62268e-08, 0, -1, 0, -0.35, -0.5, + 0.25, 0, 4.37114e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.5, + 0.202254, 0, -0.146946, 0.723607, 0.447214, -0.525731, 0.1, 0.5, + 0.161803, 0.1, -0.117557, 0.723607, 0.447214, -0.525731, 0.1, 0.6, + 0.2, 0.1, 3.49691e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.6, + 0.25, 0, 4.37114e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.5, + 0.161803, 0.1, -0.117557, 0.723607, 0.447214, -0.525731, 0.1, 0.6, + 0.161803, -0.5, -0.117557, 0, -1, 0, -0.338197, -0.617557, + 0.202254, -0.5, -0.146946, 0, -1, 0, -0.297746, -0.646946, + 0.25, -0.5, 4.37114e-08, 0, -1, 0, -0.25, -0.5, + 0.161803, -0.5, -0.117557, 0, -1, 0, -0.338197, -0.617557, + 0.25, -0.5, 4.37114e-08, 0, -1, 0, -0.25, -0.5, + 0.2, -0.5, 3.49691e-08, 0, -1, 0, -0.3, -0.5, + 0.3, -0.1, 5.24537e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.4, + 0.242705, -0.1, -0.176335, 0.723607, 0.447214, -0.525731, 0.1, 0.4, + 0.202254, 0, -0.146946, 0.723607, 0.447214, -0.525731, 0.1, 0.5, + 0.25, 0, 4.37114e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.5, + 0.3, -0.1, 5.24537e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.4, + 0.202254, 0, -0.146946, 0.723607, 0.447214, -0.525731, 0.1, 0.5, + 0.202254, -0.5, -0.146946, 0, -1, 0, -0.297746, -0.646946, + 0.242705, -0.5, -0.176335, 0, -1, 0, -0.257295, -0.676335, + 0.3, -0.5, 5.24537e-08, 0, -1, 0, -0.2, -0.5, + 0.202254, -0.5, -0.146946, 0, -1, 0, -0.297746, -0.646946, + 0.3, -0.5, 5.24537e-08, 0, -1, 0, -0.2, -0.5, + 0.25, -0.5, 4.37114e-08, 0, -1, 0, -0.25, -0.5, + 0.35, -0.2, 6.11959e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.3, + 0.283156, -0.2, -0.205725, 0.723607, 0.447214, -0.525731, 0.1, 0.3, + 0.242705, -0.1, -0.176335, 0.723607, 0.447214, -0.525731, 0.1, 0.4, + 0.3, -0.1, 5.24537e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.4, + 0.35, -0.2, 6.11959e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.3, + 0.242705, -0.1, -0.176335, 0.723607, 0.447214, -0.525731, 0.1, 0.4, + 0.242705, -0.5, -0.176335, 0, -1, 0, -0.257295, -0.676335, + 0.283156, -0.5, -0.205725, 0, -1, 0, -0.216844, -0.705725, + 0.35, -0.5, 6.11959e-08, 0, -1, 0, -0.15, -0.5, + 0.242705, -0.5, -0.176335, 0, -1, 0, -0.257295, -0.676335, + 0.35, -0.5, 6.11959e-08, 0, -1, 0, -0.15, -0.5, + 0.3, -0.5, 5.24537e-08, 0, -1, 0, -0.2, -0.5, + 0.4, -0.3, 6.99382e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.2, + 0.323607, -0.3, -0.235114, 0.723607, 0.447214, -0.525731, 0.1, 0.2, + 0.283156, -0.2, -0.205725, 0.723607, 0.447214, -0.525731, 0.1, 0.3, + 0.35, -0.2, 6.11959e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.3, + 0.4, -0.3, 6.99382e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.2, + 0.283156, -0.2, -0.205725, 0.723607, 0.447214, -0.525731, 0.1, 0.3, + 0.283156, -0.5, -0.205725, 0, -1, 0, -0.216844, -0.705725, + 0.323607, -0.5, -0.235114, 0, -1, 0, -0.176393, -0.735114, + 0.4, -0.5, 6.99382e-08, 0, -1, 0, -0.1, -0.5, + 0.283156, -0.5, -0.205725, 0, -1, 0, -0.216844, -0.705725, + 0.4, -0.5, 6.99382e-08, 0, -1, 0, -0.1, -0.5, + 0.35, -0.5, 6.11959e-08, 0, -1, 0, -0.15, -0.5, + 0.45, -0.4, 7.86805e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.1, + 0.364058, -0.4, -0.264503, 0.723607, 0.447214, -0.525731, 0.1, 0.1, + 0.323607, -0.3, -0.235114, 0.723607, 0.447214, -0.525731, 0.1, 0.2, + 0.4, -0.3, 6.99382e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.2, + 0.45, -0.4, 7.86805e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.1, + 0.323607, -0.3, -0.235114, 0.723607, 0.447214, -0.525731, 0.1, 0.2, + 0.323607, -0.5, -0.235114, 0, -1, 0, -0.176393, -0.735114, + 0.364058, -0.5, -0.264503, 0, -1, 0, -0.135942, -0.764503, + 0.45, -0.5, 7.86805e-08, 0, -1, 0, -0.05, -0.5, + 0.323607, -0.5, -0.235114, 0, -1, 0, -0.176393, -0.735114, + 0.45, -0.5, 7.86805e-08, 0, -1, 0, -0.05, -0.5, + 0.4, -0.5, 6.99382e-08, 0, -1, 0, -0.1, -0.5, + 0.5, -0.5, 8.74228e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0, + 0.404509, -0.5, -0.293892, 0.723607, 0.447214, -0.525731, 0.1, 0, + 0.364058, -0.4, -0.264503, 0.723607, 0.447214, -0.525731, 0.1, 0.1, + 0.45, -0.4, 7.86805e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0.1, + 0.5, -0.5, 8.74228e-08, 0.894427, 0.447214, 1.56387e-07, 0, 0, + 0.364058, -0.4, -0.264503, 0.723607, 0.447214, -0.525731, 0.1, 0.1, + 0.364058, -0.5, -0.264503, 0, -1, 0, -0.135942, -0.764503, + 0.404509, -0.5, -0.293892, 0, -1, 0, -0.0954914, -0.793893, + 0.5, -0.5, 8.74228e-08, 0, -1, 0, 0, -0.5, + 0.364058, -0.5, -0.264503, 0, -1, 0, -0.135942, -0.764503, + 0.5, -0.5, 8.74228e-08, 0, -1, 0, 0, -0.5, + 0.45, -0.5, 7.86805e-08, 0, -1, 0, -0.05, -0.5 +};
\ No newline at end of file diff --git a/engine-ocean/Graphics/textrenderer.cpp b/engine-ocean/Graphics/textrenderer.cpp new file mode 100644 index 0000000..d5551f9 --- /dev/null +++ b/engine-ocean/Graphics/textrenderer.cpp @@ -0,0 +1,87 @@ +#include "textrenderer.h" +#include "debug.h" + +void TextRenderer::initialize(){ + glGenVertexArrays(1, &m_vao); + glGenBuffers(1, &m_vbo); + glBindVertexArray(m_vao); + glBindBuffer(GL_ARRAY_BUFFER, m_vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, NULL, GL_DYNAMIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); +} + +void TextRenderer::renderUIText(std::shared_ptr<Font> font, std::string text, glm::vec2 anchorPosition, AnchorPoint anchorPoint, float textBoxWidth, float fontSize, float lineSpacing, glm::vec3 textColor){ + glActiveTexture(GL_TEXTURE0); + glBindVertexArray(m_vao); + + float x = 0; + float y = 0; + + float maxY = font->getCharacter(73).size.y * fontSize; + float minY = - (font->getCharacter(106).size.y - font->getCharacter(106).bearing.y) * fontSize; + + switch(anchorPoint){ + case AnchorPoint::TopLeft: + x = anchorPosition.x; + y = anchorPosition.y - maxY; + break; + case AnchorPoint::TopCenter: + x = anchorPosition.x - textBoxWidth * 0.5f; + y = anchorPosition.y - maxY; + break; + case AnchorPoint::TopRight: + x = anchorPosition.x - textBoxWidth; + y = anchorPosition.y - maxY; + break; + } + + float initX = x; + float initY = y; + + std::string::const_iterator c; + for (c = text.begin(); c != text.end(); c++) + { + Character ch = font->getCharacter(*c); + + float xpos = x + ch.bearing.x * fontSize; + float ypos = y - (ch.size.y - ch.bearing.y) * fontSize; + + float w = ch.size.x * fontSize; + float h = ch.size.y * fontSize; + + if(xpos + w > initX + textBoxWidth){ + x = initX; + y -= (1.f + lineSpacing) * (maxY - minY); + + xpos = x + ch.bearing.x * fontSize; + ypos = y - (ch.size.y - ch.bearing.y) * fontSize; + } + + + // update VBO for each character + float vertices[6][4] = { + { xpos, ypos + h, 0.0f, 0.0f }, + { xpos, ypos, 0.0f, 1.0f }, + { xpos + w, ypos, 1.0f, 1.0f }, + + { xpos, ypos + h, 0.0f, 0.0f }, + { xpos + w, ypos, 1.0f, 1.0f }, + { xpos + w, ypos + h, 1.0f, 0.0f } + }; + // render glyph texture over quad + glBindTexture(GL_TEXTURE_2D, ch.textureID); + // update content of VBO memory + glBindBuffer(GL_ARRAY_BUFFER, m_vbo); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); + glBindBuffer(GL_ARRAY_BUFFER, 0); + // render quad + glDrawArrays(GL_TRIANGLES, 0, 6); + // now advance cursors for next glyph (note that advance is number of 1/64 pixels) + x += (ch.advance >> 6) * fontSize; // bitshift by 6 to get value in pixels (2^6 = 64) + } + glBindVertexArray(0); + glBindTexture(GL_TEXTURE_2D, 0); +}
\ No newline at end of file diff --git a/engine-ocean/Graphics/textrenderer.h b/engine-ocean/Graphics/textrenderer.h new file mode 100644 index 0000000..604d0ad --- /dev/null +++ b/engine-ocean/Graphics/textrenderer.h @@ -0,0 +1,21 @@ +#pragma once + +// Credit to https://learnopengl.com/In-Practice/Text-Rendering + +#include "font.h" +#include <string> +#include <memory> + +enum class AnchorPoint{ + TopLeft, TopCenter, TopRight +}; + +class TextRenderer{ +public: + void initialize(); + void renderUIText(std::shared_ptr<Font> font, std::string text, glm::vec2 anchorPosition, AnchorPoint anchorPoint, float textBoxWidth, float fontSize, float lineSpacing, glm::vec3 textColor); + +private: + GLuint m_vao; + GLuint m_vbo; +};
\ No newline at end of file diff --git a/engine-ocean/Graphics/tiny_obj_loader.h b/engine-ocean/Graphics/tiny_obj_loader.h new file mode 100644 index 0000000..3556710 --- /dev/null +++ b/engine-ocean/Graphics/tiny_obj_loader.h @@ -0,0 +1,3477 @@ +/* +The MIT License (MIT) + +Copyright (c) 2012-Present, Syoyo Fujita and many contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// +// version 2.0.0 : Add new object oriented API. 1.x API is still provided. +// * Support line primitive. +// * Support points primitive. +// * Support multiple search path for .mtl(v1 API). +// * Support vertex weight `vw`(as an tinyobj extension) +// * Support escaped whitespece in mtllib +// * Add robust triangulation using Mapbox earcut(TINYOBJLOADER_USE_MAPBOX_EARCUT). +// version 1.4.0 : Modifed ParseTextureNameAndOption API +// version 1.3.1 : Make ParseTextureNameAndOption API public +// version 1.3.0 : Separate warning and error message(breaking API of LoadObj) +// version 1.2.3 : Added color space extension('-colorspace') to tex opts. +// version 1.2.2 : Parse multiple group names. +// version 1.2.1 : Added initial support for line('l') primitive(PR #178) +// version 1.2.0 : Hardened implementation(#175) +// version 1.1.1 : Support smoothing groups(#162) +// version 1.1.0 : Support parsing vertex color(#144) +// version 1.0.8 : Fix parsing `g` tag just after `usemtl`(#138) +// version 1.0.7 : Support multiple tex options(#126) +// version 1.0.6 : Add TINYOBJLOADER_USE_DOUBLE option(#124) +// version 1.0.5 : Ignore `Tr` when `d` exists in MTL(#43) +// version 1.0.4 : Support multiple filenames for 'mtllib'(#112) +// version 1.0.3 : Support parsing texture options(#85) +// version 1.0.2 : Improve parsing speed by about a factor of 2 for large +// files(#105) +// version 1.0.1 : Fixes a shape is lost if obj ends with a 'usemtl'(#104) +// version 1.0.0 : Change data structure. Change license from BSD to MIT. +// + +// +// Use this in *one* .cc +// #define TINYOBJLOADER_IMPLEMENTATION +// #include "tiny_obj_loader.h" +// + +#ifndef TINY_OBJ_LOADER_H_ +#define TINY_OBJ_LOADER_H_ + +#include <map> +#include <string> +#include <vector> + +namespace tinyobj { + +// TODO(syoyo): Better C++11 detection for older compiler +#if __cplusplus > 199711L +#define TINYOBJ_OVERRIDE override +#else +#define TINYOBJ_OVERRIDE +#endif + +#ifdef __clang__ +#pragma clang diagnostic push +#if __has_warning("-Wzero-as-null-pointer-constant") +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" +#endif + +#pragma clang diagnostic ignored "-Wpadded" + +#endif + +// https://en.wikipedia.org/wiki/Wavefront_.obj_file says ... +// +// -blendu on | off # set horizontal texture blending +// (default on) +// -blendv on | off # set vertical texture blending +// (default on) +// -boost real_value # boost mip-map sharpness +// -mm base_value gain_value # modify texture map values (default +// 0 1) +// # base_value = brightness, +// gain_value = contrast +// -o u [v [w]] # Origin offset (default +// 0 0 0) +// -s u [v [w]] # Scale (default +// 1 1 1) +// -t u [v [w]] # Turbulence (default +// 0 0 0) +// -texres resolution # texture resolution to create +// -clamp on | off # only render texels in the clamped +// 0-1 range (default off) +// # When unclamped, textures are +// repeated across a surface, +// # when clamped, only texels which +// fall within the 0-1 +// # range are rendered. +// -bm mult_value # bump multiplier (for bump maps +// only) +// +// -imfchan r | g | b | m | l | z # specifies which channel of the file +// is used to +// # create a scalar or bump texture. +// r:red, g:green, +// # b:blue, m:matte, l:luminance, +// z:z-depth.. +// # (the default for bump is 'l' and +// for decal is 'm') +// bump -imfchan r bumpmap.tga # says to use the red channel of +// bumpmap.tga as the bumpmap +// +// For reflection maps... +// +// -type sphere # specifies a sphere for a "refl" +// reflection map +// -type cube_top | cube_bottom | # when using a cube map, the texture +// file for each +// cube_front | cube_back | # side of the cube is specified +// separately +// cube_left | cube_right +// +// TinyObjLoader extension. +// +// -colorspace SPACE # Color space of the texture. e.g. +// 'sRGB` or 'linear' +// + +#ifdef TINYOBJLOADER_USE_DOUBLE +//#pragma message "using double" +typedef double real_t; +#else +//#pragma message "using float" +typedef float real_t; +#endif + +typedef enum { + TEXTURE_TYPE_NONE, // default + TEXTURE_TYPE_SPHERE, + TEXTURE_TYPE_CUBE_TOP, + TEXTURE_TYPE_CUBE_BOTTOM, + TEXTURE_TYPE_CUBE_FRONT, + TEXTURE_TYPE_CUBE_BACK, + TEXTURE_TYPE_CUBE_LEFT, + TEXTURE_TYPE_CUBE_RIGHT +} texture_type_t; + +struct texture_option_t { + texture_type_t type; // -type (default TEXTURE_TYPE_NONE) + real_t sharpness; // -boost (default 1.0?) + real_t brightness; // base_value in -mm option (default 0) + real_t contrast; // gain_value in -mm option (default 1) + real_t origin_offset[3]; // -o u [v [w]] (default 0 0 0) + real_t scale[3]; // -s u [v [w]] (default 1 1 1) + real_t turbulence[3]; // -t u [v [w]] (default 0 0 0) + int texture_resolution; // -texres resolution (No default value in the spec. + // We'll use -1) + bool clamp; // -clamp (default false) + char imfchan; // -imfchan (the default for bump is 'l' and for decal is 'm') + bool blendu; // -blendu (default on) + bool blendv; // -blendv (default on) + real_t bump_multiplier; // -bm (for bump maps only, default 1.0) + + // extension + std::string colorspace; // Explicitly specify color space of stored texel + // value. Usually `sRGB` or `linear` (default empty). +}; + +struct material_t { + std::string name; + + real_t ambient[3]; + real_t diffuse[3]; + real_t specular[3]; + real_t transmittance[3]; + real_t emission[3]; + real_t shininess; + real_t ior; // index of refraction + real_t dissolve; // 1 == opaque; 0 == fully transparent + // illumination model (see http://www.fileformat.info/format/material/) + int illum; + + int dummy; // Suppress padding warning. + + std::string ambient_texname; // map_Ka. For ambient or ambient occlusion. + std::string diffuse_texname; // map_Kd + std::string specular_texname; // map_Ks + std::string specular_highlight_texname; // map_Ns + std::string bump_texname; // map_bump, map_Bump, bump + std::string displacement_texname; // disp + std::string alpha_texname; // map_d + std::string reflection_texname; // refl + + texture_option_t ambient_texopt; + texture_option_t diffuse_texopt; + texture_option_t specular_texopt; + texture_option_t specular_highlight_texopt; + texture_option_t bump_texopt; + texture_option_t displacement_texopt; + texture_option_t alpha_texopt; + texture_option_t reflection_texopt; + + // PBR extension + // http://exocortex.com/blog/extending_wavefront_mtl_to_support_pbr + real_t roughness; // [0, 1] default 0 + real_t metallic; // [0, 1] default 0 + real_t sheen; // [0, 1] default 0 + real_t clearcoat_thickness; // [0, 1] default 0 + real_t clearcoat_roughness; // [0, 1] default 0 + real_t anisotropy; // aniso. [0, 1] default 0 + real_t anisotropy_rotation; // anisor. [0, 1] default 0 + real_t pad0; + std::string roughness_texname; // map_Pr + std::string metallic_texname; // map_Pm + std::string sheen_texname; // map_Ps + std::string emissive_texname; // map_Ke + std::string normal_texname; // norm. For normal mapping. + + texture_option_t roughness_texopt; + texture_option_t metallic_texopt; + texture_option_t sheen_texopt; + texture_option_t emissive_texopt; + texture_option_t normal_texopt; + + int pad2; + + std::map<std::string, std::string> unknown_parameter; + +#ifdef TINY_OBJ_LOADER_PYTHON_BINDING + // For pybind11 + std::array<double, 3> GetDiffuse() { + std::array<double, 3> values; + values[0] = double(diffuse[0]); + values[1] = double(diffuse[1]); + values[2] = double(diffuse[2]); + + return values; + } + + std::array<double, 3> GetSpecular() { + std::array<double, 3> values; + values[0] = double(specular[0]); + values[1] = double(specular[1]); + values[2] = double(specular[2]); + + return values; + } + + std::array<double, 3> GetTransmittance() { + std::array<double, 3> values; + values[0] = double(transmittance[0]); + values[1] = double(transmittance[1]); + values[2] = double(transmittance[2]); + + return values; + } + + std::array<double, 3> GetEmission() { + std::array<double, 3> values; + values[0] = double(emission[0]); + values[1] = double(emission[1]); + values[2] = double(emission[2]); + + return values; + } + + std::array<double, 3> GetAmbient() { + std::array<double, 3> values; + values[0] = double(ambient[0]); + values[1] = double(ambient[1]); + values[2] = double(ambient[2]); + + return values; + } + + void SetDiffuse(std::array<double, 3> &a) { + diffuse[0] = real_t(a[0]); + diffuse[1] = real_t(a[1]); + diffuse[2] = real_t(a[2]); + } + + void SetAmbient(std::array<double, 3> &a) { + ambient[0] = real_t(a[0]); + ambient[1] = real_t(a[1]); + ambient[2] = real_t(a[2]); + } + + void SetSpecular(std::array<double, 3> &a) { + specular[0] = real_t(a[0]); + specular[1] = real_t(a[1]); + specular[2] = real_t(a[2]); + } + + void SetTransmittance(std::array<double, 3> &a) { + transmittance[0] = real_t(a[0]); + transmittance[1] = real_t(a[1]); + transmittance[2] = real_t(a[2]); + } + + std::string GetCustomParameter(const std::string &key) { + std::map<std::string, std::string>::const_iterator it = + unknown_parameter.find(key); + + if (it != unknown_parameter.end()) { + return it->second; + } + return std::string(); + } + +#endif +}; + +struct tag_t { + std::string name; + + std::vector<int> intValues; + std::vector<real_t> floatValues; + std::vector<std::string> stringValues; +}; + +struct joint_and_weight_t { + int joint_id; + real_t weight; +}; + +struct skin_weight_t { + int vertex_id; // Corresponding vertex index in `attrib_t::vertices`. + // Compared to `index_t`, this index must be positive and + // start with 0(does not allow relative indexing) + std::vector<joint_and_weight_t> weightValues; +}; + +// Index struct to support different indices for vtx/normal/texcoord. +// -1 means not used. +struct index_t { + int vertex_index; + int normal_index; + int texcoord_index; +}; + +struct mesh_t { + std::vector<index_t> indices; + std::vector<unsigned char> + num_face_vertices; // The number of vertices per + // face. 3 = triangle, 4 = quad, + // ... Up to 255 vertices per face. + std::vector<int> material_ids; // per-face material ID + std::vector<unsigned int> smoothing_group_ids; // per-face smoothing group + // ID(0 = off. positive value + // = group id) + std::vector<tag_t> tags; // SubD tag +}; + +// struct path_t { +// std::vector<int> indices; // pairs of indices for lines +//}; + +struct lines_t { + // Linear flattened indices. + std::vector<index_t> indices; // indices for vertices(poly lines) + std::vector<int> num_line_vertices; // The number of vertices per line. +}; + +struct points_t { + std::vector<index_t> indices; // indices for points +}; + +struct shape_t { + std::string name; + mesh_t mesh; + lines_t lines; + points_t points; +}; + +// Vertex attributes +struct attrib_t { + std::vector<real_t> vertices; // 'v'(xyz) + + // For backward compatibility, we store vertex weight in separate array. + std::vector<real_t> vertex_weights; // 'v'(w) + std::vector<real_t> normals; // 'vn' + std::vector<real_t> texcoords; // 'vt'(uv) + + // For backward compatibility, we store texture coordinate 'w' in separate + // array. + std::vector<real_t> texcoord_ws; // 'vt'(w) + std::vector<real_t> colors; // extension: vertex colors + + // + // TinyObj extension. + // + + // NOTE(syoyo): array index is based on the appearance order. + // To get a corresponding skin weight for a specific vertex id `vid`, + // Need to reconstruct a look up table: `skin_weight_t::vertex_id` == `vid` + // (e.g. using std::map, std::unordered_map) + std::vector<skin_weight_t> skin_weights; + + attrib_t() {} + + // + // For pybind11 + // + const std::vector<real_t> &GetVertices() const { return vertices; } + + const std::vector<real_t> &GetVertexWeights() const { return vertex_weights; } +}; + +struct callback_t { + // W is optional and set to 1 if there is no `w` item in `v` line + void (*vertex_cb)(void *user_data, real_t x, real_t y, real_t z, real_t w); + void (*vertex_color_cb)(void *user_data, real_t x, real_t y, real_t z, + real_t r, real_t g, real_t b, bool has_color); + void (*normal_cb)(void *user_data, real_t x, real_t y, real_t z); + + // y and z are optional and set to 0 if there is no `y` and/or `z` item(s) in + // `vt` line. + void (*texcoord_cb)(void *user_data, real_t x, real_t y, real_t z); + + // called per 'f' line. num_indices is the number of face indices(e.g. 3 for + // triangle, 4 for quad) + // 0 will be passed for undefined index in index_t members. + void (*index_cb)(void *user_data, index_t *indices, int num_indices); + // `name` material name, `material_id` = the array index of material_t[]. -1 + // if + // a material not found in .mtl + void (*usemtl_cb)(void *user_data, const char *name, int material_id); + // `materials` = parsed material data. + void (*mtllib_cb)(void *user_data, const material_t *materials, + int num_materials); + // There may be multiple group names + void (*group_cb)(void *user_data, const char **names, int num_names); + void (*object_cb)(void *user_data, const char *name); + + callback_t() + : vertex_cb(NULL), + vertex_color_cb(NULL), + normal_cb(NULL), + texcoord_cb(NULL), + index_cb(NULL), + usemtl_cb(NULL), + mtllib_cb(NULL), + group_cb(NULL), + object_cb(NULL) {} +}; + +class MaterialReader { + public: + MaterialReader() {} + virtual ~MaterialReader(); + + virtual bool operator()(const std::string &matId, + std::vector<material_t> *materials, + std::map<std::string, int> *matMap, std::string *warn, + std::string *err) = 0; +}; + +/// +/// Read .mtl from a file. +/// +class MaterialFileReader : public MaterialReader { + public: + // Path could contain separator(';' in Windows, ':' in Posix) + explicit MaterialFileReader(const std::string &mtl_basedir) + : m_mtlBaseDir(mtl_basedir) {} + virtual ~MaterialFileReader() TINYOBJ_OVERRIDE {} + virtual bool operator()(const std::string &matId, + std::vector<material_t> *materials, + std::map<std::string, int> *matMap, std::string *warn, + std::string *err) TINYOBJ_OVERRIDE; + + private: + std::string m_mtlBaseDir; +}; + +/// +/// Read .mtl from a stream. +/// +class MaterialStreamReader : public MaterialReader { + public: + explicit MaterialStreamReader(std::istream &inStream) + : m_inStream(inStream) {} + virtual ~MaterialStreamReader() TINYOBJ_OVERRIDE {} + virtual bool operator()(const std::string &matId, + std::vector<material_t> *materials, + std::map<std::string, int> *matMap, std::string *warn, + std::string *err) TINYOBJ_OVERRIDE; + + private: + std::istream &m_inStream; +}; + +// v2 API +struct ObjReaderConfig { + bool triangulate; // triangulate polygon? + + // Currently not used. + // "simple" or empty: Create triangle fan + // "earcut": Use the algorithm based on Ear clipping + std::string triangulation_method; + + /// Parse vertex color. + /// If vertex color is not present, its filled with default value. + /// false = no vertex color + /// This will increase memory of parsed .obj + bool vertex_color; + + /// + /// Search path to .mtl file. + /// Default = "" = search from the same directory of .obj file. + /// Valid only when loading .obj from a file. + /// + std::string mtl_search_path; + + ObjReaderConfig() + : triangulate(true), triangulation_method("simple"), vertex_color(true) {} +}; + +/// +/// Wavefront .obj reader class(v2 API) +/// +class ObjReader { + public: + ObjReader() : valid_(false) {} + + /// + /// Load .obj and .mtl from a file. + /// + /// @param[in] filename wavefront .obj filename + /// @param[in] config Reader configuration + /// + bool ParseFromFile(const std::string &filename, + const ObjReaderConfig &config = ObjReaderConfig()); + + /// + /// Parse .obj from a text string. + /// Need to supply .mtl text string by `mtl_text`. + /// This function ignores `mtllib` line in .obj text. + /// + /// @param[in] obj_text wavefront .obj filename + /// @param[in] mtl_text wavefront .mtl filename + /// @param[in] config Reader configuration + /// + bool ParseFromString(const std::string &obj_text, const std::string &mtl_text, + const ObjReaderConfig &config = ObjReaderConfig()); + + /// + /// .obj was loaded or parsed correctly. + /// + bool Valid() const { return valid_; } + + const attrib_t &GetAttrib() const { return attrib_; } + + const std::vector<shape_t> &GetShapes() const { return shapes_; } + + const std::vector<material_t> &GetMaterials() const { return materials_; } + + /// + /// Warning message(may be filled after `Load` or `Parse`) + /// + const std::string &Warning() const { return warning_; } + + /// + /// Error message(filled when `Load` or `Parse` failed) + /// + const std::string &Error() const { return error_; } + + private: + bool valid_; + + attrib_t attrib_; + std::vector<shape_t> shapes_; + std::vector<material_t> materials_; + + std::string warning_; + std::string error_; +}; + +/// ==>>========= Legacy v1 API ============================================= + +/// Loads .obj from a file. +/// 'attrib', 'shapes' and 'materials' will be filled with parsed shape data +/// 'shapes' will be filled with parsed shape data +/// Returns true when loading .obj become success. +/// Returns warning message into `warn`, and error message into `err` +/// 'mtl_basedir' is optional, and used for base directory for .mtl file. +/// In default(`NULL'), .mtl file is searched from an application's working +/// directory. +/// 'triangulate' is optional, and used whether triangulate polygon face in .obj +/// or not. +/// Option 'default_vcols_fallback' specifies whether vertex colors should +/// always be defined, even if no colors are given (fallback to white). +bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes, + std::vector<material_t> *materials, std::string *warn, + std::string *err, const char *filename, + const char *mtl_basedir = NULL, bool triangulate = true, + bool default_vcols_fallback = true); + +/// Loads .obj from a file with custom user callback. +/// .mtl is loaded as usual and parsed material_t data will be passed to +/// `callback.mtllib_cb`. +/// Returns true when loading .obj/.mtl become success. +/// Returns warning message into `warn`, and error message into `err` +/// See `examples/callback_api/` for how to use this function. +bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback, + void *user_data = NULL, + MaterialReader *readMatFn = NULL, + std::string *warn = NULL, std::string *err = NULL); + +/// Loads object from a std::istream, uses `readMatFn` to retrieve +/// std::istream for materials. +/// Returns true when loading .obj become success. +/// Returns warning and error message into `err` +bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes, + std::vector<material_t> *materials, std::string *warn, + std::string *err, std::istream *inStream, + MaterialReader *readMatFn = NULL, bool triangulate = true, + bool default_vcols_fallback = true); + +/// Loads materials into std::map +void LoadMtl(std::map<std::string, int> *material_map, + std::vector<material_t> *materials, std::istream *inStream, + std::string *warning, std::string *err); + +/// +/// Parse texture name and texture option for custom texture parameter through +/// material::unknown_parameter +/// +/// @param[out] texname Parsed texture name +/// @param[out] texopt Parsed texopt +/// @param[in] linebuf Input string +/// +bool ParseTextureNameAndOption(std::string *texname, texture_option_t *texopt, + const char *linebuf); + +/// =<<========== Legacy v1 API ============================================= + +} // namespace tinyobj + +#endif // TINY_OBJ_LOADER_H_ + +#ifdef TINYOBJLOADER_IMPLEMENTATION +#include <cassert> +#include <cctype> +#include <cmath> +#include <cstddef> +#include <cstdlib> +#include <cstring> +#include <fstream> +#include <limits> +#include <set> +#include <sstream> +#include <utility> + +#ifdef TINYOBJLOADER_USE_MAPBOX_EARCUT + +#ifdef TINYOBJLOADER_DONOT_INCLUDE_MAPBOX_EARCUT +// Assume earcut.hpp is included outside of tiny_obj_loader.h +#else + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Weverything" +#endif + +#include <array> +#include "mapbox/earcut.hpp" + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#endif + +#endif // TINYOBJLOADER_USE_MAPBOX_EARCUT + +namespace tinyobj { + +MaterialReader::~MaterialReader() {} + +struct vertex_index_t { + int v_idx, vt_idx, vn_idx; + vertex_index_t() : v_idx(-1), vt_idx(-1), vn_idx(-1) {} + explicit vertex_index_t(int idx) : v_idx(idx), vt_idx(idx), vn_idx(idx) {} + vertex_index_t(int vidx, int vtidx, int vnidx) + : v_idx(vidx), vt_idx(vtidx), vn_idx(vnidx) {} +}; + +// Internal data structure for face representation +// index + smoothing group. +struct face_t { + unsigned int + smoothing_group_id; // smoothing group id. 0 = smoothing groupd is off. + int pad_; + std::vector<vertex_index_t> vertex_indices; // face vertex indices. + + face_t() : smoothing_group_id(0), pad_(0) {} +}; + +// Internal data structure for line representation +struct __line_t { + // l v1/vt1 v2/vt2 ... + // In the specification, line primitrive does not have normal index, but + // TinyObjLoader allow it + std::vector<vertex_index_t> vertex_indices; +}; + +// Internal data structure for points representation +struct __points_t { + // p v1 v2 ... + // In the specification, point primitrive does not have normal index and + // texture coord index, but TinyObjLoader allow it. + std::vector<vertex_index_t> vertex_indices; +}; + +struct tag_sizes { + tag_sizes() : num_ints(0), num_reals(0), num_strings(0) {} + int num_ints; + int num_reals; + int num_strings; +}; + +struct obj_shape { + std::vector<real_t> v; + std::vector<real_t> vn; + std::vector<real_t> vt; +}; + +// +// Manages group of primitives(face, line, points, ...) +struct PrimGroup { + std::vector<face_t> faceGroup; + std::vector<__line_t> lineGroup; + std::vector<__points_t> pointsGroup; + + void clear() { + faceGroup.clear(); + lineGroup.clear(); + pointsGroup.clear(); + } + + bool IsEmpty() const { + return faceGroup.empty() && lineGroup.empty() && pointsGroup.empty(); + } + + // TODO(syoyo): bspline, surface, ... +}; + +// See +// http://stackoverflow.com/questions/6089231/getting-std-ifstream-to-handle-lf-cr-and-crlf +static std::istream &safeGetline(std::istream &is, std::string &t) { + t.clear(); + + // The characters in the stream are read one-by-one using a std::streambuf. + // That is faster than reading them one-by-one using the std::istream. + // Code that uses streambuf this way must be guarded by a sentry object. + // The sentry object performs various tasks, + // such as thread synchronization and updating the stream state. + + std::istream::sentry se(is, true); + std::streambuf *sb = is.rdbuf(); + + if (se) { + for (;;) { + int c = sb->sbumpc(); + switch (c) { + case '\n': + return is; + case '\r': + if (sb->sgetc() == '\n') sb->sbumpc(); + return is; + case EOF: + // Also handle the case when the last line has no line ending + if (t.empty()) is.setstate(std::ios::eofbit); + return is; + default: + t += static_cast<char>(c); + } + } + } + + return is; +} + +#define IS_SPACE(x) (((x) == ' ') || ((x) == '\t')) +#define IS_DIGIT(x) \ + (static_cast<unsigned int>((x) - '0') < static_cast<unsigned int>(10)) +#define IS_NEW_LINE(x) (((x) == '\r') || ((x) == '\n') || ((x) == '\0')) + +template <typename T> +static inline std::string toString(const T &t) { + std::stringstream ss; + ss << t; + return ss.str(); +} + +struct warning_context +{ + std::string *warn; + size_t line_number; +}; + +// Make index zero-base, and also support relative index. +static inline bool fixIndex(int idx, int n, int *ret, bool allow_zero, const warning_context &context) { + if (!ret) { + return false; + } + + if (idx > 0) { + (*ret) = idx - 1; + return true; + } + + if (idx == 0) { + // zero is not allowed according to the spec. + if (context.warn) { + (*context.warn) += "A zero value index found (will have a value of -1 for normal and tex indices. Line " + + toString(context.line_number) + ").\n"; + } + + (*ret) = idx - 1; + return allow_zero; + } + + if (idx < 0) { + (*ret) = n + idx; // negative value = relative + if((*ret) < 0){ + return false; // invalid relative index + } + return true; + } + + return false; // never reach here. +} + +static inline std::string parseString(const char **token) { + std::string s; + (*token) += strspn((*token), " \t"); + size_t e = strcspn((*token), " \t\r"); + s = std::string((*token), &(*token)[e]); + (*token) += e; + return s; +} + +static inline int parseInt(const char **token) { + (*token) += strspn((*token), " \t"); + int i = atoi((*token)); + (*token) += strcspn((*token), " \t\r"); + return i; +} + +// Tries to parse a floating point number located at s. +// +// s_end should be a location in the string where reading should absolutely +// stop. For example at the end of the string, to prevent buffer overflows. +// +// Parses the following EBNF grammar: +// sign = "+" | "-" ; +// END = ? anything not in digit ? +// digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ; +// integer = [sign] , digit , {digit} ; +// decimal = integer , ["." , integer] ; +// float = ( decimal , END ) | ( decimal , ("E" | "e") , integer , END ) ; +// +// Valid strings are for example: +// -0 +3.1417e+2 -0.0E-3 1.0324 -1.41 11e2 +// +// If the parsing is a success, result is set to the parsed value and true +// is returned. +// +// The function is greedy and will parse until any of the following happens: +// - a non-conforming character is encountered. +// - s_end is reached. +// +// The following situations triggers a failure: +// - s >= s_end. +// - parse failure. +// +static bool tryParseDouble(const char *s, const char *s_end, double *result) { + if (s >= s_end) { + return false; + } + + double mantissa = 0.0; + // This exponent is base 2 rather than 10. + // However the exponent we parse is supposed to be one of ten, + // thus we must take care to convert the exponent/and or the + // mantissa to a * 2^E, where a is the mantissa and E is the + // exponent. + // To get the final double we will use ldexp, it requires the + // exponent to be in base 2. + int exponent = 0; + + // NOTE: THESE MUST BE DECLARED HERE SINCE WE ARE NOT ALLOWED + // TO JUMP OVER DEFINITIONS. + char sign = '+'; + char exp_sign = '+'; + char const *curr = s; + + // How many characters were read in a loop. + int read = 0; + // Tells whether a loop terminated due to reaching s_end. + bool end_not_reached = false; + bool leading_decimal_dots = false; + + /* + BEGIN PARSING. + */ + + // Find out what sign we've got. + if (*curr == '+' || *curr == '-') { + sign = *curr; + curr++; + if ((curr != s_end) && (*curr == '.')) { + // accept. Somethig like `.7e+2`, `-.5234` + leading_decimal_dots = true; + } + } else if (IS_DIGIT(*curr)) { /* Pass through. */ + } else if (*curr == '.') { + // accept. Somethig like `.7e+2`, `-.5234` + leading_decimal_dots = true; + } else { + goto fail; + } + + // Read the integer part. + end_not_reached = (curr != s_end); + if (!leading_decimal_dots) { + while (end_not_reached && IS_DIGIT(*curr)) { + mantissa *= 10; + mantissa += static_cast<int>(*curr - 0x30); + curr++; + read++; + end_not_reached = (curr != s_end); + } + + // We must make sure we actually got something. + if (read == 0) goto fail; + } + + // We allow numbers of form "#", "###" etc. + if (!end_not_reached) goto assemble; + + // Read the decimal part. + if (*curr == '.') { + curr++; + read = 1; + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + static const double pow_lut[] = { + 1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001, + }; + const int lut_entries = sizeof pow_lut / sizeof pow_lut[0]; + + // NOTE: Don't use powf here, it will absolutely murder precision. + mantissa += static_cast<int>(*curr - 0x30) * + (read < lut_entries ? pow_lut[read] : std::pow(10.0, -read)); + read++; + curr++; + end_not_reached = (curr != s_end); + } + } else if (*curr == 'e' || *curr == 'E') { + } else { + goto assemble; + } + + if (!end_not_reached) goto assemble; + + // Read the exponent part. + if (*curr == 'e' || *curr == 'E') { + curr++; + // Figure out if a sign is present and if it is. + end_not_reached = (curr != s_end); + if (end_not_reached && (*curr == '+' || *curr == '-')) { + exp_sign = *curr; + curr++; + } else if (IS_DIGIT(*curr)) { /* Pass through. */ + } else { + // Empty E is not allowed. + goto fail; + } + + read = 0; + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + // To avoid annoying MSVC's min/max macro definiton, + // Use hardcoded int max value + if (exponent > (2147483647/10)) { // 2147483647 = std::numeric_limits<int>::max() + // Integer overflow + goto fail; + } + exponent *= 10; + exponent += static_cast<int>(*curr - 0x30); + curr++; + read++; + end_not_reached = (curr != s_end); + } + exponent *= (exp_sign == '+' ? 1 : -1); + if (read == 0) goto fail; + } + +assemble: + *result = (sign == '+' ? 1 : -1) * + (exponent ? std::ldexp(mantissa * std::pow(5.0, exponent), exponent) + : mantissa); + return true; +fail: + return false; +} + +static inline real_t parseReal(const char **token, double default_value = 0.0) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + double val = default_value; + tryParseDouble((*token), end, &val); + real_t f = static_cast<real_t>(val); + (*token) = end; + return f; +} + +static inline bool parseReal(const char **token, real_t *out) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + double val; + bool ret = tryParseDouble((*token), end, &val); + if (ret) { + real_t f = static_cast<real_t>(val); + (*out) = f; + } + (*token) = end; + return ret; +} + +static inline void parseReal2(real_t *x, real_t *y, const char **token, + const double default_x = 0.0, + const double default_y = 0.0) { + (*x) = parseReal(token, default_x); + (*y) = parseReal(token, default_y); +} + +static inline void parseReal3(real_t *x, real_t *y, real_t *z, + const char **token, const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + (*x) = parseReal(token, default_x); + (*y) = parseReal(token, default_y); + (*z) = parseReal(token, default_z); +} + +static inline void parseV(real_t *x, real_t *y, real_t *z, real_t *w, + const char **token, const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0, + const double default_w = 1.0) { + (*x) = parseReal(token, default_x); + (*y) = parseReal(token, default_y); + (*z) = parseReal(token, default_z); + (*w) = parseReal(token, default_w); +} + +// Extension: parse vertex with colors(6 items) +static inline bool parseVertexWithColor(real_t *x, real_t *y, real_t *z, + real_t *r, real_t *g, real_t *b, + const char **token, + const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + (*x) = parseReal(token, default_x); + (*y) = parseReal(token, default_y); + (*z) = parseReal(token, default_z); + + const bool found_color = + parseReal(token, r) && parseReal(token, g) && parseReal(token, b); + + if (!found_color) { + (*r) = (*g) = (*b) = 1.0; + } + + return found_color; +} + +static inline bool parseOnOff(const char **token, bool default_value = true) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + + bool ret = default_value; + if ((0 == strncmp((*token), "on", 2))) { + ret = true; + } else if ((0 == strncmp((*token), "off", 3))) { + ret = false; + } + + (*token) = end; + return ret; +} + +static inline texture_type_t parseTextureType( + const char **token, texture_type_t default_value = TEXTURE_TYPE_NONE) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + texture_type_t ty = default_value; + + if ((0 == strncmp((*token), "cube_top", strlen("cube_top")))) { + ty = TEXTURE_TYPE_CUBE_TOP; + } else if ((0 == strncmp((*token), "cube_bottom", strlen("cube_bottom")))) { + ty = TEXTURE_TYPE_CUBE_BOTTOM; + } else if ((0 == strncmp((*token), "cube_left", strlen("cube_left")))) { + ty = TEXTURE_TYPE_CUBE_LEFT; + } else if ((0 == strncmp((*token), "cube_right", strlen("cube_right")))) { + ty = TEXTURE_TYPE_CUBE_RIGHT; + } else if ((0 == strncmp((*token), "cube_front", strlen("cube_front")))) { + ty = TEXTURE_TYPE_CUBE_FRONT; + } else if ((0 == strncmp((*token), "cube_back", strlen("cube_back")))) { + ty = TEXTURE_TYPE_CUBE_BACK; + } else if ((0 == strncmp((*token), "sphere", strlen("sphere")))) { + ty = TEXTURE_TYPE_SPHERE; + } + + (*token) = end; + return ty; +} + +static tag_sizes parseTagTriple(const char **token) { + tag_sizes ts; + + (*token) += strspn((*token), " \t"); + ts.num_ints = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return ts; + } + + (*token)++; // Skip '/' + + (*token) += strspn((*token), " \t"); + ts.num_reals = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return ts; + } + (*token)++; // Skip '/' + + ts.num_strings = parseInt(token); + + return ts; +} + +// Parse triples with index offsets: i, i/j/k, i//k, i/j +static bool parseTriple(const char **token, int vsize, int vnsize, int vtsize, + vertex_index_t *ret, const warning_context &context) { + if (!ret) { + return false; + } + + vertex_index_t vi(-1); + + if (!fixIndex(atoi((*token)), vsize, &vi.v_idx, false, context)) { + return false; + } + + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + (*ret) = vi; + return true; + } + (*token)++; + + // i//k + if ((*token)[0] == '/') { + (*token)++; + if (!fixIndex(atoi((*token)), vnsize, &vi.vn_idx, true, context)) { + return false; + } + (*token) += strcspn((*token), "/ \t\r"); + (*ret) = vi; + return true; + } + + // i/j/k or i/j + if (!fixIndex(atoi((*token)), vtsize, &vi.vt_idx, true, context)) { + return false; + } + + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + (*ret) = vi; + return true; + } + + // i/j/k + (*token)++; // skip '/' + if (!fixIndex(atoi((*token)), vnsize, &vi.vn_idx, true, context)) { + return false; + } + (*token) += strcspn((*token), "/ \t\r"); + + (*ret) = vi; + + return true; +} + +// Parse raw triples: i, i/j/k, i//k, i/j +static vertex_index_t parseRawTriple(const char **token) { + vertex_index_t vi(static_cast<int>(0)); // 0 is an invalid index in OBJ + + vi.v_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + (*token)++; + + // i//k + if ((*token)[0] == '/') { + (*token)++; + vi.vn_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + return vi; + } + + // i/j/k or i/j + vi.vt_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + + // i/j/k + (*token)++; // skip '/' + vi.vn_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + return vi; +} + +bool ParseTextureNameAndOption(std::string *texname, texture_option_t *texopt, + const char *linebuf) { + // @todo { write more robust lexer and parser. } + bool found_texname = false; + std::string texture_name; + + const char *token = linebuf; // Assume line ends with NULL + + while (!IS_NEW_LINE((*token))) { + token += strspn(token, " \t"); // skip space + if ((0 == strncmp(token, "-blendu", 7)) && IS_SPACE((token[7]))) { + token += 8; + texopt->blendu = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-blendv", 7)) && IS_SPACE((token[7]))) { + token += 8; + texopt->blendv = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-clamp", 6)) && IS_SPACE((token[6]))) { + token += 7; + texopt->clamp = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-boost", 6)) && IS_SPACE((token[6]))) { + token += 7; + texopt->sharpness = parseReal(&token, 1.0); + } else if ((0 == strncmp(token, "-bm", 3)) && IS_SPACE((token[3]))) { + token += 4; + texopt->bump_multiplier = parseReal(&token, 1.0); + } else if ((0 == strncmp(token, "-o", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseReal3(&(texopt->origin_offset[0]), &(texopt->origin_offset[1]), + &(texopt->origin_offset[2]), &token); + } else if ((0 == strncmp(token, "-s", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseReal3(&(texopt->scale[0]), &(texopt->scale[1]), &(texopt->scale[2]), + &token, 1.0, 1.0, 1.0); + } else if ((0 == strncmp(token, "-t", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseReal3(&(texopt->turbulence[0]), &(texopt->turbulence[1]), + &(texopt->turbulence[2]), &token); + } else if ((0 == strncmp(token, "-type", 5)) && IS_SPACE((token[5]))) { + token += 5; + texopt->type = parseTextureType((&token), TEXTURE_TYPE_NONE); + } else if ((0 == strncmp(token, "-texres", 7)) && IS_SPACE((token[7]))) { + token += 7; + // TODO(syoyo): Check if arg is int type. + texopt->texture_resolution = parseInt(&token); + } else if ((0 == strncmp(token, "-imfchan", 8)) && IS_SPACE((token[8]))) { + token += 9; + token += strspn(token, " \t"); + const char *end = token + strcspn(token, " \t\r"); + if ((end - token) == 1) { // Assume one char for -imfchan + texopt->imfchan = (*token); + } + token = end; + } else if ((0 == strncmp(token, "-mm", 3)) && IS_SPACE((token[3]))) { + token += 4; + parseReal2(&(texopt->brightness), &(texopt->contrast), &token, 0.0, 1.0); + } else if ((0 == strncmp(token, "-colorspace", 11)) && + IS_SPACE((token[11]))) { + token += 12; + texopt->colorspace = parseString(&token); + } else { +// Assume texture filename +#if 0 + size_t len = strcspn(token, " \t\r"); // untile next space + texture_name = std::string(token, token + len); + token += len; + + token += strspn(token, " \t"); // skip space +#else + // Read filename until line end to parse filename containing whitespace + // TODO(syoyo): Support parsing texture option flag after the filename. + texture_name = std::string(token); + token += texture_name.length(); +#endif + + found_texname = true; + } + } + + if (found_texname) { + (*texname) = texture_name; + return true; + } else { + return false; + } +} + +static void InitTexOpt(texture_option_t *texopt, const bool is_bump) { + if (is_bump) { + texopt->imfchan = 'l'; + } else { + texopt->imfchan = 'm'; + } + texopt->bump_multiplier = static_cast<real_t>(1.0); + texopt->clamp = false; + texopt->blendu = true; + texopt->blendv = true; + texopt->sharpness = static_cast<real_t>(1.0); + texopt->brightness = static_cast<real_t>(0.0); + texopt->contrast = static_cast<real_t>(1.0); + texopt->origin_offset[0] = static_cast<real_t>(0.0); + texopt->origin_offset[1] = static_cast<real_t>(0.0); + texopt->origin_offset[2] = static_cast<real_t>(0.0); + texopt->scale[0] = static_cast<real_t>(1.0); + texopt->scale[1] = static_cast<real_t>(1.0); + texopt->scale[2] = static_cast<real_t>(1.0); + texopt->turbulence[0] = static_cast<real_t>(0.0); + texopt->turbulence[1] = static_cast<real_t>(0.0); + texopt->turbulence[2] = static_cast<real_t>(0.0); + texopt->texture_resolution = -1; + texopt->type = TEXTURE_TYPE_NONE; +} + +static void InitMaterial(material_t *material) { + InitTexOpt(&material->ambient_texopt, /* is_bump */ false); + InitTexOpt(&material->diffuse_texopt, /* is_bump */ false); + InitTexOpt(&material->specular_texopt, /* is_bump */ false); + InitTexOpt(&material->specular_highlight_texopt, /* is_bump */ false); + InitTexOpt(&material->bump_texopt, /* is_bump */ true); + InitTexOpt(&material->displacement_texopt, /* is_bump */ false); + InitTexOpt(&material->alpha_texopt, /* is_bump */ false); + InitTexOpt(&material->reflection_texopt, /* is_bump */ false); + InitTexOpt(&material->roughness_texopt, /* is_bump */ false); + InitTexOpt(&material->metallic_texopt, /* is_bump */ false); + InitTexOpt(&material->sheen_texopt, /* is_bump */ false); + InitTexOpt(&material->emissive_texopt, /* is_bump */ false); + InitTexOpt(&material->normal_texopt, + /* is_bump */ false); // @fixme { is_bump will be true? } + material->name = ""; + material->ambient_texname = ""; + material->diffuse_texname = ""; + material->specular_texname = ""; + material->specular_highlight_texname = ""; + material->bump_texname = ""; + material->displacement_texname = ""; + material->reflection_texname = ""; + material->alpha_texname = ""; + for (int i = 0; i < 3; i++) { + material->ambient[i] = static_cast<real_t>(0.0); + material->diffuse[i] = static_cast<real_t>(0.0); + material->specular[i] = static_cast<real_t>(0.0); + material->transmittance[i] = static_cast<real_t>(0.0); + material->emission[i] = static_cast<real_t>(0.0); + } + material->illum = 0; + material->dissolve = static_cast<real_t>(1.0); + material->shininess = static_cast<real_t>(1.0); + material->ior = static_cast<real_t>(1.0); + + material->roughness = static_cast<real_t>(0.0); + material->metallic = static_cast<real_t>(0.0); + material->sheen = static_cast<real_t>(0.0); + material->clearcoat_thickness = static_cast<real_t>(0.0); + material->clearcoat_roughness = static_cast<real_t>(0.0); + material->anisotropy_rotation = static_cast<real_t>(0.0); + material->anisotropy = static_cast<real_t>(0.0); + material->roughness_texname = ""; + material->metallic_texname = ""; + material->sheen_texname = ""; + material->emissive_texname = ""; + material->normal_texname = ""; + + material->unknown_parameter.clear(); +} + +// code from https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html +template <typename T> +static int pnpoly(int nvert, T *vertx, T *verty, T testx, T testy) { + int i, j, c = 0; + for (i = 0, j = nvert - 1; i < nvert; j = i++) { + if (((verty[i] > testy) != (verty[j] > testy)) && + (testx < + (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + + vertx[i])) + c = !c; + } + return c; +} + +struct TinyObjPoint { + real_t x, y, z; + TinyObjPoint() : x(0), y(0), z(0) {} + TinyObjPoint(real_t x_, real_t y_, real_t z_) : + x(x_), y(y_), z(z_) {} +}; + +inline TinyObjPoint cross(const TinyObjPoint &v1, const TinyObjPoint &v2) { + return TinyObjPoint(v1.y * v2.z - v1.z * v2.y, + v1.z * v2.x - v1.x * v2.z, + v1.x * v2.y - v1.y * v2.x); +} + +inline real_t dot(const TinyObjPoint &v1, const TinyObjPoint &v2) { + return (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z); +} + +inline real_t GetLength(TinyObjPoint &e) { + return std::sqrt(e.x*e.x + e.y*e.y + e.z*e.z); +} + +inline TinyObjPoint Normalize(TinyObjPoint e) { + real_t inv_length = real_t(1) / GetLength(e); + return TinyObjPoint(e.x * inv_length, e.y * inv_length, e.z * inv_length ); +} + + +inline TinyObjPoint WorldToLocal(const TinyObjPoint& a, + const TinyObjPoint& u, + const TinyObjPoint& v, + const TinyObjPoint& w) { + return TinyObjPoint(dot(a,u),dot(a,v),dot(a,w)); +} + + +// TODO(syoyo): refactor function. +static bool exportGroupsToShape(shape_t *shape, const PrimGroup &prim_group, + const std::vector<tag_t> &tags, + const int material_id, const std::string &name, + bool triangulate, const std::vector<real_t> &v, + std::string *warn) { + if (prim_group.IsEmpty()) { + return false; + } + + shape->name = name; + + // polygon + if (!prim_group.faceGroup.empty()) { + // Flatten vertices and indices + for (size_t i = 0; i < prim_group.faceGroup.size(); i++) { + const face_t &face = prim_group.faceGroup[i]; + + size_t npolys = face.vertex_indices.size(); + + if (npolys < 3) { + // Face must have 3+ vertices. + if (warn) { + (*warn) += "Degenerated face found\n."; + } + continue; + } + + if (triangulate && npolys != 3) { + if (npolys == 4) { + vertex_index_t i0 = face.vertex_indices[0]; + vertex_index_t i1 = face.vertex_indices[1]; + vertex_index_t i2 = face.vertex_indices[2]; + vertex_index_t i3 = face.vertex_indices[3]; + + size_t vi0 = size_t(i0.v_idx); + size_t vi1 = size_t(i1.v_idx); + size_t vi2 = size_t(i2.v_idx); + size_t vi3 = size_t(i3.v_idx); + + if (((3 * vi0 + 2) >= v.size()) || ((3 * vi1 + 2) >= v.size()) || + ((3 * vi2 + 2) >= v.size()) || ((3 * vi3 + 2) >= v.size())) { + // Invalid triangle. + // FIXME(syoyo): Is it ok to simply skip this invalid triangle? + if (warn) { + (*warn) += "Face with invalid vertex index found.\n"; + } + continue; + } + + real_t v0x = v[vi0 * 3 + 0]; + real_t v0y = v[vi0 * 3 + 1]; + real_t v0z = v[vi0 * 3 + 2]; + real_t v1x = v[vi1 * 3 + 0]; + real_t v1y = v[vi1 * 3 + 1]; + real_t v1z = v[vi1 * 3 + 2]; + real_t v2x = v[vi2 * 3 + 0]; + real_t v2y = v[vi2 * 3 + 1]; + real_t v2z = v[vi2 * 3 + 2]; + real_t v3x = v[vi3 * 3 + 0]; + real_t v3y = v[vi3 * 3 + 1]; + real_t v3z = v[vi3 * 3 + 2]; + + // There are two candidates to split the quad into two triangles. + // + // Choose the shortest edge. + // TODO: Is it better to determine the edge to split by calculating + // the area of each triangle? + // + // +---+ + // |\ | + // | \ | + // | \| + // +---+ + // + // +---+ + // | /| + // | / | + // |/ | + // +---+ + + real_t e02x = v2x - v0x; + real_t e02y = v2y - v0y; + real_t e02z = v2z - v0z; + real_t e13x = v3x - v1x; + real_t e13y = v3y - v1y; + real_t e13z = v3z - v1z; + + real_t sqr02 = e02x * e02x + e02y * e02y + e02z * e02z; + real_t sqr13 = e13x * e13x + e13y * e13y + e13z * e13z; + + index_t idx0, idx1, idx2, idx3; + + idx0.vertex_index = i0.v_idx; + idx0.normal_index = i0.vn_idx; + idx0.texcoord_index = i0.vt_idx; + idx1.vertex_index = i1.v_idx; + idx1.normal_index = i1.vn_idx; + idx1.texcoord_index = i1.vt_idx; + idx2.vertex_index = i2.v_idx; + idx2.normal_index = i2.vn_idx; + idx2.texcoord_index = i2.vt_idx; + idx3.vertex_index = i3.v_idx; + idx3.normal_index = i3.vn_idx; + idx3.texcoord_index = i3.vt_idx; + + if (sqr02 < sqr13) { + // [0, 1, 2], [0, 2, 3] + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx2); + shape->mesh.indices.push_back(idx3); + } else { + // [0, 1, 3], [1, 2, 3] + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx3); + + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + shape->mesh.indices.push_back(idx3); + } + + // Two triangle faces + shape->mesh.num_face_vertices.push_back(3); + shape->mesh.num_face_vertices.push_back(3); + + shape->mesh.material_ids.push_back(material_id); + shape->mesh.material_ids.push_back(material_id); + + shape->mesh.smoothing_group_ids.push_back(face.smoothing_group_id); + shape->mesh.smoothing_group_ids.push_back(face.smoothing_group_id); + + } else { +#ifdef TINYOBJLOADER_USE_MAPBOX_EARCUT + vertex_index_t i0 = face.vertex_indices[0]; + vertex_index_t i0_2 = i0; + + // TMW change: Find the normal axis of the polygon using Newell's method + TinyObjPoint n; + for (size_t k = 0; k < npolys; ++k) { + i0 = face.vertex_indices[k % npolys]; + size_t vi0 = size_t(i0.v_idx); + + size_t j = (k + 1) % npolys; + i0_2 = face.vertex_indices[j]; + size_t vi0_2 = size_t(i0_2.v_idx); + + real_t v0x = v[vi0 * 3 + 0]; + real_t v0y = v[vi0 * 3 + 1]; + real_t v0z = v[vi0 * 3 + 2]; + + real_t v0x_2 = v[vi0_2 * 3 + 0]; + real_t v0y_2 = v[vi0_2 * 3 + 1]; + real_t v0z_2 = v[vi0_2 * 3 + 2]; + + const TinyObjPoint point1(v0x,v0y,v0z); + const TinyObjPoint point2(v0x_2,v0y_2,v0z_2); + + TinyObjPoint a(point1.x - point2.x, point1.y - point2.y, point1.z - point2.z); + TinyObjPoint b(point1.x + point2.x, point1.y + point2.y, point1.z + point2.z); + + n.x += (a.y * b.z); + n.y += (a.z * b.x); + n.z += (a.x * b.y); + } + real_t length_n = GetLength(n); + //Check if zero length normal + if(length_n <= 0) { + continue; + } + //Negative is to flip the normal to the correct direction + real_t inv_length = -real_t(1.0) / length_n; + n.x *= inv_length; + n.y *= inv_length; + n.z *= inv_length; + + TinyObjPoint axis_w, axis_v, axis_u; + axis_w = n; + TinyObjPoint a; + if(std::abs(axis_w.x) > real_t(0.9999999)) { + a = TinyObjPoint(0,1,0); + } else { + a = TinyObjPoint(1,0,0); + } + axis_v = Normalize(cross(axis_w, a)); + axis_u = cross(axis_w, axis_v); + using Point = std::array<real_t, 2>; + + // first polyline define the main polygon. + // following polylines define holes(not used in tinyobj). + std::vector<std::vector<Point> > polygon; + + std::vector<Point> polyline; + + //TMW change: Find best normal and project v0x and v0y to those coordinates, instead of + //picking a plane aligned with an axis (which can flip polygons). + + // Fill polygon data(facevarying vertices). + for (size_t k = 0; k < npolys; k++) { + i0 = face.vertex_indices[k]; + size_t vi0 = size_t(i0.v_idx); + + assert(((3 * vi0 + 2) < v.size())); + + real_t v0x = v[vi0 * 3 + 0]; + real_t v0y = v[vi0 * 3 + 1]; + real_t v0z = v[vi0 * 3 + 2]; + + TinyObjPoint polypoint(v0x,v0y,v0z); + TinyObjPoint loc = WorldToLocal(polypoint, axis_u, axis_v, axis_w); + + polyline.push_back({loc.x, loc.y}); + } + + polygon.push_back(polyline); + std::vector<uint32_t> indices = mapbox::earcut<uint32_t>(polygon); + // => result = 3 * faces, clockwise + + assert(indices.size() % 3 == 0); + + // Reconstruct vertex_index_t + for (size_t k = 0; k < indices.size() / 3; k++) { + { + index_t idx0, idx1, idx2; + idx0.vertex_index = face.vertex_indices[indices[3 * k + 0]].v_idx; + idx0.normal_index = + face.vertex_indices[indices[3 * k + 0]].vn_idx; + idx0.texcoord_index = + face.vertex_indices[indices[3 * k + 0]].vt_idx; + idx1.vertex_index = face.vertex_indices[indices[3 * k + 1]].v_idx; + idx1.normal_index = + face.vertex_indices[indices[3 * k + 1]].vn_idx; + idx1.texcoord_index = + face.vertex_indices[indices[3 * k + 1]].vt_idx; + idx2.vertex_index = face.vertex_indices[indices[3 * k + 2]].v_idx; + idx2.normal_index = + face.vertex_indices[indices[3 * k + 2]].vn_idx; + idx2.texcoord_index = + face.vertex_indices[indices[3 * k + 2]].vt_idx; + + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + + shape->mesh.num_face_vertices.push_back(3); + shape->mesh.material_ids.push_back(material_id); + shape->mesh.smoothing_group_ids.push_back( + face.smoothing_group_id); + } + } + +#else // Built-in ear clipping triangulation + vertex_index_t i0 = face.vertex_indices[0]; + vertex_index_t i1(-1); + vertex_index_t i2 = face.vertex_indices[1]; + + // find the two axes to work in + size_t axes[2] = {1, 2}; + for (size_t k = 0; k < npolys; ++k) { + i0 = face.vertex_indices[(k + 0) % npolys]; + i1 = face.vertex_indices[(k + 1) % npolys]; + i2 = face.vertex_indices[(k + 2) % npolys]; + size_t vi0 = size_t(i0.v_idx); + size_t vi1 = size_t(i1.v_idx); + size_t vi2 = size_t(i2.v_idx); + + if (((3 * vi0 + 2) >= v.size()) || ((3 * vi1 + 2) >= v.size()) || + ((3 * vi2 + 2) >= v.size())) { + // Invalid triangle. + // FIXME(syoyo): Is it ok to simply skip this invalid triangle? + continue; + } + real_t v0x = v[vi0 * 3 + 0]; + real_t v0y = v[vi0 * 3 + 1]; + real_t v0z = v[vi0 * 3 + 2]; + real_t v1x = v[vi1 * 3 + 0]; + real_t v1y = v[vi1 * 3 + 1]; + real_t v1z = v[vi1 * 3 + 2]; + real_t v2x = v[vi2 * 3 + 0]; + real_t v2y = v[vi2 * 3 + 1]; + real_t v2z = v[vi2 * 3 + 2]; + real_t e0x = v1x - v0x; + real_t e0y = v1y - v0y; + real_t e0z = v1z - v0z; + real_t e1x = v2x - v1x; + real_t e1y = v2y - v1y; + real_t e1z = v2z - v1z; + real_t cx = std::fabs(e0y * e1z - e0z * e1y); + real_t cy = std::fabs(e0z * e1x - e0x * e1z); + real_t cz = std::fabs(e0x * e1y - e0y * e1x); + const real_t epsilon = std::numeric_limits<real_t>::epsilon(); + // std::cout << "cx " << cx << ", cy " << cy << ", cz " << cz << + // "\n"; + if (cx > epsilon || cy > epsilon || cz > epsilon) { + // std::cout << "corner\n"; + // found a corner + if (cx > cy && cx > cz) { + // std::cout << "pattern0\n"; + } else { + // std::cout << "axes[0] = 0\n"; + axes[0] = 0; + if (cz > cx && cz > cy) { + // std::cout << "axes[1] = 1\n"; + axes[1] = 1; + } + } + break; + } + } + + face_t remainingFace = face; // copy + size_t guess_vert = 0; + vertex_index_t ind[3]; + real_t vx[3]; + real_t vy[3]; + + // How many iterations can we do without decreasing the remaining + // vertices. + size_t remainingIterations = face.vertex_indices.size(); + size_t previousRemainingVertices = + remainingFace.vertex_indices.size(); + + while (remainingFace.vertex_indices.size() > 3 && + remainingIterations > 0) { + // std::cout << "remainingIterations " << remainingIterations << + // "\n"; + + npolys = remainingFace.vertex_indices.size(); + if (guess_vert >= npolys) { + guess_vert -= npolys; + } + + if (previousRemainingVertices != npolys) { + // The number of remaining vertices decreased. Reset counters. + previousRemainingVertices = npolys; + remainingIterations = npolys; + } else { + // We didn't consume a vertex on previous iteration, reduce the + // available iterations. + remainingIterations--; + } + + for (size_t k = 0; k < 3; k++) { + ind[k] = remainingFace.vertex_indices[(guess_vert + k) % npolys]; + size_t vi = size_t(ind[k].v_idx); + if (((vi * 3 + axes[0]) >= v.size()) || + ((vi * 3 + axes[1]) >= v.size())) { + // ??? + vx[k] = static_cast<real_t>(0.0); + vy[k] = static_cast<real_t>(0.0); + } else { + vx[k] = v[vi * 3 + axes[0]]; + vy[k] = v[vi * 3 + axes[1]]; + } + } + + // + // area is calculated per face + // + real_t e0x = vx[1] - vx[0]; + real_t e0y = vy[1] - vy[0]; + real_t e1x = vx[2] - vx[1]; + real_t e1y = vy[2] - vy[1]; + real_t cross = e0x * e1y - e0y * e1x; + // std::cout << "axes = " << axes[0] << ", " << axes[1] << "\n"; + // std::cout << "e0x, e0y, e1x, e1y " << e0x << ", " << e0y << ", " + // << e1x << ", " << e1y << "\n"; + + real_t area = (vx[0] * vy[1] - vy[0] * vx[1]) * static_cast<real_t>(0.5); + // std::cout << "cross " << cross << ", area " << area << "\n"; + // if an internal angle + if (cross * area < static_cast<real_t>(0.0)) { + // std::cout << "internal \n"; + guess_vert += 1; + // std::cout << "guess vert : " << guess_vert << "\n"; + continue; + } + + // check all other verts in case they are inside this triangle + bool overlap = false; + for (size_t otherVert = 3; otherVert < npolys; ++otherVert) { + size_t idx = (guess_vert + otherVert) % npolys; + + if (idx >= remainingFace.vertex_indices.size()) { + // std::cout << "???0\n"; + // ??? + continue; + } + + size_t ovi = size_t(remainingFace.vertex_indices[idx].v_idx); + + if (((ovi * 3 + axes[0]) >= v.size()) || + ((ovi * 3 + axes[1]) >= v.size())) { + // std::cout << "???1\n"; + // ??? + continue; + } + real_t tx = v[ovi * 3 + axes[0]]; + real_t ty = v[ovi * 3 + axes[1]]; + if (pnpoly(3, vx, vy, tx, ty)) { + // std::cout << "overlap\n"; + overlap = true; + break; + } + } + + if (overlap) { + // std::cout << "overlap2\n"; + guess_vert += 1; + continue; + } + + // this triangle is an ear + { + index_t idx0, idx1, idx2; + idx0.vertex_index = ind[0].v_idx; + idx0.normal_index = ind[0].vn_idx; + idx0.texcoord_index = ind[0].vt_idx; + idx1.vertex_index = ind[1].v_idx; + idx1.normal_index = ind[1].vn_idx; + idx1.texcoord_index = ind[1].vt_idx; + idx2.vertex_index = ind[2].v_idx; + idx2.normal_index = ind[2].vn_idx; + idx2.texcoord_index = ind[2].vt_idx; + + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + + shape->mesh.num_face_vertices.push_back(3); + shape->mesh.material_ids.push_back(material_id); + shape->mesh.smoothing_group_ids.push_back( + face.smoothing_group_id); + } + + // remove v1 from the list + size_t removed_vert_index = (guess_vert + 1) % npolys; + while (removed_vert_index + 1 < npolys) { + remainingFace.vertex_indices[removed_vert_index] = + remainingFace.vertex_indices[removed_vert_index + 1]; + removed_vert_index += 1; + } + remainingFace.vertex_indices.pop_back(); + } + + // std::cout << "remainingFace.vi.size = " << + // remainingFace.vertex_indices.size() << "\n"; + if (remainingFace.vertex_indices.size() == 3) { + i0 = remainingFace.vertex_indices[0]; + i1 = remainingFace.vertex_indices[1]; + i2 = remainingFace.vertex_indices[2]; + { + index_t idx0, idx1, idx2; + idx0.vertex_index = i0.v_idx; + idx0.normal_index = i0.vn_idx; + idx0.texcoord_index = i0.vt_idx; + idx1.vertex_index = i1.v_idx; + idx1.normal_index = i1.vn_idx; + idx1.texcoord_index = i1.vt_idx; + idx2.vertex_index = i2.v_idx; + idx2.normal_index = i2.vn_idx; + idx2.texcoord_index = i2.vt_idx; + + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + + shape->mesh.num_face_vertices.push_back(3); + shape->mesh.material_ids.push_back(material_id); + shape->mesh.smoothing_group_ids.push_back( + face.smoothing_group_id); + } + } +#endif + } // npolys + } else { + for (size_t k = 0; k < npolys; k++) { + index_t idx; + idx.vertex_index = face.vertex_indices[k].v_idx; + idx.normal_index = face.vertex_indices[k].vn_idx; + idx.texcoord_index = face.vertex_indices[k].vt_idx; + shape->mesh.indices.push_back(idx); + } + + shape->mesh.num_face_vertices.push_back( + static_cast<unsigned char>(npolys)); + shape->mesh.material_ids.push_back(material_id); // per face + shape->mesh.smoothing_group_ids.push_back( + face.smoothing_group_id); // per face + } + } + + shape->mesh.tags = tags; + } + + // line + if (!prim_group.lineGroup.empty()) { + // Flatten indices + for (size_t i = 0; i < prim_group.lineGroup.size(); i++) { + for (size_t j = 0; j < prim_group.lineGroup[i].vertex_indices.size(); + j++) { + const vertex_index_t &vi = prim_group.lineGroup[i].vertex_indices[j]; + + index_t idx; + idx.vertex_index = vi.v_idx; + idx.normal_index = vi.vn_idx; + idx.texcoord_index = vi.vt_idx; + + shape->lines.indices.push_back(idx); + } + + shape->lines.num_line_vertices.push_back( + int(prim_group.lineGroup[i].vertex_indices.size())); + } + } + + // points + if (!prim_group.pointsGroup.empty()) { + // Flatten & convert indices + for (size_t i = 0; i < prim_group.pointsGroup.size(); i++) { + for (size_t j = 0; j < prim_group.pointsGroup[i].vertex_indices.size(); + j++) { + const vertex_index_t &vi = prim_group.pointsGroup[i].vertex_indices[j]; + + index_t idx; + idx.vertex_index = vi.v_idx; + idx.normal_index = vi.vn_idx; + idx.texcoord_index = vi.vt_idx; + + shape->points.indices.push_back(idx); + } + } + } + + return true; +} + +// Split a string with specified delimiter character and escape character. +// https://rosettacode.org/wiki/Tokenize_a_string_with_escaping#C.2B.2B +static void SplitString(const std::string &s, char delim, char escape, + std::vector<std::string> &elems) { + std::string token; + + bool escaping = false; + for (size_t i = 0; i < s.size(); ++i) { + char ch = s[i]; + if (escaping) { + escaping = false; + } else if (ch == escape) { + escaping = true; + continue; + } else if (ch == delim) { + if (!token.empty()) { + elems.push_back(token); + } + token.clear(); + continue; + } + token += ch; + } + + elems.push_back(token); +} + +static std::string JoinPath(const std::string &dir, + const std::string &filename) { + if (dir.empty()) { + return filename; + } else { + // check '/' + char lastChar = *dir.rbegin(); + if (lastChar != '/') { + return dir + std::string("/") + filename; + } else { + return dir + filename; + } + } +} + +void LoadMtl(std::map<std::string, int> *material_map, + std::vector<material_t> *materials, std::istream *inStream, + std::string *warning, std::string *err) { + (void)err; + + // Create a default material anyway. + material_t material; + InitMaterial(&material); + + // Issue 43. `d` wins against `Tr` since `Tr` is not in the MTL specification. + bool has_d = false; + bool has_tr = false; + + // has_kd is used to set a default diffuse value when map_Kd is present + // and Kd is not. + bool has_kd = false; + + std::stringstream warn_ss; + + size_t line_no = 0; + std::string linebuf; + while (inStream->peek() != -1) { + safeGetline(*inStream, linebuf); + line_no++; + + // Trim trailing whitespace. + if (linebuf.size() > 0) { + linebuf = linebuf.substr(0, linebuf.find_last_not_of(" \t") + 1); + } + + // Trim newline '\r\n' or '\n' + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\n') + linebuf.erase(linebuf.size() - 1); + } + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\r') + linebuf.erase(linebuf.size() - 1); + } + + // Skip if empty line. + if (linebuf.empty()) { + continue; + } + + // Skip leading space. + const char *token = linebuf.c_str(); + token += strspn(token, " \t"); + + assert(token); + if (token[0] == '\0') continue; // empty line + + if (token[0] == '#') continue; // comment line + + // new mtl + if ((0 == strncmp(token, "newmtl", 6)) && IS_SPACE((token[6]))) { + // flush previous material. + if (!material.name.empty()) { + material_map->insert(std::pair<std::string, int>( + material.name, static_cast<int>(materials->size()))); + materials->push_back(material); + } + + // initial temporary material + InitMaterial(&material); + + has_d = false; + has_tr = false; + + // set new mtl name + token += 7; + { + std::string namebuf = parseString(&token); + // TODO: empty name check? + if (namebuf.empty()) { + if (warning) { + (*warning) += "empty material name in `newmtl`\n"; + } + } + material.name = namebuf; + } + continue; + } + + // ambient + if (token[0] == 'K' && token[1] == 'a' && IS_SPACE((token[2]))) { + token += 2; + real_t r, g, b; + parseReal3(&r, &g, &b, &token); + material.ambient[0] = r; + material.ambient[1] = g; + material.ambient[2] = b; + continue; + } + + // diffuse + if (token[0] == 'K' && token[1] == 'd' && IS_SPACE((token[2]))) { + token += 2; + real_t r, g, b; + parseReal3(&r, &g, &b, &token); + material.diffuse[0] = r; + material.diffuse[1] = g; + material.diffuse[2] = b; + has_kd = true; + continue; + } + + // specular + if (token[0] == 'K' && token[1] == 's' && IS_SPACE((token[2]))) { + token += 2; + real_t r, g, b; + parseReal3(&r, &g, &b, &token); + material.specular[0] = r; + material.specular[1] = g; + material.specular[2] = b; + continue; + } + + // transmittance + if ((token[0] == 'K' && token[1] == 't' && IS_SPACE((token[2]))) || + (token[0] == 'T' && token[1] == 'f' && IS_SPACE((token[2])))) { + token += 2; + real_t r, g, b; + parseReal3(&r, &g, &b, &token); + material.transmittance[0] = r; + material.transmittance[1] = g; + material.transmittance[2] = b; + continue; + } + + // ior(index of refraction) + if (token[0] == 'N' && token[1] == 'i' && IS_SPACE((token[2]))) { + token += 2; + material.ior = parseReal(&token); + continue; + } + + // emission + if (token[0] == 'K' && token[1] == 'e' && IS_SPACE(token[2])) { + token += 2; + real_t r, g, b; + parseReal3(&r, &g, &b, &token); + material.emission[0] = r; + material.emission[1] = g; + material.emission[2] = b; + continue; + } + + // shininess + if (token[0] == 'N' && token[1] == 's' && IS_SPACE(token[2])) { + token += 2; + material.shininess = parseReal(&token); + continue; + } + + // illum model + if (0 == strncmp(token, "illum", 5) && IS_SPACE(token[5])) { + token += 6; + material.illum = parseInt(&token); + continue; + } + + // dissolve + if ((token[0] == 'd' && IS_SPACE(token[1]))) { + token += 1; + material.dissolve = parseReal(&token); + + if (has_tr) { + warn_ss << "Both `d` and `Tr` parameters defined for \"" + << material.name + << "\". Use the value of `d` for dissolve (line " << line_no + << " in .mtl.)\n"; + } + has_d = true; + continue; + } + if (token[0] == 'T' && token[1] == 'r' && IS_SPACE(token[2])) { + token += 2; + if (has_d) { + // `d` wins. Ignore `Tr` value. + warn_ss << "Both `d` and `Tr` parameters defined for \"" + << material.name + << "\". Use the value of `d` for dissolve (line " << line_no + << " in .mtl.)\n"; + } else { + // We invert value of Tr(assume Tr is in range [0, 1]) + // NOTE: Interpretation of Tr is application(exporter) dependent. For + // some application(e.g. 3ds max obj exporter), Tr = d(Issue 43) + material.dissolve = static_cast<real_t>(1.0) - parseReal(&token); + } + has_tr = true; + continue; + } + + // PBR: roughness + if (token[0] == 'P' && token[1] == 'r' && IS_SPACE(token[2])) { + token += 2; + material.roughness = parseReal(&token); + continue; + } + + // PBR: metallic + if (token[0] == 'P' && token[1] == 'm' && IS_SPACE(token[2])) { + token += 2; + material.metallic = parseReal(&token); + continue; + } + + // PBR: sheen + if (token[0] == 'P' && token[1] == 's' && IS_SPACE(token[2])) { + token += 2; + material.sheen = parseReal(&token); + continue; + } + + // PBR: clearcoat thickness + if (token[0] == 'P' && token[1] == 'c' && IS_SPACE(token[2])) { + token += 2; + material.clearcoat_thickness = parseReal(&token); + continue; + } + + // PBR: clearcoat roughness + if ((0 == strncmp(token, "Pcr", 3)) && IS_SPACE(token[3])) { + token += 4; + material.clearcoat_roughness = parseReal(&token); + continue; + } + + // PBR: anisotropy + if ((0 == strncmp(token, "aniso", 5)) && IS_SPACE(token[5])) { + token += 6; + material.anisotropy = parseReal(&token); + continue; + } + + // PBR: anisotropy rotation + if ((0 == strncmp(token, "anisor", 6)) && IS_SPACE(token[6])) { + token += 7; + material.anisotropy_rotation = parseReal(&token); + continue; + } + + // ambient or ambient occlusion texture + if ((0 == strncmp(token, "map_Ka", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.ambient_texname), + &(material.ambient_texopt), token); + continue; + } + + // diffuse texture + if ((0 == strncmp(token, "map_Kd", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.diffuse_texname), + &(material.diffuse_texopt), token); + + // Set a decent diffuse default value if a diffuse texture is specified + // without a matching Kd value. + if (!has_kd) { + material.diffuse[0] = static_cast<real_t>(0.6); + material.diffuse[1] = static_cast<real_t>(0.6); + material.diffuse[2] = static_cast<real_t>(0.6); + } + + continue; + } + + // specular texture + if ((0 == strncmp(token, "map_Ks", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.specular_texname), + &(material.specular_texopt), token); + continue; + } + + // specular highlight texture + if ((0 == strncmp(token, "map_Ns", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.specular_highlight_texname), + &(material.specular_highlight_texopt), token); + continue; + } + + // bump texture + if (((0 == strncmp(token, "map_bump", 8)) || + (0 == strncmp(token, "map_Bump", 8))) && + IS_SPACE(token[8])) { + token += 9; + ParseTextureNameAndOption(&(material.bump_texname), + &(material.bump_texopt), token); + continue; + } + + // bump texture + if ((0 == strncmp(token, "bump", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption(&(material.bump_texname), + &(material.bump_texopt), token); + continue; + } + + // alpha texture + if ((0 == strncmp(token, "map_d", 5)) && IS_SPACE(token[5])) { + token += 6; + material.alpha_texname = token; + ParseTextureNameAndOption(&(material.alpha_texname), + &(material.alpha_texopt), token); + continue; + } + + // displacement texture + if (((0 == strncmp(token, "map_disp", 8)) || + (0 == strncmp(token, "map_Disp", 8))) && + IS_SPACE(token[8])) { + token += 9; + ParseTextureNameAndOption(&(material.displacement_texname), + &(material.displacement_texopt), token); + continue; + } + + // displacement texture + if ((0 == strncmp(token, "disp", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption(&(material.displacement_texname), + &(material.displacement_texopt), token); + continue; + } + + // reflection map + if ((0 == strncmp(token, "refl", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption(&(material.reflection_texname), + &(material.reflection_texopt), token); + continue; + } + + // PBR: roughness texture + if ((0 == strncmp(token, "map_Pr", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.roughness_texname), + &(material.roughness_texopt), token); + continue; + } + + // PBR: metallic texture + if ((0 == strncmp(token, "map_Pm", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.metallic_texname), + &(material.metallic_texopt), token); + continue; + } + + // PBR: sheen texture + if ((0 == strncmp(token, "map_Ps", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.sheen_texname), + &(material.sheen_texopt), token); + continue; + } + + // PBR: emissive texture + if ((0 == strncmp(token, "map_Ke", 6)) && IS_SPACE(token[6])) { + token += 7; + ParseTextureNameAndOption(&(material.emissive_texname), + &(material.emissive_texopt), token); + continue; + } + + // PBR: normal map texture + if ((0 == strncmp(token, "norm", 4)) && IS_SPACE(token[4])) { + token += 5; + ParseTextureNameAndOption(&(material.normal_texname), + &(material.normal_texopt), token); + continue; + } + + // unknown parameter + const char *_space = strchr(token, ' '); + if (!_space) { + _space = strchr(token, '\t'); + } + if (_space) { + std::ptrdiff_t len = _space - token; + std::string key(token, static_cast<size_t>(len)); + std::string value = _space + 1; + material.unknown_parameter.insert( + std::pair<std::string, std::string>(key, value)); + } + } + // flush last material. + material_map->insert(std::pair<std::string, int>( + material.name, static_cast<int>(materials->size()))); + materials->push_back(material); + + if (warning) { + (*warning) = warn_ss.str(); + } +} + +bool MaterialFileReader::operator()(const std::string &matId, + std::vector<material_t> *materials, + std::map<std::string, int> *matMap, + std::string *warn, std::string *err) { + if (!m_mtlBaseDir.empty()) { +#ifdef _WIN32 + char sep = ';'; +#else + char sep = ':'; +#endif + + // https://stackoverflow.com/questions/5167625/splitting-a-c-stdstring-using-tokens-e-g + std::vector<std::string> paths; + std::istringstream f(m_mtlBaseDir); + + std::string s; + while (getline(f, s, sep)) { + std::cout << "s: " << s << std::endl; + //std::cout << "line: " << getline(f, s, sep) << std::endl; + + paths.push_back(s); + } + + for (size_t i = 0; i < paths.size(); i++) { + std::string filepath = JoinPath(paths[i], matId); + + std::ifstream matIStream(paths[i].c_str()); + + std::cout << "mat file: " << filepath.c_str() << std::endl; + if (matIStream) { + std::cout << "Mat IS stream!" << std::endl; + LoadMtl(matMap, materials, &matIStream, warn, err); + + return true; + } + + std::cout << "Mat NOT stream!" << std::endl; + + } + + std::stringstream ss; + ss << "Material file [ " << matId + << " ] not found in a path : " << m_mtlBaseDir << "\n"; + if (warn) { + (*warn) += ss.str(); + } + return false; + + } else { + std::string filepath = matId; + std::ifstream matIStream(filepath.c_str()); + if (matIStream) { + LoadMtl(matMap, materials, &matIStream, warn, err); + + return true; + } + + std::stringstream ss; + ss << "Material file [ " << filepath + << " ] not found in a path : " << m_mtlBaseDir << "\n"; + if (warn) { + (*warn) += ss.str(); + } + + return false; + } +} + +bool MaterialStreamReader::operator()(const std::string &matId, + std::vector<material_t> *materials, + std::map<std::string, int> *matMap, + std::string *warn, std::string *err) { + (void)err; + (void)matId; + if (!m_inStream) { + std::stringstream ss; + ss << "Material stream in error state. \n"; + if (warn) { + (*warn) += ss.str(); + } + return false; + } + + LoadMtl(matMap, materials, &m_inStream, warn, err); + + return true; +} + +bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes, + std::vector<material_t> *materials, std::string *warn, + std::string *err, const char *filename, const char *mtl_basedir, + bool triangulate, bool default_vcols_fallback) { + attrib->vertices.clear(); + attrib->normals.clear(); + attrib->texcoords.clear(); + attrib->colors.clear(); + shapes->clear(); + + std::stringstream errss; + + std::ifstream ifs(filename); + if (!ifs) { + errss << "Cannot open file [" << filename << "]\n"; + if (err) { + (*err) = errss.str(); + } + return false; + } + + std::string baseDir = mtl_basedir ? mtl_basedir : ""; + if (!baseDir.empty()) { +//#ifndef _WIN32 +// const char dirsep = '/'; +//#else +// const char dirsep = '\\'; +//#endif +// if (baseDir[baseDir.length() - 1] != dirsep) baseDir += dirsep; + } + + std::cout << "base dir: " << baseDir << std::endl; + MaterialFileReader matFileReader(baseDir); + + return LoadObj(attrib, shapes, materials, warn, err, &ifs, &matFileReader, + triangulate, default_vcols_fallback); +} + +bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes, + std::vector<material_t> *materials, std::string *warn, + std::string *err, std::istream *inStream, + MaterialReader *readMatFn /*= NULL*/, bool triangulate, + bool default_vcols_fallback) { + std::stringstream errss; + + std::vector<real_t> v; + std::vector<real_t> vn; + std::vector<real_t> vt; + std::vector<real_t> vc; + std::vector<skin_weight_t> vw; + std::vector<tag_t> tags; + PrimGroup prim_group; + std::string name; + + // material + std::set<std::string> material_filenames; + std::map<std::string, int> material_map; + int material = -1; + + // smoothing group id + unsigned int current_smoothing_id = + 0; // Initial value. 0 means no smoothing. + + int greatest_v_idx = -1; + int greatest_vn_idx = -1; + int greatest_vt_idx = -1; + + shape_t shape; + + bool found_all_colors = true; + + size_t line_num = 0; + std::string linebuf; + while (inStream->peek() != -1) { + safeGetline(*inStream, linebuf); + + line_num++; + + // Trim newline '\r\n' or '\n' + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\n') + linebuf.erase(linebuf.size() - 1); + } + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\r') + linebuf.erase(linebuf.size() - 1); + } + + // Skip if empty line. + if (linebuf.empty()) { + continue; + } + + // Skip leading space. + const char *token = linebuf.c_str(); + token += strspn(token, " \t"); + + assert(token); + if (token[0] == '\0') continue; // empty line + + if (token[0] == '#') continue; // comment line + + // vertex + if (token[0] == 'v' && IS_SPACE((token[1]))) { + token += 2; + real_t x, y, z; + real_t r, g, b; + + found_all_colors &= parseVertexWithColor(&x, &y, &z, &r, &g, &b, &token); + + v.push_back(x); + v.push_back(y); + v.push_back(z); + + if (found_all_colors || default_vcols_fallback) { + vc.push_back(r); + vc.push_back(g); + vc.push_back(b); + } + + continue; + } + + // normal + if (token[0] == 'v' && token[1] == 'n' && IS_SPACE((token[2]))) { + token += 3; + real_t x, y, z; + parseReal3(&x, &y, &z, &token); + vn.push_back(x); + vn.push_back(y); + vn.push_back(z); + continue; + } + + // texcoord + if (token[0] == 'v' && token[1] == 't' && IS_SPACE((token[2]))) { + token += 3; + real_t x, y; + parseReal2(&x, &y, &token); + vt.push_back(x); + vt.push_back(y); + continue; + } + + // skin weight. tinyobj extension + if (token[0] == 'v' && token[1] == 'w' && IS_SPACE((token[2]))) { + token += 3; + + // vw <vid> <joint_0> <weight_0> <joint_1> <weight_1> ... + // example: + // vw 0 0 0.25 1 0.25 2 0.5 + + // TODO(syoyo): Add syntax check + int vid = 0; + vid = parseInt(&token); + + skin_weight_t sw; + + sw.vertex_id = vid; + + while (!IS_NEW_LINE(token[0])) { + real_t j, w; + // joint_id should not be negative, weight may be negative + // TODO(syoyo): # of elements check + parseReal2(&j, &w, &token, -1.0); + + if (j < static_cast<real_t>(0)) { + if (err) { + std::stringstream ss; + ss << "Failed parse `vw' line. joint_id is negative. " + "line " + << line_num << ".)\n"; + (*err) += ss.str(); + } + return false; + } + + joint_and_weight_t jw; + + jw.joint_id = int(j); + jw.weight = w; + + sw.weightValues.push_back(jw); + + size_t n = strspn(token, " \t\r"); + token += n; + } + + vw.push_back(sw); + } + + warning_context context; + context.warn = warn; + context.line_number = line_num; + + // line + if (token[0] == 'l' && IS_SPACE((token[1]))) { + token += 2; + + __line_t line; + + while (!IS_NEW_LINE(token[0])) { + vertex_index_t vi; + if (!parseTriple(&token, static_cast<int>(v.size() / 3), + static_cast<int>(vn.size() / 3), + static_cast<int>(vt.size() / 2), &vi, context)) { + if (err) { + (*err) += "Failed to parse `l' line (e.g. a zero value for vertex index. Line " + + toString(line_num) + ").\n"; + } + return false; + } + + line.vertex_indices.push_back(vi); + + size_t n = strspn(token, " \t\r"); + token += n; + } + + prim_group.lineGroup.push_back(line); + + continue; + } + + // points + if (token[0] == 'p' && IS_SPACE((token[1]))) { + token += 2; + + __points_t pts; + + while (!IS_NEW_LINE(token[0])) { + vertex_index_t vi; + if (!parseTriple(&token, static_cast<int>(v.size() / 3), + static_cast<int>(vn.size() / 3), + static_cast<int>(vt.size() / 2), &vi, context)) { + if (err) { + (*err) += "Failed to parse `p' line (e.g. a zero value for vertex index. Line " + + toString(line_num) + ").\n"; + } + return false; + } + + pts.vertex_indices.push_back(vi); + + size_t n = strspn(token, " \t\r"); + token += n; + } + + prim_group.pointsGroup.push_back(pts); + + continue; + } + + // face + if (token[0] == 'f' && IS_SPACE((token[1]))) { + token += 2; + token += strspn(token, " \t"); + + face_t face; + + face.smoothing_group_id = current_smoothing_id; + face.vertex_indices.reserve(3); + + while (!IS_NEW_LINE(token[0])) { + vertex_index_t vi; + if (!parseTriple(&token, static_cast<int>(v.size() / 3), + static_cast<int>(vn.size() / 3), + static_cast<int>(vt.size() / 2), &vi, context)) { + if (err) { + (*err) += "Failed to parse `f' line (e.g. a zero value for vertex index or invalid relative vertex index). Line " + + toString(line_num) + ").\n"; + } + return false; + } + + greatest_v_idx = greatest_v_idx > vi.v_idx ? greatest_v_idx : vi.v_idx; + greatest_vn_idx = + greatest_vn_idx > vi.vn_idx ? greatest_vn_idx : vi.vn_idx; + greatest_vt_idx = + greatest_vt_idx > vi.vt_idx ? greatest_vt_idx : vi.vt_idx; + + face.vertex_indices.push_back(vi); + size_t n = strspn(token, " \t\r"); + token += n; + } + + // replace with emplace_back + std::move on C++11 + prim_group.faceGroup.push_back(face); + + continue; + } + + // use mtl + if ((0 == strncmp(token, "usemtl", 6))) { + token += 6; + std::string namebuf = parseString(&token); + + int newMaterialId = -1; + std::map<std::string, int>::const_iterator it = + material_map.find(namebuf); + if (it != material_map.end()) { + newMaterialId = it->second; + } else { + // { error!! material not found } + if (warn) { + (*warn) += "material [ '" + namebuf + "' ] not found in .mtl\n"; + } + } + + if (newMaterialId != material) { + // Create per-face material. Thus we don't add `shape` to `shapes` at + // this time. + // just clear `faceGroup` after `exportGroupsToShape()` call. + exportGroupsToShape(&shape, prim_group, tags, material, name, + triangulate, v, warn); + prim_group.faceGroup.clear(); + material = newMaterialId; + } + + continue; + } + + // load mtl + if ((0 == strncmp(token, "mtllib", 6)) && IS_SPACE((token[6]))) { + if (readMatFn) { + token += 7; + + std::vector<std::string> filenames; + SplitString(std::string(token), ' ', '\\', filenames); + + if (filenames.empty()) { + if (warn) { + std::stringstream ss; + ss << "Looks like empty filename for mtllib. Use default " + "material (line " + << line_num << ".)\n"; + + (*warn) += ss.str(); + } + } else { + bool found = false; + for (size_t s = 0; s < filenames.size(); s++) { + if (material_filenames.count(filenames[s]) > 0) { + found = true; + continue; + } + + std::string warn_mtl; + std::string err_mtl; + + std::cout << "CHECKING IF OK" << std::endl; + + bool ok = (*readMatFn)(filenames[s].c_str(), materials, + &material_map, &warn_mtl, &err_mtl); + if (warn && (!warn_mtl.empty())) { + (*warn) += warn_mtl; + } + + if (err && (!err_mtl.empty())) { + (*err) += err_mtl; + } + + std::cout << "in mtl loader" << std::endl; + if (ok) { + std::cout << "in mtl loader --- OK" << std::endl; + + found = true; + material_filenames.insert(filenames[s]); + std::cout << "filename:" << filenames[s] << std::endl; + break; + } + } + + if (!found) { + if (warn) { + (*warn) += + "Failed to load material file(s). Use default " + "material.\n"; + } + } + } + } + + continue; + } + + // group name + if (token[0] == 'g' && IS_SPACE((token[1]))) { + // flush previous face group. + bool ret = exportGroupsToShape(&shape, prim_group, tags, material, name, + triangulate, v, warn); + (void)ret; // return value not used. + + if (shape.mesh.indices.size() > 0) { + shapes->push_back(shape); + } + + shape = shape_t(); + + // material = -1; + prim_group.clear(); + + std::vector<std::string> names; + + while (!IS_NEW_LINE(token[0])) { + std::string str = parseString(&token); + names.push_back(str); + token += strspn(token, " \t\r"); // skip tag + } + + // names[0] must be 'g' + + if (names.size() < 2) { + // 'g' with empty names + if (warn) { + std::stringstream ss; + ss << "Empty group name. line: " << line_num << "\n"; + (*warn) += ss.str(); + name = ""; + } + } else { + std::stringstream ss; + ss << names[1]; + + // tinyobjloader does not support multiple groups for a primitive. + // Currently we concatinate multiple group names with a space to get + // single group name. + + for (size_t i = 2; i < names.size(); i++) { + ss << " " << names[i]; + } + + name = ss.str(); + } + + continue; + } + + // object name + if (token[0] == 'o' && IS_SPACE((token[1]))) { + // flush previous face group. + bool ret = exportGroupsToShape(&shape, prim_group, tags, material, name, + triangulate, v, warn); + (void)ret; // return value not used. + + if (shape.mesh.indices.size() > 0 || shape.lines.indices.size() > 0 || + shape.points.indices.size() > 0) { + shapes->push_back(shape); + } + + // material = -1; + prim_group.clear(); + shape = shape_t(); + + // @todo { multiple object name? } + token += 2; + std::stringstream ss; + ss << token; + name = ss.str(); + + continue; + } + + if (token[0] == 't' && IS_SPACE(token[1])) { + const int max_tag_nums = 8192; // FIXME(syoyo): Parameterize. + tag_t tag; + + token += 2; + + tag.name = parseString(&token); + + tag_sizes ts = parseTagTriple(&token); + + if (ts.num_ints < 0) { + ts.num_ints = 0; + } + if (ts.num_ints > max_tag_nums) { + ts.num_ints = max_tag_nums; + } + + if (ts.num_reals < 0) { + ts.num_reals = 0; + } + if (ts.num_reals > max_tag_nums) { + ts.num_reals = max_tag_nums; + } + + if (ts.num_strings < 0) { + ts.num_strings = 0; + } + if (ts.num_strings > max_tag_nums) { + ts.num_strings = max_tag_nums; + } + + tag.intValues.resize(static_cast<size_t>(ts.num_ints)); + + for (size_t i = 0; i < static_cast<size_t>(ts.num_ints); ++i) { + tag.intValues[i] = parseInt(&token); + } + + tag.floatValues.resize(static_cast<size_t>(ts.num_reals)); + for (size_t i = 0; i < static_cast<size_t>(ts.num_reals); ++i) { + tag.floatValues[i] = parseReal(&token); + } + + tag.stringValues.resize(static_cast<size_t>(ts.num_strings)); + for (size_t i = 0; i < static_cast<size_t>(ts.num_strings); ++i) { + tag.stringValues[i] = parseString(&token); + } + + tags.push_back(tag); + + continue; + } + + if (token[0] == 's' && IS_SPACE(token[1])) { + // smoothing group id + token += 2; + + // skip space. + token += strspn(token, " \t"); // skip space + + if (token[0] == '\0') { + continue; + } + + if (token[0] == '\r' || token[1] == '\n') { + continue; + } + + if (strlen(token) >= 3 && token[0] == 'o' && token[1] == 'f' && + token[2] == 'f') { + current_smoothing_id = 0; + } else { + // assume number + int smGroupId = parseInt(&token); + if (smGroupId < 0) { + // parse error. force set to 0. + // FIXME(syoyo): Report warning. + current_smoothing_id = 0; + } else { + current_smoothing_id = static_cast<unsigned int>(smGroupId); + } + } + + continue; + } // smoothing group id + + // Ignore unknown command. + } + + // not all vertices have colors, no default colors desired? -> clear colors + if (!found_all_colors && !default_vcols_fallback) { + vc.clear(); + } + + if (greatest_v_idx >= static_cast<int>(v.size() / 3)) { + if (warn) { + std::stringstream ss; + ss << "Vertex indices out of bounds (line " << line_num << ".)\n\n"; + (*warn) += ss.str(); + } + } + if (greatest_vn_idx >= static_cast<int>(vn.size() / 3)) { + if (warn) { + std::stringstream ss; + ss << "Vertex normal indices out of bounds (line " << line_num << ".)\n\n"; + (*warn) += ss.str(); + } + } + if (greatest_vt_idx >= static_cast<int>(vt.size() / 2)) { + if (warn) { + std::stringstream ss; + ss << "Vertex texcoord indices out of bounds (line " << line_num << ".)\n\n"; + (*warn) += ss.str(); + } + } + + bool ret = exportGroupsToShape(&shape, prim_group, tags, material, name, + triangulate, v, warn); + // exportGroupsToShape return false when `usemtl` is called in the last + // line. + // we also add `shape` to `shapes` when `shape.mesh` has already some + // faces(indices) + if (ret || shape.mesh.indices + .size()) { // FIXME(syoyo): Support other prims(e.g. lines) + shapes->push_back(shape); + } + prim_group.clear(); // for safety + + if (err) { + (*err) += errss.str(); + } + + attrib->vertices.swap(v); + attrib->vertex_weights.swap(v); + attrib->normals.swap(vn); + attrib->texcoords.swap(vt); + attrib->texcoord_ws.swap(vt); + attrib->colors.swap(vc); + attrib->skin_weights.swap(vw); + + return true; +} + +bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback, + void *user_data /*= NULL*/, + MaterialReader *readMatFn /*= NULL*/, + std::string *warn, /* = NULL*/ + std::string *err /*= NULL*/) { + std::stringstream errss; + + // material + std::set<std::string> material_filenames; + std::map<std::string, int> material_map; + int material_id = -1; // -1 = invalid + + std::vector<index_t> indices; + std::vector<material_t> materials; + std::vector<std::string> names; + names.reserve(2); + std::vector<const char *> names_out; + + std::string linebuf; + while (inStream.peek() != -1) { + safeGetline(inStream, linebuf); + + // Trim newline '\r\n' or '\n' + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\n') + linebuf.erase(linebuf.size() - 1); + } + if (linebuf.size() > 0) { + if (linebuf[linebuf.size() - 1] == '\r') + linebuf.erase(linebuf.size() - 1); + } + + // Skip if empty line. + if (linebuf.empty()) { + continue; + } + + // Skip leading space. + const char *token = linebuf.c_str(); + token += strspn(token, " \t"); + + assert(token); + if (token[0] == '\0') continue; // empty line + + if (token[0] == '#') continue; // comment line + + // vertex + if (token[0] == 'v' && IS_SPACE((token[1]))) { + token += 2; + real_t x, y, z; + real_t r, g, b; + + bool found_color = parseVertexWithColor(&x, &y, &z, &r, &g, &b, &token); + if (callback.vertex_cb) { + callback.vertex_cb(user_data, x, y, z, r); // r=w is optional + } + if (callback.vertex_color_cb) { + callback.vertex_color_cb(user_data, x, y, z, r, g, b, found_color); + } + continue; + } + + // normal + if (token[0] == 'v' && token[1] == 'n' && IS_SPACE((token[2]))) { + token += 3; + real_t x, y, z; + parseReal3(&x, &y, &z, &token); + if (callback.normal_cb) { + callback.normal_cb(user_data, x, y, z); + } + continue; + } + + // texcoord + if (token[0] == 'v' && token[1] == 't' && IS_SPACE((token[2]))) { + token += 3; + real_t x, y, z; // y and z are optional. default = 0.0 + parseReal3(&x, &y, &z, &token); + if (callback.texcoord_cb) { + callback.texcoord_cb(user_data, x, y, z); + } + continue; + } + + // face + if (token[0] == 'f' && IS_SPACE((token[1]))) { + token += 2; + token += strspn(token, " \t"); + + indices.clear(); + while (!IS_NEW_LINE(token[0])) { + vertex_index_t vi = parseRawTriple(&token); + + index_t idx; + idx.vertex_index = vi.v_idx; + idx.normal_index = vi.vn_idx; + idx.texcoord_index = vi.vt_idx; + + indices.push_back(idx); + size_t n = strspn(token, " \t\r"); + token += n; + } + + if (callback.index_cb && indices.size() > 0) { + callback.index_cb(user_data, &indices.at(0), + static_cast<int>(indices.size())); + } + + continue; + } + + // use mtl + if ((0 == strncmp(token, "usemtl", 6)) && IS_SPACE((token[6]))) { + token += 7; + std::stringstream ss; + ss << token; + std::string namebuf = ss.str(); + + int newMaterialId = -1; + std::map<std::string, int>::const_iterator it = + material_map.find(namebuf); + if (it != material_map.end()) { + newMaterialId = it->second; + } else { + // { warn!! material not found } + if (warn && (!callback.usemtl_cb)) { + (*warn) += "material [ " + namebuf + " ] not found in .mtl\n"; + } + } + + if (newMaterialId != material_id) { + material_id = newMaterialId; + } + + if (callback.usemtl_cb) { + callback.usemtl_cb(user_data, namebuf.c_str(), material_id); + } + + continue; + } + + // load mtl + if ((0 == strncmp(token, "mtllib", 6)) && IS_SPACE((token[6]))) { + if (readMatFn) { + token += 7; + + std::vector<std::string> filenames; + SplitString(std::string(token), ' ', '\\', filenames); + + if (filenames.empty()) { + if (warn) { + (*warn) += + "Looks like empty filename for mtllib. Use default " + "material. \n"; + } + } else { + bool found = false; + for (size_t s = 0; s < filenames.size(); s++) { + if (material_filenames.count(filenames[s]) > 0) { + found = true; + continue; + } + + std::string warn_mtl; + std::string err_mtl; + bool ok = (*readMatFn)(filenames[s].c_str(), &materials, + &material_map, &warn_mtl, &err_mtl); + + if (warn && (!warn_mtl.empty())) { + (*warn) += warn_mtl; // This should be warn message. + } + + if (err && (!err_mtl.empty())) { + (*err) += err_mtl; + } + + if (ok) { + found = true; + material_filenames.insert(filenames[s]); + break; + } + } + + if (!found) { + if (warn) { + (*warn) += + "Failed to load material file(s). Use default " + "material.\n"; + } + } else { + if (callback.mtllib_cb) { + callback.mtllib_cb(user_data, &materials.at(0), + static_cast<int>(materials.size())); + } + } + } + } + + continue; + } + + // group name + if (token[0] == 'g' && IS_SPACE((token[1]))) { + names.clear(); + + while (!IS_NEW_LINE(token[0])) { + std::string str = parseString(&token); + names.push_back(str); + token += strspn(token, " \t\r"); // skip tag + } + + assert(names.size() > 0); + + if (callback.group_cb) { + if (names.size() > 1) { + // create const char* array. + names_out.resize(names.size() - 1); + for (size_t j = 0; j < names_out.size(); j++) { + names_out[j] = names[j + 1].c_str(); + } + callback.group_cb(user_data, &names_out.at(0), + static_cast<int>(names_out.size())); + + } else { + callback.group_cb(user_data, NULL, 0); + } + } + + continue; + } + + // object name + if (token[0] == 'o' && IS_SPACE((token[1]))) { + // @todo { multiple object name? } + token += 2; + + std::stringstream ss; + ss << token; + std::string object_name = ss.str(); + + if (callback.object_cb) { + callback.object_cb(user_data, object_name.c_str()); + } + + continue; + } + +#if 0 // @todo + if (token[0] == 't' && IS_SPACE(token[1])) { + tag_t tag; + + token += 2; + std::stringstream ss; + ss << token; + tag.name = ss.str(); + + token += tag.name.size() + 1; + + tag_sizes ts = parseTagTriple(&token); + + tag.intValues.resize(static_cast<size_t>(ts.num_ints)); + + for (size_t i = 0; i < static_cast<size_t>(ts.num_ints); ++i) { + tag.intValues[i] = atoi(token); + token += strcspn(token, "/ \t\r") + 1; + } + + tag.floatValues.resize(static_cast<size_t>(ts.num_reals)); + for (size_t i = 0; i < static_cast<size_t>(ts.num_reals); ++i) { + tag.floatValues[i] = parseReal(&token); + token += strcspn(token, "/ \t\r") + 1; + } + + tag.stringValues.resize(static_cast<size_t>(ts.num_strings)); + for (size_t i = 0; i < static_cast<size_t>(ts.num_strings); ++i) { + std::stringstream ss; + ss << token; + tag.stringValues[i] = ss.str(); + token += tag.stringValues[i].size() + 1; + } + + tags.push_back(tag); + } +#endif + + // Ignore unknown command. + } + + if (err) { + (*err) += errss.str(); + } + + return true; +} + +bool ObjReader::ParseFromFile(const std::string &filename, + const ObjReaderConfig &config) { + std::string mtl_search_path; + + if (config.mtl_search_path.empty()) { + // + // split at last '/'(for unixish system) or '\\'(for windows) to get + // the base directory of .obj file + // + size_t pos = filename.find_last_of("/\\"); + if (pos != std::string::npos) { + mtl_search_path = filename.substr(0, pos); + } + } else { + mtl_search_path = config.mtl_search_path; + } + + valid_ = LoadObj(&attrib_, &shapes_, &materials_, &warning_, &error_, + filename.c_str(), mtl_search_path.c_str(), + config.triangulate, config.vertex_color); + + return valid_; +} + +bool ObjReader::ParseFromString(const std::string &obj_text, + const std::string &mtl_text, + const ObjReaderConfig &config) { + std::stringbuf obj_buf(obj_text); + std::stringbuf mtl_buf(mtl_text); + + std::istream obj_ifs(&obj_buf); + std::istream mtl_ifs(&mtl_buf); + + MaterialStreamReader mtl_ss(mtl_ifs); + + valid_ = LoadObj(&attrib_, &shapes_, &materials_, &warning_, &error_, + &obj_ifs, &mtl_ss, config.triangulate, config.vertex_color); + + return valid_; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +} // namespace tinyobj + +#endif |