From bee3c7a91530d16bc444d3c10720b16783ba1bed Mon Sep 17 00:00:00 2001 From: Alexandre Deckner Date: Fri, 31 Jul 2009 15:38:12 +0000 Subject: [PATCH] * New demo showing an OpenGL animated Haiku logo. Could be a good base for future 3d demos i have in mind and the missing ones (ie: 3dmov and 3dmix). Makes for a nice Haiku sample code too, without legacy. Not in the image yet, waiting for the green light. Enjoy! ps: Will commit the Blender object files and export script later. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32027 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/Jamfile | 1 + src/apps/haiku3d/App.cpp | 49 ++ src/apps/haiku3d/App.h | 26 + src/apps/haiku3d/Camera.cpp | 26 + src/apps/haiku3d/Camera.h | 72 +++ src/apps/haiku3d/Haiku3d.rdef | 89 +++ src/apps/haiku3d/Jamfile | 27 + src/apps/haiku3d/MainWindow.cpp | 60 ++ src/apps/haiku3d/MainWindow.h | 28 + src/apps/haiku3d/MathUtils.cpp | 55 ++ src/apps/haiku3d/MathUtils.h | 21 + src/apps/haiku3d/Mesh.cpp | 14 + src/apps/haiku3d/Mesh.h | 39 ++ src/apps/haiku3d/MeshInstance.cpp | 183 ++++++ src/apps/haiku3d/MeshInstance.h | 44 ++ src/apps/haiku3d/Quaternion.h | 407 ++++++++++++++ src/apps/haiku3d/RenderView.cpp | 264 +++++++++ src/apps/haiku3d/RenderView.h | 53 ++ src/apps/haiku3d/Texture.cpp | 34 ++ src/apps/haiku3d/Texture.h | 29 + src/apps/haiku3d/Vector3.h | 353 ++++++++++++ src/apps/haiku3d/data/LetterA.hk3d | 193 +++++++ src/apps/haiku3d/data/LetterA.hk3d.bin | Bin 0 -> 2590 bytes src/apps/haiku3d/data/LetterH.hk3d | 205 +++++++ src/apps/haiku3d/data/LetterH.hk3d.bin | Bin 0 -> 2754 bytes src/apps/haiku3d/data/LetterI.hk3d | 37 ++ src/apps/haiku3d/data/LetterI.hk3d.bin | Bin 0 -> 496 bytes src/apps/haiku3d/data/LetterK.hk3d | 149 +++++ src/apps/haiku3d/data/LetterK.hk3d.bin | Bin 0 -> 2014 bytes src/apps/haiku3d/data/LetterU.hk3d | 529 ++++++++++++++++++ src/apps/haiku3d/data/LetterU.hk3d.bin | Bin 0 -> 7182 bytes src/apps/haiku3d/data/texture.png | Bin 0 -> 40828 bytes src/apps/haiku3d/mesh/StaticMesh.cpp | 165 ++++++ src/apps/haiku3d/mesh/StaticMesh.h | 33 ++ src/apps/haiku3d/texture/BitmapTexture.cpp | 52 ++ src/apps/haiku3d/texture/BitmapTexture.h | 24 + src/apps/haiku3d/texture/VideoFileTexture.cpp | 136 +++++ src/apps/haiku3d/texture/VideoFileTexture.h | 33 ++ 38 files changed, 3430 insertions(+) create mode 100644 src/apps/haiku3d/App.cpp create mode 100644 src/apps/haiku3d/App.h create mode 100644 src/apps/haiku3d/Camera.cpp create mode 100644 src/apps/haiku3d/Camera.h create mode 100644 src/apps/haiku3d/Haiku3d.rdef create mode 100644 src/apps/haiku3d/Jamfile create mode 100644 src/apps/haiku3d/MainWindow.cpp create mode 100644 src/apps/haiku3d/MainWindow.h create mode 100644 src/apps/haiku3d/MathUtils.cpp create mode 100644 src/apps/haiku3d/MathUtils.h create mode 100644 src/apps/haiku3d/Mesh.cpp create mode 100644 src/apps/haiku3d/Mesh.h create mode 100644 src/apps/haiku3d/MeshInstance.cpp create mode 100644 src/apps/haiku3d/MeshInstance.h create mode 100644 src/apps/haiku3d/Quaternion.h create mode 100644 src/apps/haiku3d/RenderView.cpp create mode 100644 src/apps/haiku3d/RenderView.h create mode 100644 src/apps/haiku3d/Texture.cpp create mode 100644 src/apps/haiku3d/Texture.h create mode 100644 src/apps/haiku3d/Vector3.h create mode 100644 src/apps/haiku3d/data/LetterA.hk3d create mode 100644 src/apps/haiku3d/data/LetterA.hk3d.bin create mode 100644 src/apps/haiku3d/data/LetterH.hk3d create mode 100644 src/apps/haiku3d/data/LetterH.hk3d.bin create mode 100644 src/apps/haiku3d/data/LetterI.hk3d create mode 100644 src/apps/haiku3d/data/LetterI.hk3d.bin create mode 100644 src/apps/haiku3d/data/LetterK.hk3d create mode 100644 src/apps/haiku3d/data/LetterK.hk3d.bin create mode 100644 src/apps/haiku3d/data/LetterU.hk3d create mode 100644 src/apps/haiku3d/data/LetterU.hk3d.bin create mode 100644 src/apps/haiku3d/data/texture.png create mode 100644 src/apps/haiku3d/mesh/StaticMesh.cpp create mode 100644 src/apps/haiku3d/mesh/StaticMesh.h create mode 100644 src/apps/haiku3d/texture/BitmapTexture.cpp create mode 100644 src/apps/haiku3d/texture/BitmapTexture.h create mode 100644 src/apps/haiku3d/texture/VideoFileTexture.cpp create mode 100644 src/apps/haiku3d/texture/VideoFileTexture.h diff --git a/src/apps/Jamfile b/src/apps/Jamfile index 8e1337291f..fbd2228ea4 100644 --- a/src/apps/Jamfile +++ b/src/apps/Jamfile @@ -22,6 +22,7 @@ HaikuSubInclude expander ; HaikuSubInclude fontdemo ; HaikuSubInclude glteapot ; HaikuSubInclude gradients ; +HaikuSubInclude haiku3d ; HaikuSubInclude icon-o-matic ; HaikuSubInclude installedpackages ; HaikuSubInclude installer ; diff --git a/src/apps/haiku3d/App.cpp b/src/apps/haiku3d/App.cpp new file mode 100644 index 0000000000..f4cc783095 --- /dev/null +++ b/src/apps/haiku3d/App.cpp @@ -0,0 +1,49 @@ +/* + * Copyright 2009, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ + +#include + +#include "App.h" +#include "MainWindow.h" + + +App::App() + : + BApplication("application/x-vnd.Haiku3d") +{ + BRect frame(50, 50, 640 + 50, 480 + 50); + const char *title = "Hauku3d"; + fMainWindow = new MainWindow(frame, title); +} + + +App::~App() +{ +} + + +void App::AboutRequested() +{ + BAlert* alert; + alert = new BAlert("About", "A little 3d demo", "ok"); + alert->Go(NULL); +} + + +void App::MessageReceived(BMessage *message) +{ +} + + +int +main(int argc, char** argv) +{ + App app; + app.Run(); + return 0; +} diff --git a/src/apps/haiku3d/App.h b/src/apps/haiku3d/App.h new file mode 100644 index 0000000000..a329845766 --- /dev/null +++ b/src/apps/haiku3d/App.h @@ -0,0 +1,26 @@ +/* + * Copyright 2008, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ + +#ifndef _APP_H +#define _APP_H + +#include + +class App: public BApplication { +protected: + BWindow* fMainWindow; +public: + App(); + ~App(); + + virtual void AboutRequested(); + virtual void MessageReceived(BMessage *message); + +}; + +#endif /* _APP_H */ diff --git a/src/apps/haiku3d/Camera.cpp b/src/apps/haiku3d/Camera.cpp new file mode 100644 index 0000000000..f9cb5f7fd4 --- /dev/null +++ b/src/apps/haiku3d/Camera.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 2008, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ + +#include "Camera.h" + + +Camera::Camera(const Vector3& position, const Quaternion& orientation, + float fov, float near, float far) + : + fPosition(position), + fOrientation(orientation), + fFieldOfView(fov), + fNear(near), + fFar(far) +{ +} + + +Camera::~Camera() +{ +} diff --git a/src/apps/haiku3d/Camera.h b/src/apps/haiku3d/Camera.h new file mode 100644 index 0000000000..5863017a5f --- /dev/null +++ b/src/apps/haiku3d/Camera.h @@ -0,0 +1,72 @@ +/* + * Copyright 2009, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ +#ifndef _CAMERA_H +#define _CAMERA_H + +#include "Vector3.h" +#include "Quaternion.h" + + +class Camera { +public: + Camera(const Vector3& position, + const Quaternion& orientation, float fov = 50.0f, float near = 1.0f, + float far = 100.0f); + virtual ~Camera(); + + const Vector3& Position() const; + const Quaternion& Orientation() const; + float FieldOfView() const; + float Near() const; + float Far() const; + +protected: + Vector3 fPosition; + Quaternion fOrientation; + float fFieldOfView; + float fNear; + float fFar; + bool fOrtho; +}; + + +inline const Vector3& +Camera::Position() const +{ + return fPosition; +} + + +inline const Quaternion& +Camera::Orientation() const +{ + return fOrientation; +} + + +inline float +Camera::FieldOfView() const +{ + return fFieldOfView; +} + + +inline float +Camera::Near() const +{ + return fNear; +} + + +inline float +Camera::Far() const +{ + return fFar; +} + +#endif /* _CAMERA_H */ diff --git a/src/apps/haiku3d/Haiku3d.rdef b/src/apps/haiku3d/Haiku3d.rdef new file mode 100644 index 0000000000..63e280ee0c --- /dev/null +++ b/src/apps/haiku3d/Haiku3d.rdef @@ -0,0 +1,89 @@ +/* + * Copyright 2009, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner alex@zappotek.com + * + * Copyright Be, Inc. (for the temporary icon) + */ + +resource(1, "BEOS:APP_SIG") #'MIMS' "application/x-vnd.Haiku3d"; + +resource app_version { + major = 1, + middle = 0, + minor = 0, + + variety = B_APPV_BETA, + internal = 0, + + short_info = "Haiku3d", + long_info = "Haiku3d ©2009 Haiku, Inc." +}; + +resource(101, "BEOS:L:STD_ICON") #'ICON' array { + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF005D00FFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF005D5D00FFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF005D5D5D00FFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003F5D5D5D5D00FFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003F5D5D5D5D00FFFFFFFFFFFFFF" + $"FFFFFFFF000000FFFFFFFFFFFFFFFFFFFF00FA3F5D5D5D5D5D00FFFFFFFFFFFF" + $"FFFFFF005E5E5E0000FFFFFFFFFFFFFFFF00FA3F5D5D5D5D5D00FFFFFFFFFFFF" + $"FFFF005E5E5E5E5E5E0000FFFFFFFFFF00FAFA3F5D5D5D5D5D00FFFFFFFFFFFF" + $"FF005E5E5E5E5E5E5E5E5E00FFFFFFFF00FAFAFA3F5D5D5D5D5D00FFFFFFFFFF" + $"005E5E5E5E5E5E5E5E5EB200FFFFFF00FAFAFAFA3F5D5D5D5D5D00FFFFFFFFFF" + $"00B2B25E5E5E5E5E5EB22100FFFF00FAFAFAFAFA3F5D5D5D5D5D5D00FFFFFFFF" + $"002121B2B25E5E5EB2212400FFFF00FAFAFAFAFAFA3F5D5D5D5D5D00FFFFFFFF" + $"0021212021B2B2B221242500FF00FAFAFAFAFAFAFA3F5D5D5D5D5D5D00FFFFFF" + $"002121202121BE2124252500FF00FAFAFAFAFAFAFAFA3F5D5D5D5D5D00FFFFFF" + $"002121202121BE212425250000FAFAFAFAFAFAFAFAFA3F5D5D5D5D5D00FFFFFF" + $"002121202121BE212425250000FAFAFAFAFAFAFAFAFA3F5D5D5D5D5D5D00FFFF" + $"002121202121BE2124252500FF0000FAFAFA00000000003F5D5D5D5D5D0011FF" + $"002121202121BE2124252500FFFFFF0000002FEB2F302F00005D5D5D5D001111" + $"002121202121BE2124252500FFFFFF002F2B2B2B2D2D2F302F005D5D00111111" + $"002121202121BE2124252500FFFF002F2B2A2B2A2C2C2BEB2F2F0000111111FF" + $"002121202121BE2124252500FFFF002B2B2B2A2B2B2B2D2D2F2F00111111FFFF" + $"002121202121BE2124252500FF002F2B2B2A5A2B2B2B2C2D2DEB3000FFFFFFFF" + $"002121202121BE212425250011002F2B2B5A3F5A2B2C2C2D2D2F2F00FFFFFFFF" + $"002121202121BE212425250011002F2C2C2A5A2C2B2C2C2DEB2F2F00FFFFFFFF" + $"002121202121BE21242500111100302E2B2C2B2B2C2C2D2CEB2F2F0011FFFFFF" + $"FF0000212120BE2124001111FF002F2F2D2C2C2C2C2D2D2E2EEB30001111FFFF" + $"FFFFFF000021BE21001111FFFFFF00302D2D2D2C2D2DEBEB2F2F00111111FFFF" + $"FFFFFFFFFF0000001111FFFFFFFF00302EEBEBEBEBEBEB2FEB3000111111FFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00302F2FEB2FEB2F2F2F0011111111FFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000302F2F302F000011111111FFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000011111111FFFFFFFFFF" +}; + +resource(101, "BEOS:M:STD_ICON") #'MICN' array { + $"FFFFFFFFFFFFFFFFFFFFFF0000FFFFFF" + $"FFFFFFFFFFFFFFFFFFFF005D5D00FFFF" + $"FFFF000000FFFFFFFF005D5D5D00FFFF" + $"FF005E5E5E00FFFF00FA5D5D5D00FFFF" + $"005E5E5E5E5E00FF00FAFA5D5D5D00FF" + $"00215E5E5E250000FAFAFA5D5D5D00FF" + $"0021212025250000FAFAFA5D5D5D5D00" + $"00202121242500FAFAFAFAFA5D5D5D00" + $"00212021252400FAFA000000005D5D00" + $"00212120252500FA002B2D2F30000000" + $"00202121242500002B2B2B2D2D2F0011" + $"00212021252400002B5A2C2C2D2F00FF" + $"00212120250000002D2B2B2D2D2F0011" + $"00002120001111002F2E2C2E2E2F0011" + $"FFFF00001111FFFF0030EB2F2F001111" + $"FFFFFFFFFFFFFFFFFF00000000111111" +}; + +resource(1, "texture") #'PNG ' import "./data/texture.png"; + +resource(2, "LetterH") import "./data/LetterH.hk3d.bin"; + +resource(3, "LetterA") import "./data/LetterA.hk3d.bin"; + +resource(4, "LetterI") import "./data/LetterI.hk3d.bin"; + +resource(5, "LetterK") import "./data/LetterK.hk3d.bin"; + +resource(6, "LetterU") import "./data/LetterU.hk3d.bin"; diff --git a/src/apps/haiku3d/Jamfile b/src/apps/haiku3d/Jamfile new file mode 100644 index 0000000000..9977ebd32b --- /dev/null +++ b/src/apps/haiku3d/Jamfile @@ -0,0 +1,27 @@ +SubDir HAIKU_TOP src apps haiku3d ; + +SEARCH_SOURCE += [ FDirName $(SUBDIR) mesh ] ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) texture ] ; + +UsePrivateHeaders shared ; + +Application Haiku3d : + App.cpp + Camera.cpp + MainWindow.cpp + MathUtils.cpp + Mesh.cpp + MeshInstance.cpp + RenderView.cpp + Texture.cpp + + # mesh + StaticMesh.cpp + + # texture + BitmapTexture.cpp + VideoFileTexture.cpp + + : be game GL media translation + : Haiku3d.rdef +; diff --git a/src/apps/haiku3d/MainWindow.cpp b/src/apps/haiku3d/MainWindow.cpp new file mode 100644 index 0000000000..bf71610710 --- /dev/null +++ b/src/apps/haiku3d/MainWindow.cpp @@ -0,0 +1,60 @@ +/* + * Copyright 2009, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ + +#include "MainWindow.h" +#include "RenderView.h" + +#include +#include +#include + +#include + +MainWindow::MainWindow(BRect frame, const char* title) + : + BDirectWindow(frame, title, B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, 0) +{ + fRenderView = new RenderView(Bounds()); + fRenderView->SetViewColor(0, 0, 0); + + AddChild(fRenderView); + Show(); +} + + +MainWindow::~MainWindow() +{ +} + + +bool +MainWindow::QuitRequested() +{ + be_app->Lock(); + if (be_app->CountWindows() < 2) + be_app_messenger.SendMessage(B_QUIT_REQUESTED); + be_app->Unlock(); + return true; +} + + +void +MainWindow::MessageReceived(BMessage *message) +{ + switch (message->what) { + default: + BDirectWindow::MessageReceived(message); + } +} + + +void +MainWindow::DirectConnected(direct_buffer_info* info) +{ + fRenderView->DirectConnected(info); +} diff --git a/src/apps/haiku3d/MainWindow.h b/src/apps/haiku3d/MainWindow.h new file mode 100644 index 0000000000..70ab86949a --- /dev/null +++ b/src/apps/haiku3d/MainWindow.h @@ -0,0 +1,28 @@ +/* + * Copyright 2009, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ +#ifndef _MAINWINDOW_H +#define _MAINWINDOW_H + +#include + +class RenderView; + +class MainWindow: public BDirectWindow { +public: + MainWindow(BRect frame, const char* title); + ~MainWindow(); + + virtual bool QuitRequested(); + virtual void MessageReceived(BMessage *message); + virtual void DirectConnected(direct_buffer_info* info); + +protected: + RenderView* fRenderView; +}; + +#endif /* _MAINWINDOW_H */ diff --git a/src/apps/haiku3d/MathUtils.cpp b/src/apps/haiku3d/MathUtils.cpp new file mode 100644 index 0000000000..145de5c871 --- /dev/null +++ b/src/apps/haiku3d/MathUtils.cpp @@ -0,0 +1,55 @@ +/* + * Copyright 2008, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ + +// Some math utils, useful for animation + + +#include "MathUtils.h" + + +float +MathUtils::EaseInOutCubic(float t /*time*/, float b /*begin*/, float c /*distance*/, float d /*duration*/) +{ + t /= d / 2.0; + if (t < 1.0) + return c / 2.0 * t * t * t + b; + t -= 2.0; + return c / 2.0 * (t * t * t + 2.0) + b; +} + + +float +MathUtils::EaseInOutQuart(float t /*time*/, float b /*begin*/, float c /*distance*/, float d /*duration*/) +{ + t /= d / 2; + + if (t < 1) + return c / 2 * t * t * t * t + b; + + t -= 2; + + return -c / 2 * (t * t * t * t - 2) + b; +} + + +float +MathUtils::EaseInOutQuint(float t /*time*/, float b /*begin*/, float c /*distance*/, float d /*duration*/) +{ + t /= d / 2; + if (t < 1) + return c / 2 * t * t * t * t * t + b; + t -= 2; + return c / 2 *(t * t * t * t * t + 2) + b; +} + + +float +MathUtils::EaseInOutSine(float t /*time*/, float b /*begin*/, float c /*distance*/, float d /*duration*/) +{ + return -c / 2 * (cos(3.14159 * t / d) - 1) + b; +} diff --git a/src/apps/haiku3d/MathUtils.h b/src/apps/haiku3d/MathUtils.h new file mode 100644 index 0000000000..78f362d4e4 --- /dev/null +++ b/src/apps/haiku3d/MathUtils.h @@ -0,0 +1,21 @@ +/* + * Copyright 2009, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ +#ifndef _MATH_UTILS_H +#define _MATH_UTILS_H + + +class MathUtils +{ +public: + static float EaseInOutCubic(float time, float begin, float distance, float duration); + static float EaseInOutQuart(float time, float begin, float distance, float duration); + static float EaseInOutQuint(float time, float begin, float distance, float duration); + static float EaseInOutSine(float time, float begin, float distance, float duration); +}; + +#endif /* _MATH_UTILS_H */ diff --git a/src/apps/haiku3d/Mesh.cpp b/src/apps/haiku3d/Mesh.cpp new file mode 100644 index 0000000000..96f43e07d9 --- /dev/null +++ b/src/apps/haiku3d/Mesh.cpp @@ -0,0 +1,14 @@ +/* + * Copyright 2009, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ + +#include "Mesh.h" + + +Mesh::~Mesh() +{ +} diff --git a/src/apps/haiku3d/Mesh.h b/src/apps/haiku3d/Mesh.h new file mode 100644 index 0000000000..4999d2b2c9 --- /dev/null +++ b/src/apps/haiku3d/Mesh.h @@ -0,0 +1,39 @@ +/* + * Copyright 2009, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ +#ifndef _MESH_H +#define _MESH_H + +#include +#include + +#include "Vector3.h" + + +struct Vertex { + Vector3 p; + float u; + float v; +}; + + +struct Face { + Vertex v[4]; + uint16 vertexCount; +}; + + +class Mesh : public Referenceable { +public: + virtual ~Mesh(); + + virtual Face& GetFace(uint32 index) const = 0; + virtual uint32 FaceCount() const = 0; +}; + + +#endif /* _MESH_H */ diff --git a/src/apps/haiku3d/MeshInstance.cpp b/src/apps/haiku3d/MeshInstance.cpp new file mode 100644 index 0000000000..3db9c8cbf6 --- /dev/null +++ b/src/apps/haiku3d/MeshInstance.cpp @@ -0,0 +1,183 @@ +/* + * Copyright 2008, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ + +#include "MeshInstance.h" +#include "MathUtils.h" +#include + +//#include // debug + + +MeshInstance::MeshInstance(Mesh* mesh, Texture* texture, + const Vector3& position, const Quaternion& orientation, float animOffset) + : + fMeshReference(mesh), + fTextureReference(texture), + fPosition(position), + fOrientation(orientation), + fScale(1.0f), + fTime(0.0f), + fAnimOffset(animOffset), + fDoubleSided(true), + fDrawNormals(false) +{ +} + + +MeshInstance::~MeshInstance() +{ +} + + +void +MeshInstance::Update(float dt) +{ + fTextureReference->Update(dt); + + float animDuration = 4.0f; + + fTime += dt; + if (fTime >= fAnimOffset) { + float animTime = (fTime - fAnimOffset); + + float rotAngle = MathUtils::EaseInOutQuart(animTime, 0, + 3 * 2 * 3.14159, animDuration); + + fOrientation = Quaternion(Vector3(0.0f, 1.0f, 0.0f), rotAngle); + } + + if (fTime >= fAnimOffset + animDuration) { + fOrientation = Quaternion(Vector3(0.0f, 1.0f, 0.0f), 0.0); + } + + if (fTime >= animDuration * 6) { + fTime = 0.0; + } +} + + +void +MeshInstance::Render() +{ + if (fMeshReference->FaceCount() == 0) + return; + + glPushMatrix(); + glTranslatef(fPosition.x(), fPosition.y(), fPosition.z()); + float mat[4][4]; + fOrientation.toOpenGLMatrix(mat); + glMultMatrixf((GLfloat*) mat); + glScalef(fScale, fScale, fScale); + glBindTexture(GL_TEXTURE_2D, fTextureReference->Id()); + + int lastVertexCount = 0; + //int batchCount = 0; + + for(uint32 i = 0; i < fMeshReference->FaceCount(); i++) { + + const Face& face = fMeshReference->GetFace(i); + + // switch face mode + if (face.vertexCount != lastVertexCount) { + if (lastVertexCount != 0) + glEnd(); + + if (face.vertexCount == 3) + glBegin(GL_TRIANGLES); + else + glBegin(GL_QUADS); + + //batchCount++; + } + + // calculate normal + Vector3 lu(face.v[0].p - face.v[1].p); + Vector3 lv(face.v[1].p - face.v[2].p); + Vector3 normal(lu.cross(lv)); + if (normal.length() <= 0.000001) + normal.setValue(0, 0, -1.0); + normal.normalize(); + + // draw face + glNormal3f(normal.x(), normal.y(), normal.z()); + glTexCoord2f(face.v[0].u, face.v[0].v); + glVertex3f(face.v[0].p.x(), face.v[0].p.y(), face.v[0].p.z()); + + glNormal3f(normal.x(), normal.y(), normal.z()); + glTexCoord2f(face.v[1].u, face.v[1].v); + glVertex3f(face.v[1].p.x(), face.v[1].p.y(), face.v[1].p.z()); + + glNormal3f(normal.x(), normal.y(), normal.z()); + glTexCoord2f(face.v[2].u, face.v[2].v); + glVertex3f(face.v[2].p.x(), face.v[2].p.y(), face.v[2].p.z()); + + if (face.vertexCount == 4) { + glNormal3f(normal.x(), normal.y(), normal.z()); + glTexCoord2f(face.v[3].u, face.v[3].v); + glVertex3f(face.v[3].p.x(), face.v[3].p.y(), face.v[3].p.z()); + } + + if (fDoubleSided) { + if (face.vertexCount == 4) { + glNormal3f(-normal.x(), -normal.y(), -normal.z()); + glTexCoord2f(face.v[3].u, face.v[3].v); + glVertex3f(face.v[3].p.x(), face.v[3].p.y(), face.v[3].p.z()); + } + + glNormal3f(-normal.x(), -normal.y(), -normal.z()); + glTexCoord2f(face.v[2].u, face.v[2].v); + glVertex3f(face.v[2].p.x(), face.v[2].p.y(), face.v[2].p.z()); + + glNormal3f(-normal.x(), -normal.y(), -normal.z()); + glTexCoord2f(face.v[1].u, face.v[1].v); + glVertex3f(face.v[1].p.x(), face.v[1].p.y(), face.v[1].p.z()); + + glNormal3f(-normal.x(), -normal.y(), -normal.z()); + glTexCoord2f(face.v[0].u, face.v[0].v); + glVertex3f(face.v[0].p.x(), face.v[0].p.y(), face.v[0].p.z()); + } + lastVertexCount = face.vertexCount; + } + glEnd(); + //printf("batchCount %d\n", batchCount); + + if (fDrawNormals) { + glBegin(GL_LINES); + for(uint32 i = 0; i < fMeshReference->FaceCount(); i++) { + + const Face& face = fMeshReference->GetFace(i); + + if (face.vertexCount == 4) { + + // calculate normal + Vector3 lu(face.v[0].p - face.v[1].p); + Vector3 lv(face.v[1].p - face.v[2].p); + Vector3 normal(lu.cross(lv)); + if (normal.length() <= 0.000001) + normal.setValue(0, 0, -1.0); + normal.normalize(); + + // center of the face + Vector3 g; + if (face.vertexCount == 4) + g = (face.v[0].p + face.v[1].p + face.v[2].p + face.v[3].p) + / 4.0; + else + g = (face.v[0].p + face.v[1].p + face.v[2].p) / 3.0; + + Vector3 h(g + normal); + + glVertex3f(g.x(), g.y(), g.z()); + glVertex3f(h.x(), h.y(), h.z()); + } + } + glEnd(); + } + + glPopMatrix(); +} diff --git a/src/apps/haiku3d/MeshInstance.h b/src/apps/haiku3d/MeshInstance.h new file mode 100644 index 0000000000..551caee6e3 --- /dev/null +++ b/src/apps/haiku3d/MeshInstance.h @@ -0,0 +1,44 @@ +/* + * Copyright 2009, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ + +#ifndef _MESH_INSTANCE_H +#define _MESH_INSTANCE_H + +#include "Mesh.h" +#include "Texture.h" +#include "Vector3.h" +#include "Quaternion.h" + + +class MeshInstance { +public: + MeshInstance(Mesh* mesh, Texture* texture, + const Vector3& position, const Quaternion& orientation, + float animOffset); + ~MeshInstance(); + + void Update(float dt); + void Render(); + +protected: + Reference fMeshReference; + Reference fTextureReference; + + Vector3 fPosition; + Quaternion fOrientation; + float fScale; + + // TODO: manage the animation externally + float fTime; + float fAnimOffset; + + bool fDoubleSided; + bool fDrawNormals; +}; + +#endif /* _MESH_INSTANCE_H */ diff --git a/src/apps/haiku3d/Quaternion.h b/src/apps/haiku3d/Quaternion.h new file mode 100644 index 0000000000..305fd8e1f6 --- /dev/null +++ b/src/apps/haiku3d/Quaternion.h @@ -0,0 +1,407 @@ +/* + * Copyright 2008 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + * + */ + +/* + * + * This is a refactored and stripped down version of bullet-2.66 src\LinearMath\btQuaternion.h + * The dependancies on base class btQuadWord have been removed for simplification. + * Added gl matrix conversion method. + * + */ + +/* +Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef __QUATERNION_H__ +#define __QUATERNION_H__ + +#include "Vector3.h" +#include //pout FLT_EPSILON + +class Quaternion { +protected: + float m_x; + float m_y; + float m_z; + float m_w; +public: + Quaternion() {} + + Quaternion(const Quaternion& q) + { + *((Quaternion*)this) = q; + } + + Quaternion(const float& x, const float& y, const float& z,const float& w) + { + m_x = x, m_y = y, m_z = z, m_w = w; + } + + Quaternion(const Vector3& axis, const float& angle) + { + setRotation(axis, angle); + } + + Quaternion(const float& yaw, const float& pitch, const float& roll) + { + setEuler(yaw, pitch, roll); + } + + inline const float& x() const { return m_x; } + + + inline const float& y() const { return m_y; } + + + inline const float& z() const { return m_z; } + + + inline const float& w() const { return m_w; } + + + void setValue(const float& x, const float& y, const float& z) + { + m_x=x; + m_y=y; + m_z=z; + m_w = 0.f; + } + + + void setValue(const float& x, const float& y, const float& z,const float& w) + { + m_x=x; + m_y=y; + m_z=z; + m_w=w; + } + + + void setRotation(const Vector3& axis, const float& angle) + { + float d = axis.length(); + assert(d != 0.0f); + float s = sin(angle * 0.5f) / d; + setValue(axis.x() * s, axis.y() * s, axis.z() * s, + cos(angle * 0.5f)); + } + + + void setEuler(const float& yaw, const float& pitch, const float& roll) + { + float halfYaw = yaw * 0.5f; + float halfPitch = pitch * 0.5f; + float halfRoll = roll * 0.5f; + float cosYaw = cos(halfYaw); + float sinYaw = sin(halfYaw); + float cosPitch = cos(halfPitch); + float sinPitch = sin(halfPitch); + float cosRoll = cos(halfRoll); + float sinRoll = sin(halfRoll); + setValue(cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, + cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, + sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, + cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); + } + + + Quaternion& operator+=(const Quaternion& q) + { + m_x += q.x(); m_y += q.y(); m_z += q.z(); m_w += q.m_w; + return *this; + } + + + Quaternion& operator-=(const Quaternion& q) + { + m_x -= q.x(); m_y -= q.y(); m_z -= q.z(); m_w -= q.m_w; + return *this; + } + + + Quaternion& operator*=(const float& s) + { + m_x *= s; m_y *= s; m_z *= s; m_w *= s; + return *this; + } + + + Quaternion& operator*=(const Quaternion& q) + { + setValue(m_w * q.x() + m_x * q.m_w + m_y * q.z() - m_z * q.y(), + m_w * q.y() + m_y * q.m_w + m_z * q.x() - m_x * q.z(), + m_w * q.z() + m_z * q.m_w + m_x * q.y() - m_y * q.x(), + m_w * q.m_w - m_x * q.x() - m_y * q.y() - m_z * q.z()); + return *this; + } + + + float dot(const Quaternion& q) const + { + return m_x * q.x() + m_y * q.y() + m_z * q.z() + m_w * q.m_w; + } + + + float length2() const + { + return dot(*this); + } + + + float length() const + { + return sqrt(length2()); + } + + + Quaternion& normalize() + { + return *this /= length(); + } + + + inline Quaternion + operator*(const float& s) const + { + return Quaternion(x() * s, y() * s, z() * s, m_w * s); + } + + + Quaternion operator/(const float& s) const + { + assert(s != 0.0f); + return *this * (1.0f / s); + } + + + Quaternion& operator/=(const float& s) + { + assert(s != 0.0f); + return *this *= 1.0f / s; + } + + + Quaternion normalized() const + { + return *this / length(); + } + + + float angle(const Quaternion& q) const + { + float s = sqrt(length2() * q.length2()); + assert(s != 0.0f); + return acos(dot(q) / s); + } + + + float getAngle() const + { + float s = 2.0f * acos(m_w); + return s; + } + + + Quaternion inverse() const + { + return Quaternion(m_x, m_y, m_z, -m_w); + } + + + inline Quaternion + operator+(const Quaternion& q2) const + { + const Quaternion& q1 = *this; + return Quaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_w + q2.m_w); + } + + + inline Quaternion + operator-(const Quaternion& q2) const + { + const Quaternion& q1 = *this; + return Quaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_w - q2.m_w); + } + + + inline Quaternion operator-() const + { + const Quaternion& q2 = *this; + return Quaternion( - q2.x(), - q2.y(), - q2.z(), - q2.m_w); + } + + + inline Quaternion farthest( const Quaternion& qd) const + { + Quaternion diff,sum; + diff = *this - qd; + sum = *this + qd; + if( diff.dot(diff) > sum.dot(sum) ) + return qd; + return (-qd); + } + + + Quaternion slerp(const Quaternion& q, const float& t) const + { + float theta = angle(q); + if (theta != 0.0f) + { + float d = 1.0f / sin(theta); + float s0 = sin((1.0f - t) * theta); + float s1 = sin(t * theta); + return Quaternion((m_x * s0 + q.x() * s1) * d, + (m_y * s0 + q.y() * s1) * d, + (m_z * s0 + q.z() * s1) * d, + (m_w * s0 + q.m_w * s1) * d); + } + else + { + return *this; + } + } + + + void toOpenGLMatrix(float m[4][4]){ + + float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2; + + // calculate coefficients + x2 = m_x + m_x; y2 = m_y + m_y; + z2 = m_z + m_z; + xx = m_x * x2; xy = m_x * y2; xz = m_x * z2; + yy = m_y * y2; yz = m_y * z2; zz = m_z * z2; + wx = m_w * x2; wy = m_w * y2; wz = m_w * z2; + + + m[0][0] = 1.0 - (yy + zz); m[1][0] = xy - wz; + m[2][0] = xz + wy; m[3][0] = 0.0; + + m[0][1] = xy + wz; m[1][1] = 1.0 - (xx + zz); + m[2][1] = yz - wx; m[3][1] = 0.0; + + + m[0][2] = xz - wy; m[1][2] = yz + wx; + m[2][2] = 1.0 - (xx + yy); m[3][2] = 0.0; + + + m[0][3] = 0; m[1][3] = 0; + m[2][3] = 0; m[3][3] = 1; + } +}; + + +inline Quaternion +operator-(const Quaternion& q) +{ + return Quaternion(-q.x(), -q.y(), -q.z(), -q.w()); +} + + +inline Quaternion +operator*(const Quaternion& q1, const Quaternion& q2) { + return Quaternion(q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(), + q1.w() * q2.y() + q1.y() * q2.w() + q1.z() * q2.x() - q1.x() * q2.z(), + q1.w() * q2.z() + q1.z() * q2.w() + q1.x() * q2.y() - q1.y() * q2.x(), + q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z()); +} + + +inline Quaternion +operator*(const Quaternion& q, const Vector3& w) +{ + return Quaternion( q.w() * w.x() + q.y() * w.z() - q.z() * w.y(), + q.w() * w.y() + q.z() * w.x() - q.x() * w.z(), + q.w() * w.z() + q.x() * w.y() - q.y() * w.x(), + -q.x() * w.x() - q.y() * w.y() - q.z() * w.z()); +} + + +inline Quaternion +operator*(const Vector3& w, const Quaternion& q) +{ + return Quaternion( w.x() * q.w() + w.y() * q.z() - w.z() * q.y(), + w.y() * q.w() + w.z() * q.x() - w.x() * q.z(), + w.z() * q.w() + w.x() * q.y() - w.y() * q.x(), + -w.x() * q.x() - w.y() * q.y() - w.z() * q.z()); +} + + +inline float +dot(const Quaternion& q1, const Quaternion& q2) +{ + return q1.dot(q2); +} + + +inline float +length(const Quaternion& q) +{ + return q.length(); +} + + +inline float +angle(const Quaternion& q1, const Quaternion& q2) +{ + return q1.angle(q2); +} + + +inline Quaternion +inverse(const Quaternion& q) +{ + return q.inverse(); +} + + +inline Quaternion +slerp(const Quaternion& q1, const Quaternion& q2, const float& t) +{ + return q1.slerp(q2, t); +} + + +inline Quaternion +shortestArcQuat(const Vector3& v0, const Vector3& v1) // Game Programming Gems 2.10. make sure v0,v1 are normalized +{ + Vector3 c = v0.cross(v1); + float d = v0.dot(v1); + + if (d < -1.0 + FLT_EPSILON) + return Quaternion(0.0f, 1.0f, 0.0f, 0.0f); // just pick any vector + + float s = sqrt((1.0f + d) * 2.0f); + float rs = 1.0f / s; + + return Quaternion(c.x() * rs, c.y() * rs, c.z() * rs, s * 0.5f); +} + + +inline Quaternion +shortestArcQuatNormalize2(Vector3& v0, Vector3& v1) +{ + v0.normalize(); + v1.normalize(); + return shortestArcQuat(v0, v1); +} +#endif + + + diff --git a/src/apps/haiku3d/RenderView.cpp b/src/apps/haiku3d/RenderView.cpp new file mode 100644 index 0000000000..de3cec4b04 --- /dev/null +++ b/src/apps/haiku3d/RenderView.cpp @@ -0,0 +1,264 @@ +/* + * Copyright 2008, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ + +#include "RenderView.h" + +#include "BitmapTexture.h" +#include "Camera.h" +#include "MeshInstance.h" +#include "StaticMesh.h" +#include "VideoFileTexture.h" + +#include +#include + +#include +#include + +RenderView::RenderView(BRect frame) + : + BGLView(frame, "renderView", B_FOLLOW_ALL, B_WILL_DRAW, + BGL_RGB | BGL_DOUBLE | BGL_DEPTH), + fMainCamera(NULL), + fRenderThread(-1), + fStopRendering(false), + fRes(0, 0), + fNextRes(0, 0), + fLastFrameTime(0) +{ +} + + +RenderView::~RenderView() +{ + _StopRenderThread(); + + if (fRenderThread >= 0) + wait_for_thread(fRenderThread, NULL); + + _DeleteScene(); +} + + +void +RenderView::AttachedToWindow() +{ + BGLView::AttachedToWindow(); + + _CreateScene(); + _InitGL(); + if (_CreateRenderThread() != B_OK) + printf("Error trying to start the render thread!\n"); +} + + +uint32 +RenderView::_CreateRenderThread() +{ + fRenderThread = spawn_thread(RenderView::_RenderThreadEntry, + "renderThread", + B_NORMAL_PRIORITY, + this); + if (fRenderThread < 0) + return fRenderThread; + + return resume_thread(fRenderThread); +} + + +void +RenderView::_StopRenderThread() +{ + LockGL(); + fStopRendering = true; + UnlockGL(); +} + + +int32 +RenderView::_RenderThreadEntry(void *pointer) +{ + return reinterpret_cast(pointer)->_RenderLoop(); +} + + +int32 +RenderView::_RenderLoop() +{ + fLastFrameTime = system_time(); + + while (_Render()) { + snooze(10000); + } + return B_OK; +} + + +void RenderView::_InitGL(void) +{ + LockGL(); + + float position[] = {0.0, 3.0, 6.0, 0.0}; + float local_view[] = {0.0, 0.0}; + + glLightfv(GL_LIGHT0, GL_POSITION, position); + glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view); + + float white[3] = {1.0, 1.0, 1.0}; + + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_SPECULAR, white); + glLightfv(GL_LIGHT0, GL_DIFFUSE, white); + glLightfv(GL_LIGHT0, GL_AMBIENT, white); + + glMaterialf(GL_FRONT, GL_SHININESS, 0.6 * 128.0); + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_TEXTURE_2D); + + fNextRes.Set(Bounds().Width(), Bounds().Height()); + _UpdateViewport(); + + UnlockGL(); +} + + +void +RenderView::_CreateScene() +{ + Texture *texture = new BitmapTexture( + BTranslationUtils::GetBitmap(B_PNG_FORMAT, "texture")); + + float spacing = 1.6f; + float timeSpacing = 5.0f; + float yOffset = -1.0f; + float zOffset = -16; + + Mesh* mesh = new StaticMesh("LetterH"); + MeshInstance *instance = new MeshInstance(mesh, texture, + Vector3(-3.6 * spacing, yOffset, zOffset), + Quaternion(0, 0, 0, 1), 0.0f); + fMeshInstances.push_back(instance); + mesh->ReleaseReference(); + + mesh = new StaticMesh("LetterA"); + instance = new MeshInstance(mesh, texture, + Vector3(-1.6 * spacing, yOffset, zOffset), + Quaternion(0, 0, 0, 1), 1.0f * timeSpacing); + fMeshInstances.push_back(instance); + mesh->ReleaseReference(); + + mesh = new StaticMesh("LetterI"); + instance = new MeshInstance(mesh, texture, + Vector3(0 * spacing, yOffset, zOffset), + Quaternion(0, 0, 0, 1), 2.0f * timeSpacing); + fMeshInstances.push_back(instance); + mesh->ReleaseReference(); + + mesh = new StaticMesh("LetterK"); + instance = new MeshInstance(mesh, texture, + Vector3(1.5 * spacing, yOffset, zOffset), + Quaternion(0, 0, 0, 1), 3.0f * timeSpacing); + fMeshInstances.push_back(instance); + mesh->ReleaseReference(); + + mesh = new StaticMesh("LetterU"); + instance = new MeshInstance(mesh, texture, + Vector3(3.4 * spacing, yOffset, zOffset), + Quaternion(0, 0, 0, 1), 4.0f * timeSpacing); + fMeshInstances.push_back(instance); + mesh->ReleaseReference(); + + fMainCamera = new Camera(Vector3(0, 0, 0), Quaternion(0, 0, 0, 1), 50); + + texture->ReleaseReference(); +} + + +void +RenderView::_DeleteScene() +{ + MeshInstanceList::iterator it = fMeshInstances.begin(); + for(; it != fMeshInstances.end(); it++) { + delete (*it); + } + fMeshInstances.clear(); +} + + +void +RenderView::_UpdateViewport() +{ + if (fNextRes != fRes && fNextRes.x >= 1.0 && fNextRes.y >= 1.0) { + glViewport(0, 0, (GLint)fNextRes.x + 1, (GLint)fNextRes.y + 1); + fRes = fNextRes; + _UpdateCamera(); + } +} + + +void +RenderView::_UpdateCamera() +{ + // TODO: take camera orientation into account + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(fMainCamera->FieldOfView(), fNextRes.x / fNextRes.y, + fMainCamera->Near(), fMainCamera->Far()); + glMatrixMode(GL_MODELVIEW); +} + + +bool +RenderView::_Render() +{ + LockGL(); + + _UpdateViewport(); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glLoadIdentity(); + + bigtime_t time = system_time(); + float deltaTime = 0.000001 * (float)(time - fLastFrameTime); + fLastFrameTime = time; + + MeshInstanceList::iterator it = fMeshInstances.begin(); + for(; it != fMeshInstances.end(); it++) { + (*it)->Update(deltaTime); + (*it)->Render(); + } + + if (fStopRendering) { + UnlockGL(); + return false; + } + UnlockGL(); + SwapBuffers(false); // true = vsync + return true; +} + + +void +RenderView::FrameResized(float width, float height) +{ + LockGL(); + fNextRes.Set(width, height); + UnlockGL(); + BGLView::FrameResized(width, height); +} + + +void +RenderView::ErrorCallback(uint32 error) +{ + fprintf(stderr, "OpenGL error (%li): %s\n", error, gluErrorString(error)); +} diff --git a/src/apps/haiku3d/RenderView.h b/src/apps/haiku3d/RenderView.h new file mode 100644 index 0000000000..437b7c193c --- /dev/null +++ b/src/apps/haiku3d/RenderView.h @@ -0,0 +1,53 @@ +/* + * Copyright 2009, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ +#ifndef _RENDERVIEW_H +#define _RENDERVIEW_H + +#include + +#include + + +class Camera; +class MeshInstance; + + +class RenderView : public BGLView { +public: + RenderView(BRect frame); + ~RenderView(); + + virtual void AttachedToWindow(); + virtual void FrameResized(float width, float height); + virtual void ErrorCallback(uint32 error); + +protected: + void _InitGL(); + void _CreateScene(); + void _DeleteScene(); + void _UpdateViewport(); + void _UpdateCamera(); + bool _Render(); + uint32 _CreateRenderThread(); + void _StopRenderThread(); + static int32 _RenderThreadEntry(void *pointer); + int32 _RenderLoop(); + + Camera* fMainCamera; + + typedef std::vector MeshInstanceList; + MeshInstanceList fMeshInstances; + + thread_id fRenderThread; + bool fStopRendering; + + BPoint fRes, fNextRes; + bigtime_t fLastFrameTime; +}; + +#endif /* _RENDERVIEW_H */ diff --git a/src/apps/haiku3d/Texture.cpp b/src/apps/haiku3d/Texture.cpp new file mode 100644 index 0000000000..a16a75e8ab --- /dev/null +++ b/src/apps/haiku3d/Texture.cpp @@ -0,0 +1,34 @@ +/* + * Copyright 2008, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ + +#include "Texture.h" + +#include + + +Texture::Texture() + : + fId(0) +{ +} + + +Texture::~Texture() +{ + if (glIsTexture(fId)) { + GLuint ids[1] = {fId}; + glDeleteTextures(1, ids); + } +} + + +GLuint +Texture::Id() +{ + return fId; +} diff --git a/src/apps/haiku3d/Texture.h b/src/apps/haiku3d/Texture.h new file mode 100644 index 0000000000..65127a327d --- /dev/null +++ b/src/apps/haiku3d/Texture.h @@ -0,0 +1,29 @@ +/* + * Copyright 2009, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ +#ifndef _TEXTURE_H +#define _TEXTURE_H + +#include + +#include + + +class Texture : public Referenceable { +public: + Texture(); + virtual ~Texture(); + + GLuint Id(); + + virtual void Update(float dt) {}; + +protected: + GLuint fId; +}; + +#endif /* _TEXTURE_H */ diff --git a/src/apps/haiku3d/Vector3.h b/src/apps/haiku3d/Vector3.h new file mode 100644 index 0000000000..a4607ce575 --- /dev/null +++ b/src/apps/haiku3d/Vector3.h @@ -0,0 +1,353 @@ +/* + * Copyright 2008 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + * + */ + +/* + * + * This is a refactored and stripped down version of bullet-2.66 src\LinearMath\btVector3.h + * The dependancies on base class btQuadWord have been removed for simplification. + * + */ + +/* +Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef __VECTOR3_H__ +#define __VECTOR3_H__ + +#include "assert.h" +#include "math.h" + +///Vector3 can be used to represent 3D points and vectors. + +class Vector3 { +protected: + float m_x; + float m_y; + float m_z; + +public: + inline Vector3() {} + + + inline Vector3(const Vector3& v) + { + *((Vector3*)this) = v; + } + + + inline Vector3(const float& x, const float& y, const float& z) + { + m_x = x, m_y = y, m_z = z; + } + + + inline const float& x() const { return m_x; } + + + inline const float& y() const { return m_y; } + + + inline const float& z() const { return m_z; } + + + inline void setValue(const float& x, const float& y, const float& z) + { + m_x=x; + m_y=y; + m_z=z; + } + + inline Vector3& operator+=(const Vector3& v) + { + m_x += v.x(); m_y += v.y(); m_z += v.z(); + return *this; + } + + + inline Vector3& operator-=(const Vector3& v) + { + m_x -= v.x(); m_y -= v.y(); m_z -= v.z(); + return *this; + } + + + inline Vector3& operator*=(const float& s) + { + m_x *= s; m_y *= s; m_z *= s; + return *this; + } + + + inline Vector3& operator/=(const float& s) + { + assert(s != 0.0f); + return *this *= 1.0f / s; + } + + + inline float dot(const Vector3& v) const + { + return m_x * v.x() + m_y * v.y() + m_z * v.z(); + } + + + inline float length2() const + { + return dot(*this); + } + + + inline float length() const + { + return sqrt(length2()); + } + + + inline float distance2(const Vector3& v) const; + + + inline float distance(const Vector3& v) const; + + + inline Vector3& normalize() + { + return *this /= length(); + } + + + inline Vector3 normalized() const; + + + inline Vector3 rotate( const Vector3& wAxis, const float angle ); + + + inline float angle(const Vector3& v) const + { + float s = sqrt(length2() * v.length2()); + assert(s != 0.0f); + return acos(dot(v) / s); + } + + + inline Vector3 absolute() const + { + return Vector3( + fabs(m_x), + fabs(m_y), + fabs(m_z)); + } + + + inline Vector3 cross(const Vector3& v) const + { + return Vector3( + m_y * v.z() - m_z * v.y(), + m_z * v.x() - m_x * v.z(), + m_x * v.y() - m_y * v.x()); + } + + + inline float triple(const Vector3& v1, const Vector3& v2) const + { + return m_x * (v1.y() * v2.z() - v1.z() * v2.y()) + + m_y * (v1.z() * v2.x() - v1.x() * v2.z()) + + m_z * (v1.x() * v2.y() - v1.y() * v2.x()); + } + + + inline int minAxis() const + { + return m_x < m_y ? (m_x < m_z ? 0 : 2) : (m_y < m_z ? 1 : 2); + } + + + inline int maxAxis() const + { + return m_x < m_y ? (m_y < m_z ? 2 : 1) : (m_x < m_z ? 2 : 0); + } + + + inline int furthestAxis() const + { + return absolute().minAxis(); + } + + + inline int closestAxis() const + { + return absolute().maxAxis(); + } + + + inline void setInterpolate3(const Vector3& v0, const Vector3& v1, float rt) + { + float s = 1.0f - rt; + m_x = s * v0.x() + rt * v1.x(); + m_y = s * v0.y() + rt * v1.y(); + m_z = s * v0.z() + rt * v1.z(); + //don't do the unused w component + // m_co[3] = s * v0[3] + rt * v1[3]; + } + + + inline Vector3 lerp(const Vector3& v, const float& t) const + { + return Vector3(m_x + (v.x() - m_x) * t, + m_y + (v.y() - m_y) * t, + m_z + (v.z() - m_z) * t); + } + + + inline Vector3& operator*=(const Vector3& v) + { + m_x *= v.x(); m_y *= v.y(); m_z *= v.z(); + return *this; + } + +}; + +inline Vector3 +operator+(const Vector3& v1, const Vector3& v2) +{ + return Vector3(v1.x() + v2.x(), v1.y() + v2.y(), v1.z() + v2.z()); +} + +inline Vector3 +operator*(const Vector3& v1, const Vector3& v2) +{ + return Vector3(v1.x() * v2.x(), v1.y() * v2.y(), v1.z() * v2.z()); +} + +inline Vector3 +operator-(const Vector3& v1, const Vector3& v2) +{ + return Vector3(v1.x() - v2.x(), v1.y() - v2.y(), v1.z() - v2.z()); +} + +inline Vector3 +operator-(const Vector3& v) +{ + return Vector3(-v.x(), -v.y(), -v.z()); +} + +inline Vector3 +operator*(const Vector3& v, const float& s) +{ + return Vector3(v.x() * s, v.y() * s, v.z() * s); +} + +inline Vector3 +operator*(const float& s, const Vector3& v) +{ + return v * s; +} + +inline Vector3 +operator/(const Vector3& v, const float& s) +{ + assert(s != 0.0f); + return v * (1.0f / s); +} + +inline Vector3 +operator/(const Vector3& v1, const Vector3& v2) +{ + return Vector3(v1.x() / v2.x(),v1.y() / v2.y(),v1.z() / v2.z()); +} + +inline float +dot(const Vector3& v1, const Vector3& v2) +{ + return v1.dot(v2); +} + +inline float +distance2(const Vector3& v1, const Vector3& v2) +{ + return v1.distance2(v2); +} + + +inline float +distance(const Vector3& v1, const Vector3& v2) +{ + return v1.distance(v2); +} + +inline float +angle(const Vector3& v1, const Vector3& v2) +{ + return v1.angle(v2); +} + +inline Vector3 +cross(const Vector3& v1, const Vector3& v2) +{ + return v1.cross(v2); +} + +inline float +triple(const Vector3& v1, const Vector3& v2, const Vector3& v3) +{ + return v1.triple(v2, v3); +} + +inline Vector3 +lerp(const Vector3& v1, const Vector3& v2, const float& t) +{ + return v1.lerp(v2, t); +} + + +inline bool operator==(const Vector3& p1, const Vector3& p2) +{ + return p1.x() == p2.x() && p1.y() == p2.y() && p1.z() == p2.z(); +} + +inline float Vector3::distance2(const Vector3& v) const +{ + return (v - *this).length2(); +} + +inline float Vector3::distance(const Vector3& v) const +{ + return (v - *this).length(); +} + +inline Vector3 Vector3::normalized() const +{ + return *this / length(); +} + +inline Vector3 Vector3::rotate( const Vector3& wAxis, const float angle ) +{ + // wAxis must be a unit lenght vector + + Vector3 o = wAxis * wAxis.dot( *this ); + Vector3 x = *this - o; + Vector3 y; + + y = wAxis.cross( *this ); + + return ( o + x * cos( angle ) + y * sin( angle ) ); +} + +#endif //__VECTOR3_H__ diff --git a/src/apps/haiku3d/data/LetterA.hk3d b/src/apps/haiku3d/data/LetterA.hk3d new file mode 100644 index 0000000000..19ea0a1de2 --- /dev/null +++ b/src/apps/haiku3d/data/LetterA.hk3d @@ -0,0 +1,193 @@ +33 +4 +0.026275 1.929266 0.142702 0.812137 0.849682 +0.025358 2.624107 0.142703 0.819405 0.868483 +-1.134064 -0.009465 0.142702 0.764105 0.811047 +-0.838689 -0.009465 0.142702 0.771154 0.807535 + +4 +0.026275 1.929266 0.142702 0.812137 0.849682 +0.859859 0.010343 0.142702 0.811899 0.787878 +1.177288 0.010343 0.142702 0.819474 0.784105 +0.025358 2.624107 0.142703 0.819405 0.868483 + +4 +-0.838689 -0.009465 0.142702 0.890886 0.846817 +-1.134064 -0.009465 0.142702 0.890895 0.850372 +-1.134064 -0.009465 -0.157297 0.883074 0.850400 +-0.838689 -0.009465 -0.157297 0.883065 0.846844 + +4 +0.026275 1.929266 0.142702 0.890716 0.784105 +-0.838689 -0.009465 0.142702 0.890886 0.846817 +-0.838689 -0.009465 -0.157297 0.883065 0.846844 +0.026275 1.929266 -0.157298 0.882895 0.784132 + +4 +-1.134064 -0.009465 0.142702 0.882895 0.784132 +0.025358 2.624107 0.142703 0.882665 0.869135 +0.025358 2.624107 -0.157298 0.874844 0.869107 +-1.134064 -0.009465 -0.157297 0.875074 0.784105 + +4 +0.859859 0.010343 0.142702 0.827295 0.868483 +0.026275 1.929266 0.142702 0.827409 0.910442 +0.026275 1.929266 -0.157298 0.819588 0.910469 +0.859859 0.010343 -0.157298 0.819474 0.868510 + +4 +1.177288 0.010343 0.142702 0.890726 0.907075 +0.859859 0.010343 0.142702 0.890716 0.910895 +0.859859 0.010343 -0.157298 0.882895 0.910868 +1.177288 0.010343 -0.157298 0.882905 0.907048 + +4 +0.025358 2.624107 0.142703 0.890880 0.850427 +1.177288 0.010343 0.142702 0.890726 0.907075 +1.177288 0.010343 -0.157298 0.882905 0.907048 +0.025358 2.624107 -0.157298 0.883059 0.850400 + +4 +-1.134064 -0.009465 -0.157297 0.819474 0.841541 +0.025358 2.624107 -0.157298 0.874775 0.784105 +0.026275 1.929266 -0.157298 0.867507 0.802906 +-0.838689 -0.009465 -0.157297 0.826524 0.845052 + +4 +1.177288 0.010343 -0.157298 0.874844 0.868483 +0.859859 0.010343 -0.157298 0.867268 0.864709 +0.026275 1.929266 -0.157298 0.867507 0.802906 +0.025358 2.624107 -0.157298 0.874775 0.784105 + +4 +1.535371 0.250764 0.228401 0.499244 0.606206 +1.715217 0.082734 0.228401 0.526322 0.580249 +1.754225 0.186795 0.228401 0.530271 0.590785 +1.590723 0.318781 0.228401 0.505058 0.613280 + +4 +1.535371 0.250764 0.228401 0.499244 0.606206 +1.590723 0.318781 0.228401 0.505058 0.613280 +1.395498 0.456165 0.228401 0.472996 0.635023 +1.348583 0.386538 0.228401 0.467749 0.627685 + +4 +1.348583 0.386538 0.228401 0.467749 0.627685 +1.395498 0.456165 0.228401 0.472996 0.635023 +1.188316 0.556125 0.228402 0.438971 0.653078 +1.162431 0.490136 0.228402 0.435539 0.644698 + +4 +1.162431 0.490136 0.228402 0.435539 0.644698 +1.188316 0.556125 0.228402 0.438971 0.653078 +1.035126 0.610117 0.228402 0.412175 0.661945 +1.012306 0.543007 0.228402 0.413342 0.653381 + +4 +1.012306 0.543007 0.228402 0.413342 0.653381 +1.035126 0.610117 0.228402 0.412175 0.661945 +0.916419 0.821496 0.228402 0.392680 0.696659 +0.785817 0.467855 0.228402 0.371231 0.640220 + +4 +0.785817 0.467855 0.228402 0.371231 0.640220 +0.916419 0.821496 0.228402 0.392680 0.696659 +0.765917 1.009250 0.228402 0.367963 0.726674 +0.560418 0.461997 0.228402 0.337492 0.640896 + +4 +0.412807 0.633303 0.228402 0.314888 0.669849 +0.568306 1.165478 0.228402 0.337968 0.751512 +0.431738 1.238529 0.228401 0.315540 0.763509 +0.280950 0.527645 0.228402 0.288318 0.650039 + +3 +-1.356235 0.706943 0.228402 0.022724 0.678666 +-1.324781 0.790708 0.228402 0.027071 0.689145 +-1.444222 0.763836 0.228402 0.009094 0.686371 + +3 +-0.213920 1.329425 0.228401 0.210324 0.778437 +-0.304249 1.098594 0.228402 0.194670 0.739709 +-0.022174 1.339750 0.228401 0.239356 0.779313 + +4 +-0.734788 0.460804 0.228402 0.120687 0.639881 +-0.638044 0.516145 0.228402 0.135756 0.648970 +-0.514361 0.698029 0.228402 0.162622 0.689490 +-0.979733 0.536230 0.228402 0.083737 0.650630 + +3 +-0.514361 0.698029 0.228402 0.162622 0.689490 +-0.304249 1.098594 0.228402 0.194670 0.739709 +-0.570561 1.204075 0.228401 0.152573 0.756212 + +4 +-0.257244 0.449873 0.228402 0.202390 0.638905 +-0.304249 1.098594 0.228402 0.194670 0.739709 +-0.514361 0.698029 0.228402 0.162622 0.689490 +-0.552190 0.464998 0.228402 0.162144 0.637293 + +3 +0.215441 1.299339 0.228401 0.284114 0.772676 +0.256344 1.144662 0.228402 0.290012 0.742359 +0.431738 1.238529 0.228401 0.315540 0.763509 + +4 +-0.257244 0.449873 0.228402 0.202390 0.638905 +0.107318 1.279300 0.228401 0.260622 0.770205 +-0.022174 1.339750 0.228401 0.239356 0.779313 +-0.304249 1.098594 0.228402 0.194670 0.739709 + +4 +0.055479 0.482123 0.228402 0.252109 0.643382 +0.256344 1.144662 0.228402 0.290012 0.742359 +0.107318 1.279300 0.228401 0.260622 0.770205 +-0.257244 0.449873 0.228402 0.202390 0.638905 + +4 +0.431738 1.238529 0.228401 0.315540 0.763509 +0.256344 1.144662 0.228402 0.290012 0.742359 +0.055479 0.482123 0.228402 0.252109 0.643382 +0.280950 0.527645 0.228402 0.288318 0.650039 + +3 +0.560418 0.461997 0.228402 0.337492 0.640896 +0.412807 0.633303 0.228402 0.314888 0.669849 +0.370147 0.492156 0.228402 0.311978 0.644211 + +4 +0.560418 0.461997 0.228402 0.337492 0.640896 +0.765917 1.009250 0.228402 0.367963 0.726674 +0.568306 1.165478 0.228402 0.337968 0.751512 +0.412807 0.633303 0.228402 0.314888 0.669849 + +4 +-0.751135 1.144997 0.228401 0.121279 0.747329 +-0.979733 0.536230 0.228402 0.083737 0.650630 +-0.514361 0.698029 0.228402 0.162622 0.689490 +-0.570561 1.204075 0.228401 0.152573 0.756212 + +4 +-0.751135 1.144997 0.228401 0.121279 0.747329 +-1.105109 0.939104 0.228402 0.064785 0.714335 +-1.065350 0.826734 0.228402 0.072134 0.691785 +-0.979733 0.536230 0.228402 0.083737 0.650630 + +4 +-0.979733 0.536230 0.228402 0.083737 0.650630 +-1.065350 0.826734 0.228402 0.072134 0.691785 +-1.194371 0.872022 0.228402 0.047669 0.703318 +-1.223251 0.624486 0.228402 0.045383 0.664305 + +4 +-1.356235 0.706943 0.228402 0.022724 0.678666 +-1.223251 0.624486 0.228402 0.045383 0.664305 +-1.194371 0.872022 0.228402 0.047669 0.703318 +-1.324781 0.790708 0.228402 0.027071 0.689145 + +3 +-0.213920 1.329425 0.228401 0.210324 0.778437 +-0.433769 1.262431 0.228401 0.180772 0.768254 +-0.304249 1.098594 0.228402 0.194670 0.739709 + diff --git a/src/apps/haiku3d/data/LetterA.hk3d.bin b/src/apps/haiku3d/data/LetterA.hk3d.bin new file mode 100644 index 0000000000000000000000000000000000000000..cf2d814ccaf58e01861397d8dc1ea61481d74f93 GIT binary patch literal 2590 zcmZuxdr(wm6u-jq6pF{ngfQ|9Wh-MEijswMDXdwfWcJJrxx-{qC-<;p${JwLq7sD_j zrUfRX0S}hR5l<%woRg821y`uNG%8grZ4DjZu@l45MAd2uX8xs|i?iE+Fn6dnjNDc4 z0(tj-BX%HVH!0e*8*oLPM=a^c@Rthgvy(EC7kB^?I!_rfyOC&8;T(rLix^WMH%Ap= zrrg)%>EbbQu&WWvbn?>sI4a3dfU7a1fE76?$-)iy|7Cn+p`zZHivcrb8yf596_YHK zB-<{IS2XR%fSUHWZ#j`~%pZ#;*0Fu8fh%A_w|mc7@)=DVud`HqWOndRj9pV77ynq(KHU$Bx>h2a`<`MysqceRy`ERZP>eme`83(7c#Z`9 zmJFjqGjLhk37Q`(h}*+e5U`cU)8P9@53h)!7~AZ#Jkk*0P8F-I$DwFb8$fvuIc~O* zVkHgZV3*a&D`F_dPODBKCGWgT+3(qpz;Rg(M7zD9(JI+|evh#i47haCEAVS4=xN4ljCo(@7?z0g7#!AxG^!A41Rf3@oZ!=-i-d1`Mwy^4mDNNxAIBKk1H~fsDqpP zeK@hVh_bcj8(~NPMUb?ab5>oiQA}Cj2a>fq_+j)Y7yqUW#iEY2u=O)td>(8P%M$(HcPME*!sk)<>dQpb92Xn#N5i!`MVH;x3_(fuukKO%T?jYP*Tcf*FUedyGTOLj;tKnMA_u)b>?-g(!xRG#f5~|yr_rlm+Vj}O=I4`wuv?MPUE{ literal 0 HcmV?d00001 diff --git a/src/apps/haiku3d/data/LetterH.hk3d b/src/apps/haiku3d/data/LetterH.hk3d new file mode 100644 index 0000000000..7e676f3efa --- /dev/null +++ b/src/apps/haiku3d/data/LetterH.hk3d @@ -0,0 +1,205 @@ +35 +4 +-0.585155 2.545548 0.153761 0.703908 0.578770 +-0.902892 2.545549 0.153761 0.715955 0.578811 +-0.902893 0.002049 0.153761 0.715659 0.686230 +-0.585155 0.002048 0.153761 0.703612 0.686189 + +4 +0.903000 2.545548 0.153761 0.691566 0.578770 +0.585263 2.545549 0.153761 0.703612 0.578811 +0.585263 0.002048 0.153761 0.703316 0.686230 +0.903000 0.002048 0.153761 0.691270 0.686189 + +4 +-0.585155 0.002048 0.153761 0.798693 0.578770 +-0.902893 0.002049 0.153761 0.798730 0.592189 +-0.902893 0.002049 -0.146239 0.787356 0.592228 +-0.585155 0.002048 -0.146239 0.787319 0.578809 + +4 +-0.585155 2.545548 0.153761 0.763979 0.578809 +-0.585155 0.002048 0.153761 0.763683 0.686228 +-0.585155 0.002048 -0.146239 0.752309 0.686189 +-0.585155 2.545548 -0.146239 0.752605 0.578770 + +4 +-0.902892 2.545549 0.153761 0.798730 0.619182 +-0.585155 2.545548 0.153761 0.798693 0.632601 +-0.585155 2.545548 -0.146239 0.787319 0.632562 +-0.902892 2.545549 -0.146239 0.787356 0.619143 + +4 +-0.902893 0.002049 0.153761 0.775353 0.578770 +-0.902892 2.545549 0.153761 0.775649 0.686189 +-0.902892 2.545549 -0.146239 0.764275 0.686228 +-0.902893 0.002049 -0.146239 0.763979 0.578809 + +4 +0.585263 0.002048 0.153761 0.787023 0.578770 +0.585263 2.545549 0.153761 0.787319 0.686189 +0.585263 2.545549 -0.146239 0.775945 0.686228 +0.585263 0.002049 -0.146239 0.775649 0.578809 + +4 +0.585263 2.545549 0.153761 0.798693 0.605685 +0.903000 2.545548 0.153761 0.798730 0.619104 +0.903000 2.545548 -0.146239 0.787356 0.619143 +0.585263 2.545549 -0.146239 0.787319 0.605724 + +4 +0.903000 2.545548 0.153761 0.752309 0.578809 +0.903000 0.002048 0.153761 0.752014 0.686228 +0.903000 0.002048 -0.146239 0.740639 0.686189 +0.903000 2.545548 -0.146239 0.740935 0.578770 + +4 +0.903000 0.002048 0.153761 0.798693 0.592228 +0.585263 0.002048 0.153761 0.798730 0.605647 +0.585263 0.002049 -0.146239 0.787356 0.605685 +0.903000 0.002048 -0.146239 0.787319 0.592266 + +4 +-0.902893 0.002049 -0.146239 0.740344 0.578770 +-0.902892 2.545549 -0.146239 0.740639 0.686189 +-0.585155 2.545548 -0.146239 0.728593 0.686230 +-0.585155 0.002048 -0.146239 0.728297 0.578811 + +4 +0.585263 0.002049 -0.146239 0.728001 0.578770 +0.585263 2.545549 -0.146239 0.728297 0.686189 +0.903000 2.545548 -0.146239 0.716250 0.686230 +0.903000 0.002048 -0.146239 0.715955 0.578811 + +4 +-1.618295 1.082143 0.239460 0.040080 0.887095 +-1.845677 1.176358 0.239460 0.007364 0.899381 +-1.845678 1.065225 0.239460 0.006105 0.889319 +-1.646252 0.999025 0.239460 0.037117 0.879587 + +4 +-1.618295 1.082143 0.239460 0.040080 0.887095 +-1.646252 0.999025 0.239460 0.037117 0.879587 +-1.415226 0.938906 0.239460 0.075052 0.868767 +-1.395736 1.020569 0.239460 0.076610 0.875614 + +4 +-1.395736 1.020569 0.239460 0.076610 0.875614 +-1.415226 0.938906 0.239460 0.075052 0.868767 +-1.186141 0.918025 0.239460 0.112665 0.863203 +-1.185065 0.988900 0.239460 0.112844 0.870357 + +4 +-1.185065 0.988900 0.239460 0.112844 0.870357 +-1.186141 0.918025 0.239460 0.112665 0.863203 +-1.023746 0.921236 0.239460 0.142248 0.863737 +-1.025933 0.992086 0.239460 0.140312 0.871305 + +4 +-1.025933 0.992086 0.239460 0.140312 0.871305 +-1.023746 0.921236 0.239460 0.142248 0.863737 +-0.838399 0.764972 0.239460 0.170922 0.841464 +-0.840232 1.141953 0.239460 0.171142 0.895661 + +4 +-0.840232 1.141953 0.239460 0.171142 0.895661 +-0.838399 0.764972 0.239460 0.170922 0.841464 +-0.631572 0.641988 0.239460 0.205783 0.819473 +-0.631230 1.226553 0.239460 0.204792 0.910231 + +4 +-0.432883 1.117957 0.239460 0.234051 0.885910 +-0.391698 0.565060 0.239460 0.245083 0.807750 +-0.238178 0.544592 0.239460 0.271095 0.804352 +-0.346500 1.263173 0.239460 0.254684 0.917359 + +3 +1.249456 1.669926 0.239460 0.515680 0.984007 +1.249403 1.580450 0.239460 0.514866 0.974790 +1.351814 1.647535 0.239460 0.524084 0.981095 + +3 +0.398306 0.686102 0.239460 0.375191 0.826273 +0.401868 0.933951 0.239460 0.371063 0.868469 +0.222383 0.609132 0.239460 0.346508 0.814543 + +4 +0.581153 1.682280 0.239460 0.409385 0.985220 +0.509988 1.596504 0.239460 0.399835 0.975509 +0.458015 1.382780 0.239460 0.384537 0.926374 +0.836988 1.697627 0.239460 0.448545 0.990012 + +3 +0.458015 1.382780 0.239460 0.384537 0.926374 +0.401868 0.933951 0.239460 0.371063 0.868469 +0.688259 0.928655 0.239460 0.421756 0.866541 + +4 +0.130154 1.524901 0.239460 0.331196 0.959238 +0.401868 0.933951 0.239460 0.371063 0.868469 +0.458015 1.382780 0.239460 0.384537 0.926374 +0.411645 1.614262 0.239460 0.369667 0.974116 + +3 +-0.014298 0.563570 0.239460 0.301447 0.805930 +-0.106890 0.694049 0.239460 0.284502 0.829689 +-0.238178 0.544592 0.239460 0.271095 0.804352 + +4 +0.130154 1.524901 0.239460 0.331196 0.959238 +0.079912 0.620284 0.239460 0.323904 0.817443 +0.222383 0.609132 0.239460 0.346508 0.814543 +0.401868 0.933951 0.239460 0.371063 0.868469 + +4 +-0.151352 1.384938 0.239460 0.284985 0.937050 +-0.106890 0.694049 0.239460 0.284502 0.829689 +0.079912 0.620284 0.239460 0.323904 0.817443 +0.130154 1.524901 0.239460 0.331196 0.959238 + +4 +-0.238178 0.544592 0.239460 0.271095 0.804352 +-0.106890 0.694049 0.239460 0.284502 0.829689 +-0.151352 1.384938 0.239460 0.284985 0.937050 +-0.346500 1.263173 0.239460 0.254684 0.917359 + +3 +-0.631230 1.226553 0.239460 0.204792 0.910231 +-0.432883 1.117957 0.239460 0.234051 0.885910 +-0.442479 1.265096 0.239460 0.231409 0.913484 + +4 +-0.631230 1.226553 0.239460 0.204792 0.910231 +-0.631572 0.641988 0.239460 0.205783 0.819473 +-0.391698 0.565060 0.239460 0.245083 0.807750 +-0.432883 1.117957 0.239460 0.234051 0.885910 + +4 +0.836608 1.047355 0.239460 0.445860 0.887296 +0.836988 1.697627 0.239460 0.448545 0.990012 +0.458015 1.382780 0.239460 0.384537 0.926374 +0.688259 0.928655 0.239460 0.421756 0.866541 + +4 +0.836608 1.047355 0.239460 0.445860 0.887296 +1.095794 1.364391 0.239460 0.484801 0.934893 +1.019124 1.455657 0.239460 0.475830 0.954877 +0.836988 1.697627 0.239460 0.448545 0.990012 + +4 +0.836988 1.697627 0.239460 0.448545 0.990012 +1.019124 1.455657 0.239460 0.475830 0.954877 +1.155831 1.458537 0.239460 0.499868 0.955892 +1.095991 1.700460 0.239460 0.491813 0.988271 + +4 +1.249456 1.669926 0.239460 0.515680 0.984007 +1.095991 1.700460 0.239460 0.491813 0.988271 +1.155831 1.458537 0.239460 0.499868 0.955892 +1.249403 1.580450 0.239460 0.514866 0.974790 + +3 +0.398306 0.686102 0.239460 0.375191 0.826273 +0.580653 0.825999 0.239460 0.396027 0.843207 +0.401868 0.933951 0.239460 0.371063 0.868469 + diff --git a/src/apps/haiku3d/data/LetterH.hk3d.bin b/src/apps/haiku3d/data/LetterH.hk3d.bin new file mode 100644 index 0000000000000000000000000000000000000000..7033a6c45f6545d5cc4b76d7f6f0e8e78ab3540f GIT binary patch literal 2754 zcmZvcdr(zX6vmIZ6OX(pt2G-jDo6lEY75oI#GLhSGJYV96 zP7JdjDt(C?o|DfE`#F8Lh18~#z`pA@HLft~r{B79W!{)!-|D3n$)mi(V~3RwZDuM* zN&L{tSbeli@0)5dqy6!meB$9rK@V*P&j;_2ZVRhlEm4w5V21aP8Lq6KBaOsYfjcb! zy_4*ac8w>Y<6Bo4R?`lt7BgHq>t^Twt_M#X*O6bv{ZwD#hcc{A%NK}mdU=>l)CkL) zp^?-hz6xBM-Wm2-Jl07V?GSsUz2G?NF{PzPwi!%aj_T{kw?O^KFJ(iz*8^_`YpV}> zk(Z#~46Uu)D@97LP(B|Vi8mwfaO)oZE2RD5jP$kg+)n$S#fsG9Xw|ll;15T8LF+Xt zIG{V?NbVWJzJF=PJHoVEaF*Dv$V|cx8FzTsR}TsM>w85j?GeJ397feQqL+d`aWxR~aYOV|zM0_qEWQr9fXQrDfg5kn*GiTZN=ZZP@P z6Lx-SBdV7Q2wSWRfu8FZrHli`gBlOZF9{kC~5u)qBq76ws5Zr zOwKu@&#COy2wu|>_UuI+yjj%Y zGn0H9rWVzNtsQCu&(1T#^?)!munC0vnXz zF#b!^^EGZH5>=iA?w#kD`(pbUE&p1W>UxT(#r|{PIqk)qF3UI1t@+nVQ@XvDsI$jU z!t_M4!1BYY!kP}xu`Z33kyV*}k*v#S-F-pUkfw4{f6t%JeE=`J)Z)L3@ore}i}h+) zRd{a3DGXg&pFw8Uy5kl^Tp3|rAL}aEcgD(i*DnjbUUHsP>GxQGp0ISGJT3(->~0|J ze&HQz*2Aj^ArlN)o1*6atU%O-G!K-EL2^te@VBy?*ZrJ>%%ku1y&?0 dBkTWQ{}nao%uw~AP}1R}ZCwzNZO!~Y{sR>_HRn9?OK3(VPcx94)#ZytnFABkVV~P6Tv1T>uyy_w6Ca`4mWYeA?1Bxm!j+g zil)O&1c^zUjk0e8+KlSP=RqN0QDj@LXoT2rDMPpiq%{sW2aVDbaIhJ^vy zhamTOz>% literal 0 HcmV?d00001 diff --git a/src/apps/haiku3d/data/LetterK.hk3d b/src/apps/haiku3d/data/LetterK.hk3d new file mode 100644 index 0000000000..87d79494a1 --- /dev/null +++ b/src/apps/haiku3d/data/LetterK.hk3d @@ -0,0 +1,149 @@ +25 +4 +-0.199403 1.388241 0.140078 0.764164 0.508161 +-0.405399 1.189603 0.140078 0.756940 0.501238 +0.525260 0.023520 0.140078 0.789355 0.460367 +0.918858 0.023520 0.140077 0.803117 0.460325 + +4 +-0.516491 1.413274 0.140078 0.753079 0.509070 +-0.199403 1.388241 0.140078 0.764164 0.508161 +0.935562 2.545427 0.140078 0.803972 0.548499 +0.560064 2.545427 0.140078 0.790842 0.548540 + +3 +-0.516491 1.413274 0.140078 0.753079 0.509070 +-0.405399 1.189603 0.140078 0.756940 0.501238 +-0.199403 1.388241 0.140078 0.764164 0.508161 + +4 +-0.516491 1.072834 0.140078 0.753043 0.497167 +-0.405399 1.189603 0.140078 0.756940 0.501238 +-0.516491 1.413274 0.140078 0.753079 0.509070 +-0.834228 1.077333 0.140078 0.741934 0.497359 + +4 +-0.516491 0.000247 0.140078 0.752928 0.459665 +-0.516491 1.072834 0.140078 0.753043 0.497167 +-0.834228 1.077333 0.140078 0.741934 0.497359 +-0.834229 0.000247 0.140078 0.741818 0.459699 + +4 +-0.516491 2.543747 0.140078 0.753201 0.548596 +-0.834228 2.543748 0.140078 0.742091 0.548630 +-0.834228 1.077333 0.140078 0.741934 0.497359 +-0.516491 1.413274 0.140078 0.753079 0.509070 + +4 +-0.834228 2.543748 0.140078 0.814674 0.529173 +-0.834228 2.543748 -0.159922 0.804185 0.529205 +-0.834228 1.077333 -0.159922 0.804062 0.489131 +-0.834228 1.077333 0.140078 0.814551 0.489099 + +4 +-0.834228 1.077333 0.140078 0.814551 0.489099 +-0.834228 1.077333 -0.159922 0.804062 0.489131 +-0.834229 0.000247 -0.159922 0.803972 0.459697 +-0.834229 0.000247 0.140078 0.814461 0.459665 + +4 +-0.516491 1.072834 0.140078 0.715879 0.559137 +-0.516491 1.072834 -0.159922 0.715847 0.548648 +-0.405399 1.189603 -0.159922 0.721482 0.548630 +-0.405399 1.189603 0.140078 0.721514 0.559120 + +4 +-0.405399 1.189603 0.140078 0.741818 0.600795 +-0.405399 1.189603 -0.159922 0.731329 0.600827 +0.525260 0.023520 -0.159923 0.731169 0.548663 +0.525260 0.023520 0.140078 0.741658 0.548630 + +4 +0.525260 0.023520 0.140078 0.721546 0.559149 +0.525260 0.023520 -0.159923 0.721514 0.548660 +0.918858 0.023520 -0.159923 0.731137 0.548630 +0.918858 0.023520 0.140077 0.731169 0.559120 + +4 +0.918858 0.023520 0.140077 0.825146 0.590927 +0.918858 0.023520 -0.159923 0.814656 0.590894 +-0.199404 1.388241 -0.159923 0.814846 0.529205 +-0.199403 1.388241 0.140078 0.825335 0.529237 + +4 +-0.199403 1.388241 0.140078 0.752308 0.605335 +-0.199404 1.388241 -0.159923 0.741818 0.605303 +0.935562 2.545427 -0.159923 0.741992 0.548630 +0.935562 2.545427 0.140078 0.752482 0.548663 + +4 +0.935562 2.545427 0.140078 0.814656 0.592876 +0.935562 2.545427 -0.159923 0.804167 0.592908 +0.560064 2.545427 -0.159923 0.804139 0.583861 +0.560064 2.545427 0.140078 0.814628 0.583829 + +4 +0.560064 2.545427 0.140078 0.814628 0.583829 +0.560064 2.545427 -0.159923 0.804139 0.583861 +-0.516491 1.413274 -0.159922 0.803972 0.529237 +-0.516491 1.413274 0.140078 0.814461 0.529205 + +4 +-0.516491 2.543747 -0.159922 0.679665 0.548663 +-0.516491 2.543747 0.140078 0.690154 0.548630 +-0.516491 1.413274 0.140078 0.690248 0.579204 +-0.516491 1.413274 -0.159922 0.679759 0.579236 + +4 +-0.516491 0.000247 0.140078 0.762971 0.577670 +-0.516491 0.000247 -0.159923 0.752482 0.577638 +-0.516491 1.072834 -0.159922 0.752571 0.548630 +-0.516491 1.072834 0.140078 0.763060 0.548663 + +4 +-0.516491 2.543747 0.140078 0.770748 0.548654 +-0.516491 2.543747 -0.159922 0.770715 0.559143 +-0.834228 2.543748 -0.159922 0.763060 0.559120 +-0.834228 2.543748 0.140078 0.763092 0.548630 + +4 +-0.834229 0.000247 0.140078 0.698049 0.548654 +-0.834229 0.000247 -0.159922 0.698016 0.559143 +-0.516491 0.000247 -0.159923 0.690248 0.559120 +-0.516491 0.000247 0.140078 0.690280 0.548630 + +4 +0.525260 0.023520 -0.159923 0.727202 0.547929 +-0.405399 1.189603 -0.159922 0.694786 0.507058 +-0.199404 1.388241 -0.159923 0.702010 0.500134 +0.918858 0.023520 -0.159923 0.740964 0.547971 + +4 +0.935562 2.545427 -0.159923 0.741818 0.459796 +-0.199404 1.388241 -0.159923 0.702010 0.500134 +-0.516491 1.413274 -0.159922 0.690926 0.499225 +0.560064 2.545427 -0.159923 0.728689 0.459756 + +3 +-0.405399 1.189603 -0.159922 0.694786 0.507058 +-0.516491 1.413274 -0.159922 0.690926 0.499225 +-0.199404 1.388241 -0.159923 0.702010 0.500134 + +4 +-0.516491 1.413274 -0.159922 0.690926 0.499225 +-0.405399 1.189603 -0.159922 0.694786 0.507058 +-0.516491 1.072834 -0.159922 0.690890 0.511128 +-0.834228 1.077333 -0.159922 0.679781 0.510937 + +4 +-0.834228 1.077333 -0.159922 0.679781 0.510937 +-0.516491 1.072834 -0.159922 0.690890 0.511128 +-0.516491 0.000247 -0.159923 0.690775 0.548630 +-0.834229 0.000247 -0.159922 0.679665 0.548596 + +4 +-0.834228 1.077333 -0.159922 0.679781 0.510937 +-0.834228 2.543748 -0.159922 0.679938 0.459665 +-0.516491 2.543747 -0.159922 0.691047 0.459699 +-0.516491 1.413274 -0.159922 0.690926 0.499225 + diff --git a/src/apps/haiku3d/data/LetterK.hk3d.bin b/src/apps/haiku3d/data/LetterK.hk3d.bin new file mode 100644 index 0000000000000000000000000000000000000000..9dacdbbf4c8ca79ac4b7320439ab4d3d981dc43b GIT binary patch literal 2014 zcmZuyT}TvR6dl&VVv|(VN{FCRFilzQ!OeB&j%^~zE^Ufvm|ILp^r|dWoP?CAEix)@bSvyAkCdJ3uVHsir9x-8 zNAl5C)bprUMfFpkcA5D((IvyfX9DQ4^?d)nn&I-BRJn&|tPtENEOppbetsu9pK!@= zB;5$eURgzty}BmDMcf{b6(aZ1%sTqiS#-N)IKIgvA-i)4Yy4}4KcOnN(vO~RQQ+BU ztDTS-FsmunzTVm%_{9N6KNUko#0(=2aCRGj_kHZ56AF3_O4oWQVLY2UL=5+8S2`pN zCw8I2$tLE#nGd#j=zBUY(HxQ8krWTN*L$=)BDSX4%qGEaFzksLd|!-9qQIj#-JAJ+ zUhG3=3l!w`X=(nbC{9FMpdrMgVd&95rp{Xw_}p9D%wTRC*IptUYa7>jB)SE}-bGoM zN5b$vu!`!DN8co-gIMDBV%x7cA*;+S)ht~mD!S^NY+HQ7Ble`j=&D(zYaZQoLxxL% zy_ZPM1e=qPj$(F7yJ8|0}d1oX!nYWYd<+)d%%!} zp<-E;6AlIsDIWRDCX_IqO=+g|V26ZJdN8+YdhllOW#vLNbB-_Rj%FH7YzsVlLyHNn zm5gYL$bBrvKwicg{vfL*&{k{ z-a!pvadUm!Jwp`t`#w4V^Ro1?&5wMt0D^gC1p0pF-5|V9o-bi6tN2V#;#G3 zFjS0fRj0F@aO`k;TLO%hdS6`mSS(EB{qsuHkJcSf{BzMOx9&$)$STIJDLtr&+3Qa= z0-t7L(`L|j;`UKMo<_($UF(3fJRBJDNmvq`Bv z$F@M<$IZSmaOUWo(joudBNY9tWYffP5_gByiSygS+~T)hUy%}k9t#6vwEqmHzI4jO J{vUdi_z!Hlap(X5 literal 0 HcmV?d00001 diff --git a/src/apps/haiku3d/data/LetterU.hk3d b/src/apps/haiku3d/data/LetterU.hk3d new file mode 100644 index 0000000000..b01a02ec90 --- /dev/null +++ b/src/apps/haiku3d/data/LetterU.hk3d @@ -0,0 +1,529 @@ +89 +4 +-0.588498 2.595606 0.148832 0.885616 0.535726 +-0.906235 2.595606 0.148832 0.872935 0.535763 +-0.906236 0.981284 0.148831 0.872737 0.474841 +-0.588498 0.981284 0.148831 0.885419 0.474804 + +4 +0.906170 0.981285 0.148831 0.945072 0.474631 +0.906170 2.595606 0.148831 0.945270 0.535553 +0.588433 2.595606 0.148831 0.932589 0.535590 +0.588433 0.981284 0.148831 0.932391 0.474668 + +4 +-0.588498 0.981284 0.148831 0.885419 0.474804 +-0.906236 0.981284 0.148831 0.872737 0.474841 +-0.895665 0.790879 0.148831 0.873136 0.467654 +-0.580013 0.827225 0.148831 0.885738 0.468989 + +4 +0.895600 0.790880 0.148831 0.944627 0.467447 +0.906170 0.981285 0.148831 0.945072 0.474631 +0.588433 0.981284 0.148831 0.932391 0.474668 +0.579948 0.827225 0.148831 0.932034 0.468855 + +4 +-0.580013 0.827225 0.148831 0.885738 0.468989 +-0.895665 0.790879 0.148831 0.873136 0.467654 +-0.849188 0.587542 0.148832 0.874966 0.459975 +-0.549093 0.691948 0.148831 0.886956 0.463880 + +4 +0.849122 0.587543 0.148831 0.942747 0.459779 +0.895600 0.790880 0.148831 0.944627 0.467447 +0.579948 0.827225 0.148831 0.932034 0.468855 +0.549028 0.691948 0.148831 0.930783 0.463753 + +4 +-0.549093 0.691948 0.148831 0.886956 0.463880 +-0.849188 0.587542 0.148832 0.874966 0.459975 +-0.762931 0.402596 0.148832 0.878386 0.452985 +-0.491701 0.568101 0.148831 0.889231 0.459200 + +4 +0.762866 0.402596 0.148831 0.939282 0.452809 +0.849122 0.587543 0.148831 0.942747 0.459779 +0.549028 0.691948 0.148831 0.930783 0.463753 +0.491636 0.568101 0.148831 0.928477 0.459086 + +4 +-0.491701 0.568101 0.148831 0.889231 0.459200 +-0.762931 0.402596 0.148832 0.878386 0.452985 +-0.624774 0.235340 0.148832 0.883879 0.446658 +-0.404857 0.464673 0.148831 0.892685 0.455287 + +4 +0.624709 0.235340 0.148831 0.933748 0.446513 +0.762866 0.402596 0.148831 0.939282 0.452809 +0.491636 0.568101 0.148831 0.928477 0.459086 +0.404791 0.464673 0.148831 0.924999 0.455193 + +4 +-0.404857 0.464673 0.148831 0.892685 0.455287 +-0.624774 0.235340 0.148832 0.883879 0.446658 +-0.440822 0.098173 0.148832 0.891204 0.441460 +-0.287177 0.376292 0.148832 0.897371 0.451938 + +4 +0.440757 0.098173 0.148831 0.926389 0.441358 +0.624709 0.235340 0.148831 0.933748 0.446513 +0.404791 0.464673 0.148831 0.924999 0.455193 +0.287112 0.376292 0.148831 0.920291 0.451871 + +4 +-0.287177 0.376292 0.148832 0.897371 0.451938 +-0.440822 0.098173 0.148832 0.891204 0.441460 +-0.210181 0.017583 0.148831 0.900400 0.438392 +-0.148895 0.329355 0.148831 0.902884 0.450150 + +4 +0.210115 0.017583 0.148831 0.917174 0.438343 +0.440757 0.098173 0.148831 0.926389 0.441358 +0.287112 0.376292 0.148831 0.920291 0.451871 +0.148830 0.329354 0.148831 0.914766 0.450116 + +4 +-0.148895 0.329355 0.148831 0.902884 0.450150 +-0.210181 0.017583 0.148831 0.900400 0.438392 +-0.000033 0.000020 0.148831 0.908785 0.437705 +-0.000033 0.317757 0.148831 0.908824 0.449695 + +4 +-0.000033 0.000020 0.148831 0.908785 0.437705 +0.210115 0.017583 0.148831 0.917174 0.438343 +0.148830 0.329354 0.148831 0.914766 0.450116 +-0.000033 0.317757 0.148831 0.908824 0.449695 + +4 +-0.588498 2.595606 0.148832 0.957272 0.526924 +-0.588498 0.981284 0.148831 0.957470 0.587842 +-0.588498 0.981284 -0.151169 0.945496 0.587877 +-0.588498 2.595606 -0.151169 0.945299 0.526958 + +4 +0.588433 0.981284 -0.151169 0.957730 0.546342 +0.588433 0.981284 0.148831 0.969704 0.546377 +0.588433 2.595606 0.148831 0.969506 0.607295 +0.588433 2.595606 -0.151169 0.957533 0.607261 + +4 +-0.906235 2.595606 0.148832 0.896836 0.535763 +-0.588498 2.595606 0.148832 0.896875 0.547754 +-0.588498 2.595606 -0.151169 0.884901 0.547789 +-0.906235 2.595606 -0.151168 0.884862 0.535798 + +4 +0.588433 2.595606 -0.151169 0.800243 0.535763 +0.588433 2.595606 0.148831 0.812217 0.535798 +0.906170 2.595606 0.148831 0.812178 0.547789 +0.906170 2.595606 -0.151169 0.800205 0.547754 + +4 +-0.906236 0.981284 0.148831 0.969598 0.465971 +-0.906235 2.595606 0.148832 0.969795 0.526889 +-0.906235 2.595606 -0.151168 0.957822 0.526924 +-0.906236 0.981284 -0.151169 0.957624 0.466005 + +4 +0.906170 2.595606 -0.151169 0.945559 0.437705 +0.906170 2.595606 0.148831 0.957533 0.437739 +0.906170 0.981285 0.148831 0.957335 0.498658 +0.906170 0.981285 -0.151169 0.945362 0.498623 + +4 +-0.895665 0.790879 0.148831 0.969574 0.458781 +-0.906236 0.981284 0.148831 0.969598 0.465971 +-0.906236 0.981284 -0.151169 0.957624 0.466005 +-0.895665 0.790879 -0.151169 0.957601 0.458816 + +4 +0.906170 0.981285 -0.151169 0.945362 0.498623 +0.906170 0.981285 0.148831 0.957335 0.498658 +0.895600 0.790880 0.148831 0.957312 0.505847 +0.895600 0.790880 -0.151169 0.945338 0.505812 + +4 +-0.588498 0.981284 0.148831 0.957470 0.587842 +-0.580013 0.827225 0.148831 0.957489 0.593652 +-0.580013 0.827226 -0.151169 0.945515 0.593687 +-0.588498 0.981284 -0.151169 0.945496 0.587877 + +4 +0.579948 0.827225 -0.151169 0.957749 0.540532 +0.579948 0.827225 0.148831 0.969723 0.540567 +0.588433 0.981284 0.148831 0.969704 0.546377 +0.588433 0.981284 -0.151169 0.957730 0.546342 + +4 +-0.849188 0.587542 0.148832 0.969549 0.451089 +-0.895665 0.790879 0.148831 0.969574 0.458781 +-0.895665 0.790879 -0.151169 0.957601 0.458816 +-0.849188 0.587542 -0.151169 0.957576 0.451123 + +4 +0.895600 0.790880 -0.151169 0.945338 0.505812 +0.895600 0.790880 0.148831 0.957312 0.505847 +0.849122 0.587543 0.148831 0.957287 0.513540 +0.849122 0.587543 -0.151169 0.945313 0.513505 + +4 +-0.580013 0.827225 0.148831 0.957489 0.593652 +-0.549093 0.691948 0.148831 0.957505 0.598744 +-0.549094 0.691948 -0.151169 0.945532 0.598779 +-0.580013 0.827226 -0.151169 0.945515 0.593687 + +4 +0.549028 0.691948 -0.151169 0.957766 0.535440 +0.549028 0.691948 0.148831 0.969739 0.535475 +0.579948 0.827225 0.148831 0.969723 0.540567 +0.579948 0.827225 -0.151169 0.957749 0.540532 + +4 +-0.762931 0.402596 0.148832 0.969527 0.444074 +-0.849188 0.587542 0.148832 0.969549 0.451089 +-0.849188 0.587542 -0.151169 0.957576 0.451123 +-0.762931 0.402596 -0.151169 0.957553 0.444108 + +4 +0.849122 0.587543 -0.151169 0.945313 0.513505 +0.849122 0.587543 0.148831 0.957287 0.513540 +0.762866 0.402596 0.148831 0.957264 0.520555 +0.762866 0.402596 -0.151169 0.945291 0.520520 + +4 +-0.549093 0.691948 0.148831 0.957505 0.598744 +-0.491701 0.568101 0.148831 0.957520 0.603394 +-0.491701 0.568101 -0.151169 0.945547 0.603429 +-0.549094 0.691948 -0.151169 0.945532 0.598779 + +4 +0.491636 0.568101 -0.151169 0.957781 0.530791 +0.491636 0.568101 0.148831 0.969754 0.530825 +0.549028 0.691948 0.148831 0.969739 0.535475 +0.549028 0.691948 -0.151169 0.957766 0.535440 + +4 +-0.624774 0.235340 0.148832 0.969506 0.437705 +-0.762931 0.402596 0.148832 0.969527 0.444074 +-0.762931 0.402596 -0.151169 0.957553 0.444108 +-0.624774 0.235340 -0.151169 0.957533 0.437739 + +4 +0.762866 0.402596 -0.151169 0.945291 0.520520 +0.762866 0.402596 0.148831 0.957264 0.520555 +0.624709 0.235340 0.148831 0.957243 0.526924 +0.624709 0.235340 -0.151169 0.945270 0.526889 + +4 +-0.491701 0.568101 0.148831 0.957520 0.603394 +-0.404857 0.464673 0.148831 0.957533 0.607261 +-0.404857 0.464673 -0.151169 0.945559 0.607295 +-0.491701 0.568101 -0.151169 0.945547 0.603429 + +4 +0.404791 0.464673 -0.151169 0.957793 0.526924 +0.404791 0.464673 0.148831 0.969767 0.526958 +0.491636 0.568101 0.148831 0.969754 0.530825 +0.491636 0.568101 -0.151169 0.957781 0.530791 + +4 +-0.440822 0.098173 0.148832 0.884731 0.576341 +-0.624774 0.235340 0.148832 0.884711 0.582565 +-0.624774 0.235340 -0.151169 0.872737 0.582531 +-0.440822 0.098173 -0.151169 0.872757 0.576306 + +4 +0.624709 0.235340 -0.151169 0.872889 0.535763 +0.624709 0.235340 0.148831 0.884862 0.535798 +0.440757 0.098173 0.148831 0.884838 0.543344 +0.440757 0.098173 -0.151169 0.872865 0.543309 + +4 +-0.404857 0.464673 0.148831 0.872638 0.535763 +-0.287177 0.376292 0.148832 0.872653 0.540204 +-0.287177 0.376292 -0.151169 0.860679 0.540239 +-0.404857 0.464673 -0.151169 0.860665 0.535798 + +4 +0.287112 0.376293 -0.151169 0.860750 0.561912 +0.287112 0.376292 0.148831 0.872723 0.561877 +0.404791 0.464673 0.148831 0.872737 0.566318 +0.404791 0.464673 -0.151169 0.860764 0.566353 + +4 +-0.210181 0.017583 0.148831 0.884758 0.568097 +-0.440822 0.098173 0.148832 0.884731 0.576341 +-0.440822 0.098173 -0.151169 0.872757 0.576306 +-0.210181 0.017583 -0.151169 0.872784 0.568062 + +4 +0.440757 0.098173 -0.151169 0.872865 0.543309 +0.440757 0.098173 0.148831 0.884838 0.543344 +0.210115 0.017583 0.148831 0.884809 0.552365 +0.210115 0.017583 -0.151169 0.872835 0.552330 + +4 +-0.287177 0.376292 0.148832 0.872653 0.540204 +-0.148895 0.329355 0.148831 0.872669 0.545423 +-0.148896 0.329355 -0.151169 0.860696 0.545457 +-0.287177 0.376292 -0.151169 0.860679 0.540239 + +4 +0.148830 0.329355 -0.151169 0.860733 0.556693 +0.148830 0.329354 0.148831 0.872706 0.556658 +0.287112 0.376292 0.148831 0.872723 0.561877 +0.287112 0.376293 -0.151169 0.860750 0.561912 + +4 +-0.000033 0.000020 0.148831 0.884783 0.560315 +-0.210181 0.017583 0.148831 0.884758 0.568097 +-0.210181 0.017583 -0.151169 0.872784 0.568062 +-0.000033 0.000020 -0.151169 0.872809 0.560281 + +4 +0.210115 0.017583 -0.151169 0.872835 0.552330 +0.210115 0.017583 0.148831 0.884809 0.552365 +-0.000033 0.000020 0.148831 0.884783 0.560315 +-0.000033 0.000020 -0.151169 0.872809 0.560281 + +4 +-0.148895 0.329355 0.148831 0.872669 0.545423 +-0.000033 0.317757 0.148831 0.872688 0.551040 +-0.000033 0.317757 -0.151169 0.860714 0.551075 +-0.148896 0.329355 -0.151169 0.860696 0.545457 + +4 +-0.000033 0.317757 -0.151169 0.860714 0.551075 +-0.000033 0.317757 0.148831 0.872688 0.551040 +0.148830 0.329354 0.148831 0.872706 0.556658 +0.148830 0.329355 -0.151169 0.860733 0.556693 + +4 +-0.906236 0.981284 -0.151169 0.872540 0.474631 +-0.906235 2.595606 -0.151168 0.872737 0.535553 +-0.588498 2.595606 -0.151169 0.860056 0.535590 +-0.588498 0.981284 -0.151169 0.859858 0.474668 + +4 +0.588433 2.595606 -0.151169 0.813083 0.535726 +0.906170 2.595606 -0.151169 0.800402 0.535763 +0.906170 0.981285 -0.151169 0.800205 0.474841 +0.588433 0.981284 -0.151169 0.812886 0.474804 + +4 +-0.895665 0.790879 -0.151169 0.872094 0.467447 +-0.906236 0.981284 -0.151169 0.872540 0.474631 +-0.588498 0.981284 -0.151169 0.859858 0.474668 +-0.580013 0.827226 -0.151169 0.859501 0.468855 + +4 +0.588433 0.981284 -0.151169 0.812886 0.474804 +0.906170 0.981285 -0.151169 0.800205 0.474841 +0.895600 0.790880 -0.151169 0.800603 0.467654 +0.579948 0.827225 -0.151169 0.813206 0.468989 + +4 +-0.849188 0.587542 -0.151169 0.870215 0.459779 +-0.895665 0.790879 -0.151169 0.872094 0.467447 +-0.580013 0.827226 -0.151169 0.859501 0.468855 +-0.549094 0.691948 -0.151169 0.858250 0.463753 + +4 +0.579948 0.827225 -0.151169 0.813206 0.468989 +0.895600 0.790880 -0.151169 0.800603 0.467654 +0.849122 0.587543 -0.151169 0.802433 0.459975 +0.549028 0.691948 -0.151169 0.814423 0.463880 + +4 +-0.762931 0.402596 -0.151169 0.866749 0.452809 +-0.849188 0.587542 -0.151169 0.870215 0.459779 +-0.549094 0.691948 -0.151169 0.858250 0.463753 +-0.491701 0.568101 -0.151169 0.855945 0.459086 + +4 +0.549028 0.691948 -0.151169 0.814423 0.463880 +0.849122 0.587543 -0.151169 0.802433 0.459975 +0.762866 0.402596 -0.151169 0.805853 0.452985 +0.491636 0.568101 -0.151169 0.816698 0.459200 + +4 +-0.624774 0.235340 -0.151169 0.861215 0.446513 +-0.762931 0.402596 -0.151169 0.866749 0.452809 +-0.491701 0.568101 -0.151169 0.855945 0.459086 +-0.404857 0.464673 -0.151169 0.852466 0.455193 + +4 +0.491636 0.568101 -0.151169 0.816698 0.459200 +0.762866 0.402596 -0.151169 0.805853 0.452985 +0.624709 0.235340 -0.151169 0.811347 0.446658 +0.404791 0.464673 -0.151169 0.820152 0.455287 + +4 +-0.440822 0.098173 -0.151169 0.853856 0.441358 +-0.624774 0.235340 -0.151169 0.861215 0.446513 +-0.404857 0.464673 -0.151169 0.852466 0.455193 +-0.287177 0.376292 -0.151169 0.847758 0.451871 + +4 +0.404791 0.464673 -0.151169 0.820152 0.455287 +0.624709 0.235340 -0.151169 0.811347 0.446658 +0.440757 0.098173 -0.151169 0.818672 0.441460 +0.287112 0.376293 -0.151169 0.824838 0.451938 + +4 +-0.210181 0.017583 -0.151169 0.844641 0.438343 +-0.440822 0.098173 -0.151169 0.853856 0.441358 +-0.287177 0.376292 -0.151169 0.847758 0.451871 +-0.148896 0.329355 -0.151169 0.842234 0.450116 + +4 +0.287112 0.376293 -0.151169 0.824838 0.451938 +0.440757 0.098173 -0.151169 0.818672 0.441460 +0.210115 0.017583 -0.151169 0.827867 0.438392 +0.148830 0.329355 -0.151169 0.830351 0.450150 + +4 +-0.000033 0.000020 -0.151169 0.836252 0.437705 +-0.210181 0.017583 -0.151169 0.844641 0.438343 +-0.148896 0.329355 -0.151169 0.842234 0.450116 +-0.000033 0.317757 -0.151169 0.836291 0.449695 + +4 +0.148830 0.329355 -0.151169 0.830351 0.450150 +0.210115 0.017583 -0.151169 0.827867 0.438392 +-0.000033 0.000020 -0.151169 0.836252 0.437705 +-0.000033 0.317757 -0.151169 0.836291 0.449695 + +4 +0.034168 1.768577 0.235689 0.022855 0.519429 +-0.002803 1.967752 0.235689 0.017107 0.550231 +-0.079495 1.917906 0.235689 0.008921 0.544536 +-0.035731 1.750589 0.235689 0.017117 0.515965 + +4 +0.034168 1.768577 0.235689 0.022855 0.519429 +-0.035731 1.750589 0.235689 0.017117 0.515965 +0.026403 1.564192 0.235689 0.028101 0.486168 +0.091501 1.587370 0.235689 0.032789 0.488397 + +4 +0.091501 1.587370 0.235689 0.032789 0.488397 +0.026403 1.564192 0.235689 0.028101 0.486168 +0.114746 1.396734 0.235689 0.040638 0.458863 +0.164140 1.427781 0.235689 0.045455 0.462413 + +4 +0.164140 1.427781 0.235689 0.045455 0.462413 +0.114746 1.396734 0.235689 0.040638 0.458863 +0.189801 1.286104 0.235689 0.052423 0.441934 +0.237714 1.319393 0.235689 0.056569 0.445848 + +4 +0.237714 1.319393 0.235689 0.056569 0.445848 +0.189801 1.286104 0.235689 0.052423 0.441934 +0.165097 1.088106 0.235689 0.050980 0.408209 +0.424431 1.258461 0.235689 0.088029 0.433570 + +4 +0.424431 1.258461 0.235689 0.088029 0.433570 +0.165097 1.088106 0.235689 0.050980 0.408209 +0.172995 0.890212 0.235689 0.052695 0.376649 +0.576558 1.152173 0.235689 0.112141 0.416703 + +4 +0.590581 0.966584 0.235689 0.109054 0.385642 +0.227498 0.690170 0.235689 0.060276 0.345169 +0.282232 0.575044 0.235688 0.068968 0.326220 +0.729540 0.972106 0.235689 0.138969 0.386326 + +3 +1.726082 0.053175 0.235689 0.302215 0.240005 +1.664310 0.013078 0.235689 0.292163 0.233479 +1.756541 -0.027506 0.235688 0.307172 0.226875 + +3 +0.665372 0.199277 0.235688 0.130859 0.264620 +0.838012 0.307988 0.235689 0.156084 0.284693 +0.533348 0.286158 0.235688 0.110213 0.278758 + +4 +1.434852 0.519913 0.235689 0.256080 0.310926 +1.343737 0.530551 0.235689 0.243769 0.313077 +1.172933 0.470555 0.235689 0.206746 0.300377 +1.560193 0.350244 0.235689 0.275219 0.288348 + +3 +1.172933 0.470555 0.235689 0.206746 0.300377 +0.838012 0.307988 0.235689 0.156084 0.284693 +0.962813 0.107973 0.235688 0.179615 0.251607 + +4 +1.123955 0.760559 0.235689 0.202338 0.352716 +0.838012 0.307988 0.235689 0.156084 0.284693 +1.172933 0.470555 0.235689 0.206746 0.300377 +1.311882 0.606383 0.235689 0.228519 0.332128 + +3 +0.395746 0.429056 0.235688 0.083146 0.305039 +0.444260 0.551479 0.235689 0.092973 0.326465 +0.282232 0.575044 0.235688 0.068968 0.326220 + +4 +1.123955 0.760559 0.235689 0.202338 0.352716 +0.477142 0.389480 0.235688 0.100227 0.295153 +0.533348 0.286158 0.235688 0.110213 0.278758 +0.838012 0.307988 0.235689 0.156084 0.284693 + +4 +0.901101 0.892049 0.235689 0.166416 0.373942 +0.444260 0.551479 0.235689 0.092973 0.326465 +0.477142 0.389480 0.235688 0.100227 0.295153 +1.123955 0.760559 0.235689 0.202338 0.352716 + +4 +0.282232 0.575044 0.235688 0.068968 0.326220 +0.444260 0.551479 0.235689 0.092973 0.326465 +0.901101 0.892049 0.235689 0.166416 0.373942 +0.729540 0.972106 0.235689 0.138969 0.386326 + +3 +0.576558 1.152173 0.235689 0.112141 0.416703 +0.590581 0.966584 0.235689 0.109054 0.385642 +0.687818 1.039204 0.235689 0.125522 0.402614 + +4 +0.576558 1.152173 0.235689 0.112141 0.416703 +0.172995 0.890212 0.235689 0.052695 0.376649 +0.227498 0.690170 0.235689 0.060276 0.345169 +0.590581 0.966584 0.235689 0.109054 0.385642 + +4 +1.111268 0.058838 0.235688 0.202163 0.240926 +1.560193 0.350244 0.235689 0.275219 0.288348 +1.172933 0.470555 0.235689 0.206746 0.300377 +0.962813 0.107973 0.235688 0.179615 0.251607 + +4 +1.111268 0.058838 0.235688 0.202163 0.240926 +1.446309 0.022174 0.235689 0.256686 0.234960 +1.474903 0.116021 0.235689 0.265098 0.251842 +1.560193 0.350244 0.235689 0.275219 0.288348 + +4 +1.560193 0.350244 0.235689 0.275219 0.288348 +1.474903 0.116021 0.235689 0.265098 0.251842 +1.538208 0.022970 0.235689 0.277547 0.233210 +1.678319 0.172777 0.235689 0.294442 0.259468 + +4 +1.726082 0.053175 0.235689 0.302215 0.240005 +1.678319 0.172777 0.235689 0.294442 0.259468 +1.538208 0.022970 0.235689 0.277547 0.233210 +1.664310 0.013078 0.235689 0.292163 0.233479 + +3 +0.665372 0.199277 0.235688 0.130859 0.264620 +0.843705 0.136187 0.235688 0.154058 0.255124 +0.838012 0.307988 0.235689 0.156084 0.284693 + diff --git a/src/apps/haiku3d/data/LetterU.hk3d.bin b/src/apps/haiku3d/data/LetterU.hk3d.bin new file mode 100644 index 0000000000000000000000000000000000000000..72abd1d46363a651aa22638fb918daf6620ff667 GIT binary patch literal 7182 zcmZ`-eO#1P7JgYroL~Syz;DIHRmqZoOblo4Q4DnxLc~CEYTN?hJMA#}qb6Z!&1lC;TsClRZ4yB`miy2`7^1J+Hrocr^1K0K z2|KpM4&rHVFlc*!&Va?9m6qmwShLt05W_4O9d#!kv?EQTU_1p70-o%WwXYCpFf^+TmESAI$#qSMGI}o1_}A73na^;j1%VZ43rn zi5mO*JOxSH{D9NV>G@*xSArOKAISli3mLgQoSvNRHSQ+=Ll*S$+Msk;@QXiG84KN0 zH-9E|_t`ZQ4#%5x#!Fjj1g=DlCx*;{p&bH%)6MCbsuc=k#Mp?x&xWwc$jIg4^lW`N z#r?3)YBNT^y>u45v`^1Gucv$D`c0BCb6^JC+>4B9p(%n^Ua822JqH7T)6MC*FsrBN z?qTc`mJN~nkde#7=~R$V%e$EOm zNsXlE{0nv%{=%j9T7Rgbw>$A~cBn1U>%Y`UD|elZlZj4S_4;m3xSpc5W5_5vI6$OoI-^>zwGl3uveE}AH!_lL!c;vJi&)Aa zC*1QgRx{LtJw?q!7&4L`wXVV$uK-4TRg?E7907~y?K|1#X!Q+tor-wCHoM+IU* zdf&t7SU(5E7>}}N)SyxSz?D7^I3XPx1YxN03vfYYbi@BWqj+vHmd>(XDU=@f#Bdkn zE;j-BgN)=YVHi!GQ7mHH2RdQ+GW@SOF9<_M@=WbLpLce`gf6!PVaRCI98eu}OZSoU zOzn@RU?=3}e<|j8dNW3+`8(ib&X=sW290_gt{f8Xgvv8bf-uzh^=KE2JlVv0OMYW4 zeFKB0_PxeP7Yt4G2l5Ad3VBNyMw4e0i&$ic6Ph3M*L~!?APhB0m)t)en#;S*1f%Dd&(X4x|?NMh~Ca#;DFh;j?UD&u$QeVYKscD;$~G zASf2Gm#0`gy%6V_1^Rr2Xunh|bd9eT>Ws5L+XkBwtMBp_cm100xpoX=jnl30v-de& zqdMa(U1Epykg9fn&`0u?^NeDVaeuB2ejZ$MV5Xc{^l>*9pSp{v0;Y z9;(wB$sg21o~iSiIl~5%-Sr~E)ix_)bYZd;&VEwQdTY>d=EA8GSGG>ILddOJq0V8O zvuyD3om$pg?i<`a?fvOF-N*hlg8acnEYibjkw z6LvQv=b1WbF3hw+_j7fEFpS=lVuhur>sW8wc8!y-x{{(%4>5Aya^K*$*$f#EK53IT zc6AQJ(~LKEnkjMJ`unZ&#!mAHV#UE$&yAgCMMNJOJW0MP&}@d-pi6BtCCx&J;jDE?d0rLNx|be3Ro>V+-JBk^u5WxR#dBll@^E^nW}?O(KP1Ul z1-16nzBW}dP9y04{dMlCp}=8LT8 zGV?6I|B4qsj4F#ee_LX=2NswIOt>h)*WOgv?FL>-jTU4~yYFMg>5RHv6&ehjOS*xq<=OZLq_=#xE%a?#gY zuUNtkekh}ja|c^)tnh)vz)-Pb&kl)sKM-w+Ux%-S9LhyUOpg)%>)w;mOFv1rWLNn^ z-0Y{t`I=1bQPjZpjq4KM0rD&F`PFcx@O0JC?2%K_j|Bq<$uP!b;1jMfXF<=h4voolCB}5brPC zz4}21ZA|l7=u|n)f~TjcY^^Z95(9mW-$38kWHVyvMQg;z(T_m#$!ZuorDiuWZj60f zEN_U_qmMm46k-G71frK(JBq3?X1K8;8P;xnTVV8}6T!mTKMIz-XoUD>ugP_(J8LY7 z8%FB88MS#QbnMkpDr)GvOoV2HLt$$PL>%iRu{H0^7vX0ffRd0RC~9n$j1Pa5Bo_C6 z5Hd;+Kv>dti9L6@K%590q3hvRa(b>Tcm}QysIs8$*2XCDpCZup?5%nQTDQl@+}k1& zL}uwAb~jv>&l-xMVN@R(TdQS@&9{c?dPc50ETaGYo!s}+6Si1>s*eEEGvA9{!~EpR z^_gzV;hg)~@5SqBnRr7qW*v}>N5_6?Ig>Y>b(h<H@ctW8~@w aUn~6Xq`*Js`pVP%mp%PN2!kgT`!Wo@Pbc|(yy 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 JDkaO{{{w(e0!;t_ literal 0 HcmV?d00001 diff --git a/src/apps/haiku3d/mesh/StaticMesh.cpp b/src/apps/haiku3d/mesh/StaticMesh.cpp new file mode 100644 index 0000000000..80ba58d271 --- /dev/null +++ b/src/apps/haiku3d/mesh/StaticMesh.cpp @@ -0,0 +1,165 @@ +/* + * Copyright 2008, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ + +#include "StaticMesh.h" + +#include +#include +#include +#include +#include + +#include +#include + +StaticMesh::StaticMesh(const char* name) + : + fFaces(NULL), + fFaceCount(0) +{ + // TODO : move that in a utility class + //BString fileName; + //fileName << "data/" << name << ".hk3d"; + //_LoadText(fileName); + + //fileName << ".bin"; + //_WriteBinary(fileName); + + _ReadResource(name); +} + + +StaticMesh::~StaticMesh() +{ + delete [] fFaces; +} + + +void +StaticMesh::_ReadText(const char* fileName) +{ + FILE* f = fopen(fileName, "r"); + if (f == NULL) { + printf("Mesh::_ReadText, error accessing %s\n", fileName); + return; + } + + fscanf(f, "%lu", &fFaceCount); + fFaces = new Face[fFaceCount]; + + for (uint32 i = 0; i < fFaceCount; i++) { + + uint32 vertexCount = 0; + fscanf(f, "%lu", &vertexCount); + fFaces[i].vertexCount = vertexCount; + + for (uint32 vi = 0; vi < vertexCount; vi++) { + float x, y, z, u, v; + fscanf(f, "%f %f %f %f %f", &x, &y, &z, &v, &u); + fFaces[i].v[vi].p.setValue(x, y, z); + fFaces[i].v[vi].u = v; + fFaces[i].v[vi].v = 1.0 - u; + } + } + + fclose(f); + printf("Mesh::_ReadText, loaded %s (%lu faces)\n", fileName, fFaceCount); +} + + +void +StaticMesh::_WriteBinary(const char* fileName) +{ + BFile file(fileName, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); + + if (file.InitCheck() != B_OK) { + printf("Mesh::_WriteBinary, error accessing %s\n", fileName); + return; + } + + file.Write(&fFaceCount, sizeof(uint32)); + for (uint32 i = 0; i < fFaceCount; i++) { + file.Write(&fFaces[i].vertexCount, sizeof(uint16)); + for (uint32 vi = 0; vi < fFaces[i].vertexCount; vi++) { + file.Write(&fFaces[i].v[vi], sizeof(Vertex)); + } + } + printf("Mesh::_WriteBinary, wrote %s (%lu faces)\n", fileName, fFaceCount); +} + + +void +StaticMesh::_ReadBinary(const char* fileName) +{ + BFile file(fileName, B_READ_ONLY); + + if (file.InitCheck() != B_OK) { + printf("Mesh::_ReadBinary, error accessing %s\n", fileName); + return; + } + + file.Read(&fFaceCount, sizeof(uint32)); + fFaces = new Face[fFaceCount]; + for (uint32 i = 0; i < fFaceCount; i++) { + file.Read(&fFaces[i].vertexCount, sizeof(uint16)); + for (uint32 vi = 0; vi < fFaces[i].vertexCount; vi++) { + file.Read(&fFaces[i].v[vi], sizeof(Vertex)); + } + } + printf("Mesh::_ReadBinary, loaded %s (%lu faces)\n", fileName, fFaceCount); +} + + +void +StaticMesh::_ReadResource(const char* resourceName) +{ + // TODO: factorize with _ReadBinary + app_info info; + be_app->GetAppInfo(&info); + BFile file(&info.ref, B_READ_ONLY); + + BResources res; + if (res.SetTo(&file) != B_OK) { + printf("Mesh::_ReadResource, error accessing resources data\n"); + return; + } + + size_t size; + const void* data = res.LoadResource(B_RAW_TYPE, resourceName, &size); + if (data == NULL) { + printf("Mesh::_ReadResource, can't access resource %s\n", resourceName); + return; + } + + BMemoryIO memoryIO(data, size); + + memoryIO.Read(&fFaceCount, sizeof(uint32)); + fFaces = new Face[fFaceCount]; + for (uint32 i = 0; i < fFaceCount; i++) { + memoryIO.Read(&fFaces[i].vertexCount, sizeof(uint16)); + for (uint32 vi = 0; vi < fFaces[i].vertexCount; vi++) { + memoryIO.Read(&fFaces[i].v[vi], sizeof(Vertex)); + } + } + printf("Mesh::_ReadResource, loaded %s (%lu faces)\n", resourceName, + fFaceCount); +} + + +Face& +StaticMesh::GetFace(uint32 index) const +{ + return fFaces[index]; +} + + +uint32 +StaticMesh::FaceCount() const +{ + return fFaceCount; +} diff --git a/src/apps/haiku3d/mesh/StaticMesh.h b/src/apps/haiku3d/mesh/StaticMesh.h new file mode 100644 index 0000000000..95c6b282c9 --- /dev/null +++ b/src/apps/haiku3d/mesh/StaticMesh.h @@ -0,0 +1,33 @@ +/* + * Copyright 2009, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ +#ifndef _STATICMESH_H +#define _STATICMESH_H + +#include "Mesh.h" +#include "Vector3.h" + + +class StaticMesh : public Mesh { +public: + StaticMesh(const char* fileName); + virtual ~StaticMesh(); + + virtual Face& GetFace(uint32 index) const; + virtual uint32 FaceCount() const; + +protected: + void _ReadText(const char* fileName); + void _WriteBinary(const char* fileName); + void _ReadBinary(const char* fileName); + void _ReadResource(const char* resourceName); + + Face* fFaces; + uint32 fFaceCount; +}; + +#endif /* _STATICMESH_H */ diff --git a/src/apps/haiku3d/texture/BitmapTexture.cpp b/src/apps/haiku3d/texture/BitmapTexture.cpp new file mode 100644 index 0000000000..c7bfc63efd --- /dev/null +++ b/src/apps/haiku3d/texture/BitmapTexture.cpp @@ -0,0 +1,52 @@ +/* + * Copyright 2009, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ + +#include "BitmapTexture.h" + +#include + +#include +#include +#include + + +BitmapTexture::BitmapTexture(BBitmap* bitmap) + : + Texture() +{ + _Load(bitmap); +} + + +BitmapTexture::~BitmapTexture() +{ +} + + +void +BitmapTexture::_Load(BBitmap* bitmap) { + if (bitmap == NULL) + return; + + glGenTextures(1, &fId); + glBindTexture(GL_TEXTURE_2D, fId); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, 4, + (int) bitmap->Bounds().Width() + 1, + (int) bitmap->Bounds().Height() + 1, + 0, GL_BGRA, GL_UNSIGNED_BYTE, + bitmap->Bits()); + + printf("BitmapTexture::_Load, loaded texture %u (%li, %li, %libits)\n", + fId, (int32) bitmap->Bounds().Width(), + (int32) bitmap->Bounds().Height(), + 8 * bitmap->BytesPerRow() / (int)bitmap->Bounds().Width()); + + delete bitmap; +} diff --git a/src/apps/haiku3d/texture/BitmapTexture.h b/src/apps/haiku3d/texture/BitmapTexture.h new file mode 100644 index 0000000000..14b20614ce --- /dev/null +++ b/src/apps/haiku3d/texture/BitmapTexture.h @@ -0,0 +1,24 @@ +/* + * Copyright 2009, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ +#ifndef _BITMAP_TEXTURE_H +#define _BITMAP_TEXTURE_H + +#include "Texture.h" + +class BBitmap; + +class BitmapTexture : public Texture { +public: + BitmapTexture(BBitmap* bitmap); + virtual ~BitmapTexture(); + +protected: + void _Load(BBitmap* bitmap); +}; + +#endif /* _BITMAP_TEXTURE_H */ diff --git a/src/apps/haiku3d/texture/VideoFileTexture.cpp b/src/apps/haiku3d/texture/VideoFileTexture.cpp new file mode 100644 index 0000000000..dadc2302cb --- /dev/null +++ b/src/apps/haiku3d/texture/VideoFileTexture.cpp @@ -0,0 +1,136 @@ +/* + * Copyright 2008, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ + +#include "VideoFileTexture.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + + +VideoFileTexture::VideoFileTexture(const char* fileName) + : + Texture(), + fMediaFile(NULL), + fVideoTrack(NULL), + fVideoBitmap(NULL) +{ + _Load(fileName); +} + + +VideoFileTexture::~VideoFileTexture() +{ + delete fVideoBitmap; + + if (fMediaFile != NULL) { + fMediaFile->ReleaseAllTracks(); + fMediaFile->CloseFile(); + delete fMediaFile; + } +} + + +void +VideoFileTexture::_Load(const char* fileName) +{ + BEntry entry(fileName); + entry_ref ref; + entry.GetRef(&ref); + + fMediaFile = new BMediaFile(&ref); + status_t err = fMediaFile->InitCheck(); + if (err != B_OK) { + printf("cannot contruct BMediaFile object -- %s\n", strerror(err)); + return; + } + + int32 trackCount = fMediaFile->CountTracks(); + + for (int32 i = 0; i < trackCount; i++) { + BMediaTrack* track = fMediaFile->TrackAt(i); + if (track == NULL) { + printf("cannot contruct BMediaTrack object\n"); + return; + } + + // get the encoded format + media_format format; + err = track->EncodedFormat(&format); + if (err != B_OK) { + printf("BMediaTrack::EncodedFormat error -- %s\n", strerror(err)); + return; + } + + if (format.type == B_MEDIA_ENCODED_VIDEO) { + fVideoTrack = track; + // allocate a bitmap large enough to contain the decoded frame. + BRect bounds(0.0, 0.0, + format.u.encoded_video.output.display.line_width - 1.0, + format.u.encoded_video.output.display.line_count - 1.0); + fVideoBitmap = new BBitmap(bounds, B_RGB32); + + // specifiy the decoded format. we derive this information from + // the encoded format. + memset(&format, 0, sizeof(media_format)); + format.u.raw_video.last_active = (int32) (bounds.Height() - 1.0); + format.u.raw_video.orientation = B_VIDEO_TOP_LEFT_RIGHT; + format.u.raw_video.pixel_width_aspect = 1; + format.u.raw_video.pixel_height_aspect = 3; + format.u.raw_video.display.format = fVideoBitmap->ColorSpace(); + format.u.raw_video.display.line_width = (int32) bounds.Width(); + format.u.raw_video.display.line_count = (int32) bounds.Height(); + format.u.raw_video.display.bytes_per_row = + fVideoBitmap->BytesPerRow(); + + err = fVideoTrack->DecodedFormat(&format); + if (err != B_OK) { + printf("error with BMediaTrack::DecodedFormat() -- %s\n", + strerror(err)); + return; + } + + // Create Texture + glGenTextures(1, &fId); + glBindTexture(GL_TEXTURE_2D, fId); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, 4, + (int) fVideoBitmap->Bounds().Width() + 1, + (int) fVideoBitmap->Bounds().Height() + 1, + 0, GL_BGRA, GL_UNSIGNED_BYTE, fVideoBitmap->Bits()); + } + } +} + + +void +VideoFileTexture::Update(float /*dt*/) { + // TODO loop + int64 frameCount = 0; + media_header mh; + status_t err = + fVideoTrack->ReadFrames(fVideoBitmap->Bits(), &frameCount, &mh); + if (err) { + printf("BMediaTrack::ReadFrames error -- %s\n", strerror(err)); + return; + } + + glBindTexture(GL_TEXTURE_2D, fId); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, + (int)fVideoBitmap->Bounds().Width() + 1, + (int)fVideoBitmap->Bounds().Height() + 1, + GL_BGRA, GL_UNSIGNED_BYTE, fVideoBitmap->Bits()); +} + diff --git a/src/apps/haiku3d/texture/VideoFileTexture.h b/src/apps/haiku3d/texture/VideoFileTexture.h new file mode 100644 index 0000000000..7aabaeeac6 --- /dev/null +++ b/src/apps/haiku3d/texture/VideoFileTexture.h @@ -0,0 +1,33 @@ +/* + * Copyright 2009, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexandre Deckner + */ +#ifndef _VIDEO_FILE_TEXTURE_H +#define _VIDEO_FILE_TEXTURE_H + +#include "Texture.h" + + +class BMediaFile; +class BMediaTrack; +class BBitmap; + + +class VideoFileTexture : public Texture { +public: + VideoFileTexture(const char* fileName); + virtual ~VideoFileTexture(); + + virtual void Update(float dt); +protected: + void _Load(const char* fileName); + + BMediaFile* fMediaFile; + BMediaTrack* fVideoTrack; + BBitmap* fVideoBitmap; +}; + +#endif /* _VIDEO_TEXTURE_H */