Compare commits

...

3 Commits

Author SHA1 Message Date
85dbded287 cpp end 2026-04-03 12:34:06 +02:00
cd77088dbf setuo: clang cache to gitignore 2026-04-03 12:33:45 +02:00
f19e61b585 feat: rewrite to c 2026-04-01 23:51:02 +02:00
31 changed files with 3788 additions and 130 deletions

View File

@@ -1,3 +1,3 @@
CompileFlags:
Add: [-std=c++20]
#CompileFlags:
# Add: [-std=c++20]

1
.gitignore vendored
View File

@@ -1 +1,2 @@
build
.cache

56
2 Normal file
View File

@@ -0,0 +1,56 @@
#include "fastmath.hpp"
#include "polygon.hpp"
#include <QApplication>
#include <QImage>
#include <QLabel>
#include <QPixmap>
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
// testing fastmath.h
/*
void test(vec<2> *in) {
vec<2> v = {{decimal(1.0), decimal(0.5)}};
in = &v;
}*/
int main(int argc, char *argv[]) {
vec3 v1 = vec3(5.0f, 40.0f, 2.0f);
vec3 v2 = vec3(5.0, 10.0, 2.2);
vec3 v3 = v1;
std::cout << v1 << v2 << decimal(0.5) * v2 << (v1 + v2) << v1 * v2 << "\n"
<< v1.cross(v2) << v1.len() << "\n"
<< v1.normalize() << std::endl;
decimal d = decimal(2.0f);
d += decimal(0.5);
std::cout << "\n"
<< decimal(2.0) / decimal(-0.5) << "\n"
<< decimal(2.0).sqrt() << "\n"
<< d << std::endl;
polygon p = {vec3(0.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(1.0, 0.0, 0.0)};
std::cout << p.contains(vec3(0.1, 0.1, 0.1)) << std::endl;
std::cout << matN<3>::identity() * v1 << std::endl;
// QApplication a(argc, argv);
//
// uint8_t *pixel = new uint8_t[64 * 64 * 3];
//
// for (int i = 1; i < 64 * 64 * 3; i += 3) {
// pixel[i] = 255;
// }
//
// QWidget widget;
// widget.setAutoFillBackground(true);
// widget.setGeometry(0, 0, 500, 500);
// QLabel display(&widget);
// QImage img((unsigned char *)pixel, 64, 64, QImage::Format_RGB888);
// display.setPixmap(QPixmap::fromImage(img).scaled(widget.size()));
// widget.show();
// return a.exec();
}

View File

@@ -2,14 +2,15 @@ cmake_minimum_required(VERSION 3.15)
project(SDFVisual VERSION 0.1
DESCRIPTION "CPU SDF Renderer"
LANGUAGES CXX)
LANGUAGES C)
find_package(Qt6 REQUIRED COMPONENTS
Widgets Gui
)
# find_package(Qt6 REQUIRED COMPONENTS
# Widgets Gui
# )
set (CMAKE_CXX_STANDARD 20)
add_executable(one main.cpp)
# set (CMAKE_CXX_STANDARD 20)
set (C_STANDARD 11)
add_executable(one src/main.c)
target_link_libraries(one m Qt6::Widgets Qt6::Gui)
# target_link_libraries(one m)
# target_link_libraries(one m Qt6::Widgets Qt6::Gui)
target_link_libraries(one m)

32
MainWindow.hpp Normal file
View File

@@ -0,0 +1,32 @@
#include <QImage>
#include <QKeyEvent>
#include <QLabel>
#include <QObject>
#include <QPixmap>
#include <QTimer>
#include <QWidget>
#include <iostream>
class MainWindow : public QWidget {
public:
std::function<void(QKeyEvent *)> keyDownCallBack;
MainWindow() : display(QLabel(this)) {
setAutoFillBackground(true);
setGeometry(0, 0, 500, 500);
display.setFocusPolicy(Qt::StrongFocus);
}
void updateLabel(uint8_t *pixel) {
QImage img((unsigned char *)pixel, 64, 64, QImage::Format_RGB888);
display.setPixmap(QPixmap::fromImage(img).scaled(size() * 1));
}
void keyPressEvent(QKeyEvent *e) {
keyDownCallBack(e);
QWidget::keyPressEvent(e);
}
private:
QLabel display;
};

11
beziercurve.hpp Normal file
View File

@@ -0,0 +1,11 @@
#include "fastmath.hpp"
template <class T>
T calcHandels(const T curr, const T prev, const T next, T &left, T &right) {
T prev
}
template <class T> T bezierCurve(T a, T ad, T b, T bd, float t) {
return std::pow(1 - t, 3.0) * a + 3 * std::pow(1 - t, 2.0) * t * ad +
3 * (1 - t) * std::pow(t, 2.0) * bd + std::pow(t, 3.0) * b;
}

View File

@@ -35,6 +35,8 @@ struct decimal {
}
inline decimal &operator+=(const decimal &d) { return (*this) = {i + d.i}; }
inline decimal &operator-=(const decimal &d) { return (*this) = {i - d.i}; }
inline friend decimal operator-(const decimal &d1, const decimal &d2) {
return {d1.i - d2.i};
}
@@ -91,7 +93,7 @@ template <int n, class Dev> struct vec {
}
friend Dev operator+(const vec<n, Dev> &v1, const vec<n, Dev> &v2) {
Dev newV = {};
Dev newV;
for (int i = 0; i < n; i++) {
newV.v[i] = v1.v[i] + v2.v[i];
@@ -99,16 +101,24 @@ template <int n, class Dev> struct vec {
return newV;
}
friend Dev operator+=(const vec<n, Dev> &v1, const vec<n, Dev> &v2) {
Dev newV = {};
Dev newV;
for (int i = 0; i < n; i++) {
newV.v[i] = v1.v[i] + v2.v[i];
}
return newV;
}
friend Dev operator-=(const vec<n, Dev> &v1, const vec<n, Dev> &v2) {
Dev newV;
for (int i = 0; i < n; i++) {
newV.v[i] = v1.v[i] - v2.v[i];
}
return newV;
}
friend Dev operator-(const vec<n, Dev> &v1, const vec<n, Dev> &v2) {
Dev newV = {};
Dev newV;
for (int i = 0; i < n; i++) {
newV.v[i] = v1.v[i] - v2.v[i];
@@ -125,7 +135,7 @@ template <int n, class Dev> struct vec {
}
Dev operator-() {
Dev newV = {};
Dev newV;
for (int i = 0; i < n; i++) {
newV.v[i] = -v[i];
}
@@ -135,21 +145,21 @@ template <int n, class Dev> struct vec {
friend Dev operator*(const vec<n, Dev> &v, const decimal &d) {
int32_t f = d.i >> HALF_SHIFT;
Dev newV = {};
Dev newV;
for (int i = 0; i < n; i++) {
newV.v[i] = (v.v[i].i >> HALF_SHIFT) * f;
}
return newV;
}
static Dev max(const vec<n, Dev> &v1, const vec<n, Dev> &v2) {
Dev newV = {};
Dev newV;
for (int i = 0; i < n; i++) {
newV.v[i] = std::max(v1.v[i], v2.v[i]);
}
return newV;
}
static Dev min(const vec<n, Dev> &v1, const vec<n, Dev> &v2) {
Dev newV = {};
Dev newV;
for (int i = 0; i < n; i++) {
newV.v[i] = std::min(v1.v[i], v2.v[i]);
}
@@ -194,7 +204,7 @@ template <int n, class Dev> struct vec {
}
constexpr static Dev zero() {
Dev newV = {};
Dev newV;
for (int i = 0; i < n; i++) {
newV[i] = decimal(0);
}
@@ -203,6 +213,8 @@ template <int n, class Dev> struct vec {
};
struct vec2 : public vec<2, vec2> {
vec2() : vec<2, vec2>() {};
vec2(float x, float y) : vec<2, vec2>(decimal(x), decimal(y)) {}
vec2(double x, double y) : vec<2, vec2>(decimal(x), decimal(y)) {}
@@ -211,6 +223,8 @@ struct vec2 : public vec<2, vec2> {
vec2(decimal x, decimal y) : vec<2, vec2>(x, y) {}
template <class origVec> vec2(origVec v) : vec<2, vec2>(v.v[0], v.v[1]) {}
decimal &x() { return v[0]; }
decimal &y() { return v[1]; }
};

View File

@@ -1,14 +1,11 @@
#include "MainWindow.hpp"
#include "fastmath.hpp"
#include "plane.hpp"
#include "polygon.hpp"
#include "renderer.hpp"
#include "rendertarget.hpp"
#include "testModel.hpp"
#include <QApplication>
#include <QImage>
#include <QLabel>
#include <QObject>
#include <QPixmap>
#include <QTimer>
#include <chrono>
#include <functional>
#include <math.h>
@@ -46,40 +43,11 @@ char *drawToString(unsigned short *img) {
return textImg;
}
void drawImage(unsigned short *img) {
decimal heightPerPix = decimal(1.0) / decimal((float)(HIGHT * FAA_FAC));
decimal widthPerPix = decimal(1.0) / decimal((float)(WIDTH * FAA_FAC));
polygon poly = polygon(vec3(0.9, 0.9, 0.0) * decimal(128.0),
vec3(0.5, 0.1, 0.0) * decimal(128.0),
vec3(0.1, 0.9, 0.0) * decimal(128.0));
// printf("\n hpp: %f, wpp: %f
// \n",TO_FLOAT(heightPerPix),TO_FLOAT(widthPerPix)); calcViewPos(t);
for (decimal y = 0; y < decimal((float)(RHIGHT)); y += decimal(1.0)) {
for (decimal x = 0; x < decimal((float)(RWIDTH)); x += decimal(1.0)) {
vec3 p = vec3(x, y, 0.0);
if (poly.contains(p)) {
img[(y.i >> SHIFT_AMOUNT) * RWIDTH + (x.i >> SHIFT_AMOUNT)] =
(unsigned short)23; // (((-normal[1]+(1 <<
// SHIFT_AMOUNT))*14)>>SHIFT_AMOUNT);
}
}
}
printf("done writing %d \n", *(img + sizeof(unsigned short) * 32 * 32));
}
int main(int argc, char *argv[]) {
Rendertarget target(128, 128);
Renderer renderer;
renderer.target = &target;
polygon poly =
polygon(vec3(0.9, 0.9, 1.0), vec3(0.5, 0.1, 1.0), vec3(0.1, 0.9, 1.0));
std::chrono::steady_clock::time_point begin =
std::chrono::steady_clock::now();
renderer.render(&testModel, mat4::translation(vec3(0.0f, -1.0f, 5.0f)) *
@@ -103,23 +71,48 @@ int main(int argc, char *argv[]) {
arr[c] += target.pixels[start + c];
}
};
vec3 pos;
QApplication a(argc, argv);
QWidget widget;
widget.setAutoFillBackground(true);
widget.setGeometry(0, 0, 500, 500);
QLabel display(&widget);
QImage img((unsigned char *)pixel, 64, 64, QImage::Format_RGB888);
MainWindow widget;
widget.setWindowTitle("SoftwareRenderer");
// display.setPixmap(QPixmap::fromImage(img).scaled(widget.size()));
auto keyEvent = [&pos](QKeyEvent *e) {
decimal step = decimal(0.5);
switch (e->key()) {
case Qt::Key_W:
pos.z() += step;
break;
case Qt::Key_S:
pos.z() -= step;
break;
case Qt::Key_A:
pos.x() += step;
break;
case Qt::Key_D:
pos.x() -= step;
break;
}
};
widget.keyDownCallBack = keyEvent;
float rot = 0.f;
std::function<void()> renderLoop = [&addTo, &target, &pixel, &renderer,
&display, &widget, &img, &rot]() {
&widget, &rot, &pos]() {
std::chrono::steady_clock::time_point begin =
std::chrono::steady_clock::now();
renderer.render(&testModel, mat4::translation(vec3(0.0f, -1.0f, 5.0f)) *
mat4::rotateOnY(rot));
target.clearDepth();
target.clearTarget();
// renderer.render(&testModel, mat4::translation(vec3(0.0f,
// -1.0f, 5.0f)) *
// mat4::rotateOnY(rot));
// renderer.render(&testModel, mat4::translation(vec3(1.0f,
// -1.0f, 7.0f)) *
// mat4::rotateOnY(rot));
renderer.render(&plane, mat4::translation(pos));
std::chrono::steady_clock::time_point end =
std::chrono::steady_clock::now();
@@ -143,7 +136,8 @@ int main(int argc, char *argv[]) {
}
}
// QImage img((unsigned char *)pixel, 64, 64, QImage::Format_RGB888);
display.setPixmap(QPixmap::fromImage(img).scaled(widget.size() * 1));
widget.updateLabel(pixel);
rot += 0.1f;
};
renderLoop();

63
mathTest.cpp Normal file
View File

@@ -0,0 +1,63 @@
#include "fastmath.hpp"
#include "polygon.hpp"
#include <QApplication>
#include <QImage>
#include <QLabel>
#include <QPixmap>
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
// testing fastmath.h
/*
void test(vec<2> *in) {
vec<2> v = {{decimal(1.0), decimal(0.5)}};
in = &v;
}*/
int main(int argc, char *argv[]) {
vec3 v1 = vec3(5.0f, 40.0f, 2.0f);
vec3 v2 = vec3(5.0, 10.0, 2.2);
vec3 v3 = v1;
std::cout << v1 << v2 << decimal(0.5) * v2 << (v1 + v2) << v1 * v2 << "\n"
<< v1.cross(v2) << v1.len() << "\n"
<< v1.normalize() << std::endl;
decimal d = decimal(2.0f);
d += decimal(0.5);
std::cout << "\n"
<< decimal(2.0) / decimal(-0.5) << "\n"
<< decimal(2.0).sqrt() << "\n"
<< d << std::endl;
polygon p = {vec3(0.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(1.0, 0.0, 0.0)};
std::cout << p.contains(vec3(0.1, 0.1, 0.1)) << std::endl;
mat4 m = mat4::translation({2.0f, 3.0f, 5.0f});
std::cout << matN<3>::identity() * v1 << std::endl;
std::cout << m << std::endl;
std::cout << mat4::identity().cutTo<mat3>() << std::endl;
std::cout << m * vec4(v1, decimal(1.0f)) << std::endl;
std::cout << mat4::rotateOnX(1.5707f) * vec4(1.f, 0.f, 0.f, 0.f)
<< std::endl;
// QApplication a(argc, argv);
//
// uint8_t *pixel = new uint8_t[64 * 64 * 3];
//
// for (int i = 1; i < 64 * 64 * 3; i += 3) {
// pixel[i] = 255;
// }
//
// QWidget widget;
// widget.setAutoFillBackground(true);
// widget.setGeometry(0, 0, 500, 500);
// QLabel display(&widget);
// QImage img((unsigned char *)pixel, 64, 64, QImage::Format_RGB888);
// display.setPixmap(QPixmap::fromImage(img).scaled(widget.size()));
// widget.show();
// return a.exec();
}

View File

@@ -1,5 +1,5 @@
# Open the file in read mode
file = open("test.obj", "r")
file = open("plane.obj", "r")
# Read the entire content of the file
content = file.read().split("\n")
@@ -8,13 +8,13 @@ file.close()
startVerts = 0
verts = []
for index,line in enumerate(content):
if line[0] == 'o':
for index, line in enumerate(content):
if line[0] == "o":
startVerts = index + 1
content = content[startVerts:]
break
for index,line in enumerate(content):
for index, line in enumerate(content):
if "vn" in line:
endVerts = index
verts = content[:endVerts]
@@ -23,28 +23,50 @@ for index,line in enumerate(content):
normals = []
for index,line in enumerate(content):
for index, line in enumerate(content):
if "vt" in line:
normals = content[:index]
content = content[index:]
break
startFaces = 0;
startFaces = 0
faces = []
for index,line in enumerate(content):
if line[0] == 'f':
for index, line in enumerate(content):
if line[0] == "f":
startFaces = index
faces = content[startFaces:-1]
break
colors = ["vec3(" +",".join(vert.split(" ")[4:7]) + ")" for vert in verts]
verts = ["vec3(" +",".join(vert.split(" ")[1:4]) + ")" for vert in verts]
faces = [ ",".join(["{" + str(int((d.split("/")[0])) - 1) + "," + str(int((d.split("/")[2])) - 1) + "}" for d in face.split(" ")[1:4]]) for face in faces]
normals = ["vec3(" + ",".join(normal.split(" ")[1:4]) + ")" for normal in normals]
colors = ["{" + ",".join(vert.split(" ")[4:7]) + "}" for vert in verts]
verts = ["{" + ",".join(vert.split(" ")[1:4]) + "}" for vert in verts]
faces = [
",".join(
[
str(int((d.split("/")[0])) - 1) + "," + str(int((d.split("/")[2])) - 1)
for d in face.split(" ")[1:4]
]
)
for face in faces
]
normals = ["{" + ",".join(normal.split(" ")[1:4]) + "}" for normal in normals]
out = "#include \"model.hpp\" \n const model testModel({" + ",".join(verts) +"},{" + ",".join(faces) + "},{" + ",".join(normals) + "},{"+ ",".join(colors)+"});"
out = (
'#include "../renderer.h" \n const model testModel = {(vec3[]){'
+ ",".join(verts)
+ "},(int[]){"
+ ",".join(faces)
+ "},(vec3[]){"
+ ",".join(normals)
+ "},(vec3[]){"
+ ",".join(colors)
+ "},"
+ str(len(verts))
+ ","
+ str(len(faces) * 6)
+ "};"
)
with open("testModel.hpp", "w") as f:
f.write(out)
print(out)
with open("src/models/plane.h", "w") as f:
f.write(out)
print(faces)
# Close the file

2
plane.hpp Normal file
View File

@@ -0,0 +1,2 @@
#include "renderer.h"
const model testModel = create_model((vec3[]){{{7.334897,-2.436740,4.541961},{-7.899121,-2.436740,4.541961},{7.334897,-2.436740,35.009995},{-7.899121,-2.436740,35.009995}},(int[]){{1,0},{2,0},{0,0},{1,0},{3,0},{2,0}});

12
plane.mtl Normal file
View File

@@ -0,0 +1,12 @@
# Blender 5.1.0 MTL File: 'test.blend'
# www.blender.org
newmtl Material.001
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.800000 0.800000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2

727
plane.obj Normal file
View File

@@ -0,0 +1,727 @@
# Blender 5.1.0
# www.blender.org
mtllib plane.mtl
o Cylinder.002
v 0.698513 0.757563 0.000000 0.0000 0.4470 0.0334
v 0.044645 2.825787 0.000000 0.0000 0.4470 0.0334
v 0.656388 0.757563 0.238906 0.0000 0.4470 0.0334
v 0.041953 2.825787 0.015270 0.0000 0.4470 0.0334
v 0.535092 0.757563 0.448996 0.0000 0.4470 0.0334
v 0.034200 2.825787 0.028697 0.0000 0.4470 0.0334
v 0.349257 0.757563 0.604930 0.0000 0.4470 0.0334
v 0.022323 2.825787 0.038664 0.0000 0.4470 0.0334
v 0.121296 0.757563 0.687901 0.0000 0.4470 0.0334
v 0.007753 2.825787 0.043967 0.0000 0.4470 0.0334
v -0.121296 0.757563 0.687901 0.0000 0.4470 0.0334
v -0.007753 2.825787 0.043967 0.0000 0.4470 0.0334
v -0.349257 0.757563 0.604930 0.0000 0.4470 0.0334
v -0.022323 2.825787 0.038664 0.0000 0.4470 0.0334
v -0.535092 0.757563 0.448996 0.0000 0.4470 0.0334
v -0.034200 2.825787 0.028697 0.0000 0.4470 0.0334
v -0.656388 0.757563 0.238906 0.0000 0.4470 0.0334
v -0.041953 2.825787 0.015270 0.0000 0.4470 0.0334
v -0.698513 0.757563 -0.000000 0.0000 0.4470 0.0334
v -0.044645 2.825787 0.000000 0.0000 0.4470 0.0334
v -0.656388 0.757563 -0.238906 0.0000 0.4470 0.0334
v -0.041953 2.825787 -0.015270 0.0000 0.4470 0.0334
v -0.535092 0.757563 -0.448996 0.0000 0.4470 0.0334
v -0.034200 2.825787 -0.028697 0.0000 0.4470 0.0334
v -0.349257 0.757563 -0.604930 0.0000 0.4470 0.0334
v -0.022323 2.825787 -0.038664 0.0000 0.4470 0.0334
v -0.121296 0.757563 -0.687901 0.0000 0.4470 0.0334
v -0.007753 2.825787 -0.043967 0.0000 0.4470 0.0334
v 0.121296 0.757563 -0.687901 0.0000 0.4470 0.0334
v 0.007753 2.825787 -0.043967 0.0000 0.4470 0.0334
v 0.349257 0.757563 -0.604930 0.0000 0.4470 0.0334
v 0.022323 2.825787 -0.038664 0.0000 0.4470 0.0334
v 0.535092 0.757563 -0.448996 0.0000 0.4470 0.0334
v 0.034200 2.825787 -0.028697 0.0000 0.4470 0.0334
v 0.656388 0.757563 -0.238906 0.0000 0.4470 0.0334
v 0.041953 2.825787 -0.015269 0.0000 0.4470 0.0334
v 0.544639 2.240545 0.000000 0.0000 0.4470 0.0334
v 0.511793 2.240545 0.186277 0.0000 0.4470 0.0334
v 0.409479 2.128906 0.371044 0.8556 0.8746 1.0000
v 0.290178 2.227410 0.470774 0.8556 0.8746 1.0000
v 0.100778 2.227410 0.539710 0.8556 0.8746 1.0000
v -0.100778 2.227410 0.539710 0.8556 0.8746 1.0000
v -0.290178 2.227410 0.470774 0.8556 0.8746 1.0000
v -0.409479 2.128906 0.371044 0.8556 0.8746 1.0000
v -0.511793 2.240545 0.186277 0.0000 0.4470 0.0334
v -0.544639 2.240545 -0.000000 0.0000 0.4470 0.0334
v -0.511793 2.240545 -0.186277 0.0000 0.4470 0.0334
v -0.417217 2.240545 -0.350087 0.0000 0.4470 0.0334
v -0.272319 2.240545 -0.471671 0.0000 0.4470 0.0334
v -0.094576 2.240545 -0.536364 0.0000 0.4470 0.0334
v 0.094576 2.240545 -0.536364 0.0000 0.4470 0.0334
v 0.272319 2.240545 -0.471671 0.0000 0.4470 0.0334
v 0.417218 2.240545 -0.350087 0.0000 0.4470 0.0334
v 0.511793 2.240545 -0.186277 0.0000 0.4470 0.0334
v 0.694426 1.474881 0.252751 0.0000 0.4470 0.0334
v 0.527394 1.631239 0.497527 0.8556 0.8746 1.0000
v 0.367433 1.488016 0.632126 0.8556 0.8746 1.0000
v 0.127608 1.488016 0.719415 0.8556 0.8746 1.0000
v -0.127608 1.488016 0.719415 0.8556 0.8746 1.0000
v -0.367433 1.488016 0.632126 0.8556 0.8746 1.0000
v -0.527394 1.631239 0.497527 0.8556 0.8746 1.0000
v -0.694426 1.474881 0.252751 0.0000 0.4470 0.0334
v -0.738993 1.474881 -0.000000 0.0000 0.4470 0.0334
v -0.694426 1.474881 -0.252751 0.0000 0.4470 0.0334
v -0.566102 1.474881 -0.475016 0.0000 0.4470 0.0334
v -0.369497 1.474881 -0.639987 0.0000 0.4470 0.0334
v -0.128325 1.474881 -0.727766 0.0000 0.4470 0.0334
v 0.128325 1.474881 -0.727766 0.0000 0.4470 0.0334
v 0.369497 1.474881 -0.639987 0.0000 0.4470 0.0334
v 0.566102 1.474881 -0.475016 0.0000 0.4470 0.0334
v 0.694426 1.474881 -0.252751 0.0000 0.4470 0.0334
v 0.738993 1.474881 0.000000 0.0000 0.4470 0.0334
v 0.410385 -0.154204 0.000000 0.0000 0.4470 0.0334
v 0.385635 -0.154204 0.140360 0.0000 0.4470 0.0334
v 0.314373 -0.154204 0.263790 0.0000 0.4470 0.0334
v 0.205192 -0.154204 0.355403 0.0000 0.4470 0.0334
v 0.071263 -0.154204 0.404150 0.0000 0.4470 0.0334
v -0.071263 -0.154204 0.404150 0.0000 0.4470 0.0334
v -0.205192 -0.154204 0.355403 0.0000 0.4470 0.0334
v -0.314373 -0.154204 0.263790 0.0000 0.4470 0.0334
v -0.385635 -0.154204 0.140360 0.0000 0.4470 0.0334
v -0.410385 -0.154204 -0.000000 0.0000 0.4470 0.0334
v -0.385635 -0.154204 -0.140360 0.0000 0.4470 0.0334
v -0.314373 -0.154204 -0.263790 0.0000 0.4470 0.0334
v -0.205192 -0.154204 -0.355403 0.0000 0.4470 0.0334
v -0.071263 -0.154204 -0.404150 0.0000 0.4470 0.0334
v 0.071263 -0.154204 -0.404150 0.0000 0.4470 0.0334
v 0.205192 -0.154204 -0.355403 0.0000 0.4470 0.0334
v 0.314373 -0.154204 -0.263790 0.0000 0.4470 0.0334
v 0.385635 -0.154204 -0.140360 0.0000 0.4470 0.0334
v 0.237705 2.675272 0.000000 0.0000 0.4470 0.0334
v 0.223370 2.675272 0.081300 0.0000 0.4470 0.0334
v 0.182093 2.675272 0.152794 0.0000 0.4470 0.0334
v 0.118853 2.675272 0.205859 0.0000 0.4470 0.0334
v 0.041277 2.675272 0.234094 0.0000 0.4470 0.0334
v -0.041277 2.675272 0.234094 0.0000 0.4470 0.0334
v -0.118853 2.675272 0.205859 0.0000 0.4470 0.0334
v -0.182093 2.675272 0.152794 0.0000 0.4470 0.0334
v -0.223370 2.675272 0.081300 0.0000 0.4470 0.0334
v -0.237705 2.675272 -0.000000 0.0000 0.4470 0.0334
v -0.223370 2.675272 -0.081300 0.0000 0.4470 0.0334
v -0.182093 2.675272 -0.152794 0.0000 0.4470 0.0334
v -0.118853 2.675272 -0.205859 0.0000 0.4470 0.0334
v -0.041277 2.675272 -0.234094 0.0000 0.4470 0.0334
v 0.041277 2.675272 -0.234094 0.0000 0.4470 0.0334
v 0.118853 2.675272 -0.205859 0.0000 0.4470 0.0334
v 0.182093 2.675272 -0.152794 0.0000 0.4470 0.0334
v 0.223370 2.675272 -0.081300 0.0000 0.4470 0.0334
v 0.046326 2.839588 0.000000 0.9696 1.0000 0.0000
v -0.023163 2.839588 -0.040120 0.9695 0.9999 0.0005
v -0.023163 2.839588 0.040120 0.9696 1.0000 0.0000
v 0.000000 3.137896 0.000000 0.9696 1.0000 0.0000
v -0.272319 2.240545 0.471671 0.0000 0.4470 0.0334
v -0.417218 2.141971 0.350087 0.0000 0.4470 0.0334
v -0.094576 2.240545 0.536364 0.0000 0.4470 0.0334
v 0.094576 2.240545 0.536364 0.0000 0.4470 0.0334
v 0.272319 2.240545 0.471671 0.0000 0.4470 0.0334
v 0.417217 2.141971 0.350087 0.0000 0.4470 0.0334
v 0.566102 1.618174 0.475016 0.0000 0.4470 0.0334
v -0.566102 1.618174 0.475016 0.0000 0.4470 0.0334
v 0.369497 1.474881 0.639987 0.0000 0.4470 0.0334
v 0.128325 1.474881 0.727766 0.0000 0.4470 0.0334
v -0.128325 1.474881 0.727766 0.0000 0.4470 0.0334
v -0.369497 1.474881 0.639987 0.0000 0.4470 0.0334
v 0.237002 2.117707 0.625731 0.1450 0.1371 0.1900
v 0.257333 1.652925 0.728921 0.1450 0.1371 0.1900
v 0.082310 2.117707 0.682034 0.1450 0.1371 0.1900
v 0.089371 1.652925 0.766453 0.1450 0.1371 0.1900
v -0.082310 2.117707 0.682034 0.1450 0.1371 0.1900
v -0.089371 1.652925 0.766453 0.1450 0.1371 0.1900
v -0.237002 2.117707 0.625731 0.1450 0.1371 0.1900
v -0.257333 1.652925 0.728921 0.1450 0.1371 0.1900
v -0.334441 2.019176 0.544276 0.1450 0.1371 0.1900
v 0.334441 2.019176 0.544276 0.1450 0.1371 0.1900
v 0.369362 1.735177 0.671046 0.1450 0.1371 0.1900
v -0.369362 1.735177 0.671046 0.1450 0.1371 0.1900
v 0.096339 2.201041 0.616476 0.1450 0.1371 0.1900
v -0.096339 2.201041 0.616476 0.1450 0.1371 0.1900
v 0.489408 1.656222 0.539235 0.1450 0.1371 0.1900
v 0.391442 2.102530 0.455240 0.1450 0.1371 0.1900
v 0.118417 1.527654 0.730721 0.1450 0.1371 0.1900
v -0.118417 1.527654 0.730721 0.1450 0.1371 0.1900
v -0.489408 1.656222 0.539235 0.1450 0.1371 0.1900
v -0.391442 2.102530 0.455240 0.1450 0.1371 0.1900
v 0.277396 2.201041 0.550577 0.1450 0.1371 0.1900
v -0.340969 1.527654 0.655392 0.1450 0.1371 0.1900
v -0.277396 2.201041 0.550577 0.1450 0.1371 0.1900
v 0.340969 1.527654 0.655392 0.1450 0.1371 0.1900
vn 0.9841 -0.1778 -0.0000
vn 0.9146 0.4043 -0.0000
vn 0.9247 -0.1778 0.3366
vn 0.7754 0.5378 0.3310
vn 0.7540 -0.1768 0.6327
vn 0.4942 0.7357 0.4632
vn 0.4920 -0.1778 0.8522
vn 0.3013 0.7980 0.5219
vn 0.1709 -0.1778 0.9691
vn 0.1541 0.7357 0.6596
vn -0.1709 -0.1778 0.9691
vn -0.1010 0.5378 0.8370
vn -0.4920 -0.1778 0.8522
vn -0.4573 0.4043 0.7921
vn -0.7540 -0.1768 0.6327
vn -0.6743 0.5378 0.5060
vn -0.9247 -0.1778 0.3366
vn -0.6483 0.7357 0.1964
vn -0.9841 -0.1778 -0.0000
vn -0.6026 0.7980 -0.0000
vn -0.9247 -0.1778 -0.3366
vn -0.6483 0.7357 -0.1964
vn -0.7538 -0.1778 -0.6325
vn -0.6743 0.5378 -0.5060
vn -0.4920 -0.1778 -0.8522
vn -0.4573 0.4043 -0.7921
vn -0.1709 -0.1778 -0.9691
vn -0.1010 0.5378 -0.8370
vn 0.1709 -0.1778 -0.9691
vn 0.1541 0.7357 -0.6596
vn 0.4920 -0.1778 -0.8522
vn 0.3013 0.7980 -0.5219
vn 0.7538 -0.1778 -0.6325
vn 0.4942 0.7357 -0.4632
vn 0.9247 -0.1778 -0.3366
vn 0.7754 0.5378 -0.3310
vn 0.9117 0.4109 -0.0000
vn 0.8130 0.4345 0.3877
vn 0.8011 0.3907 0.4535
vn 0.5809 0.7552 0.3037
vn 0.1433 0.7300 0.6682
vn -0.1433 0.7300 0.6682
vn -0.5809 0.7552 0.3037
vn -0.8011 0.3907 0.4535
vn -0.8130 0.4345 0.3877
vn -0.9117 0.4109 -0.0000
vn -0.8567 0.4109 -0.3118
vn -0.6984 0.4109 -0.5860
vn -0.4558 0.4109 -0.7895
vn -0.1583 0.4109 -0.8978
vn 0.1583 0.4109 -0.8978
vn 0.4558 0.4109 -0.7895
vn 0.6984 0.4109 -0.5860
vn 0.8567 0.4109 -0.3118
vn 0.9423 0.0728 0.3267
vn 0.6347 0.1973 0.7472
vn 0.4225 0.2699 0.8652
vn 0.1829 0.1701 0.9683
vn -0.1829 0.1701 0.9683
vn -0.4225 0.2699 0.8652
vn -0.6347 0.1973 0.7472
vn -0.9423 0.0728 0.3267
vn -0.9955 0.0944 -0.0000
vn -0.9355 0.0944 -0.3405
vn -0.7626 0.0944 -0.6399
vn -0.4978 0.0944 -0.8622
vn -0.1729 0.0944 -0.9804
vn 0.1729 0.0944 -0.9804
vn 0.4978 0.0944 -0.8622
vn 0.7626 0.0944 -0.6399
vn 0.9355 0.0944 -0.3405
vn 0.9955 0.0944 -0.0000
vn 0.6306 -0.7761 -0.0000
vn 0.5926 -0.7761 0.2157
vn 0.4830 -0.7761 0.4053
vn 0.3153 -0.7761 0.5461
vn 0.1095 -0.7761 0.6210
vn -0.1095 -0.7761 0.6210
vn -0.3153 -0.7761 0.5461
vn -0.4831 -0.7761 0.4053
vn -0.5925 -0.7761 0.2157
vn -0.6306 -0.7761 -0.0000
vn -0.5925 -0.7761 -0.2157
vn -0.4831 -0.7761 -0.4053
vn -0.3153 -0.7761 -0.5461
vn -0.1095 -0.7761 -0.6210
vn 0.1095 -0.7761 -0.6210
vn 0.3153 -0.7761 -0.5461
vn 0.4830 -0.7761 -0.4053
vn 0.5925 -0.7761 -0.2157
vn 0.7312 0.6821 -0.0000
vn 0.6871 0.6821 0.2501
vn 0.5656 0.6745 0.4746
vn 0.3656 0.6821 0.6333
vn 0.1270 0.6821 0.7201
vn -0.1270 0.6821 0.7201
vn -0.3656 0.6821 0.6333
vn -0.5656 0.6745 0.4746
vn -0.6871 0.6821 0.2501
vn -0.7312 0.6821 -0.0000
vn -0.6871 0.6821 -0.2501
vn -0.5601 0.6821 -0.4700
vn -0.3656 0.6821 -0.6333
vn -0.1270 0.6821 -0.7201
vn 0.1270 0.6821 -0.7201
vn 0.3656 0.6821 -0.6333
vn 0.5601 0.6821 -0.4700
vn 0.6871 0.6821 -0.2501
vn 0.9437 0.3307 -0.0000
vn -0.4719 0.3307 -0.8173
vn -0.4719 0.3307 0.8173
vn -0.0000 1.0000 -0.0000
vn -0.4787 0.5258 0.7031
vn -0.7169 0.4126 0.5620
vn -0.1342 0.4369 0.8895
vn 0.1342 0.4369 0.8895
vn 0.4787 0.5258 0.7031
vn 0.7169 0.4126 0.5620
vn 0.7577 0.1650 0.6315
vn -0.7577 0.1650 0.6315
vn 0.4534 0.1969 0.8693
vn 0.1663 0.2444 0.9553
vn -0.1663 0.2444 0.9553
vn -0.4534 0.1969 0.8693
vn 0.4906 0.3661 0.7907
vn 0.3424 -0.0553 0.9379
vn 0.1431 0.4003 0.9051
vn 0.1012 -0.0377 0.9942
vn -0.1431 0.4003 0.9051
vn -0.1012 -0.0377 0.9942
vn -0.4906 0.3661 0.7907
vn -0.3424 -0.0553 0.9379
vn -0.7362 0.2805 0.6159
vn 0.7362 0.2805 0.6159
vn 0.6174 0.1400 0.7741
vn -0.6174 0.1400 0.7741
vn 0.1165 0.7887 0.6037
vn -0.1165 0.7887 0.6037
vn 0.7537 0.0880 0.6512
vn 0.8090 0.3734 0.4541
vn 0.1400 -0.2577 0.9560
vn -0.1400 -0.2577 0.9560
vn -0.7537 0.0880 0.6512
vn -0.8090 0.3734 0.4541
vn 0.5043 0.6625 0.5539
vn -0.4814 -0.2028 0.8527
vn -0.5043 0.6625 0.5539
vn 0.4814 -0.2028 0.8527
vt 1.000000 1.000000
vt 0.944444 0.875000
vt 1.000000 0.875000
vt 0.888889 1.000000
vt 0.888889 0.875000
vt 0.833333 0.875000
vt 0.833333 1.000000
vt 0.777778 0.875000
vt 0.777778 1.000000
vt 0.722222 0.875000
vt 0.722222 1.000000
vt 0.666667 0.875000
vt 0.611111 1.000000
vt 0.611111 0.875000
vt 0.555555 0.875000
vt 0.500000 1.000000
vt 0.500000 0.875000
vt 0.444444 0.875000
vt 0.388889 1.000000
vt 0.388889 0.875000
vt 0.333333 0.875000
vt 0.333333 1.000000
vt 0.277778 0.875000
vt 0.277778 1.000000
vt 0.222222 0.875000
vt 0.166666 1.000000
vt 0.166666 0.875000
vt 0.111111 0.875000
vt 0.111111 1.000000
vt 0.055555 0.875000
vt 0.055555 1.000000
vt -0.000000 0.875000
vt 0.888889 0.500000
vt 0.944444 0.500000
vt 0.055555 0.750000
vt -0.000000 0.620925
vt 0.055555 0.620925
vt 0.111111 0.750000
vt 0.111111 0.620925
vt 0.166666 0.750000
vt 0.166666 0.620925
vt 0.222222 0.750000
vt 0.222222 0.620925
vt 0.277778 0.750000
vt 0.277778 0.620925
vt 0.333333 0.620925
vt 0.388889 0.620925
vt 0.333333 0.750000
vt 0.444444 0.750000
vt 0.444444 0.620925
vt 0.500000 0.620925
vt 0.555555 0.750000
vt 0.555555 0.620925
vt 0.611111 0.620925
vt 0.777791 0.742476
vt 0.833347 0.742476
vt 0.833347 0.742476
vt 0.621250 0.628449
vt 0.623706 0.742476
vt 0.722233 0.628449
vt 0.777789 0.628449
vt 0.722236 0.742476
vt 0.878750 0.628449
vt 0.876294 0.742476
vt 0.878750 0.628449
vt 0.944444 0.750000
vt 0.888889 0.620925
vt 0.944444 0.620925
vt 1.000000 0.620925
vt 1.000000 0.500000
vt 0.833333 0.620925
vt 0.833333 0.500000
vt 0.777778 0.500000
vt 0.777778 0.620925
vt 0.722222 0.500000
vt 0.722222 0.620925
vt 0.666667 0.500000
vt 0.666666 0.620925
vt 0.611111 0.500000
vt 0.555555 0.500000
vt 0.500000 0.500000
vt 0.444444 0.500000
vt 0.388889 0.500000
vt 0.333333 0.500000
vt 0.277778 0.500000
vt 0.222222 0.500000
vt 0.166666 0.500000
vt 0.111111 0.500000
vt 0.055555 0.500000
vt -0.000000 0.500000
vt 0.957846 0.370000
vt 0.595731 0.066149
vt 0.542154 0.370000
vt -0.000000 0.750000
vt 0.388889 0.750000
vt 0.500000 0.750000
vt 0.611111 0.750000
vt 0.666667 0.750000
vt 0.722222 0.750000
vt 0.777778 0.750000
vt 0.833333 0.750000
vt 0.888889 0.750000
vt 1.000000 0.750000
vt 0.000000 0.000000
vt 0.944444 1.000000
vt 0.666667 1.000000
vt 0.555555 1.000000
vt 0.444444 1.000000
vt 0.222222 1.000000
vt -0.000000 1.000000
vt 0.666680 0.742476
vt 0.722236 0.742476
vt 0.833345 0.628449
vt 0.666678 0.628449
vt 0.666680 0.742476
vt 0.833345 0.628449
vt 0.876294 0.742476
vt 0.777789 0.628449
vt 0.667915 0.475526
vt 0.750000 0.490000
vt 0.832085 0.475526
vt 0.904269 0.433851
vt 0.986354 0.291676
vt 0.986354 0.208324
vt 0.957846 0.130000
vt 0.904269 0.066149
vt 0.832085 0.024474
vt 0.750000 0.010000
vt 0.667915 0.024474
vt 0.542154 0.130000
vt 0.513646 0.208324
vt 0.513646 0.291676
vt 0.595731 0.433851
s 1
usemtl Material.001
f 2/1/2 92/2/92 91/3/91
f 92/2/92 6/4/6 93/5/93
f 6/4/6 94/6/94 93/5/93
f 8/7/8 95/8/95 94/6/94
f 10/9/10 96/10/96 95/8/95
f 12/11/12 97/12/97 96/10/96
f 97/12/97 16/13/16 98/14/98
f 16/13/16 99/15/99 98/14/98
f 99/15/99 20/16/20 100/17/100
f 20/16/20 101/18/101 100/17/100
f 101/18/101 24/19/24 102/20/102
f 24/19/24 103/21/103 102/20/102
f 26/22/26 104/23/104 103/21/103
f 28/24/28 105/25/105 104/23/104
f 105/25/105 32/26/32 106/27/106
f 32/26/32 107/28/107 106/27/106
f 34/29/34 108/30/108 107/28/107
f 36/31/36 91/32/91 108/30/108
f 5/33/5 74/34/74 3/34/3
f 54/35/54 72/36/72 71/37/71
f 53/38/53 71/37/71 70/39/70
f 52/40/52 70/39/70 69/41/69
f 51/42/51 69/41/69 68/43/68
f 50/44/50 68/43/68 67/45/67
f 66/46/66 50/44/50 67/45/67
f 65/47/65 49/48/49 66/46/66
f 47/49/47 65/47/65 64/50/64
f 63/51/63 47/49/47 64/50/64
f 45/52/45 63/51/63 62/53/62
f 120/54/120 45/52/45 62/53/62
f 137/55/137 125/56/125 145/57/145
f 143/58/143 133/59/133 144/59/144
f 142/60/142 128/61/128 130/60/130
f 138/62/138 127/55/127 137/55/137
f 139/63/139 134/64/134 135/65/135
f 38/66/38 119/67/119 55/68/55
f 72/69/72 38/66/38 55/68/55
f 1/70/1 55/68/55 3/34/3
f 55/68/55 5/33/5 3/34/3
f 5/33/5 121/71/121 7/72/7
f 121/71/121 9/73/9 7/72/7
f 122/74/122 11/75/11 9/73/9
f 123/76/123 13/77/13 11/75/11
f 124/78/124 15/79/15 13/77/13
f 15/79/15 62/53/62 17/80/17
f 17/80/17 63/51/63 19/81/19
f 19/81/19 64/50/64 21/82/21
f 64/50/64 23/83/23 21/82/21
f 65/47/65 25/84/25 23/83/23
f 66/46/66 27/85/27 25/84/25
f 67/45/67 29/86/29 27/85/27
f 68/43/68 31/87/31 29/86/29
f 69/41/69 33/88/33 31/87/31
f 70/39/70 35/89/35 33/88/33
f 35/89/35 72/36/72 1/90/1
f 76/91/76 84/92/84 88/93/88
f 15/79/15 79/77/79 13/77/13
f 25/84/25 84/83/84 23/83/23
f 35/89/35 89/88/89 33/88/33
f 11/75/11 77/73/77 9/73/9
f 21/82/21 82/81/82 19/81/19
f 31/87/31 87/86/87 29/86/29
f 7/72/7 75/33/75 5/33/5
f 17/80/17 80/79/80 15/79/15
f 3/34/3 73/70/73 1/70/1
f 27/85/27 85/84/85 25/84/25
f 1/90/1 90/89/90 35/89/35
f 13/77/13 78/75/78 11/75/11
f 23/83/23 83/82/83 21/82/21
f 33/88/33 88/87/88 31/87/31
f 9/73/9 76/72/76 7/72/7
f 19/81/19 81/80/81 17/80/17
f 29/86/29 86/85/86 27/85/27
f 108/30/108 37/94/37 54/35/54
f 107/28/107 54/35/54 53/38/53
f 106/27/106 53/38/53 52/40/52
f 105/25/105 52/40/52 51/42/51
f 104/23/104 51/42/51 50/44/50
f 103/21/103 50/44/50 49/48/49
f 102/20/102 49/48/49 48/95/48
f 101/18/101 48/95/48 47/49/47
f 100/17/100 47/49/47 46/96/46
f 99/15/99 46/96/46 45/52/45
f 98/14/98 45/52/45 114/97/114
f 113/98/113 98/14/98 114/97/114
f 96/10/96 113/98/113 115/99/115
f 95/8/95 115/99/115 116/100/116
f 117/101/117 95/8/95 116/100/116
f 93/5/93 117/101/117 118/102/118
f 38/66/38 93/5/93 118/102/118
f 91/3/91 38/66/38 37/103/37
f 109/104/109 6/4/6 4/105/4
f 109/104/109 8/7/8 6/4/6
f 111/104/111 8/7/8 109/104/109
f 111/104/111 12/11/12 10/9/10
f 111/104/111 14/106/14 12/11/12
f 111/104/111 16/13/16 14/106/14
f 111/104/111 18/107/18 16/13/16
f 111/104/111 20/16/20 18/107/18
f 110/104/110 20/16/20 111/104/111
f 110/104/110 24/19/24 22/108/22
f 110/104/110 26/22/26 24/19/24
f 110/104/110 28/24/28 26/22/26
f 110/104/110 30/109/30 28/24/28
f 110/104/110 32/26/32 30/109/30
f 109/104/109 32/26/32 110/104/110
f 109/104/109 36/31/36 34/29/34
f 109/104/109 2/110/2 36/31/36
f 109/104/109 4/105/4 2/1/2
f 111/104/111 10/9/10 8/7/8
f 110/104/110 22/108/22 20/16/20
f 109/104/109 34/29/34 32/26/32
f 111/104/111 109/104/109 112/104/112
f 110/104/110 111/104/111 112/104/112
f 109/104/109 110/104/110 112/104/112
f 43/111/43 114/97/114 44/59/44
f 42/112/42 113/98/113 43/111/43
f 41/55/41 115/99/115 42/112/42
f 41/55/41 117/101/117 116/100/116
f 40/56/40 118/102/118 117/101/117
f 39/64/39 119/67/119 118/102/118
f 44/59/44 120/54/120 61/58/61
f 57/113/57 119/67/119 56/65/56
f 58/61/58 121/71/121 57/113/57
f 59/60/59 122/74/122 58/61/58
f 59/60/59 124/78/124 123/76/123
f 60/114/60 120/54/120 124/78/124
f 131/111/131 136/58/136 132/114/132
f 129/112/129 132/114/132 130/60/130
f 127/55/127 130/60/130 128/61/128
f 126/113/126 127/55/127 128/61/128
f 135/65/135 125/56/125 126/113/126
f 142/60/142 132/114/132 146/114/146
f 147/115/147 133/59/133 131/111/131
f 148/116/148 135/65/135 126/113/126
f 145/57/145 134/64/134 140/117/140
f 146/114/146 136/58/136 143/58/143
f 138/62/138 131/111/131 129/112/129
f 141/118/141 126/113/126 128/61/128
f 58/61/58 148/116/148 141/118/141
f 42/112/42 147/115/147 138/62/138
f 60/114/60 143/58/143 61/58/61
f 40/56/40 140/117/140 39/64/39
f 57/113/57 139/63/139 148/116/148
f 43/111/43 144/59/144 147/115/147
f 59/60/59 146/114/146 60/114/60
f 56/65/56 140/117/140 139/63/139
f 42/112/42 137/55/137 41/55/41
f 58/61/58 142/60/142 59/60/59
f 61/58/61 144/59/144 44/59/44
f 41/55/41 145/57/145 40/56/40
f 2/1/2 4/105/4 92/2/92
f 92/2/92 4/105/4 6/4/6
f 6/4/6 8/7/8 94/6/94
f 8/7/8 10/9/10 95/8/95
f 10/9/10 12/11/12 96/10/96
f 12/11/12 14/106/14 97/12/97
f 97/12/97 14/106/14 16/13/16
f 16/13/16 18/107/18 99/15/99
f 99/15/99 18/107/18 20/16/20
f 20/16/20 22/108/22 101/18/101
f 101/18/101 22/108/22 24/19/24
f 24/19/24 26/22/26 103/21/103
f 26/22/26 28/24/28 104/23/104
f 28/24/28 30/109/30 105/25/105
f 105/25/105 30/109/30 32/26/32
f 32/26/32 34/29/34 107/28/107
f 34/29/34 36/31/36 108/30/108
f 36/31/36 2/110/2 91/32/91
f 5/33/5 75/33/75 74/34/74
f 54/35/54 37/94/37 72/36/72
f 53/38/53 54/35/54 71/37/71
f 52/40/52 53/38/53 70/39/70
f 51/42/51 52/40/52 69/41/69
f 50/44/50 51/42/51 68/43/68
f 66/46/66 49/48/49 50/44/50
f 65/47/65 48/95/48 49/48/49
f 47/49/47 48/95/48 65/47/65
f 63/51/63 46/96/46 47/49/47
f 45/52/45 46/96/46 63/51/63
f 120/54/120 114/97/114 45/52/45
f 137/55/137 127/55/127 125/56/125
f 143/58/143 136/58/136 133/59/133
f 142/60/142 141/118/141 128/61/128
f 138/62/138 129/112/129 127/55/127
f 139/63/139 140/117/140 134/64/134
f 38/66/38 118/102/118 119/67/119
f 72/69/72 37/103/37 38/66/38
f 1/70/1 72/69/72 55/68/55
f 55/68/55 119/67/119 5/33/5
f 5/33/5 119/67/119 121/71/121
f 121/71/121 122/74/122 9/73/9
f 122/74/122 123/76/123 11/75/11
f 123/76/123 124/78/124 13/77/13
f 124/78/124 120/54/120 15/79/15
f 15/79/15 120/54/120 62/53/62
f 17/80/17 62/53/62 63/51/63
f 19/81/19 63/51/63 64/50/64
f 64/50/64 65/47/65 23/83/23
f 65/47/65 66/46/66 25/84/25
f 66/46/66 67/45/67 27/85/27
f 67/45/67 68/43/68 29/86/29
f 68/43/68 69/41/69 31/87/31
f 69/41/69 70/39/70 33/88/33
f 70/39/70 71/37/71 35/89/35
f 35/89/35 71/37/71 72/36/72
f 90/119/90 73/120/73 74/121/74
f 74/121/74 75/122/75 76/91/76
f 76/91/76 77/123/77 78/124/78
f 78/124/78 79/125/79 80/126/80
f 80/126/80 81/127/81 82/128/82
f 82/128/82 83/129/83 84/92/84
f 84/92/84 85/130/85 86/131/86
f 86/131/86 87/132/87 88/93/88
f 88/93/88 89/133/89 90/119/90
f 90/119/90 74/121/74 76/91/76
f 76/91/76 78/124/78 80/126/80
f 80/126/80 82/128/82 84/92/84
f 84/92/84 86/131/86 88/93/88
f 88/93/88 90/119/90 76/91/76
f 76/91/76 80/126/80 84/92/84
f 15/79/15 80/79/80 79/77/79
f 25/84/25 85/84/85 84/83/84
f 35/89/35 90/89/90 89/88/89
f 11/75/11 78/75/78 77/73/77
f 21/82/21 83/82/83 82/81/82
f 31/87/31 88/87/88 87/86/87
f 7/72/7 76/72/76 75/33/75
f 17/80/17 81/80/81 80/79/80
f 3/34/3 74/34/74 73/70/73
f 27/85/27 86/85/86 85/84/85
f 1/90/1 73/90/73 90/89/90
f 13/77/13 79/77/79 78/75/78
f 23/83/23 84/83/84 83/82/83
f 33/88/33 89/88/89 88/87/88
f 9/73/9 77/73/77 76/72/76
f 19/81/19 82/81/82 81/80/81
f 29/86/29 87/86/87 86/85/86
f 108/30/108 91/32/91 37/94/37
f 107/28/107 108/30/108 54/35/54
f 106/27/106 107/28/107 53/38/53
f 105/25/105 106/27/106 52/40/52
f 104/23/104 105/25/105 51/42/51
f 103/21/103 104/23/104 50/44/50
f 102/20/102 103/21/103 49/48/49
f 101/18/101 102/20/102 48/95/48
f 100/17/100 101/18/101 47/49/47
f 99/15/99 100/17/100 46/96/46
f 98/14/98 99/15/99 45/52/45
f 113/98/113 97/12/97 98/14/98
f 96/10/96 97/12/97 113/98/113
f 95/8/95 96/10/96 115/99/115
f 117/101/117 94/6/94 95/8/95
f 93/5/93 94/6/94 117/101/117
f 38/66/38 92/2/92 93/5/93
f 91/3/91 92/2/92 38/66/38
f 43/111/43 113/98/113 114/97/114
f 42/112/42 115/99/115 113/98/113
f 41/55/41 116/100/116 115/99/115
f 41/55/41 40/56/40 117/101/117
f 40/56/40 39/64/39 118/102/118
f 39/64/39 56/65/56 119/67/119
f 44/59/44 114/97/114 120/54/120
f 57/113/57 121/71/121 119/67/119
f 58/61/58 122/74/122 121/71/121
f 59/60/59 123/76/123 122/74/122
f 59/60/59 60/114/60 124/78/124
f 60/114/60 61/58/61 120/54/120
f 131/111/131 133/59/133 136/58/136
f 129/112/129 131/111/131 132/114/132
f 127/55/127 129/112/129 130/60/130
f 126/113/126 125/56/125 127/55/127
f 135/65/135 134/64/134 125/56/125
f 142/60/142 130/60/130 132/114/132
f 147/115/147 144/59/144 133/59/133
f 148/116/148 139/63/139 135/65/135
f 145/57/145 125/56/125 134/64/134
f 146/114/146 132/114/132 136/58/136
f 138/62/138 147/115/147 131/111/131
f 141/118/141 148/116/148 126/113/126
f 58/61/58 57/113/57 148/116/148
f 42/112/42 43/111/43 147/115/147
f 60/114/60 146/114/146 143/58/143
f 40/56/40 145/57/145 140/117/140
f 57/113/57 56/65/56 139/63/139
f 43/111/43 44/59/44 144/59/144
f 59/60/59 142/60/142 146/114/146
f 56/65/56 39/64/39 140/117/140
f 42/112/42 138/62/138 137/55/137
f 58/61/58 141/118/141 142/60/142
f 61/58/61 143/58/143 144/59/144
f 41/55/41 137/55/137 145/57/145

View File

@@ -10,28 +10,39 @@ struct polygon {
bool small = false;
decimal baryFactor;
decimal dot00;
decimal dot01;
decimal dot11;
vec2 v0;
vec2 v1;
decimal bounding[4]; // min x, max x, min y, max y
vec3 normals[3];
vec3 colors[3];
vec3 barycentrics;
vec3 boundingBarycentrics;
polygon(const vec3 &v1, const vec3 &v2, const vec3 &v3)
: points{v1, v2, v3}, delta{} {}
polygon() : points{}, delta{} {}
void calcDelta() {
for (int i = 0; i < 3; i++) {
int n = (i + 1) % 3;
// for (int i = 0; i < 3; i++) {
// int n = (i + 1) % 3;
//
// delta[i * 3] = points[i].y() - points[n].y();
// delta[i * 3 + 1] = points[n].x() - points[i].x();
// delta[i * 3 + 2] =
// points[i].x() * points[n].y() - points[i].y() *
// points[n].x();
// if (delta[i * 3].i == 0 && delta[i * 3 + 1].i == 0)
// small = true;
// }
v0 = vec2(points[2]) - vec2(points[0]);
v1 = vec2(points[1]) - vec2(points[0]);
dot00 = v0 * v0;
dot01 = v1 * v0;
dot11 = v1 * v1;
delta[i * 3] = points[i].y() - points[n].y();
delta[i * 3 + 1] = points[n].x() - points[i].x();
delta[i * 3 + 2] =
points[i].x() * points[n].y() - points[i].y() * points[n].x();
if (delta[i * 3].i == 0 && delta[i * 3 + 1].i == 0)
small = true;
}
bounding[0] = points[0].x();
bounding[1] = points[0].x();
bounding[2] = points[0].y();
@@ -47,11 +58,14 @@ struct polygon {
bounding[3] = points[i].y();
}
baryFactor =
(points[1].x() - points[0].x()) * (points[2].y() - points[1].y()) -
(points[1].y() - points[0].y()) * (points[2].x() - points[1].x());
if (baryFactor.isSmall()) {
// baryFactor =
// (points[1].x() - points[0].x()) * (points[2].y() - points[1].y())
// - (points[1].y() - points[0].y()) * (points[2].x() -
// points[1].x());
std::cout << dot00 << " " << dot01 << " " << dot11 << std::endl;
baryFactor = dot00 * dot11 - dot01 * dot01;
std::cout << "baryFactor:" << baryFactor << std::endl;
if (baryFactor.i == 0) {
small = true;
} else
baryFactor = decimal(1.0) / baryFactor;
@@ -62,10 +76,10 @@ struct polygon {
}
vec3 avgNormal() {
vec3 result;
for (int i = 0; i < 3; i++) {
result += normals[i];
}
vec3 result = normals[0] + normals[1] + normals[2];
// for (int i = 0; i < 3; i++) {
// result += normals[i];
// }
return result * decimal(0.3333);
}
@@ -74,7 +88,7 @@ struct polygon {
// return false;
for (int i = 0; i < 3; i++) {
if (small)
return true;
return false;
vec3 d = p;
if ((d.x() * delta[i * 3] + d.y() * delta[i * 3 + 1] +
delta[i * 3 + 2]) > decimal(0.2))
@@ -86,9 +100,9 @@ struct polygon {
if (small)
return true;
else
return (barycentrics[0] >= decimal(-0.01)) &&
(barycentrics[1] >= decimal(-0.01)) &&
(barycentrics[2] >= decimal(-0.01));
return (barycentrics[0] >= decimal(-0.0)) &&
(barycentrics[1] >= decimal(-0.0)) &&
(barycentrics[0] + barycentrics[1] <= decimal(1.0));
}
friend std::ostream &operator<<(std::ostream &os, const polygon &p) {
for (int i = 0; i < 3; i++) {
@@ -119,13 +133,25 @@ struct polygon {
// if (small)
// return vec3(decimal(0.333), decimal(0.333), decimal(0.333));
barycentrics[0] = (points[1].x() - s.x()) * (points[2].y() - s.y()) -
(points[2].x() - s.x()) * (points[1].y() - s.y());
barycentrics[1] = (points[2].x() - s.x()) * (points[0].y() - s.y()) -
(points[0].x() - s.x()) * (points[2].y() - s.y());
vec2 v2 = vec2(s) - vec2(points[0]);
decimal dot02 = v0 * v2;
decimal dot12 = v1 * v2;
barycentrics = {};
barycentrics[0] = dot11 * dot02 - dot01 * dot12;
barycentrics[1] = dot00 * dot12 - dot01 * dot02;
// barycentrics[0] = (points[1].x() - s.x()) * (points[2].y() -
// s.y()) -
// (points[2].x() - s.x()) * (points[1].y() -
// s.y());
// barycentrics[1] = (points[2].x() - s.x()) * (points[0].y() -
// s.y()) -
// (points[0].x() - s.x()) * (points[2].y() -
// s.y());
barycentrics = barycentrics * baryFactor;
barycentrics[2] = decimal(1.0) - barycentrics[1] - barycentrics[0];
// return result;
// barycentrics[0]; return result;
boundingBarycentrics = vec3::max(
vec3::min(barycentrics, vec3(1.0, 1.0, 1.0)), vec3(0.0, 0.0, 0.0));
}

View File

@@ -6,11 +6,10 @@
#include "model.hpp"
#include "polygon.hpp"
#include "rendertarget.hpp"
#include <bits/stdc++.h>
#include <cstring>
#include <memory.h>
#define SCREEN_SPACE_SIZE 8.0
#define SCREEN_SPACE_SIZE 2.0
class Renderer {
@@ -22,9 +21,9 @@ class Renderer {
void toScreenSpace(vec3 *np, mat4 matrix) {
vec4 tp = (matrix * vec4(*np, decimal(1.0f)));
tp.x() = tp.x() / tp.z() * decimal(2.0) * decimal(SCREEN_SPACE_SIZE) +
tp.x() = tp.x() / tp.z() * decimal(SCREEN_SPACE_SIZE) +
decimal(SCREEN_SPACE_SIZE);
tp.y() = tp.y() / tp.z() * decimal(2.0) * decimal(SCREEN_SPACE_SIZE) +
tp.y() = tp.y() / tp.z() * decimal(SCREEN_SPACE_SIZE) +
decimal(SCREEN_SPACE_SIZE);
*np = vec3(tp.x(), tp.y(), tp.z());
}
@@ -41,12 +40,6 @@ class Renderer {
decimal((float)(target->height / SCREEN_SPACE_SIZE / 2));
// TODO clear target with memset
if (clearTarget) {
// memset((wchar_t *)target->pixels, 0,
// target->height * target->width * sizeof(target[0]));
target->clearDepth();
target->clearTarget();
}
vec3 verts[model->verts.size()] = {};
@@ -79,22 +72,37 @@ class Renderer {
int startX = std::max<int>(
(testP.bounding[0] * invWidthScale).i >> SHIFT_AMOUNT, 0);
int endX = std::min<int>((testP.bounding[1] * invWidthScale).i >>
SHIFT_AMOUNT,
(uint32_t)target->width - 1);
int endX = std::max<int>(
std::min<int>((testP.bounding[1] * invWidthScale).i >>
SHIFT_AMOUNT,
(uint32_t)target->width - 1),
0);
int startY = std::max<int>(
(testP.bounding[2] * invHeightScale).i >> SHIFT_AMOUNT, 0);
int endY = std::min<int>((testP.bounding[3] * invHeightScale).i >>
SHIFT_AMOUNT,
target->height - 1);
std::cout << "Polys:\n" << testP.baryFactor << "\n";
for (int i = 0; i < 3; i++) {
std::cout << testP.points[i];
}
std::cout << "Boundings:\n";
std::cout << testP.bounding[0] << " " << startX << "\n";
std::cout << testP.bounding[1] << " " << endX << "\n";
std::cout << testP.bounding[2] << " " << startY << "\n";
std::cout << testP.bounding[3] << " " << endY << "\n";
vec3 pos = vec3(testP.bounding[0], testP.bounding[2], 0.0);
for (int x = startX; x < endX; x++) {
for (int y = startY; y < endY; y++) {
for (int x = 0; x < target->width; x++) {
for (int y = 0; y < target->height; y++) {
// for (int x = startX; x < endX; x++) {
// for (int y = startY; y < endY; y++) {
if (testP.depContains(pos)) {
testP.calcBarycentric(pos);
if (testP.contains(pos)) {
testP.calcBarycentric(pos);
// testP.calcBarycentric(pos);
decimal depth = testP.calcDepth();
if (depth < target->getDepth(x, y)) {
// std::cout << factors << std::endl;
@@ -105,8 +113,8 @@ class Renderer {
decimal(0.5);
;
target->setDepth(x, y, depth);
target->set(x, y,
(color * decimal(120.0)) * lightFac);
// target->set(x, y,
// (color * decimal(120.0)) * lightFac);
// target->set(x, y,
// vec3(lightFac * decimal(200.0), 0, 0));
@@ -117,8 +125,8 @@ class Renderer {
// x, y,
// (testP.avgNormal() + vec3(1.0, 1.0, 1.0)) *
// decimal(120.0));
// target->set(x, y,
// testP.barycentrics * decimal(200.0));
target->set(x, y,
testP.barycentrics * decimal(200.0));
// if (!factors.isSmall())
// target->set(x, y, vec3(0., 255.0, 0.));
}

26
src/gameObjs.h Normal file
View File

@@ -0,0 +1,26 @@
#include "models/plane.h"
#include "renderer.h"
typedef struct {
mat4x4 transform;
vec3 velocity;
model model;
} gameObj;
gameObj rocket = {
{{1., 0., 0., 0.}, {0., 1., 0., 0.}, {0., 0., 1., 0.}, {0., -1., -10., 0.}},
{0.0, 0.0, 0.0},
testModel};
const gameObj *allGameObjs[] = {&rocket};
int vertBufferSize() {
int count = sizeof(allGameObjs) / sizeof(void *);
int result = 0;
for (int i = 0; i < count; i++) {
if (result < allGameObjs[i]->model.vert_size) {
result = allGameObjs[i]->model.vert_size;
}
}
return result * sizeof(vec4);
}

612
src/linmath.h Normal file
View File

@@ -0,0 +1,612 @@
#ifndef LINMATH_H
#define LINMATH_H
#include <math.h>
#include <stdio.h>
#include <string.h>
#ifdef LINMATH_NO_INLINE
#define LINMATH_H_FUNC static
#else
#define LINMATH_H_FUNC static inline
#endif
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define REPEAT_1(FN) FN(0)
#define REPEAT_2(FN) REPEAT_1(FN) FN(1)
#define REPEAT_3(FN) REPEAT_2(FN) FN(2)
#define REPEAT_4(FN) REPEAT_3(FN) FN(3)
#define add(i) r[i] = a[i] + b[i];
#define set(i) r[i] = v;
#define sub(i) r[i] = a[i] - b[i];
#define scale(i) r[i] = v[i] * s;
#define add_scale(i) r[i] = v[i] * s;
#define dot(i) p += a[i] * b[i];
#define min(i) r[i] = a[i] < b[i] ? a[i] : b[i];
#define max(i) r[i] = a[i] > b[i] ? a[i] : b[i];
#define dup(i) r[i] = src[i];
#define LINMATH_H_DEFINE_VEC(n) \
typedef float vec##n[n]; \
LINMATH_H_FUNC void vec##n##_set(vec##n r, float const v) { \
REPEAT_##n(set); \
} \
LINMATH_H_FUNC void vec##n##_add(vec##n r, vec##n const a, vec##n const b) { \
REPEAT_##n(add); \
} \
\
LINMATH_H_FUNC void vec##n##_sub(vec##n r, vec##n const a, vec##n const b) { \
REPEAT_##n(sub); \
} \
\
LINMATH_H_FUNC void vec##n##_scale(vec##n r, vec##n const v, \
float const s) { \
REPEAT_##n(scale); \
} \
LINMATH_H_FUNC void vec##n##_add_scale(vec##n r, vec##n const v, \
float const s) { \
REPEAT_##n(add_scale); \
} \
LINMATH_H_FUNC void vec##n##_to_str(vec##n const v, char *b) { \
strcat(b, "("); \
for (int i = 0; i < n; ++i) { \
char s[20] = {0}; \
sprintf(s, "%f, ", v[i]); \
strcat(b, s); \
} \
b[strlen(b) - 2] = '\0'; \
strcat(b, ")"); \
} \
LINMATH_H_FUNC void vec##n##_print(vec##n const v) { \
char r[n * 20 + 5] = {0}; \
vec##n##_to_str(v, r); \
strcat(r, "\n"); \
printf("%s", r); \
} \
LINMATH_H_FUNC float vec##n##_dot(vec##n const a, vec##n const b) { \
float p = 0.f; \
REPEAT_##n(dot); \
return p; \
} \
LINMATH_H_FUNC float vec##n##_len(vec##n const v) { \
return sqrtf(vec##n##_dot(v, v)); \
} \
LINMATH_H_FUNC void vec##n##_norm(vec##n r, vec##n const v) { \
float k = 1.f / vec##n##_len(v); \
vec##n##_scale(r, v, k); \
} \
LINMATH_H_FUNC void vec##n##_min(vec##n r, vec##n const a, vec##n const b) { \
REPEAT_##n(min); \
} \
LINMATH_H_FUNC void vec##n##_max(vec##n r, vec##n const a, vec##n const b) { \
REPEAT_##n(max); \
} \
LINMATH_H_FUNC void vec##n##_dup(vec##n r, vec##n const src) { \
REPEAT_##n(dup) \
}
LINMATH_H_DEFINE_VEC(2)
LINMATH_H_DEFINE_VEC(3)
LINMATH_H_DEFINE_VEC(4)
#undef set
#undef add
#undef sub
#undef scale
#undef add_scale
#undef dot
#undef min
#undef max
#undef dup
LINMATH_H_FUNC void vec3_mul_cross(vec3 r, vec3 const a, vec3 const b) {
r[0] = a[1] * b[2] - a[2] * b[1];
r[1] = a[2] * b[0] - a[0] * b[2];
r[2] = a[0] * b[1] - a[1] * b[0];
}
LINMATH_H_FUNC void vec3_reflect(vec3 r, vec3 const v, vec3 const n) {
float p = 2.f * vec3_dot(v, n);
int i;
for (i = 0; i < 3; ++i)
r[i] = v[i] - p * n[i];
}
LINMATH_H_FUNC void vec4_mul_cross(vec4 r, vec4 const a, vec4 const b) {
r[0] = a[1] * b[2] - a[2] * b[1];
r[1] = a[2] * b[0] - a[0] * b[2];
r[2] = a[0] * b[1] - a[1] * b[0];
r[3] = 1.f;
}
LINMATH_H_FUNC void vec4_reflect(vec4 r, vec4 const v, vec4 const n) {
float p = 2.f * vec4_dot(v, n);
int i;
for (i = 0; i < 4; ++i)
r[i] = v[i] - p * n[i];
}
typedef vec4 mat4x4[4];
LINMATH_H_FUNC void mat4x4_getPos(vec3 r, mat4x4 const M) {
r[0] = M[3][0];
r[1] = M[3][1];
r[2] = M[3][2];
}
LINMATH_H_FUNC void mat4x4_identity(mat4x4 M) {
int i, j;
for (i = 0; i < 4; ++i)
for (j = 0; j < 4; ++j)
M[i][j] = i == j ? 1.f : 0.f;
}
LINMATH_H_FUNC void mat4x4_dup(mat4x4 M, mat4x4 const N) {
int i;
for (i = 0; i < 4; ++i)
vec4_dup(M[i], N[i]);
}
LINMATH_H_FUNC void mat4x4_row(vec4 r, mat4x4 const M, int i) {
int k;
for (k = 0; k < 4; ++k)
r[k] = M[k][i];
}
LINMATH_H_FUNC void mat4x4_col(vec4 r, mat4x4 const M, int i) {
int k;
for (k = 0; k < 4; ++k)
r[k] = M[i][k];
}
LINMATH_H_FUNC void mat4x4_transpose(mat4x4 M, mat4x4 const N) {
// Note: if M and N are the same, the user has to
// explicitly make a copy of M and set it to N.
int i, j;
for (j = 0; j < 4; ++j)
for (i = 0; i < 4; ++i)
M[i][j] = N[j][i];
}
LINMATH_H_FUNC void mat4x4_add(mat4x4 M, mat4x4 const a, mat4x4 const b) {
int i;
for (i = 0; i < 4; ++i)
vec4_add(M[i], a[i], b[i]);
}
LINMATH_H_FUNC void mat4x4_sub(mat4x4 M, mat4x4 const a, mat4x4 const b) {
int i;
for (i = 0; i < 4; ++i)
vec4_sub(M[i], a[i], b[i]);
}
LINMATH_H_FUNC void mat4x4_scale(mat4x4 M, mat4x4 const a, float k) {
int i;
for (i = 0; i < 4; ++i)
vec4_scale(M[i], a[i], k);
}
LINMATH_H_FUNC void mat4x4_scale_aniso(mat4x4 M, mat4x4 const a, float x,
float y, float z) {
vec4_scale(M[0], a[0], x);
vec4_scale(M[1], a[1], y);
vec4_scale(M[2], a[2], z);
vec4_dup(M[3], a[3]);
}
LINMATH_H_FUNC void mat4x4_mul(mat4x4 M, mat4x4 const a, mat4x4 const b) {
mat4x4 temp;
int k, r, c;
for (c = 0; c < 4; ++c)
for (r = 0; r < 4; ++r) {
temp[c][r] = 0.f;
for (k = 0; k < 4; ++k)
temp[c][r] += a[k][r] * b[c][k];
}
mat4x4_dup(M, temp);
}
LINMATH_H_FUNC void mat4x4_mul_vec4(vec4 r, mat4x4 const M, vec4 const v) {
int i, j;
for (j = 0; j < 4; ++j) {
r[j] = 0.f;
for (i = 0; i < 4; ++i)
r[j] += M[i][j] * v[i];
}
}
LINMATH_H_FUNC void mat4x4_translate(mat4x4 T, float x, float y, float z) {
mat4x4_identity(T);
T[3][0] = x;
T[3][1] = y;
T[3][2] = z;
}
LINMATH_H_FUNC void mat4x4_translate_in_place(mat4x4 M, float x, float y,
float z) {
vec4 t = {x, y, z, 0};
vec4 r;
int i;
for (i = 0; i < 4; ++i) {
mat4x4_row(r, M, i);
M[3][i] += vec4_dot(r, t);
}
}
LINMATH_H_FUNC void mat4x4_from_vec3_mul_outer(mat4x4 M, vec3 const a,
vec3 const b) {
int i, j;
for (i = 0; i < 4; ++i)
for (j = 0; j < 4; ++j)
M[i][j] = i < 3 && j < 3 ? a[i] * b[j] : 0.f;
}
LINMATH_H_FUNC void mat4x4_rotate(mat4x4 R, mat4x4 const M, float x, float y,
float z, float angle) {
float s = sinf(angle);
float c = cosf(angle);
vec3 u = {x, y, z};
if (vec3_len(u) > 1e-4) {
vec3_norm(u, u);
mat4x4 T;
mat4x4_from_vec3_mul_outer(T, u, u);
mat4x4 S = {{0, u[2], -u[1], 0},
{-u[2], 0, u[0], 0},
{u[1], -u[0], 0, 0},
{0, 0, 0, 0}};
mat4x4_scale(S, S, s);
mat4x4 C;
mat4x4_identity(C);
mat4x4_sub(C, C, T);
mat4x4_scale(C, C, c);
mat4x4_add(T, T, C);
mat4x4_add(T, T, S);
T[3][3] = 1.f;
mat4x4_mul(R, M, T);
} else {
mat4x4_dup(R, M);
}
}
LINMATH_H_FUNC void mat4x4_rotate_X(mat4x4 Q, mat4x4 const M, float angle) {
float s = sinf(angle);
float c = cosf(angle);
mat4x4 R = {{1.f, 0.f, 0.f, 0.f},
{0.f, c, s, 0.f},
{0.f, -s, c, 0.f},
{0.f, 0.f, 0.f, 1.f}};
mat4x4_mul(Q, M, R);
}
LINMATH_H_FUNC void mat4x4_rotate_Y(mat4x4 Q, mat4x4 const M, float angle) {
float s = sinf(angle);
float c = cosf(angle);
mat4x4 R = {{c, 0.f, -s, 0.f},
{0.f, 1.f, 0.f, 0.f},
{s, 0.f, c, 0.f},
{0.f, 0.f, 0.f, 1.f}};
mat4x4_mul(Q, M, R);
}
LINMATH_H_FUNC void mat4x4_rotate_Z(mat4x4 Q, mat4x4 const M, float angle) {
float s = sinf(angle);
float c = cosf(angle);
mat4x4 R = {{c, s, 0.f, 0.f},
{-s, c, 0.f, 0.f},
{0.f, 0.f, 1.f, 0.f},
{0.f, 0.f, 0.f, 1.f}};
mat4x4_mul(Q, M, R);
}
LINMATH_H_FUNC void mat4x4_invert(mat4x4 T, mat4x4 const M) {
float s[6];
float c[6];
s[0] = M[0][0] * M[1][1] - M[1][0] * M[0][1];
s[1] = M[0][0] * M[1][2] - M[1][0] * M[0][2];
s[2] = M[0][0] * M[1][3] - M[1][0] * M[0][3];
s[3] = M[0][1] * M[1][2] - M[1][1] * M[0][2];
s[4] = M[0][1] * M[1][3] - M[1][1] * M[0][3];
s[5] = M[0][2] * M[1][3] - M[1][2] * M[0][3];
c[0] = M[2][0] * M[3][1] - M[3][0] * M[2][1];
c[1] = M[2][0] * M[3][2] - M[3][0] * M[2][2];
c[2] = M[2][0] * M[3][3] - M[3][0] * M[2][3];
c[3] = M[2][1] * M[3][2] - M[3][1] * M[2][2];
c[4] = M[2][1] * M[3][3] - M[3][1] * M[2][3];
c[5] = M[2][2] * M[3][3] - M[3][2] * M[2][3];
/* Assumes it is invertible */
float idet = 1.0f / (s[0] * c[5] - s[1] * c[4] + s[2] * c[3] + s[3] * c[2] -
s[4] * c[1] + s[5] * c[0]);
T[0][0] = (M[1][1] * c[5] - M[1][2] * c[4] + M[1][3] * c[3]) * idet;
T[0][1] = (-M[0][1] * c[5] + M[0][2] * c[4] - M[0][3] * c[3]) * idet;
T[0][2] = (M[3][1] * s[5] - M[3][2] * s[4] + M[3][3] * s[3]) * idet;
T[0][3] = (-M[2][1] * s[5] + M[2][2] * s[4] - M[2][3] * s[3]) * idet;
T[1][0] = (-M[1][0] * c[5] + M[1][2] * c[2] - M[1][3] * c[1]) * idet;
T[1][1] = (M[0][0] * c[5] - M[0][2] * c[2] + M[0][3] * c[1]) * idet;
T[1][2] = (-M[3][0] * s[5] + M[3][2] * s[2] - M[3][3] * s[1]) * idet;
T[1][3] = (M[2][0] * s[5] - M[2][2] * s[2] + M[2][3] * s[1]) * idet;
T[2][0] = (M[1][0] * c[4] - M[1][1] * c[2] + M[1][3] * c[0]) * idet;
T[2][1] = (-M[0][0] * c[4] + M[0][1] * c[2] - M[0][3] * c[0]) * idet;
T[2][2] = (M[3][0] * s[4] - M[3][1] * s[2] + M[3][3] * s[0]) * idet;
T[2][3] = (-M[2][0] * s[4] + M[2][1] * s[2] - M[2][3] * s[0]) * idet;
T[3][0] = (-M[1][0] * c[3] + M[1][1] * c[1] - M[1][2] * c[0]) * idet;
T[3][1] = (M[0][0] * c[3] - M[0][1] * c[1] + M[0][2] * c[0]) * idet;
T[3][2] = (-M[3][0] * s[3] + M[3][1] * s[1] - M[3][2] * s[0]) * idet;
T[3][3] = (M[2][0] * s[3] - M[2][1] * s[1] + M[2][2] * s[0]) * idet;
}
LINMATH_H_FUNC void mat4x4_orthonormalize(mat4x4 R, mat4x4 const M) {
mat4x4_dup(R, M);
float s = 1.f;
vec3 h;
vec3_norm(R[2], R[2]);
s = vec3_dot(R[1], R[2]);
vec3_scale(h, R[2], s);
vec3_sub(R[1], R[1], h);
vec3_norm(R[1], R[1]);
s = vec3_dot(R[0], R[2]);
vec3_scale(h, R[2], s);
vec3_sub(R[0], R[0], h);
s = vec3_dot(R[0], R[1]);
vec3_scale(h, R[1], s);
vec3_sub(R[0], R[0], h);
vec3_norm(R[0], R[0]);
}
LINMATH_H_FUNC void mat4x4_frustum(mat4x4 M, float l, float r, float b, float t,
float n, float f) {
M[0][0] = 2.f * n / (r - l);
M[0][1] = M[0][2] = M[0][3] = 0.f;
M[1][1] = 2.f * n / (t - b);
M[1][0] = M[1][2] = M[1][3] = 0.f;
M[2][0] = (r + l) / (r - l);
M[2][1] = (t + b) / (t - b);
M[2][2] = -(f + n) / (f - n);
M[2][3] = -1.f;
M[3][2] = -2.f * (f * n) / (f - n);
M[3][0] = M[3][1] = M[3][3] = 0.f;
}
LINMATH_H_FUNC void mat4x4_ortho(mat4x4 M, float l, float r, float b, float t,
float n, float f) {
M[0][0] = 2.f / (r - l);
M[0][1] = M[0][2] = M[0][3] = 0.f;
M[1][1] = 2.f / (t - b);
M[1][0] = M[1][2] = M[1][3] = 0.f;
M[2][2] = -2.f / (f - n);
M[2][0] = M[2][1] = M[2][3] = 0.f;
M[3][0] = -(r + l) / (r - l);
M[3][1] = -(t + b) / (t - b);
M[3][2] = -(f + n) / (f - n);
M[3][3] = 1.f;
}
LINMATH_H_FUNC void mat4x4_perspective(mat4x4 m, float y_fov, float aspect,
float n, float f) {
/* NOTE: Degrees are an unhandy unit to work with.
* linmath.h uses radians for everything! */
float const a = 1.f / tanf(y_fov / 2.f);
m[0][0] = a / aspect;
m[0][1] = 0.f;
m[0][2] = 0.f;
m[0][3] = 0.f;
m[1][0] = 0.f;
m[1][1] = a;
m[1][2] = 0.f;
m[1][3] = 0.f;
m[2][0] = 0.f;
m[2][1] = 0.f;
m[2][2] = -((f + n) / (f - n));
m[2][3] = -1.f;
m[3][0] = 0.f;
m[3][1] = 0.f;
m[3][2] = -((2.f * f * n) / (f - n));
m[3][3] = 0.f;
}
LINMATH_H_FUNC void mat4x4_look_at(mat4x4 m, vec3 const eye, vec3 const center,
vec3 const up) {
/* Adapted from Android's OpenGL Matrix.java. */
/* See the OpenGL GLUT documentation for gluLookAt for a description */
/* of the algorithm. We implement it in a straightforward way: */
/* TODO: The negation of of can be spared by swapping the order of
* operands in the following cross products in the right way. */
vec3 f;
vec3_sub(f, center, eye);
vec3_norm(f, f);
vec3 s;
vec3_mul_cross(s, f, up);
vec3_norm(s, s);
vec3 t;
vec3_mul_cross(t, s, f);
m[0][0] = s[0];
m[0][1] = t[0];
m[0][2] = -f[0];
m[0][3] = 0.f;
m[1][0] = s[1];
m[1][1] = t[1];
m[1][2] = -f[1];
m[1][3] = 0.f;
m[2][0] = s[2];
m[2][1] = t[2];
m[2][2] = -f[2];
m[2][3] = 0.f;
m[3][0] = 0.f;
m[3][1] = 0.f;
m[3][2] = 0.f;
m[3][3] = 1.f;
mat4x4_translate_in_place(m, -eye[0], -eye[1], -eye[2]);
}
typedef float quat[4];
#define quat_add vec4_add
#define quat_sub vec4_sub
#define quat_norm vec4_norm
#define quat_scale vec4_scale
#define quat_dot vec4_dot
LINMATH_H_FUNC void quat_identity(quat q) {
q[0] = q[1] = q[2] = 0.f;
q[3] = 1.f;
}
LINMATH_H_FUNC void quat_mul(quat r, quat const p, quat const q) {
vec3 w, tmp;
vec3_mul_cross(tmp, p, q);
vec3_scale(w, p, q[3]);
vec3_add(tmp, tmp, w);
vec3_scale(w, q, p[3]);
vec3_add(tmp, tmp, w);
vec3_dup(r, tmp);
r[3] = p[3] * q[3] - vec3_dot(p, q);
}
LINMATH_H_FUNC void quat_conj(quat r, quat const q) {
int i;
for (i = 0; i < 3; ++i)
r[i] = -q[i];
r[3] = q[3];
}
LINMATH_H_FUNC void quat_rotate(quat r, float angle, vec3 const axis) {
vec3 axis_norm;
vec3_norm(axis_norm, axis);
float s = sinf(angle / 2);
float c = cosf(angle / 2);
vec3_scale(r, axis_norm, s);
r[3] = c;
}
LINMATH_H_FUNC void quat_mul_vec3(vec3 r, quat const q, vec3 const v) {
/*
* Method by Fabian 'ryg' Giessen (of Farbrausch)
t = 2 * cross(q.xyz, v)
v' = v + q.w * t + cross(q.xyz, t)
*/
vec3 t;
vec3 q_xyz = {q[0], q[1], q[2]};
vec3 u = {q[0], q[1], q[2]};
vec3_mul_cross(t, q_xyz, v);
vec3_scale(t, t, 2);
vec3_mul_cross(u, q_xyz, t);
vec3_scale(t, t, q[3]);
vec3_add(r, v, t);
vec3_add(r, r, u);
}
LINMATH_H_FUNC void mat4x4_from_quat(mat4x4 M, quat const q) {
float a = q[3];
float b = q[0];
float c = q[1];
float d = q[2];
float a2 = a * a;
float b2 = b * b;
float c2 = c * c;
float d2 = d * d;
M[0][0] = a2 + b2 - c2 - d2;
M[0][1] = 2.f * (b * c + a * d);
M[0][2] = 2.f * (b * d - a * c);
M[0][3] = 0.f;
M[1][0] = 2 * (b * c - a * d);
M[1][1] = a2 - b2 + c2 - d2;
M[1][2] = 2.f * (c * d + a * b);
M[1][3] = 0.f;
M[2][0] = 2.f * (b * d + a * c);
M[2][1] = 2.f * (c * d - a * b);
M[2][2] = a2 - b2 - c2 + d2;
M[2][3] = 0.f;
M[3][0] = M[3][1] = M[3][2] = 0.f;
M[3][3] = 1.f;
}
LINMATH_H_FUNC void mat4x4o_mul_quat(mat4x4 R, mat4x4 const M, quat const q) {
/* XXX: The way this is written only works for orthogonal matrices. */
/* TODO: Take care of non-orthogonal case. */
quat_mul_vec3(R[0], q, M[0]);
quat_mul_vec3(R[1], q, M[1]);
quat_mul_vec3(R[2], q, M[2]);
R[3][0] = R[3][1] = R[3][2] = 0.f;
R[0][3] = M[0][3];
R[1][3] = M[1][3];
R[2][3] = M[2][3];
R[3][3] = M[3][3]; // typically 1.0, but here we make it general
}
LINMATH_H_FUNC void quat_from_mat4x4(quat q, mat4x4 const M) {
float r = 0.f;
int i;
int perm[] = {0, 1, 2, 0, 1};
int *p = perm;
for (i = 0; i < 3; i++) {
float m = M[i][i];
if (m < r)
continue;
m = r;
p = &perm[i];
}
r = sqrtf(1.f + M[p[0]][p[0]] - M[p[1]][p[1]] - M[p[2]][p[2]]);
if (r < 1e-6) {
q[0] = 1.f;
q[1] = q[2] = q[3] = 0.f;
return;
}
q[0] = r / 2.f;
q[1] = (M[p[0]][p[1]] - M[p[1]][p[0]]) / (2.f * r);
q[2] = (M[p[2]][p[0]] - M[p[0]][p[2]]) / (2.f * r);
q[3] = (M[p[2]][p[1]] - M[p[1]][p[2]]) / (2.f * r);
}
LINMATH_H_FUNC void mat4x4_arcball(mat4x4 R, mat4x4 const M, vec2 const _a,
vec2 const _b, float s) {
vec2 a;
memcpy(a, _a, sizeof(a));
vec2 b;
memcpy(b, _b, sizeof(b));
float z_a = 0.;
float z_b = 0.;
if (vec2_len(a) < 1.) {
z_a = sqrtf(1. - vec2_dot(a, a));
} else {
vec2_norm(a, a);
}
if (vec2_len(b) < 1.) {
z_b = sqrtf(1. - vec2_dot(b, b));
} else {
vec2_norm(b, b);
}
vec3 a_ = {a[0], a[1], z_a};
vec3 b_ = {b[0], b[1], z_b};
vec3 c_;
vec3_mul_cross(c_, a_, b_);
float const angle = acos(vec3_dot(a_, b_)) * s;
mat4x4_rotate(R, M, c_[0], c_[1], c_[2], angle);
}
#endif

174
src/main.c Normal file
View File

@@ -0,0 +1,174 @@
#include "gameObjs.h"
#include "linmath.h"
#include "renderer.h"
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>
#define PI 3.141592653589793f
#define WIDTH 512
#define HEIGHT 512
#define PIX_COUNT (WIDTH * HEIGHT)
volatile sig_atomic_t stop = 0;
struct termios oldt;
void handle_sigint(int sig) { stop = 1; }
void restore_terminal() {
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
printf("\033[?1049l");
}
static char encoding_table[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
void base64encode(render_target *t, char *buff) {
for (int i = 0; i < PIX_COUNT * 4; i += 4) {
uint8_t r = t->pixels[i];
uint8_t g = t->pixels[i + 1];
uint8_t b = t->pixels[i + 2];
int s = 0;
s |= r << 16;
s |= g << 8;
s |= b;
buff[i] = encoding_table[s >> 18];
s &= 0777777;
buff[i + 1] = encoding_table[s >> 12];
s &= 07777;
buff[i + 2] = encoding_table[s >> 6];
s &= 077;
buff[i + 3] = encoding_table[s];
}
}
void setupKeyboard() {
struct termios newt;
// Save original terminal settings
if (tcgetattr(STDIN_FILENO, &oldt) == -1) {
perror("tcgetattr failed");
exit(1);
}
// Copy old settings to newt
newt = oldt;
// Disable canonical mode (ICANON) and echo (ECHO)
newt.c_lflag &= ~(ICANON | ECHO);
newt.c_cc[VMIN] = 0; // minimum bytes
newt.c_cc[VTIME] = 0; // timeout (0 = no wait)
// Apply new settings
if (tcsetattr(STDIN_FILENO, TCSANOW, &newt) == -1) {
perror("tcsetattr failed");
exit(1);
}
}
void printImage(char *buff) {
int buffSize = PIX_COUNT * 4;
int start = 0;
int chunkSize = MIN(4096, buffSize - start);
int notLast = start < buffSize - 4096;
printf("\033_Gf=24,s=%d,v=%d,a=T,t=d,m=%d;%.*s\033\\", HEIGHT, WIDTH, notLast,
chunkSize, buff);
start += 4096;
while (start < buffSize) {
notLast = start < buffSize - 4096;
int chunkSize = MIN(4096, buffSize - start);
printf("\033_Gm=%d;%.*s\033\\", notLast, chunkSize, buff + start);
start += 4096;
}
printf("\n");
}
int main(void) {
signal(SIGINT, handle_sigint);
printf("\033[?1049h\n");
setupKeyboard();
render_target target = {WIDTH, HEIGHT, malloc(PIX_COUNT * 4)};
clearTarget(&target);
vec4 *buffer = malloc(vertBufferSize());
mat4x4 projMat = {};
mat4x4 viewMat = {};
mat4x4 drawMat = {};
mat4x4_identity(viewMat);
mat4x4_perspective(projMat, 45.0 / 180.0 * PI, 1, 2.f, 20.0f);
const int buffSize = PIX_COUNT * 4;
char *encodeBuff = malloc(buffSize);
memset(encodeBuff, 0, buffSize);
char lastKey;
clock_t start = clock();
clock_t now = clock();
clock_t renderC;
float deltaTime; // in seconds
while (!stop) {
now = clock();
deltaTime = ((float)(now - start)) / CLOCKS_PER_SEC;
start = now;
printf("total time: %fms\n", deltaTime * 1000);
printf("render time: %fms\n", ((float)renderC) / (0.001 * CLOCKS_PER_SEC));
if (read(STDIN_FILENO, &lastKey, 1) == -1) {
perror("read failed");
stop = 1;
continue;
}
switch (lastKey) {
case 'w':
rocket.velocity[1] = (rocket.velocity[1] * 0.9 + 20 * 0.1);
break;
case 's':
mat4x4_translate_in_place(viewMat, 0, 0, 0.2);
break;
case 'a':
mat4x4_translate_in_place(viewMat, -0.2, 0, 0);
break;
case 'd':
mat4x4_translate_in_place(viewMat, 0.2, 0, 0);
break;
}
lastKey = 0;
rocket.velocity[1] +=
(-4.0f + 0.5 * powf(MIN(rocket.velocity[1], 0.0), 2.0f)) * deltaTime;
mat4x4_translate_in_place(rocket.transform, rocket.velocity[0] * deltaTime,
rocket.velocity[1] * deltaTime,
rocket.velocity[2] * deltaTime);
// mat4x4_translate_in_place(viewMat, 0, 0, .1);
mat4x4_mul(drawMat, projMat, rocket.transform);
clearTarget(&target);
renderC = clock();
render(&target, &rocket.model, &drawMat, buffer);
renderC = clock() - renderC;
base64encode(&target, encodeBuff);
printf("\033[H");
printImage(encodeBuff);
printf("\033[J");
}
restore_terminal();
}

355
src/models/plane.h Normal file
View File

@@ -0,0 +1,355 @@
#include "../renderer.h"
const model testModel = {
(vec3[]){
{0.698513, 0.757563, 0.000000}, {0.044645, 2.825787, 0.000000},
{0.656388, 0.757563, 0.238906}, {0.041953, 2.825787, 0.015270},
{0.535092, 0.757563, 0.448996}, {0.034200, 2.825787, 0.028697},
{0.349257, 0.757563, 0.604930}, {0.022323, 2.825787, 0.038664},
{0.121296, 0.757563, 0.687901}, {0.007753, 2.825787, 0.043967},
{-0.121296, 0.757563, 0.687901}, {-0.007753, 2.825787, 0.043967},
{-0.349257, 0.757563, 0.604930}, {-0.022323, 2.825787, 0.038664},
{-0.535092, 0.757563, 0.448996}, {-0.034200, 2.825787, 0.028697},
{-0.656388, 0.757563, 0.238906}, {-0.041953, 2.825787, 0.015270},
{-0.698513, 0.757563, -0.000000}, {-0.044645, 2.825787, 0.000000},
{-0.656388, 0.757563, -0.238906}, {-0.041953, 2.825787, -0.015270},
{-0.535092, 0.757563, -0.448996}, {-0.034200, 2.825787, -0.028697},
{-0.349257, 0.757563, -0.604930}, {-0.022323, 2.825787, -0.038664},
{-0.121296, 0.757563, -0.687901}, {-0.007753, 2.825787, -0.043967},
{0.121296, 0.757563, -0.687901}, {0.007753, 2.825787, -0.043967},
{0.349257, 0.757563, -0.604930}, {0.022323, 2.825787, -0.038664},
{0.535092, 0.757563, -0.448996}, {0.034200, 2.825787, -0.028697},
{0.656388, 0.757563, -0.238906}, {0.041953, 2.825787, -0.015269},
{0.544639, 2.240545, 0.000000}, {0.511793, 2.240545, 0.186277},
{0.409479, 2.128906, 0.371044}, {0.290178, 2.227410, 0.470774},
{0.100778, 2.227410, 0.539710}, {-0.100778, 2.227410, 0.539710},
{-0.290178, 2.227410, 0.470774}, {-0.409479, 2.128906, 0.371044},
{-0.511793, 2.240545, 0.186277}, {-0.544639, 2.240545, -0.000000},
{-0.511793, 2.240545, -0.186277}, {-0.417217, 2.240545, -0.350087},
{-0.272319, 2.240545, -0.471671}, {-0.094576, 2.240545, -0.536364},
{0.094576, 2.240545, -0.536364}, {0.272319, 2.240545, -0.471671},
{0.417218, 2.240545, -0.350087}, {0.511793, 2.240545, -0.186277},
{0.694426, 1.474881, 0.252751}, {0.527394, 1.631239, 0.497527},
{0.367433, 1.488016, 0.632126}, {0.127608, 1.488016, 0.719415},
{-0.127608, 1.488016, 0.719415}, {-0.367433, 1.488016, 0.632126},
{-0.527394, 1.631239, 0.497527}, {-0.694426, 1.474881, 0.252751},
{-0.738993, 1.474881, -0.000000}, {-0.694426, 1.474881, -0.252751},
{-0.566102, 1.474881, -0.475016}, {-0.369497, 1.474881, -0.639987},
{-0.128325, 1.474881, -0.727766}, {0.128325, 1.474881, -0.727766},
{0.369497, 1.474881, -0.639987}, {0.566102, 1.474881, -0.475016},
{0.694426, 1.474881, -0.252751}, {0.738993, 1.474881, 0.000000},
{0.410385, -0.154204, 0.000000}, {0.385635, -0.154204, 0.140360},
{0.314373, -0.154204, 0.263790}, {0.205192, -0.154204, 0.355403},
{0.071263, -0.154204, 0.404150}, {-0.071263, -0.154204, 0.404150},
{-0.205192, -0.154204, 0.355403}, {-0.314373, -0.154204, 0.263790},
{-0.385635, -0.154204, 0.140360}, {-0.410385, -0.154204, -0.000000},
{-0.385635, -0.154204, -0.140360}, {-0.314373, -0.154204, -0.263790},
{-0.205192, -0.154204, -0.355403}, {-0.071263, -0.154204, -0.404150},
{0.071263, -0.154204, -0.404150}, {0.205192, -0.154204, -0.355403},
{0.314373, -0.154204, -0.263790}, {0.385635, -0.154204, -0.140360},
{0.237705, 2.675272, 0.000000}, {0.223370, 2.675272, 0.081300},
{0.182093, 2.675272, 0.152794}, {0.118853, 2.675272, 0.205859},
{0.041277, 2.675272, 0.234094}, {-0.041277, 2.675272, 0.234094},
{-0.118853, 2.675272, 0.205859}, {-0.182093, 2.675272, 0.152794},
{-0.223370, 2.675272, 0.081300}, {-0.237705, 2.675272, -0.000000},
{-0.223370, 2.675272, -0.081300}, {-0.182093, 2.675272, -0.152794},
{-0.118853, 2.675272, -0.205859}, {-0.041277, 2.675272, -0.234094},
{0.041277, 2.675272, -0.234094}, {0.118853, 2.675272, -0.205859},
{0.182093, 2.675272, -0.152794}, {0.223370, 2.675272, -0.081300},
{0.046326, 2.839588, 0.000000}, {-0.023163, 2.839588, -0.040120},
{-0.023163, 2.839588, 0.040120}, {0.000000, 3.137896, 0.000000},
{-0.272319, 2.240545, 0.471671}, {-0.417218, 2.141971, 0.350087},
{-0.094576, 2.240545, 0.536364}, {0.094576, 2.240545, 0.536364},
{0.272319, 2.240545, 0.471671}, {0.417217, 2.141971, 0.350087},
{0.566102, 1.618174, 0.475016}, {-0.566102, 1.618174, 0.475016},
{0.369497, 1.474881, 0.639987}, {0.128325, 1.474881, 0.727766},
{-0.128325, 1.474881, 0.727766}, {-0.369497, 1.474881, 0.639987},
{0.237002, 2.117707, 0.625731}, {0.257333, 1.652925, 0.728921},
{0.082310, 2.117707, 0.682034}, {0.089371, 1.652925, 0.766453},
{-0.082310, 2.117707, 0.682034}, {-0.089371, 1.652925, 0.766453},
{-0.237002, 2.117707, 0.625731}, {-0.257333, 1.652925, 0.728921},
{-0.334441, 2.019176, 0.544276}, {0.334441, 2.019176, 0.544276},
{0.369362, 1.735177, 0.671046}, {-0.369362, 1.735177, 0.671046},
{0.096339, 2.201041, 0.616476}, {-0.096339, 2.201041, 0.616476},
{0.489408, 1.656222, 0.539235}, {0.391442, 2.102530, 0.455240},
{0.118417, 1.527654, 0.730721}, {-0.118417, 1.527654, 0.730721},
{-0.489408, 1.656222, 0.539235}, {-0.391442, 2.102530, 0.455240},
{0.277396, 2.201041, 0.550577}, {-0.340969, 1.527654, 0.655392},
{-0.277396, 2.201041, 0.550577}, {0.340969, 1.527654, 0.655392}},
(int[]){
1, 1, 91, 91, 90, 90, 91, 91, 5, 5, 92, 92, 5, 5,
93, 93, 92, 92, 7, 7, 94, 94, 93, 93, 9, 9, 95, 95,
94, 94, 11, 11, 96, 96, 95, 95, 96, 96, 15, 15, 97, 97,
15, 15, 98, 98, 97, 97, 98, 98, 19, 19, 99, 99, 19, 19,
100, 100, 99, 99, 100, 100, 23, 23, 101, 101, 23, 23, 102, 102,
101, 101, 25, 25, 103, 103, 102, 102, 27, 27, 104, 104, 103, 103,
104, 104, 31, 31, 105, 105, 31, 31, 106, 106, 105, 105, 33, 33,
107, 107, 106, 106, 35, 35, 90, 90, 107, 107, 4, 4, 73, 73,
2, 2, 53, 53, 71, 71, 70, 70, 52, 52, 70, 70, 69, 69,
51, 51, 69, 69, 68, 68, 50, 50, 68, 68, 67, 67, 49, 49,
67, 67, 66, 66, 65, 65, 49, 49, 66, 66, 64, 64, 48, 48,
65, 65, 46, 46, 64, 64, 63, 63, 62, 62, 46, 46, 63, 63,
44, 44, 62, 62, 61, 61, 119, 119, 44, 44, 61, 61, 136, 136,
124, 124, 144, 144, 142, 142, 132, 132, 143, 143, 141, 141, 127, 127,
129, 129, 137, 137, 126, 126, 136, 136, 138, 138, 133, 133, 134, 134,
37, 37, 118, 118, 54, 54, 71, 71, 37, 37, 54, 54, 0, 0,
54, 54, 2, 2, 54, 54, 4, 4, 2, 2, 4, 4, 120, 120,
6, 6, 120, 120, 8, 8, 6, 6, 121, 121, 10, 10, 8, 8,
122, 122, 12, 12, 10, 10, 123, 123, 14, 14, 12, 12, 14, 14,
61, 61, 16, 16, 16, 16, 62, 62, 18, 18, 18, 18, 63, 63,
20, 20, 63, 63, 22, 22, 20, 20, 64, 64, 24, 24, 22, 22,
65, 65, 26, 26, 24, 24, 66, 66, 28, 28, 26, 26, 67, 67,
30, 30, 28, 28, 68, 68, 32, 32, 30, 30, 69, 69, 34, 34,
32, 32, 34, 34, 71, 71, 0, 0, 75, 75, 83, 83, 87, 87,
14, 14, 78, 78, 12, 12, 24, 24, 83, 83, 22, 22, 34, 34,
88, 88, 32, 32, 10, 10, 76, 76, 8, 8, 20, 20, 81, 81,
18, 18, 30, 30, 86, 86, 28, 28, 6, 6, 74, 74, 4, 4,
16, 16, 79, 79, 14, 14, 2, 2, 72, 72, 0, 0, 26, 26,
84, 84, 24, 24, 0, 0, 89, 89, 34, 34, 12, 12, 77, 77,
10, 10, 22, 22, 82, 82, 20, 20, 32, 32, 87, 87, 30, 30,
8, 8, 75, 75, 6, 6, 18, 18, 80, 80, 16, 16, 28, 28,
85, 85, 26, 26, 107, 107, 36, 36, 53, 53, 106, 106, 53, 53,
52, 52, 105, 105, 52, 52, 51, 51, 104, 104, 51, 51, 50, 50,
103, 103, 50, 50, 49, 49, 102, 102, 49, 49, 48, 48, 101, 101,
48, 48, 47, 47, 100, 100, 47, 47, 46, 46, 99, 99, 46, 46,
45, 45, 98, 98, 45, 45, 44, 44, 97, 97, 44, 44, 113, 113,
112, 112, 97, 97, 113, 113, 95, 95, 112, 112, 114, 114, 94, 94,
114, 114, 115, 115, 116, 116, 94, 94, 115, 115, 92, 92, 116, 116,
117, 117, 37, 37, 92, 92, 117, 117, 90, 90, 37, 37, 36, 36,
108, 108, 5, 5, 3, 3, 108, 108, 7, 7, 5, 5, 110, 110,
7, 7, 108, 108, 110, 110, 11, 11, 9, 9, 110, 110, 13, 13,
11, 11, 110, 110, 15, 15, 13, 13, 110, 110, 17, 17, 15, 15,
110, 110, 19, 19, 17, 17, 109, 109, 19, 19, 110, 110, 109, 109,
23, 23, 21, 21, 109, 109, 25, 25, 23, 23, 109, 109, 27, 27,
25, 25, 109, 109, 29, 29, 27, 27, 109, 109, 31, 31, 29, 29,
108, 108, 31, 31, 109, 109, 108, 108, 35, 35, 33, 33, 108, 108,
1, 1, 35, 35, 108, 108, 3, 3, 1, 1, 110, 110, 9, 9,
7, 7, 109, 109, 21, 21, 19, 19, 108, 108, 33, 33, 31, 31,
110, 110, 108, 108, 111, 111, 109, 109, 110, 110, 111, 111, 108, 108,
109, 109, 111, 111, 42, 42, 113, 113, 43, 43, 41, 41, 112, 112,
42, 42, 40, 40, 114, 114, 41, 41, 40, 40, 116, 116, 115, 115,
39, 39, 117, 117, 116, 116, 38, 38, 118, 118, 117, 117, 43, 43,
119, 119, 60, 60, 56, 56, 118, 118, 55, 55, 57, 57, 120, 120,
56, 56, 58, 58, 121, 121, 57, 57, 58, 58, 123, 123, 122, 122,
59, 59, 119, 119, 123, 123, 130, 130, 135, 135, 131, 131, 128, 128,
131, 131, 129, 129, 126, 126, 129, 129, 127, 127, 125, 125, 126, 126,
127, 127, 134, 134, 124, 124, 125, 125, 141, 141, 131, 131, 145, 145,
146, 146, 132, 132, 130, 130, 147, 147, 134, 134, 125, 125, 144, 144,
133, 133, 139, 139, 145, 145, 135, 135, 142, 142, 137, 137, 130, 130,
128, 128, 140, 140, 125, 125, 127, 127, 57, 57, 147, 147, 140, 140,
41, 41, 146, 146, 137, 137, 59, 59, 142, 142, 60, 60, 39, 39,
139, 139, 38, 38, 56, 56, 138, 138, 147, 147, 42, 42, 143, 143,
146, 146, 58, 58, 145, 145, 59, 59, 55, 55, 139, 139, 138, 138,
41, 41, 136, 136, 40, 40, 57, 57, 141, 141, 58, 58, 60, 60,
143, 143, 43, 43, 40, 40, 144, 144, 39, 39, 1, 1, 3, 3,
91, 91, 91, 91, 3, 3, 5, 5, 5, 5, 7, 7, 93, 93,
7, 7, 9, 9, 94, 94, 9, 9, 11, 11, 95, 95, 11, 11,
13, 13, 96, 96, 96, 96, 13, 13, 15, 15, 15, 15, 17, 17,
98, 98, 98, 98, 17, 17, 19, 19, 19, 19, 21, 21, 100, 100,
100, 100, 21, 21, 23, 23, 23, 23, 25, 25, 102, 102, 25, 25,
27, 27, 103, 103, 27, 27, 29, 29, 104, 104, 104, 104, 29, 29,
31, 31, 31, 31, 33, 33, 106, 106, 33, 33, 35, 35, 107, 107,
35, 35, 1, 1, 90, 90, 4, 4, 74, 74, 73, 73, 53, 53,
36, 36, 71, 71, 52, 52, 53, 53, 70, 70, 51, 51, 52, 52,
69, 69, 50, 50, 51, 51, 68, 68, 49, 49, 50, 50, 67, 67,
65, 65, 48, 48, 49, 49, 64, 64, 47, 47, 48, 48, 46, 46,
47, 47, 64, 64, 62, 62, 45, 45, 46, 46, 44, 44, 45, 45,
62, 62, 119, 119, 113, 113, 44, 44, 136, 136, 126, 126, 124, 124,
142, 142, 135, 135, 132, 132, 141, 141, 140, 140, 127, 127, 137, 137,
128, 128, 126, 126, 138, 138, 139, 139, 133, 133, 37, 37, 117, 117,
118, 118, 71, 71, 36, 36, 37, 37, 0, 0, 71, 71, 54, 54,
54, 54, 118, 118, 4, 4, 4, 4, 118, 118, 120, 120, 120, 120,
121, 121, 8, 8, 121, 121, 122, 122, 10, 10, 122, 122, 123, 123,
12, 12, 123, 123, 119, 119, 14, 14, 14, 14, 119, 119, 61, 61,
16, 16, 61, 61, 62, 62, 18, 18, 62, 62, 63, 63, 63, 63,
64, 64, 22, 22, 64, 64, 65, 65, 24, 24, 65, 65, 66, 66,
26, 26, 66, 66, 67, 67, 28, 28, 67, 67, 68, 68, 30, 30,
68, 68, 69, 69, 32, 32, 69, 69, 70, 70, 34, 34, 34, 34,
70, 70, 71, 71, 89, 89, 72, 72, 73, 73, 73, 73, 74, 74,
75, 75, 75, 75, 76, 76, 77, 77, 77, 77, 78, 78, 79, 79,
79, 79, 80, 80, 81, 81, 81, 81, 82, 82, 83, 83, 83, 83,
84, 84, 85, 85, 85, 85, 86, 86, 87, 87, 87, 87, 88, 88,
89, 89, 89, 89, 73, 73, 75, 75, 75, 75, 77, 77, 79, 79,
79, 79, 81, 81, 83, 83, 83, 83, 85, 85, 87, 87, 87, 87,
89, 89, 75, 75, 75, 75, 79, 79, 83, 83, 14, 14, 79, 79,
78, 78, 24, 24, 84, 84, 83, 83, 34, 34, 89, 89, 88, 88,
10, 10, 77, 77, 76, 76, 20, 20, 82, 82, 81, 81, 30, 30,
87, 87, 86, 86, 6, 6, 75, 75, 74, 74, 16, 16, 80, 80,
79, 79, 2, 2, 73, 73, 72, 72, 26, 26, 85, 85, 84, 84,
0, 0, 72, 72, 89, 89, 12, 12, 78, 78, 77, 77, 22, 22,
83, 83, 82, 82, 32, 32, 88, 88, 87, 87, 8, 8, 76, 76,
75, 75, 18, 18, 81, 81, 80, 80, 28, 28, 86, 86, 85, 85,
107, 107, 90, 90, 36, 36, 106, 106, 107, 107, 53, 53, 105, 105,
106, 106, 52, 52, 104, 104, 105, 105, 51, 51, 103, 103, 104, 104,
50, 50, 102, 102, 103, 103, 49, 49, 101, 101, 102, 102, 48, 48,
100, 100, 101, 101, 47, 47, 99, 99, 100, 100, 46, 46, 98, 98,
99, 99, 45, 45, 97, 97, 98, 98, 44, 44, 112, 112, 96, 96,
97, 97, 95, 95, 96, 96, 112, 112, 94, 94, 95, 95, 114, 114,
116, 116, 93, 93, 94, 94, 92, 92, 93, 93, 116, 116, 37, 37,
91, 91, 92, 92, 90, 90, 91, 91, 37, 37, 42, 42, 112, 112,
113, 113, 41, 41, 114, 114, 112, 112, 40, 40, 115, 115, 114, 114,
40, 40, 39, 39, 116, 116, 39, 39, 38, 38, 117, 117, 38, 38,
55, 55, 118, 118, 43, 43, 113, 113, 119, 119, 56, 56, 120, 120,
118, 118, 57, 57, 121, 121, 120, 120, 58, 58, 122, 122, 121, 121,
58, 58, 59, 59, 123, 123, 59, 59, 60, 60, 119, 119, 130, 130,
132, 132, 135, 135, 128, 128, 130, 130, 131, 131, 126, 126, 128, 128,
129, 129, 125, 125, 124, 124, 126, 126, 134, 134, 133, 133, 124, 124,
141, 141, 129, 129, 131, 131, 146, 146, 143, 143, 132, 132, 147, 147,
138, 138, 134, 134, 144, 144, 124, 124, 133, 133, 145, 145, 131, 131,
135, 135, 137, 137, 146, 146, 130, 130, 140, 140, 147, 147, 125, 125,
57, 57, 56, 56, 147, 147, 41, 41, 42, 42, 146, 146, 59, 59,
145, 145, 142, 142, 39, 39, 144, 144, 139, 139, 56, 56, 55, 55,
138, 138, 42, 42, 43, 43, 143, 143, 58, 58, 141, 141, 145, 145,
55, 55, 38, 38, 139, 139, 41, 41, 137, 137, 136, 136, 57, 57,
140, 140, 141, 141, 60, 60, 142, 142, 143, 143, 40, 40, 136, 136,
144, 144},
(vec3[]){{0.9841, -0.1778, -0.0000}, {0.9146, 0.4043, -0.0000},
{0.9247, -0.1778, 0.3366}, {0.7754, 0.5378, 0.3310},
{0.7540, -0.1768, 0.6327}, {0.4942, 0.7357, 0.4632},
{0.4920, -0.1778, 0.8522}, {0.3013, 0.7980, 0.5219},
{0.1709, -0.1778, 0.9691}, {0.1541, 0.7357, 0.6596},
{-0.1709, -0.1778, 0.9691}, {-0.1010, 0.5378, 0.8370},
{-0.4920, -0.1778, 0.8522}, {-0.4573, 0.4043, 0.7921},
{-0.7540, -0.1768, 0.6327}, {-0.6743, 0.5378, 0.5060},
{-0.9247, -0.1778, 0.3366}, {-0.6483, 0.7357, 0.1964},
{-0.9841, -0.1778, -0.0000}, {-0.6026, 0.7980, -0.0000},
{-0.9247, -0.1778, -0.3366}, {-0.6483, 0.7357, -0.1964},
{-0.7538, -0.1778, -0.6325}, {-0.6743, 0.5378, -0.5060},
{-0.4920, -0.1778, -0.8522}, {-0.4573, 0.4043, -0.7921},
{-0.1709, -0.1778, -0.9691}, {-0.1010, 0.5378, -0.8370},
{0.1709, -0.1778, -0.9691}, {0.1541, 0.7357, -0.6596},
{0.4920, -0.1778, -0.8522}, {0.3013, 0.7980, -0.5219},
{0.7538, -0.1778, -0.6325}, {0.4942, 0.7357, -0.4632},
{0.9247, -0.1778, -0.3366}, {0.7754, 0.5378, -0.3310},
{0.9117, 0.4109, -0.0000}, {0.8130, 0.4345, 0.3877},
{0.8011, 0.3907, 0.4535}, {0.5809, 0.7552, 0.3037},
{0.1433, 0.7300, 0.6682}, {-0.1433, 0.7300, 0.6682},
{-0.5809, 0.7552, 0.3037}, {-0.8011, 0.3907, 0.4535},
{-0.8130, 0.4345, 0.3877}, {-0.9117, 0.4109, -0.0000},
{-0.8567, 0.4109, -0.3118}, {-0.6984, 0.4109, -0.5860},
{-0.4558, 0.4109, -0.7895}, {-0.1583, 0.4109, -0.8978},
{0.1583, 0.4109, -0.8978}, {0.4558, 0.4109, -0.7895},
{0.6984, 0.4109, -0.5860}, {0.8567, 0.4109, -0.3118},
{0.9423, 0.0728, 0.3267}, {0.6347, 0.1973, 0.7472},
{0.4225, 0.2699, 0.8652}, {0.1829, 0.1701, 0.9683},
{-0.1829, 0.1701, 0.9683}, {-0.4225, 0.2699, 0.8652},
{-0.6347, 0.1973, 0.7472}, {-0.9423, 0.0728, 0.3267},
{-0.9955, 0.0944, -0.0000}, {-0.9355, 0.0944, -0.3405},
{-0.7626, 0.0944, -0.6399}, {-0.4978, 0.0944, -0.8622},
{-0.1729, 0.0944, -0.9804}, {0.1729, 0.0944, -0.9804},
{0.4978, 0.0944, -0.8622}, {0.7626, 0.0944, -0.6399},
{0.9355, 0.0944, -0.3405}, {0.9955, 0.0944, -0.0000},
{0.6306, -0.7761, -0.0000}, {0.5926, -0.7761, 0.2157},
{0.4830, -0.7761, 0.4053}, {0.3153, -0.7761, 0.5461},
{0.1095, -0.7761, 0.6210}, {-0.1095, -0.7761, 0.6210},
{-0.3153, -0.7761, 0.5461}, {-0.4831, -0.7761, 0.4053},
{-0.5925, -0.7761, 0.2157}, {-0.6306, -0.7761, -0.0000},
{-0.5925, -0.7761, -0.2157}, {-0.4831, -0.7761, -0.4053},
{-0.3153, -0.7761, -0.5461}, {-0.1095, -0.7761, -0.6210},
{0.1095, -0.7761, -0.6210}, {0.3153, -0.7761, -0.5461},
{0.4830, -0.7761, -0.4053}, {0.5925, -0.7761, -0.2157},
{0.7312, 0.6821, -0.0000}, {0.6871, 0.6821, 0.2501},
{0.5656, 0.6745, 0.4746}, {0.3656, 0.6821, 0.6333},
{0.1270, 0.6821, 0.7201}, {-0.1270, 0.6821, 0.7201},
{-0.3656, 0.6821, 0.6333}, {-0.5656, 0.6745, 0.4746},
{-0.6871, 0.6821, 0.2501}, {-0.7312, 0.6821, -0.0000},
{-0.6871, 0.6821, -0.2501}, {-0.5601, 0.6821, -0.4700},
{-0.3656, 0.6821, -0.6333}, {-0.1270, 0.6821, -0.7201},
{0.1270, 0.6821, -0.7201}, {0.3656, 0.6821, -0.6333},
{0.5601, 0.6821, -0.4700}, {0.6871, 0.6821, -0.2501},
{0.9437, 0.3307, -0.0000}, {-0.4719, 0.3307, -0.8173},
{-0.4719, 0.3307, 0.8173}, {-0.0000, 1.0000, -0.0000},
{-0.4787, 0.5258, 0.7031}, {-0.7169, 0.4126, 0.5620},
{-0.1342, 0.4369, 0.8895}, {0.1342, 0.4369, 0.8895},
{0.4787, 0.5258, 0.7031}, {0.7169, 0.4126, 0.5620},
{0.7577, 0.1650, 0.6315}, {-0.7577, 0.1650, 0.6315},
{0.4534, 0.1969, 0.8693}, {0.1663, 0.2444, 0.9553},
{-0.1663, 0.2444, 0.9553}, {-0.4534, 0.1969, 0.8693},
{0.4906, 0.3661, 0.7907}, {0.3424, -0.0553, 0.9379},
{0.1431, 0.4003, 0.9051}, {0.1012, -0.0377, 0.9942},
{-0.1431, 0.4003, 0.9051}, {-0.1012, -0.0377, 0.9942},
{-0.4906, 0.3661, 0.7907}, {-0.3424, -0.0553, 0.9379},
{-0.7362, 0.2805, 0.6159}, {0.7362, 0.2805, 0.6159},
{0.6174, 0.1400, 0.7741}, {-0.6174, 0.1400, 0.7741},
{0.1165, 0.7887, 0.6037}, {-0.1165, 0.7887, 0.6037},
{0.7537, 0.0880, 0.6512}, {0.8090, 0.3734, 0.4541},
{0.1400, -0.2577, 0.9560}, {-0.1400, -0.2577, 0.9560},
{-0.7537, 0.0880, 0.6512}, {-0.8090, 0.3734, 0.4541},
{0.5043, 0.6625, 0.5539}, {-0.4814, -0.2028, 0.8527},
{-0.5043, 0.6625, 0.5539}, {0.4814, -0.2028, 0.8527}},
(vec3[]){{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.8556, 0.8746, 1.0000}, {0.8556, 0.8746, 1.0000},
{0.8556, 0.8746, 1.0000}, {0.8556, 0.8746, 1.0000},
{0.8556, 0.8746, 1.0000}, {0.8556, 0.8746, 1.0000},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.8556, 0.8746, 1.0000},
{0.8556, 0.8746, 1.0000}, {0.8556, 0.8746, 1.0000},
{0.8556, 0.8746, 1.0000}, {0.8556, 0.8746, 1.0000},
{0.8556, 0.8746, 1.0000}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.9696, 1.0000, 0.0000}, {0.9695, 0.9999, 0.0005},
{0.9696, 1.0000, 0.0000}, {0.9696, 1.0000, 0.0000},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.0000, 0.4470, 0.0334}, {0.0000, 0.4470, 0.0334},
{0.1450, 0.1371, 0.1900}, {0.1450, 0.1371, 0.1900},
{0.1450, 0.1371, 0.1900}, {0.1450, 0.1371, 0.1900},
{0.1450, 0.1371, 0.1900}, {0.1450, 0.1371, 0.1900},
{0.1450, 0.1371, 0.1900}, {0.1450, 0.1371, 0.1900},
{0.1450, 0.1371, 0.1900}, {0.1450, 0.1371, 0.1900},
{0.1450, 0.1371, 0.1900}, {0.1450, 0.1371, 0.1900},
{0.1450, 0.1371, 0.1900}, {0.1450, 0.1371, 0.1900},
{0.1450, 0.1371, 0.1900}, {0.1450, 0.1371, 0.1900},
{0.1450, 0.1371, 0.1900}, {0.1450, 0.1371, 0.1900},
{0.1450, 0.1371, 0.1900}, {0.1450, 0.1371, 0.1900},
{0.1450, 0.1371, 0.1900}, {0.1450, 0.1371, 0.1900},
{0.1450, 0.1371, 0.1900}, {0.1450, 0.1371, 0.1900}},
148,
1752,
20.f};

83
src/polygon.h Normal file
View File

@@ -0,0 +1,83 @@
#ifndef POLYGON_H
#define POLYGON_H
#include "linmath.h"
typedef struct {
vec3 points[3];
vec3 colors[3];
vec3 normals[3];
vec3 barycentrics;
float baryFactor;
float dot00;
float dot01;
float dot11;
float v0[2];
vec2 v1;
float bounding[4]; // min x, max x, min y, max y
} polygon;
void preCalc(polygon *p) {
p->v0[0] = p->points[2][0] - p->points[0][0];
p->v0[1] = p->points[2][1] - p->points[0][1];
p->v1[0] = p->points[1][0] - p->points[0][0];
p->v1[1] = p->points[1][1] - p->points[0][1];
p->dot00 = vec3_dot(p->v0, p->v0);
p->dot01 = vec3_dot(p->v1, p->v0);
p->dot11 = vec3_dot(p->v1, p->v1);
p->baryFactor = 1.0f / (p->dot00 * p->dot11 - p->dot01 * p->dot01);
p->bounding[0] = p->points[0][0];
p->bounding[1] = p->points[0][0];
p->bounding[2] = p->points[0][1];
p->bounding[3] = p->points[0][1];
for (int i = 1; i < 3; i++) {
if (p->bounding[0] > p->points[i][0])
p->bounding[0] = p->points[i][0];
if (p->bounding[1] < p->points[i][0])
p->bounding[1] = p->points[i][0];
if (p->bounding[2] > p->points[i][1])
p->bounding[2] = p->points[i][1];
if (p->bounding[3] < p->points[i][1])
p->bounding[3] = p->points[i][1];
}
}
void calcBarycentric(polygon *p, vec3 s) {
vec2 v2 = {s[0] - p->points[0][0], s[1] - p->points[0][1]};
float dot02 = vec3_dot(p->v0, v2);
float dot12 = vec3_dot(p->v1, v2);
p->barycentrics[0] = (p->dot11 * dot02 - p->dot01 * dot12) * p->baryFactor;
p->barycentrics[1] = (p->dot00 * dot12 - p->dot01 * dot02) * p->baryFactor;
p->barycentrics[2] = 1.f - p->barycentrics[1] - p->barycentrics[0];
}
void calcNormal(vec3 d, polygon *p) {
vec3_scale(d, p->normals[0], p->barycentrics[0]);
vec3_add_scale(d, p->normals[1], p->barycentrics[1]);
vec3_add_scale(d, p->normals[2], p->barycentrics[2]);
}
void calcColor(vec3 d, polygon *p) {
vec3_scale(d, p->colors[0], p->barycentrics[0]);
vec3_add_scale(d, p->colors[1], p->barycentrics[1]);
vec3_add_scale(d, p->colors[2], p->barycentrics[2]);
}
float calcDepth(polygon *p) {
return p->points[0][0] * p->barycentrics[0] +
p->points[1][0] * p->barycentrics[1] +
p->points[2][0] * p->barycentrics[2];
}
#endif

8
src/quick.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef QUICK_H
#define QUICK_H
struct vec3 {
int i[3];
};
#endif

222
src/renderer.h Normal file
View File

@@ -0,0 +1,222 @@
#ifndef RENDERER_H
#define RENDERER_H
#include "linmath.h"
#include "rendertarget.h"
typedef struct {
vec3 *verts;
int *index;
vec3 *normals;
vec3 *color;
int vert_size;
int index_size;
float shininess;
} model;
typedef struct {
vec4 *points[3];
float dot00;
float dot01;
float dot11;
vec2 v0;
vec2 v1;
vec3 norm;
float baryFactor;
float bounding[4]; // min x, max x, min y, max y
vec3 barycentrics;
} polygon;
// model static inline create_model(vec3 *verts, int *index, int vert_size,
// int index_size) {
// model m = {verts, 0, 0, index, vert_size, index_size};
// // printf("%f\n", verts[0][0]);
// vec3_print(verts[0]);
// return m;
// };
//
const vec3 lightDir = {0.707, 0.707, 0.0f};
void initPoly(polygon *p) {
vec4 **points = p->points;
float *bounding = p->bounding;
// vec2_sub(p->v0, *points[2], *points[0]);
// vec2_sub(p->v1, *points[1], *points[0]);
vec3 v0 = {};
vec3 v1 = {};
vec3_sub(v0, *points[2], *points[0]);
vec3_sub(v1, *points[1], *points[0]);
vec3_mul_cross(p->norm, v0, v1);
vec2_dup(p->v0, v0);
vec2_dup(p->v1, v1);
p->dot00 = vec2_dot(p->v0, p->v0);
p->dot01 = vec2_dot(p->v0, p->v1);
p->dot11 = vec2_dot(p->v1, p->v1);
p->baryFactor = 1.0f / (p->dot00 * p->dot11 - p->dot01 * p->dot01);
bounding[0] = (*points[0])[0];
bounding[1] = (*points[0])[0];
bounding[2] = (*points[0])[1];
bounding[3] = (*points[0])[1];
for (int i = 1; i < 3; i++) {
if (bounding[0] > (*points[i])[0])
bounding[0] = (*points[i])[0];
if (bounding[1] < (*points[i])[0])
bounding[1] = (*points[i])[0];
if (bounding[2] > (*points[i])[1])
bounding[2] = (*points[i])[1];
if (bounding[3] < (*points[i])[1])
bounding[3] = (*points[i])[1];
}
}
void calcBarycentrics(polygon *p, vec2 s, vec3 r) {
vec2 v2 = {};
vec2_sub(v2, s, *p->points[0]);
float dot02 = vec2_dot(p->v0, v2);
float dot12 = vec2_dot(p->v1, v2);
r[2] = p->dot11 * dot02 - p->dot01 * dot12;
r[1] = p->dot00 * dot12 - p->dot01 * dot02;
vec3_scale(r, r, p->baryFactor);
r[0] = 1.f - r[1] - r[2];
}
float fApplyBary(const vec3 bary, float a, float b, float c) {
return bary[0] * a + bary[1] * b + bary[2] * c;
}
void vApplyBary(const vec3 bary, const vec3 a, const vec3 b, const vec3 c,
vec3 dst) {
vec3 tmp = {};
dst[0] = 0;
dst[1] = 0;
dst[2] = 0;
vec3_scale(tmp, a, bary[0]);
vec3_add(dst, dst, tmp);
vec3_scale(tmp, b, bary[1]);
vec3_add(dst, dst, tmp);
vec3_scale(tmp, c, bary[2]);
vec3_add(dst, dst, tmp);
}
void render(render_target *target, const model *model, mat4x4 *matrix,
vec4 *buffer) {
vec4 tmp = {};
for (int i = 0; i < model->vert_size; i++) {
tmp[0] = model->verts[i][0];
tmp[1] = model->verts[i][1];
tmp[2] = model->verts[i][2];
tmp[3] = 1.0f;
mat4x4_mul_vec4(buffer[i], *matrix, tmp);
vec4_scale(buffer[i], buffer[i], 1.0 / buffer[i][3]);
// vec4_print(buffer[i]);
}
polygon p = {};
vec3 *normals[3] = {};
vec3 *colors[3] = {};
for (int i = 0; i < model->index_size; i += 6) {
p.points[0] = buffer + model->index[i];
p.points[1] = buffer + model->index[i + 2];
p.points[2] = buffer + model->index[i + 4];
initPoly(&p);
if (p.norm[2] > 0)
continue;
normals[0] = model->normals + model->index[i + 1];
normals[1] = model->normals + model->index[i + 3];
normals[2] = model->normals + model->index[i + 5];
colors[0] = model->color + model->index[i];
colors[1] = model->color + model->index[i + 2];
colors[2] = model->color + model->index[i + 4];
float texWidth = 2.0f / target->width;
float texHight = 2.0f / target->width;
// float startX = MAX(-1.0f, p.bounding[0]);
// float startY = MAX(-1.0f, p.bounding[2]);
// float endX = MIN(1.0f, p.bounding[1]);
// float endY = MIN(1.0f, p.bounding[3]);
float startX = (MAX(-1.0f, p.bounding[0]) + 1.0f) * 0.5f * target->width;
float endY = (-MAX(-1.0f, p.bounding[2]) + 1.0f) * 0.5f * target->height;
float endX = (MIN(1.0f, p.bounding[1]) + 1.0f) * 0.5f * target->width;
float startY = (-MIN(1.0f, p.bounding[3]) + 1.0f) * 0.5f * target->height;
vec2 sp = {};
vec3 bary = {};
vec4 val = {0};
vec3 nor = {};
vec3 color = {};
vec3 viewDir = {};
vec3 halfWay = {};
for (int y = startY; y < endY; y += 1) {
for (int x = startX; x < endX; x += 1) {
// for (float y = startY; y < endY; y += texHight) {
// for (float x = startX; x < endX; x += texWidth) {
float fX = ((float)x) * texWidth - 1.0f;
float fY = 1.0f - ((float)y) * texHight;
sp[0] = fX;
sp[1] = fY;
calcBarycentrics(&p, sp, bary);
if (bary[0] >= 0.0f && bary[1] >= 0.0f && bary[2] >= 0.0f) {
uint8_t depth = (uint8_t)(255.0 * fApplyBary(bary, (*p.points[0])[2],
(*p.points[1])[2],
(*p.points[2])[2]));
// if (depth < getDepth(target, x, y)) {
vApplyBary(bary, (*normals[0]), (*normals[1]), (*normals[2]), nor);
vApplyBary(bary, (*colors[0]), (*colors[1]), (*colors[2]), color);
viewDir[0] = fX;
viewDir[1] = -fY;
viewDir[2] = 2.144663;
vec3_norm(viewDir, viewDir);
vec3_add(halfWay, viewDir, lightDir);
vec3_norm(halfWay, halfWay);
vec3_dup(val, color);
float diffuse = MAX(vec3_dot(nor, lightDir), 0.0f);
// float l = powf(MAX(vec3_dot(halfWay, nor), 0.0), 2.0);
float spec = powf(MAX(vec3_dot(halfWay, nor), 0.0), model->shininess);
spec *= (model->shininess + 8.0) / 25.1327;
// val[0] = nor[0] * 0.5 + 0.5;
// val[1] = nor[1] * 0.5 + 0.5;
// val[2] = nor[2] * 0.5 + 0.5;
// val[0] = ((float)depth) / 255.0f;
// val[1] = ((float)depth) / 255.0f;
// val[2] = ((float)depth) / 255.0f;
vec3_scale(val, val, diffuse * 0.5 + spec + 0.5);
// vec3_set(val, l);
val[3] = ((float)depth) / 255.0f;
set(target, x, y, val);
// }
}
}
}
}
}
#endif

55
src/rendertarget.h Normal file
View File

@@ -0,0 +1,55 @@
#ifndef RENDER_TARGET
#define RENDER_TARGET
#include "linmath.h"
#include <stdint.h>
#include <string.h>
typedef struct {
int width;
int height;
uint8_t *pixels;
} render_target;
int bufferSize(int width, int height) {
return width * height * 4 * sizeof(uint8_t);
}
void clearTarget(render_target *r) {
memset(r->pixels, 0, 4 * r->height * r->width * sizeof(uint8_t));
for (int i = 3; i < r->height * r->height * 4; i += 4) {
r->pixels[i] = 255;
}
}
void setColor(render_target *r, int x, int y, vec3 val) {
int start = (r->width * y + x) * 4;
r->pixels[start + 0] = (uint8_t)(val[0] * 255);
r->pixels[start + 1] = (uint8_t)(val[1] * 255);
r->pixels[start + 2] = (uint8_t)(val[2] * 255);
}
void getColor(render_target *r, int x, int y, int dst[3]) {
int start = (r->width * y + x) * 4;
dst[0] = r->pixels[start + 0];
dst[1] = r->pixels[start + 1];
dst[2] = r->pixels[start + 2];
}
void set(render_target *r, int x, int y, vec4 val) {
int start = (r->width * y + x) * 4;
r->pixels[start + 0] = (uint8_t)(val[0] * 255);
r->pixels[start + 1] = (uint8_t)(val[1] * 255);
r->pixels[start + 2] = (uint8_t)(val[2] * 255);
r->pixels[start + 3] = (uint8_t)(val[3] * 255);
}
void get(render_target *r, int x, int y, int dst[4]) {
int start = (r->width * y + x) * 4;
dst[0] = r->pixels[start + 0];
dst[1] = r->pixels[start + 1];
dst[2] = r->pixels[start + 2];
dst[3] = r->pixels[start + 3];
}
void setDepth(render_target *r, int x, int y, float val) {
r->pixels[(r->width * y + x) * 4 + 3] = (uint8_t)(val * 255);
}
uint8_t getDepth(render_target *r, int x, int y) {
return r->pixels[(r->width * y + x) * 4 + 3];
}
#endif

9
switch.sh Executable file
View File

@@ -0,0 +1,9 @@
#!/usr/bin/env bash
if [ -e "mathTest.cpp" ]; then
mv main.cpp oldMain.cpp
mv mathTest.cpp main.cpp
else
mv main.cpp mathTest.cpp
mv oldMain.cpp main.cpp
fi

BIN
test.bin Normal file

Binary file not shown.

BIN
test.fbx Normal file

Binary file not shown.

297
test.gltf Normal file
View File

@@ -0,0 +1,297 @@
{
"asset":{
"generator":"Khronos glTF Blender I/O v5.1.18",
"version":"2.0"
},
"scene":0,
"scenes":[
{
"name":"Scene.009",
"nodes":[
0,
1,
2
]
}
],
"nodes":[
{
"mesh":0,
"name":"Fairy_Dust_full.002",
"scale":[
0.007043707650154829,
0.007043707650154829,
0.007043707650154829
],
"translation":[
0,
-1.292056679725647,
0
]
},
{
"mesh":1,
"name":"Cylinder.002",
"rotation":[
0,
-0.7071068286895752,
0,
0.7071068286895752
],
"scale":[
0.7209481596946716,
0.7209481596946716,
0.7209481596946716
],
"translation":[
0,
0.47851109504699707,
-10
]
},
{
"mesh":2,
"name":"Suzanne.001",
"translation":[
0,
2.779357671737671,
0
]
}
],
"materials":[
{
"doubleSided":true,
"name":"Material.001",
"pbrMetallicRoughness":{
"metallicFactor":0
}
}
],
"meshes":[
{
"name":"Fairy_Dust_full.002",
"primitives":[
{
"attributes":{
"POSITION":0,
"NORMAL":1
},
"indices":2
}
]
},
{
"name":"Cylinder.002",
"primitives":[
{
"attributes":{
"POSITION":3,
"NORMAL":4,
"TEXCOORD_0":5,
"COLOR_0":6
},
"indices":7,
"material":0
}
]
},
{
"name":"Suzanne",
"primitives":[
{
"attributes":{
"POSITION":8,
"NORMAL":9,
"TEXCOORD_0":10
},
"indices":11
}
]
}
],
"accessors":[
{
"bufferView":0,
"componentType":5126,
"count":444720,
"max":[
151.8914031982422,
630.0626220703125,
133.6092071533203
],
"min":[
-103.52690124511719,
-4.516704088378728e-15,
-133.6092071533203
],
"type":"VEC3"
},
{
"bufferView":1,
"componentType":5126,
"count":444720,
"type":"VEC3"
},
{
"bufferView":2,
"componentType":5125,
"count":471222,
"type":"SCALAR"
},
{
"bufferView":3,
"componentType":5126,
"count":172,
"max":[
1.0631183385849,
2.3016695976257324,
1.0250295400619507
],
"min":[
-1.0094571113586426,
-2.2646777629852295,
-1.0250295400619507
],
"type":"VEC3"
},
{
"bufferView":4,
"componentType":5126,
"count":172,
"type":"VEC3"
},
{
"bufferView":5,
"componentType":5126,
"count":172,
"type":"VEC2"
},
{
"bufferView":6,
"componentType":5126,
"count":172,
"type":"VEC3"
},
{
"bufferView":7,
"componentType":5123,
"count":876,
"type":"SCALAR"
},
{
"bufferView":8,
"componentType":5126,
"count":555,
"max":[
1.3671875,
0.984375,
0.8515625
],
"min":[
-1.3671875,
-0.984375,
-0.8515625
],
"type":"VEC3"
},
{
"bufferView":9,
"componentType":5126,
"count":555,
"type":"VEC3"
},
{
"bufferView":10,
"componentType":5126,
"count":555,
"type":"VEC2"
},
{
"bufferView":11,
"componentType":5123,
"count":2904,
"type":"SCALAR"
}
],
"bufferViews":[
{
"buffer":0,
"byteLength":5336640,
"byteOffset":0,
"target":34962
},
{
"buffer":0,
"byteLength":5336640,
"byteOffset":5336640,
"target":34962
},
{
"buffer":0,
"byteLength":1884888,
"byteOffset":10673280,
"target":34963
},
{
"buffer":0,
"byteLength":2064,
"byteOffset":12558168,
"target":34962
},
{
"buffer":0,
"byteLength":2064,
"byteOffset":12560232,
"target":34962
},
{
"buffer":0,
"byteLength":1376,
"byteOffset":12562296,
"target":34962
},
{
"buffer":0,
"byteLength":2064,
"byteOffset":12563672,
"target":34962
},
{
"buffer":0,
"byteLength":1752,
"byteOffset":12565736,
"target":34963
},
{
"buffer":0,
"byteLength":6660,
"byteOffset":12567488,
"target":34962
},
{
"buffer":0,
"byteLength":6660,
"byteOffset":12574148,
"target":34962
},
{
"buffer":0,
"byteLength":4440,
"byteOffset":12580808,
"target":34962
},
{
"buffer":0,
"byteLength":5808,
"byteOffset":12585248,
"target":34963
}
],
"buffers":[
{
"byteLength":12591056,
"uri":"test.bin"
}
]
}

12
test.mtl Normal file
View File

@@ -0,0 +1,12 @@
# Blender 5.0.0 MTL File: 'test.blend'
# www.blender.org
newmtl Material.001
Ns 0.000000
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.800000 0.800000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.500000
d 1.000000
illum 2

836
test.obj Normal file
View File

@@ -0,0 +1,836 @@
# Blender 5.0.0
# www.blender.org
mtllib test.mtl
o Cylinder.003
v -0.000000 0.757563 0.698513 0.0000 0.4470 0.0334
v -0.000000 2.825787 0.044645 0.0000 0.4470 0.0334
v -0.238906 0.757563 0.656388 0.0000 0.4470 0.0334
v -0.015270 2.825787 0.041953 0.0000 0.4470 0.0334
v -0.448996 0.757563 0.535092 0.0000 0.4470 0.0334
v -0.028697 2.825787 0.034200 0.0000 0.4470 0.0334
v -0.604930 0.757563 0.349257 0.0000 0.4470 0.0334
v -0.038664 2.825787 0.022323 0.0000 0.4470 0.0334
v -0.687901 0.757563 0.043996 0.0000 0.4470 0.0334
v -0.043967 2.825787 0.018354 0.0000 0.4470 0.0334
v -0.687901 0.757563 -0.043996 0.0000 0.4470 0.0334
v -0.043967 2.825787 -0.018354 0.0000 0.4470 0.0334
v -0.604930 0.757563 -0.349257 0.0000 0.4470 0.0334
v -0.038664 2.825787 -0.022323 0.0000 0.4470 0.0334
v -0.448996 0.757563 -0.535092 0.0000 0.4470 0.0334
v -0.028697 2.825787 -0.034200 0.0000 0.4470 0.0334
v -0.238906 0.757563 -0.656388 0.0000 0.4470 0.0334
v -0.015270 2.825787 -0.041953 0.0000 0.4470 0.0334
v -0.000000 0.757563 -0.698513 0.0000 0.4470 0.0334
v -0.000000 2.825787 -0.044645 0.0000 0.4470 0.0334
v 0.238906 0.757563 -0.656388 0.0000 0.4470 0.0334
v 0.015270 2.825787 -0.041953 0.0000 0.4470 0.0334
v 0.448996 0.757563 -0.535092 0.0000 0.4470 0.0334
v 0.028697 2.825787 -0.034200 0.0000 0.4470 0.0334
v 0.604930 0.757563 -0.349257 0.0000 0.4470 0.0334
v 0.038664 2.825787 -0.022323 0.0000 0.4470 0.0334
v 0.687901 0.757563 -0.121296 0.0000 0.4470 0.0334
v 0.043967 2.825787 -0.007753 0.0000 0.4470 0.0334
v 0.687901 0.757563 0.121296 0.0000 0.4470 0.0334
v 0.043967 2.825787 0.007753 0.0000 0.4470 0.0334
v 0.604930 0.757563 0.349257 0.0000 0.4470 0.0334
v 0.038664 2.825787 0.022323 0.0000 0.4470 0.0334
v 0.448996 0.757563 0.535092 0.0000 0.4470 0.0334
v 0.028697 2.825787 0.034200 0.0000 0.4470 0.0334
v 0.238906 0.757563 0.656388 0.0000 0.4470 0.0334
v 0.015270 2.825787 0.041953 0.0000 0.4470 0.0334
v -0.000000 2.240545 0.544639 0.0000 0.4470 0.0334
v -0.186277 2.240545 0.511793 0.0000 0.4470 0.0334
v -0.371044 2.128906 0.409479 0.8556 0.8746 1.0000
v -0.470774 2.227410 0.290178 0.8556 0.8746 1.0000
v -0.539710 2.227410 0.100778 0.8556 0.8746 1.0000
v -0.539710 2.227410 -0.100778 0.8556 0.8746 1.0000
v -0.470774 2.227410 -0.290178 0.8556 0.8746 1.0000
v -0.371044 2.128906 -0.409479 0.8556 0.8746 1.0000
v -0.186277 2.240545 -0.511793 0.0000 0.4470 0.0334
v -0.000000 2.240545 -0.544639 0.0000 0.4470 0.0334
v 0.186277 2.240545 -0.511793 0.0000 0.4470 0.0334
v 0.350087 2.240545 -0.417218 0.0000 0.4470 0.0334
v 0.471671 2.240545 -0.272319 0.0000 0.4470 0.0334
v 0.536364 2.240545 -0.094576 0.0000 0.4470 0.0334
v 0.536364 2.240545 0.094576 0.0000 0.4470 0.0334
v 0.471671 2.240545 0.272319 0.0000 0.4470 0.0334
v 0.350087 2.240545 0.417218 0.0000 0.4470 0.0334
v 0.186277 2.240545 0.511793 0.0000 0.4470 0.0334
v -0.252751 1.474881 0.694426 0.0000 0.4470 0.0334
v -0.497527 1.631239 0.527394 0.8556 0.8746 1.0000
v -0.632126 1.488016 0.367433 0.8556 0.8746 1.0000
v -0.719415 1.488016 0.127608 0.8556 0.8746 1.0000
v -0.719415 1.488016 -0.127608 0.8556 0.8746 1.0000
v -0.632126 1.488016 -0.367433 0.8556 0.8746 1.0000
v -0.497527 1.631239 -0.527394 0.8556 0.8746 1.0000
v -0.252751 1.474881 -0.694426 0.0000 0.4470 0.0334
v -0.000000 1.474881 -0.738993 0.0000 0.4470 0.0334
v 0.252751 1.474881 -0.694426 0.0000 0.4470 0.0334
v 0.475016 1.474881 -0.566102 0.0000 0.4470 0.0334
v 0.639987 1.474881 -0.369497 0.0000 0.4470 0.0334
v 0.727766 1.474881 -0.128325 0.0000 0.4470 0.0334
v 0.727766 1.474881 0.128325 0.0000 0.4470 0.0334
v 0.639987 1.474881 0.369497 0.0000 0.4470 0.0334
v 0.475016 1.474881 0.566102 0.0000 0.4470 0.0334
v 0.252751 1.474881 0.694426 0.0000 0.4470 0.0334
v -0.000000 1.474881 0.738993 0.0000 0.4470 0.0334
v 0.000000 -0.154204 0.410385 0.0000 0.4470 0.0334
v -0.140360 -0.154204 0.385635 0.0000 0.4470 0.0334
v -0.263790 -0.154204 0.314373 0.0000 0.4470 0.0334
v -0.355403 -0.154204 0.205192 0.0000 0.4470 0.0334
v -0.404150 -0.154204 0.071263 0.0000 0.4470 0.0334
v -0.404150 -0.154204 -0.071263 0.0000 0.4470 0.0334
v -0.355403 -0.154204 -0.205192 0.0000 0.4470 0.0334
v -0.263790 -0.154204 -0.314373 0.0000 0.4470 0.0334
v -0.140360 -0.154204 -0.385635 0.0000 0.4470 0.0334
v 0.000000 -0.154204 -0.410385 0.0000 0.4470 0.0334
v 0.140360 -0.154204 -0.385635 0.0000 0.4470 0.0334
v 0.263790 -0.154204 -0.314373 0.0000 0.4470 0.0334
v 0.355403 -0.154204 -0.205192 0.0000 0.4470 0.0334
v 0.404150 -0.154204 -0.071263 0.0000 0.4470 0.0334
v 0.404150 -0.154204 0.071263 0.0000 0.4470 0.0334
v 0.355403 -0.154204 0.205192 0.0000 0.4470 0.0334
v 0.263790 -0.154204 0.314373 0.0000 0.4470 0.0334
v 0.140360 -0.154204 0.385635 0.0000 0.4470 0.0334
v -0.000000 2.675272 0.237705 0.0000 0.4470 0.0334
v -0.081300 2.675272 0.223370 0.0000 0.4470 0.0334
v -0.152794 2.675272 0.182093 0.0000 0.4470 0.0334
v -0.205859 2.675272 0.118853 0.0000 0.4470 0.0334
v -0.234094 2.675272 0.041277 0.0000 0.4470 0.0334
v -0.234094 2.675272 -0.041277 0.0000 0.4470 0.0334
v -0.205859 2.675272 -0.118853 0.0000 0.4470 0.0334
v -0.152794 2.675272 -0.182093 0.0000 0.4470 0.0334
v -0.081300 2.675272 -0.223370 0.0000 0.4470 0.0334
v -0.000000 2.675272 -0.237705 0.0000 0.4470 0.0334
v 0.081300 2.675272 -0.223370 0.0000 0.4470 0.0334
v 0.152794 2.675272 -0.182093 0.0000 0.4470 0.0334
v 0.205859 2.675272 -0.118853 0.0000 0.4470 0.0334
v 0.234094 2.675272 -0.041277 0.0000 0.4470 0.0334
v 0.234094 2.675272 0.041277 0.0000 0.4470 0.0334
v 0.205859 2.675272 0.118853 0.0000 0.4470 0.0334
v 0.152794 2.675272 0.182093 0.0000 0.4470 0.0334
v 0.081300 2.675272 0.223370 0.0000 0.4470 0.0334
v -0.000000 2.839588 0.046326 0.9696 1.0000 0.0000
v 0.040120 2.839588 -0.023163 0.9695 0.9999 0.0005
v -0.040120 2.839588 -0.023163 0.9696 1.0000 0.0000
v -0.000000 3.137896 0.000000 0.9696 1.0000 0.0000
v -0.471671 2.240545 -0.272319 0.0000 0.4470 0.0334
v -0.350087 2.141971 -0.417218 0.0000 0.4470 0.0334
v -0.536364 2.240545 -0.061970 0.0000 0.4470 0.0334
v -0.536364 2.240545 0.061970 0.0000 0.4470 0.0334
v -0.471671 2.240545 0.272319 0.0000 0.4470 0.0334
v -0.350087 2.141971 0.417218 0.0000 0.4470 0.0334
v -0.475016 1.618174 0.566102 0.0000 0.4470 0.0334
v -0.475016 1.618174 -0.566102 0.0000 0.4470 0.0334
v -0.639987 1.474881 0.369497 0.0000 0.4470 0.0334
v -0.727766 1.474881 0.046546 0.0000 0.4470 0.0334
v -0.727766 1.474881 -0.046546 0.0000 0.4470 0.0334
v -0.639987 1.474881 -0.369497 0.0000 0.4470 0.0334
v -0.625731 2.117707 0.237002 0.1450 0.1371 0.1900
v -0.728921 1.652925 0.257333 0.1450 0.1371 0.1900
v -0.682034 2.117707 0.082310 0.1450 0.1371 0.1900
v -0.766453 1.652925 0.089371 0.1450 0.1371 0.1900
v -0.682034 2.117707 -0.082310 0.1450 0.1371 0.1900
v -0.766453 1.652925 -0.089371 0.1450 0.1371 0.1900
v -0.625731 2.117707 -0.237002 0.1450 0.1371 0.1900
v -0.728921 1.652925 -0.257333 0.1450 0.1371 0.1900
v -0.544276 2.019176 -0.334441 0.1450 0.1371 0.1900
v -0.544276 2.019176 0.334441 0.1450 0.1371 0.1900
v -0.671046 1.735177 0.369362 0.1450 0.1371 0.1900
v -0.671046 1.735177 -0.369362 0.1450 0.1371 0.1900
v -0.616476 2.201041 0.096339 0.1450 0.1371 0.1900
v -0.616476 2.201041 -0.096339 0.1450 0.1371 0.1900
v -0.539235 1.656222 0.489408 0.1450 0.1371 0.1900
v -0.455240 2.102530 0.391442 0.1450 0.1371 0.1900
v -0.730721 1.527654 0.118417 0.1450 0.1371 0.1900
v -0.730721 1.527654 -0.118417 0.1450 0.1371 0.1900
v -0.539235 1.656222 -0.489408 0.1450 0.1371 0.1900
v -0.455240 2.102530 -0.391442 0.1450 0.1371 0.1900
v -0.550577 2.201041 0.277396 0.1450 0.1371 0.1900
v -0.655392 1.527654 -0.340969 0.1450 0.1371 0.1900
v -0.550577 2.201041 -0.277396 0.1450 0.1371 0.1900
v -0.655392 1.527654 0.340969 0.1450 0.1371 0.1900
v -0.687901 0.757563 0.040432 0.7050 0.7349 0.2011
v -0.687901 0.757563 -0.040432 0.7050 0.7349 0.2011
v -0.043967 2.825787 -0.002584 0.7050 0.7349 0.2011
v -0.043967 2.825787 0.002584 0.7050 0.7349 0.2011
v -0.536364 2.240545 0.031525 0.7050 0.7349 0.2011
v -0.536364 2.240545 -0.031525 0.7050 0.7349 0.2011
v -0.727766 1.474881 0.042775 0.7050 0.7349 0.2011
v -0.727766 1.474881 -0.042775 0.7050 0.7349 0.2011
v -0.404150 -0.154204 0.023754 0.7050 0.7349 0.2011
v -0.404150 -0.154204 -0.023754 0.7050 0.7349 0.2011
v -0.234094 2.675272 0.013759 0.7050 0.7349 0.2011
v -0.234094 2.675272 -0.013759 0.7050 0.7349 0.2011
v -0.539710 2.227410 0.033593 0.8556 0.8746 1.0000
v -0.539710 2.227410 -0.033593 0.8556 0.8746 1.0000
v -0.719415 1.488016 0.042536 0.8556 0.8746 1.0000
v -0.719415 1.488016 -0.042536 0.8556 0.8746 1.0000
v -0.682034 2.117707 0.027437 0.1450 0.1371 0.1900
v -0.682034 2.117707 -0.027437 0.1450 0.1371 0.1900
v -0.766453 1.652925 0.029790 0.1450 0.1371 0.1900
v -0.766453 1.652925 -0.029790 0.1450 0.1371 0.1900
v -0.616476 2.201041 -0.032113 0.1450 0.1371 0.1900
v -0.616476 2.201041 0.032113 0.1450 0.1371 0.1900
v -0.730721 1.527654 0.039472 0.1450 0.1371 0.1900
v -0.730721 1.527654 -0.039472 0.1450 0.1371 0.1900
vn -0.0000 -0.1778 0.9841
vn -0.0000 0.4043 0.9146
vn -0.3366 -0.1778 0.9247
vn -0.3310 0.5378 0.7754
vn -0.6327 -0.1768 0.7540
vn -0.4632 0.7357 0.4942
vn -0.8715 -0.1746 0.4583
vn -0.4263 0.8241 0.3730
vn -0.9766 -0.1731 0.1279
vn -0.4586 0.8447 0.2760
vn -0.9766 -0.1731 -0.1279
vn -0.7539 0.5676 -0.3309
vn -0.8715 -0.1746 -0.4583
vn -0.6446 0.3655 -0.6715
vn -0.6327 -0.1768 -0.7540
vn -0.5060 0.5378 -0.6743
vn -0.3366 -0.1778 -0.9247
vn -0.1964 0.7357 -0.6483
vn -0.0000 -0.1778 -0.9841
vn -0.0000 0.7980 -0.6026
vn 0.3366 -0.1778 -0.9247
vn 0.1964 0.7357 -0.6483
vn 0.6325 -0.1778 -0.7538
vn 0.5060 0.5378 -0.6743
vn 0.8522 -0.1778 -0.4920
vn 0.7921 0.4043 -0.4573
vn 0.9691 -0.1778 -0.1709
vn 0.8370 0.5378 -0.1010
vn 0.9691 -0.1778 0.1709
vn 0.6596 0.7357 0.1541
vn 0.8522 -0.1778 0.4920
vn 0.5219 0.7980 0.3013
vn 0.6325 -0.1778 0.7538
vn 0.4632 0.7357 0.4942
vn 0.3366 -0.1778 0.9247
vn 0.3310 0.5378 0.7754
vn -0.0000 0.4109 0.9117
vn -0.3877 0.4345 0.8130
vn -0.4535 0.3907 0.8011
vn -0.3037 0.7552 0.5809
vn -0.5096 0.8517 0.1225
vn -0.5096 0.8517 -0.1225
vn -0.3037 0.7552 -0.5809
vn -0.4535 0.3907 -0.8011
vn -0.3877 0.4345 -0.8130
vn -0.0000 0.4109 -0.9117
vn 0.3118 0.4109 -0.8567
vn 0.5860 0.4109 -0.6984
vn 0.7895 0.4109 -0.4558
vn 0.8978 0.4109 -0.1583
vn 0.8978 0.4109 0.1583
vn 0.7895 0.4109 0.4558
vn 0.5860 0.4109 0.6984
vn 0.3118 0.4109 0.8567
vn -0.3267 0.0728 0.9423
vn -0.7472 0.1973 0.6347
vn -0.8652 0.2699 0.4225
vn -0.8748 -0.4449 0.1917
vn -0.8748 -0.4449 -0.1917
vn -0.8652 0.2699 -0.4225
vn -0.7472 0.1973 -0.6347
vn -0.3267 0.0728 -0.9423
vn -0.0000 0.0944 -0.9955
vn 0.3405 0.0944 -0.9355
vn 0.6399 0.0944 -0.7626
vn 0.8622 0.0944 -0.4978
vn 0.9804 0.0944 -0.1729
vn 0.9804 0.0944 0.1729
vn 0.8622 0.0944 0.4978
vn 0.6399 0.0944 0.7626
vn 0.3405 0.0944 0.9355
vn -0.0000 0.0944 0.9955
vn -0.0000 -0.7761 0.6306
vn -0.2157 -0.7761 0.5926
vn -0.4053 -0.7761 0.4830
vn -0.5461 -0.7761 0.3153
vn -0.6219 -0.7754 0.1097
vn -0.6219 -0.7754 -0.1097
vn -0.5461 -0.7761 -0.3153
vn -0.4053 -0.7761 -0.4831
vn -0.2157 -0.7761 -0.5925
vn -0.0000 -0.7761 -0.6306
vn 0.2157 -0.7761 -0.5925
vn 0.4053 -0.7761 -0.4831
vn 0.5461 -0.7761 -0.3153
vn 0.6210 -0.7761 -0.1095
vn 0.6210 -0.7761 0.1095
vn 0.5461 -0.7761 0.3153
vn 0.4053 -0.7761 0.4830
vn 0.2157 -0.7761 0.5926
vn -0.0000 0.6821 0.7312
vn -0.2501 0.6821 0.6871
vn -0.4746 0.6745 0.5656
vn -0.6339 0.6806 0.3674
vn -0.7224 0.6799 0.1262
vn -0.7224 0.6799 -0.1262
vn -0.6339 0.6806 -0.3674
vn -0.4746 0.6745 -0.5656
vn -0.2501 0.6821 -0.6871
vn -0.0000 0.6821 -0.7312
vn 0.2501 0.6821 -0.6871
vn 0.4700 0.6821 -0.5601
vn 0.6333 0.6821 -0.3656
vn 0.7201 0.6821 -0.1270
vn 0.7201 0.6821 0.1270
vn 0.6333 0.6821 0.3656
vn 0.4700 0.6821 0.5601
vn 0.2501 0.6821 0.6871
vn -0.0000 0.3307 0.9437
vn 0.8173 0.3307 -0.4719
vn -0.7954 0.3664 -0.4828
vn -0.0000 1.0000 -0.0000
vn -0.7054 0.5308 -0.4698
vn -0.5620 0.4126 -0.7169
vn -0.8901 0.4498 -0.0734
vn -0.8901 0.4498 0.0734
vn -0.7054 0.5308 0.4698
vn -0.5620 0.4126 0.7169
vn -0.6315 0.1650 0.7577
vn -0.6315 0.1650 -0.7577
vn -0.8818 0.1842 0.4342
vn -0.9740 0.2132 0.0768
vn -0.9740 0.2132 -0.0768
vn -0.8818 0.1842 -0.4342
vn -0.7907 0.3661 0.4906
vn -0.9379 -0.0553 0.3424
vn -0.9051 0.4003 0.1431
vn -0.9942 -0.0377 0.1012
vn -0.9051 0.4003 -0.1431
vn -0.9942 -0.0377 -0.1012
vn -0.7907 0.3661 -0.4906
vn -0.9379 -0.0553 -0.3424
vn -0.6159 0.2805 -0.7362
vn -0.6159 0.2805 0.7362
vn -0.7741 0.1400 0.6174
vn -0.7741 0.1400 -0.6174
vn -0.6037 0.7887 0.1165
vn -0.6037 0.7887 -0.1165
vn -0.6512 0.0880 0.7537
vn -0.4541 0.3734 0.8090
vn -0.9560 -0.2577 0.1400
vn -0.9560 -0.2577 -0.1400
vn -0.6512 0.0880 -0.7537
vn -0.4541 0.3734 -0.8090
vn -0.5539 0.6625 0.5043
vn -0.8527 -0.2028 -0.4814
vn -0.5539 0.6625 -0.5043
vn -0.8527 -0.2028 0.4814
vn -0.9841 -0.1777 -0.0000
vn -0.8329 0.5534 -0.0000
vn -0.8329 0.5535 -0.0000
vn -0.9096 0.4155 -0.0000
vn -0.9676 0.2526 -0.0000
vn -0.9676 0.2527 -0.0000
vn -0.5928 -0.8053 -0.0000
vn -0.7287 0.6848 -0.0000
vn -0.7353 0.6777 -0.0000
vn -0.9896 0.1437 -0.0000
vn -0.9118 0.4106 -0.0000
vn -0.9988 -0.0491 -0.0000
vn -0.5790 0.8153 -0.0000
vn -0.9616 -0.2743 -0.0000
vt 1.000000 1.000000
vt 0.944444 0.875000
vt 1.000000 0.875000
vt 0.888889 1.000000
vt 0.888889 0.875000
vt 0.833333 0.875000
vt 0.777778 1.000000
vt 0.777778 0.875000
vt 0.740741 0.875000
vt 0.722222 1.000000
vt 0.722222 0.875000
vt 0.666667 0.875000
vt 0.611111 1.000000
vt 0.611111 0.875000
vt 0.555555 0.875000
vt 0.500000 1.000000
vt 0.500000 0.875000
vt 0.444444 0.875000
vt 0.388889 1.000000
vt 0.388889 0.875000
vt 0.333333 0.875000
vt 0.333333 1.000000
vt 0.277778 0.875000
vt 0.277778 1.000000
vt 0.222222 0.875000
vt 0.166666 1.000000
vt 0.166666 0.875000
vt 0.111111 0.875000
vt 0.111111 1.000000
vt 0.055555 0.875000
vt 0.055555 1.000000
vt -0.000000 0.875000
vt 0.888889 0.500000
vt 0.944444 0.500000
vt 0.055555 0.750000
vt -0.000000 0.620925
vt 0.055555 0.620925
vt 0.111111 0.750000
vt 0.111111 0.620925
vt 0.166666 0.750000
vt 0.166666 0.620925
vt 0.222222 0.750000
vt 0.222222 0.620925
vt 0.277778 0.750000
vt 0.277778 0.620925
vt 0.333333 0.620925
vt 0.388889 0.620925
vt 0.333333 0.750000
vt 0.444444 0.750000
vt 0.444444 0.620925
vt 0.500000 0.620925
vt 0.555555 0.750000
vt 0.555555 0.620925
vt 0.611111 0.620925
vt 0.777791 0.742476
vt 0.833347 0.742476
vt 0.833347 0.742476
vt 0.621250 0.628449
vt 0.623706 0.742476
vt 0.759270 0.628449
vt 0.777789 0.628449
vt 0.759270 0.628449
vt 0.740754 0.742476
vt 0.722236 0.742476
vt 0.740754 0.742476
vt 0.878750 0.628449
vt 0.876294 0.742476
vt 0.878750 0.628449
vt 0.944444 0.750000
vt 0.888889 0.620925
vt 0.944444 0.620925
vt 1.000000 0.620925
vt 1.000000 0.500000
vt 0.833333 0.620925
vt 0.833333 0.500000
vt 0.777778 0.620925
vt 0.777778 0.500000
vt 0.740741 0.620925
vt 0.722222 0.500000
vt 0.740741 0.500000
vt 0.722222 0.620925
vt 0.666667 0.500000
vt 0.666666 0.620925
vt 0.611111 0.500000
vt 0.555555 0.500000
vt 0.500000 0.500000
vt 0.444444 0.500000
vt 0.388889 0.500000
vt 0.333333 0.500000
vt 0.277778 0.500000
vt 0.222222 0.500000
vt 0.166666 0.500000
vt 0.111111 0.500000
vt 0.055555 0.500000
vt -0.000000 0.500000
vt 0.986354 0.236108
vt 0.750000 0.010000
vt 0.513646 0.208324
vt 0.740741 0.500000
vt -0.000000 0.750000
vt 0.388889 0.750000
vt 0.500000 0.750000
vt 0.611111 0.750000
vt 0.666667 0.750000
vt 0.722222 0.750000
vt 0.740741 0.750000
vt 0.833333 0.750000
vt 0.777778 0.750000
vt 0.888889 0.750000
vt 1.000000 0.750000
vt 0.000000 0.000000
vt 0.944444 1.000000
vt 0.833333 1.000000
vt 0.740741 1.000000
vt 0.759259 1.000000
vt 0.666667 1.000000
vt 0.555555 1.000000
vt 0.444444 1.000000
vt 0.222222 1.000000
vt -0.000000 1.000000
vt 0.666680 0.742476
vt 0.759273 0.742476
vt 0.759259 0.750000
vt 0.833345 0.628449
vt 0.740752 0.628449
vt 0.722233 0.628449
vt 0.666678 0.628449
vt 0.666680 0.742476
vt 0.833345 0.628449
vt 0.876294 0.742476
vt 0.722236 0.742476
vt 0.777789 0.628449
vt 0.740754 0.742476
vt 0.740752 0.628449
vt 0.759273 0.742476
vt 0.759259 0.620925
vt 0.759259 0.875000
vt 0.759259 0.500000
vt 0.759259 0.500000
vt 0.667915 0.475526
vt 0.750000 0.490000
vt 0.832085 0.475526
vt 0.904269 0.433851
vt 0.957846 0.370000
vt 0.986354 0.291676
vt 0.986354 0.263892
vt 0.986354 0.208324
vt 0.957846 0.130000
vt 0.542154 0.370000
vt 0.595731 0.433851
vt 0.513646 0.291676
vt 0.595731 0.066149
vt 0.542154 0.130000
vt 0.667915 0.024474
vt 0.904269 0.066149
vt 0.832085 0.024474
s 1
usemtl Material.001
f 2/1/2 92/2/92 91/3/91
f 92/2/92 6/4/6 93/5/93
f 6/4/6 94/6/94 93/5/93
f 94/6/94 10/7/10 95/8/95
f 160/9/156 12/10/12 96/11/96
f 12/10/12 97/12/97 96/11/96
f 97/12/97 16/13/16 98/14/98
f 16/13/16 99/15/99 98/14/98
f 99/15/99 20/16/20 100/17/100
f 20/16/20 101/18/101 100/17/100
f 101/18/101 24/19/24 102/20/102
f 24/19/24 103/21/103 102/20/102
f 26/22/26 104/23/104 103/21/103
f 28/24/28 105/25/105 104/23/104
f 105/25/105 32/26/32 106/27/106
f 32/26/32 107/28/107 106/27/106
f 34/29/34 108/30/108 107/28/107
f 36/31/36 91/32/91 108/30/108
f 5/33/5 74/34/74 3/34/3
f 54/35/54 72/36/72 71/37/71
f 53/38/53 71/37/71 70/39/70
f 52/40/52 70/39/70 69/41/69
f 51/42/51 69/41/69 68/43/68
f 50/44/50 68/43/68 67/45/67
f 66/46/66 50/44/50 67/45/67
f 65/47/65 49/48/49 66/46/66
f 47/49/47 65/47/65 64/50/64
f 63/51/63 47/49/47 64/50/64
f 45/52/45 63/51/63 62/53/62
f 120/54/120 45/52/45 62/53/62
f 137/55/137 125/56/125 145/57/145
f 143/58/143 133/59/133 144/59/144
f 171/60/162 128/61/128 167/62/160
f 169/63/161 129/64/129 166/65/159
f 139/66/139 134/67/134 135/68/135
f 38/69/38 119/70/119 55/71/55
f 72/72/72 38/69/38 55/71/55
f 1/73/1 55/71/55 3/34/3
f 55/71/55 5/33/5 3/34/3
f 5/33/5 121/74/121 7/75/7
f 7/75/7 122/76/122 9/77/9
f 156/78/154 11/79/11 150/80/149
f 123/81/123 13/82/13 11/79/11
f 124/83/124 15/84/15 13/82/13
f 15/84/15 62/53/62 17/85/17
f 17/85/17 63/51/63 19/86/19
f 19/86/19 64/50/64 21/87/21
f 64/50/64 23/88/23 21/87/21
f 65/47/65 25/89/25 23/88/23
f 66/46/66 27/90/27 25/89/25
f 67/45/67 29/91/29 27/90/27
f 68/43/68 31/92/31 29/91/29
f 69/41/69 33/93/33 31/92/31
f 70/39/70 35/94/35 33/93/33
f 35/94/35 72/36/72 1/95/1
f 158/96/155 82/97/82 86/98/86
f 15/84/15 79/82/79 13/82/13
f 25/89/25 84/88/84 23/88/23
f 35/94/35 89/93/89 33/93/33
f 11/79/11 158/99/155 150/80/149
f 21/87/21 82/86/82 19/86/19
f 31/92/31 87/91/87 29/91/29
f 7/75/7 75/33/75 5/33/5
f 17/85/17 80/84/80 15/84/15
f 3/34/3 73/73/73 1/73/1
f 27/90/27 85/89/85 25/89/25
f 1/95/1 90/94/90 35/94/35
f 13/82/13 78/79/78 11/79/11
f 23/88/23 83/87/83 21/87/21
f 33/93/33 88/92/88 31/92/31
f 7/75/7 77/77/77 76/75/76
f 19/86/19 81/85/81 17/85/17
f 29/91/29 86/90/86 27/90/27
f 108/30/108 37/100/37 54/35/54
f 107/28/107 54/35/54 53/38/53
f 106/27/106 53/38/53 52/40/52
f 105/25/105 52/40/52 51/42/51
f 104/23/104 51/42/51 50/44/50
f 103/21/103 50/44/50 49/48/49
f 102/20/102 49/48/49 48/101/48
f 101/18/101 48/101/48 47/49/47
f 100/17/100 47/49/47 46/102/46
f 99/15/99 46/102/46 45/52/45
f 98/14/98 45/52/45 114/103/114
f 113/104/113 98/14/98 114/103/114
f 96/11/96 113/104/113 115/105/115
f 154/106/152 96/11/96 115/105/115
f 117/107/117 95/8/95 116/108/116
f 93/5/93 117/107/117 118/109/118
f 38/69/38 93/5/93 118/109/118
f 91/3/91 38/69/38 37/110/37
f 109/111/109 6/4/6 4/112/4
f 109/111/109 8/113/8 6/4/6
f 111/111/111 8/113/8 109/111/109
f 111/111/111 151/114/150 152/115/151
f 111/111/111 14/116/14 12/10/12
f 111/111/111 16/13/16 14/116/14
f 111/111/111 18/117/18 16/13/16
f 111/111/111 20/16/20 18/117/18
f 110/111/110 20/16/20 111/111/111
f 110/111/110 24/19/24 22/118/22
f 110/111/110 26/22/26 24/19/24
f 110/111/110 28/24/28 26/22/26
f 110/111/110 30/119/30 28/24/28
f 110/111/110 32/26/32 30/119/30
f 109/111/109 32/26/32 110/111/110
f 109/111/109 36/31/36 34/29/34
f 109/111/109 2/120/2 36/31/36
f 109/111/109 4/112/4 2/1/2
f 111/111/111 10/7/10 8/113/8
f 110/111/110 22/118/22 20/16/20
f 109/111/109 34/29/34 32/26/32
f 111/111/111 109/111/109 112/111/112
f 110/111/110 111/111/111 112/111/112
f 109/111/109 110/111/110 112/111/112
f 43/121/43 114/103/114 44/59/44
f 42/64/42 113/104/113 43/121/43
f 161/122/157 116/108/116 153/123/152
f 41/55/41 117/107/117 116/108/116
f 40/56/40 118/109/118 117/107/117
f 39/67/39 119/70/119 118/109/118
f 44/59/44 120/54/120 61/58/61
f 57/124/57 119/70/119 56/68/56
f 58/61/58 121/74/121 57/124/57
f 164/125/158 123/81/123 156/78/154
f 59/126/59 124/83/124 123/81/123
f 60/127/60 120/54/120 124/83/124
f 131/121/131 136/58/136 132/127/132
f 129/64/129 132/127/132 130/126/130
f 168/125/160 129/64/129 130/126/130
f 126/124/126 127/55/127 128/61/128
f 135/68/135 125/56/125 126/124/126
f 142/126/142 132/127/132 146/127/146
f 147/128/147 133/59/133 131/121/131
f 148/129/148 135/68/135 126/124/126
f 145/57/145 134/67/134 140/130/140
f 146/127/146 136/58/136 143/58/143
f 138/131/138 131/121/131 129/64/129
f 141/132/141 126/124/126 128/61/128
f 58/61/58 148/129/148 141/132/141
f 42/64/42 147/128/147 138/131/138
f 60/127/60 143/58/143 61/58/61
f 40/56/40 140/130/140 39/67/39
f 57/124/57 139/66/139 148/129/148
f 43/121/43 144/59/144 147/128/147
f 59/126/59 146/127/146 60/127/60
f 56/68/56 140/130/140 139/66/139
f 162/133/157 138/131/138 169/63/161
f 163/62/158 141/132/141 171/60/162
f 61/58/61 144/59/144 44/59/44
f 41/55/41 145/57/145 40/56/40
f 164/125/158 142/126/142 59/126/59
f 164/125/158 171/60/162 172/134/162
f 161/122/157 137/55/137 41/55/41
f 161/122/157 169/63/161 170/135/161
f 127/55/127 167/62/160 128/61/128
f 165/122/159 168/125/160 167/62/160
f 163/62/158 122/76/122 58/61/58
f 164/125/158 155/136/153 163/62/158
f 162/133/157 115/105/115 42/64/42
f 162/133/157 153/123/152 154/106/152
f 95/8/95 153/123/152 116/108/116
f 159/137/156 154/106/152 153/123/152
f 9/77/9 157/138/155 77/77/77
f 150/80/149 157/138/155 149/139/149
f 9/77/9 155/136/153 149/139/149
f 155/136/153 150/80/149 149/139/149
f 170/135/161 127/55/127 137/55/137
f 169/63/161 165/122/159 170/135/161
f 172/134/162 130/126/130 142/126/142
f 172/134/162 167/62/160 168/125/160
f 10/7/10 159/137/156 95/8/95
f 152/115/151 160/9/156 159/137/156
f 2/1/2 4/112/4 92/2/92
f 92/2/92 4/112/4 6/4/6
f 6/4/6 8/113/8 94/6/94
f 94/6/94 8/113/8 10/7/10
f 160/9/156 151/114/150 12/10/12
f 12/10/12 14/116/14 97/12/97
f 97/12/97 14/116/14 16/13/16
f 16/13/16 18/117/18 99/15/99
f 99/15/99 18/117/18 20/16/20
f 20/16/20 22/118/22 101/18/101
f 101/18/101 22/118/22 24/19/24
f 24/19/24 26/22/26 103/21/103
f 26/22/26 28/24/28 104/23/104
f 28/24/28 30/119/30 105/25/105
f 105/25/105 30/119/30 32/26/32
f 32/26/32 34/29/34 107/28/107
f 34/29/34 36/31/36 108/30/108
f 36/31/36 2/120/2 91/32/91
f 5/33/5 75/33/75 74/34/74
f 54/35/54 37/100/37 72/36/72
f 53/38/53 54/35/54 71/37/71
f 52/40/52 53/38/53 70/39/70
f 51/42/51 52/40/52 69/41/69
f 50/44/50 51/42/51 68/43/68
f 66/46/66 49/48/49 50/44/50
f 65/47/65 48/101/48 49/48/49
f 47/49/47 48/101/48 65/47/65
f 63/51/63 46/102/46 47/49/47
f 45/52/45 46/102/46 63/51/63
f 120/54/120 114/103/114 45/52/45
f 137/55/137 127/55/127 125/56/125
f 143/58/143 136/58/136 133/59/133
f 171/60/162 141/132/141 128/61/128
f 169/63/161 138/131/138 129/64/129
f 139/66/139 140/130/140 134/67/134
f 38/69/38 118/109/118 119/70/119
f 72/72/72 37/110/37 38/69/38
f 1/73/1 72/72/72 55/71/55
f 55/71/55 119/70/119 5/33/5
f 5/33/5 119/70/119 121/74/121
f 7/75/7 121/74/121 122/76/122
f 156/78/154 123/81/123 11/79/11
f 123/81/123 124/83/124 13/82/13
f 124/83/124 120/54/120 15/84/15
f 15/84/15 120/54/120 62/53/62
f 17/85/17 62/53/62 63/51/63
f 19/86/19 63/51/63 64/50/64
f 64/50/64 65/47/65 23/88/23
f 65/47/65 66/46/66 25/89/25
f 66/46/66 67/45/67 27/90/27
f 67/45/67 68/43/68 29/91/29
f 68/43/68 69/41/69 31/92/31
f 69/41/69 70/39/70 33/93/33
f 70/39/70 71/37/71 35/94/35
f 35/94/35 71/37/71 72/36/72
f 90/140/90 73/141/73 74/142/74
f 74/142/74 75/143/75 76/144/76
f 76/144/76 77/145/77 157/146/155
f 158/96/155 78/147/78 79/148/79
f 76/144/76 157/146/155 158/96/155
f 90/140/90 74/142/74 76/144/76
f 88/149/88 89/150/89 90/140/90
f 86/98/86 87/151/87 88/149/88
f 84/152/84 85/153/85 86/98/86
f 82/97/82 83/154/83 84/152/84
f 80/155/80 81/156/81 82/97/82
f 158/96/155 79/148/79 80/155/80
f 90/140/90 76/144/76 158/96/155
f 86/98/86 88/149/88 90/140/90
f 82/97/82 84/152/84 86/98/86
f 158/96/155 80/155/80 82/97/82
f 86/98/86 90/140/90 158/96/155
f 15/84/15 80/84/80 79/82/79
f 25/89/25 85/89/85 84/88/84
f 35/94/35 90/94/90 89/93/89
f 11/79/11 78/79/78 158/99/155
f 21/87/21 83/87/83 82/86/82
f 31/92/31 88/92/88 87/91/87
f 7/75/7 76/75/76 75/33/75
f 17/85/17 81/85/81 80/84/80
f 3/34/3 74/34/74 73/73/73
f 27/90/27 86/90/86 85/89/85
f 1/95/1 73/95/73 90/94/90
f 13/82/13 79/82/79 78/79/78
f 23/88/23 84/88/84 83/87/83
f 33/93/33 89/93/89 88/92/88
f 7/75/7 9/77/9 77/77/77
f 19/86/19 82/86/82 81/85/81
f 29/91/29 87/91/87 86/90/86
f 108/30/108 91/32/91 37/100/37
f 107/28/107 108/30/108 54/35/54
f 106/27/106 107/28/107 53/38/53
f 105/25/105 106/27/106 52/40/52
f 104/23/104 105/25/105 51/42/51
f 103/21/103 104/23/104 50/44/50
f 102/20/102 103/21/103 49/48/49
f 101/18/101 102/20/102 48/101/48
f 100/17/100 101/18/101 47/49/47
f 99/15/99 100/17/100 46/102/46
f 98/14/98 99/15/99 45/52/45
f 113/104/113 97/12/97 98/14/98
f 96/11/96 97/12/97 113/104/113
f 154/106/152 160/9/156 96/11/96
f 117/107/117 94/6/94 95/8/95
f 93/5/93 94/6/94 117/107/117
f 38/69/38 92/2/92 93/5/93
f 91/3/91 92/2/92 38/69/38
f 111/111/111 12/10/12 151/114/150
f 152/115/151 10/7/10 111/111/111
f 43/121/43 113/104/113 114/103/114
f 42/64/42 115/105/115 113/104/113
f 161/122/157 41/55/41 116/108/116
f 41/55/41 40/56/40 117/107/117
f 40/56/40 39/67/39 118/109/118
f 39/67/39 56/68/56 119/70/119
f 44/59/44 114/103/114 120/54/120
f 57/124/57 121/74/121 119/70/119
f 58/61/58 122/76/122 121/74/121
f 164/125/158 59/126/59 123/81/123
f 59/126/59 60/127/60 124/83/124
f 60/127/60 61/58/61 120/54/120
f 131/121/131 133/59/133 136/58/136
f 129/64/129 131/121/131 132/127/132
f 168/125/160 166/65/159 129/64/129
f 126/124/126 125/56/125 127/55/127
f 135/68/135 134/67/134 125/56/125
f 142/126/142 130/126/130 132/127/132
f 147/128/147 144/59/144 133/59/133
f 148/129/148 139/66/139 135/68/135
f 145/57/145 125/56/125 134/67/134
f 146/127/146 132/127/132 136/58/136
f 138/131/138 147/128/147 131/121/131
f 141/132/141 148/129/148 126/124/126
f 58/61/58 57/124/57 148/129/148
f 42/64/42 43/121/43 147/128/147
f 60/127/60 146/127/146 143/58/143
f 40/56/40 145/57/145 140/130/140
f 57/124/57 56/68/56 139/66/139
f 43/121/43 44/59/44 144/59/144
f 59/126/59 142/126/142 146/127/146
f 56/68/56 39/67/39 140/130/140
f 162/133/157 42/64/42 138/131/138
f 163/62/158 58/61/58 141/132/141
f 61/58/61 143/58/143 144/59/144
f 41/55/41 137/55/137 145/57/145
f 164/125/158 172/134/162 142/126/142
f 164/125/158 163/62/158 171/60/162
f 161/122/157 170/135/161 137/55/137
f 161/122/157 162/133/157 169/63/161
f 127/55/127 165/122/159 167/62/160
f 165/122/159 166/65/159 168/125/160
f 163/62/158 155/136/153 122/76/122
f 164/125/158 156/78/154 155/136/153
f 162/133/157 154/106/152 115/105/115
f 162/133/157 161/122/157 153/123/152
f 95/8/95 159/137/156 153/123/152
f 159/137/156 160/9/156 154/106/152
f 9/77/9 149/139/149 157/138/155
f 150/80/149 158/99/155 157/138/155
f 9/77/9 122/76/122 155/136/153
f 155/136/153 156/78/154 150/80/149
f 170/135/161 165/122/159 127/55/127
f 169/63/161 166/65/159 165/122/159
f 172/134/162 168/125/160 130/126/130
f 172/134/162 171/60/162 167/62/160
f 10/7/10 152/115/151 159/137/156
f 152/115/151 151/114/150 160/9/156

BIN
test.usdc Normal file

Binary file not shown.

File diff suppressed because one or more lines are too long