|
|
@ -1,3 +1,5 @@ |
|
|
|
(set-cakelisp-option cakelisp-src-dir "Dependencies/cakelisp/src") |
|
|
|
|
|
|
|
(c-import "<stdio.h>" |
|
|
|
;; Ogre dependencies |
|
|
|
"OgreItem.h" |
|
|
@ -11,25 +13,48 @@ |
|
|
|
;; Not ported over to Cakelisp yet |
|
|
|
"OgreInitialize.hpp") |
|
|
|
|
|
|
|
;; TODO: convert these functions to cakelisp eventually |
|
|
|
(defun ogre-initialize (&return bool) |
|
|
|
(return (OgreInitialize))) |
|
|
|
|
|
|
|
(defun ogre-shutdown () |
|
|
|
(OgreShutdown)) |
|
|
|
|
|
|
|
(defun ogre-load-mesh (name (* (const char))) |
|
|
|
(var sceneManager (* (in Ogre SceneManager)) (ogreGetSceneManager)) |
|
|
|
;; If false is returned, you should break from the main loop (the window has been closed) |
|
|
|
(defun ogre-handle-window-events (&return bool) |
|
|
|
(call (in Ogre WindowEventUtilities messagePump)) |
|
|
|
(return (not g_ogreWindowShouldQuit))) |
|
|
|
|
|
|
|
;; If false is returned, you should break from the main loop (an error has occurred) |
|
|
|
(defun ogre-render-frame (&return bool) |
|
|
|
(return (on-call-ptr g_ogreRoot renderOneFrame))) |
|
|
|
|
|
|
|
;; I'd be happy if this goes away in the "real" language, but it seems necessary for C++ interop |
|
|
|
(forward-declare |
|
|
|
(namespace Ogre |
|
|
|
(class Item) |
|
|
|
(class SceneNode))) |
|
|
|
|
|
|
|
;; The client of this API should not need access the internals of this structure |
|
|
|
(defstruct mesh-handle |
|
|
|
mesh-item (* (in Ogre Item))) |
|
|
|
|
|
|
|
(defstruct scene-node |
|
|
|
node (* (in Ogre SceneNode))) |
|
|
|
|
|
|
|
(defun ogre-load-mesh (name (* (const char)) &return mesh-handle) |
|
|
|
(var scene-manager (* (in Ogre SceneManager)) (ogreGetSceneManager)) |
|
|
|
;; Load the v1 mesh. Notice the v1 namespace |
|
|
|
;; Also notice the HBU_STATIC flag; since the HBU_WRITE_ONLY |
|
|
|
;; bit would prohibit us from reading the data for importing. |
|
|
|
(var v1Mesh Ogre::v1::MeshPtr |
|
|
|
(var mesh-v1 Ogre::v1::MeshPtr |
|
|
|
(on-call (call (in Ogre v1 MeshManager getSingleton)) load |
|
|
|
name Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME |
|
|
|
Ogre::v1::HardwareBuffer::HBU_STATIC Ogre::v1::HardwareBuffer::HBU_STATIC)) |
|
|
|
|
|
|
|
(var halfPosition bool true) |
|
|
|
(var halfUVs bool true) |
|
|
|
(var useQtangents bool true) |
|
|
|
(var half-position bool true) |
|
|
|
(var half-UVs bool true) |
|
|
|
(var use-Q-tangents bool true) |
|
|
|
|
|
|
|
;; Create a v2 mesh to import to, with a different name (arbitrary). |
|
|
|
(var mesh-name-v2 (const Ogre::String) (+ name (Ogre::String " Imported"))) |
|
|
@ -37,26 +62,94 @@ |
|
|
|
(var v2Mesh Ogre::MeshPtr |
|
|
|
(on-call (call (in Ogre MeshManager getSingleton)) createByImportingV1 |
|
|
|
mesh-name-v2 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME |
|
|
|
(on-call v1Mesh get) |
|
|
|
halfPosition halfUVs useQtangents)) |
|
|
|
(on-call mesh-v1 get) |
|
|
|
half-position half-UVs use-Q-tangents)) |
|
|
|
|
|
|
|
;; We don't need the v1 mesh. Free CPU memory, get it out of the GPU. |
|
|
|
;; Leave it loaded if you want to use athene with v1 Entity. |
|
|
|
(on-call-ptr v1Mesh unload) |
|
|
|
(on-call-ptr mesh-v1 unload) |
|
|
|
|
|
|
|
;; Create an Item with the model we just imported. |
|
|
|
;; Notice we use the name of the imported model. We could also use the overload |
|
|
|
;; with the mesh pointer: |
|
|
|
;; item = sceneManager->createItem( v2Mesh, Ogre::SCENE_DYNAMIC ); |
|
|
|
(var item (* Ogre::Item) (on-call-ptr sceneManager createItem |
|
|
|
;; item = scene-manager->createItem( v2Mesh, Ogre::SCENE_DYNAMIC ); |
|
|
|
(var item (* Ogre::Item) (on-call-ptr scene-manager createItem |
|
|
|
mesh-name-v2 Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME |
|
|
|
Ogre::SCENE_DYNAMIC))) |
|
|
|
Ogre::SCENE_DYNAMIC)) |
|
|
|
|
|
|
|
;; If false is returned, you should break from the main loop (the window has been closed) |
|
|
|
(defun ogre-handle-window-events (&return bool) |
|
|
|
(call (in Ogre WindowEventUtilities messagePump)) |
|
|
|
(return (not g_ogreWindowShouldQuit))) |
|
|
|
(var mesh-handle mesh-handle (array item)) |
|
|
|
(return mesh-handle)) |
|
|
|
|
|
|
|
;; If false is returned, you should break from the main loop |
|
|
|
(defun ogre-render-frame (&return bool) |
|
|
|
(return (on-call-ptr g_ogreRoot renderOneFrame))) |
|
|
|
(defun ogre-node-from-item (mesh-handle mesh-handle &return scene-node) |
|
|
|
(var new-scene-node scene-node (array nullptr)) |
|
|
|
(var scene-manager (* (in Ogre SceneManager)) (ogreGetSceneManager)) |
|
|
|
(var root-scene-node (* Ogre::SceneNode) (on-call-ptr scene-manager getRootSceneNode)) |
|
|
|
(when root-scene-node |
|
|
|
;; WTF - this should work, but it's almost like the root scene node's vtable is wrong |
|
|
|
;; Ogre::SceneNode* sceneNode = root-scene-node->createChildSceneNode(Ogre::SCENE_DYNAMIC); |
|
|
|
(var scene-node (* Ogre::SceneNode) |
|
|
|
(type-cast (on-call-ptr root-scene-node createChild) (* Ogre::SceneNode))) |
|
|
|
(when scene-node |
|
|
|
(on-call-ptr scene-node attachObject (field mesh-handle mesh-item)) |
|
|
|
(set (field new-scene-node node) scene-node))) |
|
|
|
(return new-scene-node)) |
|
|
|
|
|
|
|
;; Creates forward declarations in header files. |
|
|
|
;; Example usage: |
|
|
|
;; (forward-declare (namespace Ogre (class item) (struct my-struct))) |
|
|
|
;; Outputs namespace Ogre { class item; struct my-struct;} |
|
|
|
(defgenerator forward-declare () |
|
|
|
;; TODO: Support global vs local? |
|
|
|
(var is-global bool true) |
|
|
|
(var output-dest (& (<> std::vector StringOutput)) |
|
|
|
(? is-global output.header output.source)) |
|
|
|
|
|
|
|
(var end-invocation-index int (FindCloseParenTokenIndex tokens startTokenIndex)) |
|
|
|
(var start-body-index int (+ 2 startTokenIndex)) |
|
|
|
(var current-index int start-body-index) |
|
|
|
(var namespace-stack (<> std::vector int)) |
|
|
|
(while (< current-index end-invocation-index) |
|
|
|
(var current-token (& (const Token)) (at current-index tokens)) |
|
|
|
;; Invocations |
|
|
|
(when (= TokenType_OpenParen (field current-token type)) |
|
|
|
(var invocation-token (& (const Token)) (at (+ 1 current-index) tokens)) |
|
|
|
(cond |
|
|
|
((= 0 (on-call (field invocation-token contents) compare "namespace")) |
|
|
|
(unless (< (+ 3 current-index) end-invocation-index) |
|
|
|
(ErrorAtToken invocation-token "missing name or body arguments") |
|
|
|
(return false)) |
|
|
|
(var namespace-name-token (& (const Token)) (at (+ 2 current-index) tokens)) |
|
|
|
(addStringOutput output-dest "namespace" |
|
|
|
StringOutMod_SpaceAfter (addr invocation-token)) |
|
|
|
(addStringOutput output-dest (field namespace-name-token contents) |
|
|
|
StringOutMod_None (addr namespace-name-token)) |
|
|
|
(addLangTokenOutput output-dest StringOutMod_OpenBlock (addr namespace-name-token)) |
|
|
|
(on-call namespace-stack push_back (FindCloseParenTokenIndex tokens current-index))) |
|
|
|
|
|
|
|
((or (= 0 (on-call (field invocation-token contents) compare "class")) |
|
|
|
(= 0 (on-call (field invocation-token contents) compare "struct"))) |
|
|
|
(unless (< (+ 2 current-index) end-invocation-index) |
|
|
|
(ErrorAtToken invocation-token "missing name argument") |
|
|
|
(return false)) |
|
|
|
(var type-name-token (& (const Token)) (at (+ 2 current-index) tokens)) |
|
|
|
(unless (ExpectTokenType "forward-declare" type-name-token TokenType_Symbol) |
|
|
|
(return false)) |
|
|
|
(addStringOutput output-dest (field invocation-token contents) |
|
|
|
StringOutMod_SpaceAfter (addr invocation-token)) |
|
|
|
(addStringOutput output-dest (field type-name-token contents) |
|
|
|
StringOutMod_None (addr type-name-token)) |
|
|
|
(addLangTokenOutput output-dest StringOutMod_EndStatement (addr type-name-token))) |
|
|
|
(true |
|
|
|
(ErrorAtToken invocation-token "unknown forward-declare type") |
|
|
|
(return false)))) |
|
|
|
|
|
|
|
(when (= TokenType_CloseParen (field current-token type)) |
|
|
|
(for-in close-block-index int namespace-stack |
|
|
|
(when (= close-block-index current-index) |
|
|
|
(addLangTokenOutput output-dest StringOutMod_CloseBlock |
|
|
|
(addr (at current-index tokens)))))) |
|
|
|
;; TODO: Support function calls so we can do this recursively |
|
|
|
;; (set current-index |
|
|
|
;; (getNextArgument tokens current-index end-invocation-index)) |
|
|
|
(incr current-index)) |
|
|
|
(return true)) |
|
|
|