Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

initial commit

  • Loading branch information...
commit 4c7da80bbf3ceded7556fb29584b40dc8220dea8 1 parent f433801
@core-code authored
Showing with 40,031 additions and 0 deletions.
  1. +51 −0 Audio/MusicManager.h
  2. +331 −0 Audio/MusicManager.mm
  3. +127 −0 Audio/Scene+Sound.mm
  4. +157 −0 Audio/SceneNode+Sound.mm
  5. +26 −0 Audio/SoundBuffer.h
  6. +295 −0 Audio/SoundBuffer.mm
  7. +41 −0 CoreEngine/Camera.h
  8. +181 −0 CoreEngine/Camera.mm
  9. +30 −0 CoreEngine/FBO.h
  10. +182 −0 CoreEngine/FBO.mm
  11. +25 −0 CoreEngine/Light.h
  12. +34 −0 CoreEngine/Light.mm
  13. +92 −0 CoreEngine/Mesh.h
  14. +531 −0 CoreEngine/Mesh.mm
  15. +61 −0 CoreEngine/RenderPass.h
  16. +286 −0 CoreEngine/RenderPass.mm
  17. +31 −0 CoreEngine/RenderTarget.h
  18. +90 −0 CoreEngine/RenderTarget.mm
  19. +54 −0 CoreEngine/Scene.h
  20. +454 −0 CoreEngine/Scene.mm
  21. +64 −0 CoreEngine/SceneNode.h
  22. +315 −0 CoreEngine/SceneNode.mm
  23. +50 −0 CoreEngine/Shader.h
  24. +551 −0 CoreEngine/Shader.mm
  25. +35 −0 CoreEngine/ShaderNode.h
  26. +45 −0 CoreEngine/ShaderNode.mm
  27. +61 −0 CoreEngine/Simulation.h
  28. +294 −0 CoreEngine/Simulation.mm
  29. +74 −0 CoreEngine/Texture.h
  30. +583 −0 CoreEngine/Texture.mm
  31. +38 −0 CoreEngine/VBO.h
  32. +141 −0 CoreEngine/VBO.mm
  33. +41 −0 Editor/Editor.h
  34. +694 −0 Editor/Editor.mm
  35. +32 −0 Editor/Editorsimulation.h
  36. +197 −0 Editor/Editorsimulation.mm
  37. +1,325 −0 Editor/en.lproj/Editor.xib
  38. +5 −0 LICENSE.txt
  39. +92 −0 PlatformSupport/MacRenderViewController.h
  40. +641 −0 PlatformSupport/MacRenderViewController.mm
  41. +51 −0 PlatformSupport/PortableRenderViewController.h
  42. +325 −0 PlatformSupport/PortableRenderViewController.mm
  43. +25 −0 PlatformSupport/SDLRenderViewController.h
  44. +374 −0 PlatformSupport/SDLRenderViewController.mm
  45. +104 −0 PlatformSupport/iOS_EAGL2View.h
  46. +496 −0 PlatformSupport/iOS_EAGL2View.mm
  47. +207 −0 Preprocessing/generateOctreeFromObj.py
  48. +58 −0 Preprocessing/generateOctreeFromObj.rb
  49. +213 −0 Preprocessing/generatePathFromObj.py
  50. +46 −0 Preprocessing/vecmath.py
  51. BIN  Preprocessing/vecmath.pyc
  52. +62 −0 Preprocessing/vecmath.rb
  53. +9 −0 Shaders/color.frag
  54. +13 −0 Shaders/color.vert
  55. +6 −0 Shaders/depthonly.frag
  56. +13 −0 Shaders/depthonly.vert
  57. +39 −0 Shaders/phong.frag
  58. +28 −0 Shaders/phong.vert
  59. +22 −0 Shaders/pointsprite.frag
  60. +32 −0 Shaders/pointsprite.vert
  61. +27 −0 Shaders/texture.frag
  62. +21 −0 Shaders/texture.vert
  63. +29 −0 SpecialNodes/BatchingTextureNode.h
  64. +76 −0 SpecialNodes/BatchingTextureNode.mm
  65. +36 −0 SpecialNodes/CollideableMesh.h
  66. +1,135 −0 SpecialNodes/CollideableMesh.mm
  67. +38 −0 SpecialNodes/CollideableMeshBullet.h
  68. +409 −0 SpecialNodes/CollideableMeshBullet.mm
  69. +27 −0 SpecialNodes/CollideableSceneNode.h
  70. +277 −0 SpecialNodes/CollideableSceneNode.mm
  71. +23 −0 SpecialNodes/DynamicNode.h
  72. +98 −0 SpecialNodes/DynamicNode.mm
  73. +17 −0 SpecialNodes/FocusingCamera.h
  74. +104 −0 SpecialNodes/FocusingCamera.mm
  75. +19 −0 SpecialNodes/LODNode.h
  76. +67 −0 SpecialNodes/LODNode.mm
  77. +14 −0 SpecialNodes/OutlineShader.h
  78. +57 −0 SpecialNodes/OutlineShader.mm
  79. +17 −0 SpecialNodes/PVSNode.h
  80. +372 −0 SpecialNodes/PVSNode.mm
  81. +17 −0 SpecialNodes/Particlesystems/FireParticlesystem.h
  82. +80 −0 SpecialNodes/Particlesystems/FireParticlesystem.mm
  83. +39 −0 SpecialNodes/Particlesystems/Particlesystem.h
  84. +153 −0 SpecialNodes/Particlesystems/Particlesystem.mm
  85. +18 −0 SpecialNodes/Particlesystems/SnowParticlesystem.h
  86. +76 −0 SpecialNodes/Particlesystems/SnowParticlesystem.mm
  87. +17 −0 SpecialNodes/Particlesystems/SphereParticlesystem.h
  88. +67 −0 SpecialNodes/Particlesystems/SphereParticlesystem.mm
  89. +21 −0 SpecialNodes/PathNode.h
  90. +72 −0 SpecialNodes/PathNode.mm
  91. +19 −0 SpecialNodes/QCNode.h
  92. +51 −0 SpecialNodes/QCNode.mm
  93. +16 −0 SpecialNodes/ShadowShader.h
  94. +49 −0 SpecialNodes/ShadowShader.mm
  95. +24 −0 SpecialNodes/Skybox.h
  96. +170 −0 SpecialNodes/Skybox.mm
  97. +25 −0 SpecialNodes/SpriteNode.h
  98. +83 −0 SpecialNodes/SpriteNode.mm
  99. +230 −0 Utilities/Core3D.h
  100. +503 −0 Utilities/Core3D_Prefix.pch
  101. +38 −0 Utilities/StateUtilities.h
  102. +405 −0 Utilities/StateUtilities.mm
  103. +31 −0 Utilities/Utilities.h
  104. +449 −0 Utilities/Utilities.mm
  105. +177 −0 Utilities/opengl_linux.cpp
  106. +50 −0 Utilities/opengl_linux.h
  107. +175 −0 Utilities/opengl_win32.cpp
  108. +52 −0 Utilities/opengl_win32.h
  109. +724 −0 _DEPENDENCIES/headers/AL/al.h
  110. +277 −0 _DEPENDENCIES/headers/AL/alc.h
  111. +165 −0 _DEPENDENCIES/headers/AL/alext.h
  112. +126 −0 _DEPENDENCIES/headers/AL/alut.h
  113. +3 −0  _DEPENDENCIES/headers/AL/efx-creative.h
  114. +758 −0 _DEPENDENCIES/headers/AL/efx.h
  115. +101 −0 _DEPENDENCIES/headers/SDL/SDL.h
  116. +63 −0 _DEPENDENCIES/headers/SDL/SDL_active.h
  117. +284 −0 _DEPENDENCIES/headers/SDL/SDL_audio.h
  118. +29 −0 _DEPENDENCIES/headers/SDL/SDL_byteorder.h
  119. +202 −0 _DEPENDENCIES/headers/SDL/SDL_cdrom.h
  120. +311 −0 _DEPENDENCIES/headers/SDL/SDL_config.h
  121. +22 −0 _DEPENDENCIES/headers/SDL/SDL_copying.h
  122. +69 −0 _DEPENDENCIES/headers/SDL/SDL_cpuinfo.h
  123. +209 −0 _DEPENDENCIES/headers/SDL/SDL_endian.h
  124. +72 −0 _DEPENDENCIES/headers/SDL/SDL_error.h
  125. +356 −0 _DEPENDENCIES/headers/SDL/SDL_events.h
  126. +28 −0 _DEPENDENCIES/headers/SDL/SDL_getenv.h
  127. +187 −0 _DEPENDENCIES/headers/SDL/SDL_joystick.h
  128. +135 −0 _DEPENDENCIES/headers/SDL/SDL_keyboard.h
  129. +326 −0 _DEPENDENCIES/headers/SDL/SDL_keysym.h
  130. +78 −0 _DEPENDENCIES/headers/SDL/SDL_loadso.h
  131. +106 −0 _DEPENDENCIES/headers/SDL/SDL_main.h
  132. +143 −0 _DEPENDENCIES/headers/SDL/SDL_mouse.h
  133. +177 −0 _DEPENDENCIES/headers/SDL/SDL_mutex.h
  134. +11 −0 _DEPENDENCIES/headers/SDL/SDL_name.h
  135. +6,556 −0 _DEPENDENCIES/headers/SDL/SDL_opengl.h
  136. +110 −0 _DEPENDENCIES/headers/SDL/SDL_platform.h
  137. +55 −0 _DEPENDENCIES/headers/SDL/SDL_quit.h
  138. +155 −0 _DEPENDENCIES/headers/SDL/SDL_rwops.h
  139. +620 −0 _DEPENDENCIES/headers/SDL/SDL_stdinc.h
  140. +225 −0 _DEPENDENCIES/headers/SDL/SDL_syswm.h
  141. +120 −0 _DEPENDENCIES/headers/SDL/SDL_thread.h
  142. +125 −0 _DEPENDENCIES/headers/SDL/SDL_timer.h
  143. +28 −0 _DEPENDENCIES/headers/SDL/SDL_types.h
  144. +91 −0 _DEPENDENCIES/headers/SDL/SDL_version.h
  145. +951 −0 _DEPENDENCIES/headers/SDL/SDL_video.h
  146. +191 −0 _DEPENDENCIES/headers/SDL/begin_code.h
  147. +46 −0 _DEPENDENCIES/headers/SDL/close_code.h
  148. +625 −0 _DEPENDENCIES/headers/SDL_mixer/SDL_mixer.h
  149. +528 −0 _DEPENDENCIES/headers/freetype/include/freetype/config/ftconfig.h
  150. +780 −0 _DEPENDENCIES/headers/freetype/include/freetype/config/ftheader.h
  151. +32 −0 _DEPENDENCIES/headers/freetype/include/freetype/config/ftmodule.h
  152. +733 −0 _DEPENDENCIES/headers/freetype/include/freetype/config/ftoption.h
  153. +173 −0 _DEPENDENCIES/headers/freetype/include/freetype/config/ftstdlib.h
  154. +3,919 −0 _DEPENDENCIES/headers/freetype/include/freetype/freetype.h
  155. +179 −0 _DEPENDENCIES/headers/freetype/include/freetype/ftadvanc.h
  156. +94 −0 _DEPENDENCIES/headers/freetype/include/freetype/ftbbox.h
  157. +209 −0 _DEPENDENCIES/headers/freetype/include/freetype/ftbdf.h
  158. +227 −0 _DEPENDENCIES/headers/freetype/include/freetype/ftbitmap.h
  159. +1,128 −0 _DEPENDENCIES/headers/freetype/include/freetype/ftcache.h
  160. +103 −0 _DEPENDENCIES/headers/freetype/include/freetype/ftchapters.h
  161. +166 −0 _DEPENDENCIES/headers/freetype/include/freetype/ftcid.h
  162. +244 −0 _DEPENDENCIES/headers/freetype/include/freetype/fterrdef.h
  163. +206 −0 _DEPENDENCIES/headers/freetype/include/freetype/fterrors.h
Sorry, we could not display the entire diff because too many files (1,855) changed.
View
51 Audio/MusicManager.h
@@ -0,0 +1,51 @@
+//
+// MusicManager.h
+// Core3D
+//
+// Created by CoreCode on 08.09.11
+// Copyright 2011 - 2012 CoreCode. Licensed under the MIT License, see LICENSE.txt
+//
+
+#ifndef __BLOCKS__
+#define StringInBlock id
+#endif
+
+
+#ifdef TARGET_OS_IPHONE
+#import <AVFoundation/AVAudioPlayer.h>
+
+
+#elif defined(TARGET_OS_MAC)
+#import <QTKit/QTMovie.h>
+#endif
+
+@interface MusicManager : NSObject
+#ifdef TARGET_OS_IPHONE
+ <AVAudioPlayerDelegate>
+#endif
+{
+#ifndef DISABLE_SOUND
+ StringInBlock songChangeBlock;
+ NSMutableArray *songs;
+
+
+#if defined(SDL)
+ Mix_Music *music;
+//#elif defined(GNUSTEP)
+// NSSound *currentSong;
+//#elif defined(__COCOTRON__)
+#elif defined(TARGET_OS_MAC)
+ QTMovie *currentSong;
+#elif defined(TARGET_OS_IPHONE)
+ AVAudioPlayer *currentSong;
+#endif
+#endif
+}
+
+- (id)initWithSongs:(NSArray *)_songs andSongChangeBlock:(StringInBlock)_songChangeBlock;
+- (void)startPlayingWithDelay:(float)delay;
+- (void)playSongInBackground;
+- (void)pauseMusic;
+- (void)unpauseMusic;
+
+@end
View
331 Audio/MusicManager.mm
@@ -0,0 +1,331 @@
+//
+// MusicManager.mm
+// Core3D
+//
+// Created by CoreCode on 08.09.11
+// Copyright 2011 - 2012 CoreCode. Licensed under the MIT License, see LICENSE.txt
+//
+
+#import "Core3D.h"
+
+
+MusicManager *mm = NULL;
+
+void musicDone();
+
+@implementation MusicManager
+
+- (id)initWithSongs:(NSArray *)_songs andSongChangeBlock:(StringInBlock)_songChangeBlock
+{
+ if ((self = [super init]))
+ {
+ mm = self;
+ songs = [[NSMutableArray alloc] initWithArray:_songs];
+ songChangeBlock = [_songChangeBlock copy];
+
+#ifdef TARGET_OS_MAC
+ [(NSNotificationCenter *)[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playSongInBackground) name:QTMovieDidEndNotification object:nil];
+#endif
+
+ [self startPlayingWithDelay:3.0];
+ }
+
+ return self;
+}
+
+- (NSString *)cleanFilename:(NSString *)filename
+{
+ NSString *ret = [filename stringByReplacingOccurrencesOfString:@" " withString:@"_"];
+ ret = [ret stringByReplacingOccurrencesOfString:@"*" withString:@"_"];
+ ret = [ret stringByReplacingOccurrencesOfString:@"'" withString:@"_"];
+ ret = [ret stringByReplacingOccurrencesOfString:@"(" withString:@"_"];
+ ret = [ret stringByReplacingOccurrencesOfString:@")" withString:@"_"];
+
+ return ret;
+}
+
+#ifdef SDL
+
+- (void)playSongInBackground
+{
+
+ if (music)
+ {
+ //NSLog(@"music, halting and freeing");
+
+ Mix_HaltMusic();
+ Mix_FreeMusic(music);
+ music = NULL;
+ }
+
+ if ([songs count])
+ {
+
+ NSString *song = [songs objectAtIndex:cml::random_integer(0, [songs count]-1)];
+
+
+ //NSLog(@"Info: playing song %@ %s", song, [[[NSBundle mainBundle] pathForResource:[self cleanFilename:song] ofType:@"ogg"] fileSystemRepresentation]);
+
+
+ /* Actually loads up the music */
+ music = Mix_LoadMUS([[[NSBundle mainBundle] pathForResource:[self cleanFilename:song] ofType:@"ogg"] fileSystemRepresentation]);
+
+ /* This begins playing the music - the first argument is a
+ pointer to Mix_Music structure, and the second is how many
+ times you want it to loop (use -1 for infinite, and 0 to
+ have it just play once) */
+ Mix_PlayMusic(music, 0);
+
+ /* We want to know when our music has stopped playing so we
+ can free it up and set 'music' back to NULL. SDL_Mixer
+ provides us with a callback routine we can use to do
+ exactly that */
+ Mix_HookMusicFinished(musicDone);
+
+ Mix_VolumeMusic(MIX_MAX_VOLUME * $defaultf(kMusicVolumeKey));
+ // NSLog(@"Setting music volume to %i %f %i", MIX_MAX_VOLUME, $defaultf(kMusicVolumeKey), MIX_MAX_VOLUME * $defaultf(kMusicVolumeKey));
+
+
+
+ [songs removeObject:song];
+
+
+
+ songChangeBlock(song);
+ }
+
+}
+
+- (void)pauseMusic
+{
+ Mix_PauseMusic();
+}
+
+- (void)unpauseMusic
+{
+ Mix_ResumeMusic();
+}
+
+//#elif defined(GNUSTEP)
+//
+//- (void)playSongInBackground
+//{
+// [currentSong setDelegate:nil];
+// [currentSong release];
+// currentSong = nil;
+//
+//
+// if ([songs count])
+// {
+//
+// NSString *song = [songs objectAtIndex:cml::random_integer(0, [songs count]-1)];
+//
+// NSLog(@"playing song %@", song);
+// currentSong = [[NSSound alloc] initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:[self cleanFilename:song] withExtension:@"ogg"] byReference: NO];
+//
+//
+// [currentSong setVolume:$defaultf(kMusicVolumeKey)];
+// [currentSong play];
+// [songs removeObject:song];
+//
+// [currentSong setDelegate:self];
+//
+//
+//
+// songChangeBlock(song);
+// }
+//
+//}
+//
+//- (void)sound:(NSSound *)sound didFinishPlaying:(BOOL)finishedPlaying
+//{
+// [self playSongInBackground];
+//}
+//
+//- (void)pauseMusic
+//{
+// [currentSong pause];
+//}
+//
+//- (void)unpauseMusic
+//{
+// [currentSong play];
+//}
+//
+//#elif defined(__COCOTRON__)
+
+#elif defined(TARGET_OS_IPHONE)
+
+- (void)playSong
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ // NSLog(@"waiting to playSong");
+ @synchronized (scene)
+ {
+ // NSLog(@"playSong");
+ [currentSong release];
+ currentSong = nil;
+
+
+ if ([songs count])
+ {
+
+ NSString *song = [songs objectAtIndex:(NSUInteger) cml::random_integer(0, [songs count] - 1)];
+
+ // NSLog(@"playing song %@", song);
+ currentSong = [[AVAudioPlayer alloc] initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:[self cleanFilename:song] withExtension:@"aac"] error:nil];
+ [currentSong setVolume:$defaultf(kMusicVolumeKey)];
+ [currentSong play];
+ [currentSong setDelegate:self];
+ [songs removeObject:song];
+
+
+
+ songChangeBlock(song);
+ }
+ // else
+ // NSLog(@"no song anymore");
+
+ // TODO: test memory
+
+ }
+ // NSLog(@"end song sync");
+
+ [pool release];
+}
+
+- (void)playSongInBackground
+{
+ // NSLog(@"playSongInBackground");
+ // [self performSelectorInBackground:@selector(playSongReal) withObject:nil];
+
+ dispatch_async(dispatch_get_global_queue(0, 0), ^
+ {[self playSong];});
+}
+
+- (void)pauseMusic
+{
+ [currentSong pause];
+}
+
+- (void)unpauseMusic
+{
+ [currentSong play];
+}
+
+- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
+{
+ [self playSongInBackground];
+}
+
+#elif defined(TARGET_OS_MAC)
+
+
+
+- (void)playSong
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ // NSLog(@"waiting to playSong");
+ @synchronized(scene)
+ {
+ // NSLog(@"playSong");
+ [currentSong release];
+ currentSong = nil;
+
+
+ if ([songs count])
+ {
+
+ NSString *song = [songs objectAtIndex:cml::random_integer(0, [songs count]-1)];
+
+ // NSLog(@"playing song %@", song);
+ currentSong = [[QTMovie alloc] initWithURL:[[NSBundle mainBundle] URLForResource:[self cleanFilename:song] withExtension:@"aac"] error:nil];
+ [currentSong setVolume:$defaultf(kMusicVolumeKey)];
+ [currentSong play];
+ [songs removeObject:song];
+ NSTimeInterval timeInterval;
+ QTGetTimeInterval([currentSong duration], &timeInterval);
+ // NSLog(@"scheduling next song for %f", timeInterval);
+
+
+
+ songChangeBlock(song);
+ }
+ // else
+ // NSLog(@"no song anymore");
+
+ // TODO: test memory
+
+ }
+ // NSLog(@"end song sync");
+
+ [pool release];
+}
+
+- (void)playSongInBackground
+{
+ // NSLog(@"playSongInBackground");
+ // [self performSelectorInBackground:@selector(playSongReal) withObject:nil];
+
+ dispatch_async(dispatch_get_global_queue(0, 0), ^{ [self playSong]; });
+}
+
+- (void)pauseMusic
+{
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+ [currentSong stop];
+}
+
+- (void)unpauseMusic
+{
+ [(NSNotificationCenter *)[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playSongInBackground) name:QTMovieDidEndNotification object:nil];
+ [currentSong play];
+}
+
+#endif
+
+
+- (void)startPlayingWithDelay:(float)delay
+{
+#ifdef __BLOCKS__
+ [[scene simulator] performBlockAfterDelay:delay block:^
+ {[self playSongInBackground];}];
+#endif
+}
+
+- (void)dealloc
+{
+ //NSLog(@"music manager dealloc");
+ [songs release];
+
+#ifdef TARGET_OS_MAC
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+#endif
+
+ @synchronized (scene)
+ {
+#ifdef SDL
+ Mix_HaltMusic();
+ Mix_FreeMusic(music);
+ music = NULL;
+#else
+ [currentSong release];
+ currentSong = nil;
+#endif
+ }
+ [super dealloc];
+ mm = NULL;
+}
+@end
+
+#ifdef SDL
+void musicDone()
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ [mm startPlayingWithDelay:0.1f];
+
+ [pool release];
+}
+#endif
View
127 Audio/Scene+Sound.mm
@@ -0,0 +1,127 @@
+//
+// Scene+Sound.m
+// Core3D
+//
+// Created by CoreCode on 16.11.07.
+// Copyright 2007 - 2012 CoreCode. Licensed under the MIT License, see LICENSE.txt
+//
+
+#ifndef DISABLE_SOUND
+
+#import "Core3D.h"
+
+
+#ifdef ALUT
+#include <AL/alut.h>
+#endif
+extern int soundNodes;
+
+@implementation Scene (Sound)
+
+- (void)initSound
+{
+//#ifdef __APPLE__SHIT
+//
+ ALCcontext *newContext = NULL;
+ ALCdevice *newDevice = NULL;
+
+ // Create a new OpenAL Device
+ // Pass NULL to specify the system’s default output device
+ newDevice = alcOpenDevice(NULL);
+ if (newDevice != NULL)
+ {
+ // Create a new OpenAL Context
+ // The new context will render to the OpenAL Device just created
+ newContext = alcCreateContext(newDevice, 0);
+ if (newContext != NULL)
+ {
+ // Make the new context the Current OpenAL Context
+ alcMakeContextCurrent(newContext);
+ }
+ }
+
+ alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
+
+ int error = alGetError();
+ if (error != AL_NO_ERROR)
+ fatal("initSound alError %i", error);
+
+ error = alcGetError(newDevice);
+ if (error)
+ fatal("alcError %i", error);
+
+#ifdef ALUT
+ static BOOL alutInited = FALSE;
+ if (!alutInited)
+ {
+ if (!alutInitWithoutContext(0, NULL))
+ NSLog(@"alutInit error %i", alutGetError());
+ alutInited = TRUE;
+ }
+#endif
+//#else
+// static BOOL inited = FALSE;
+//
+// if (inited) return;
+//
+// inited = TRUE;
+// if (!alutInit(0, NULL))
+// {
+// printf("alutInit error %li", (long)alutGetError);
+// }
+//#endif
+ alListenerfv(AL_VELOCITY, vector3f(0, 0, 0).data());
+ alListenerf(AL_GAIN, globalSettings.soundVolume);
+}
+
+- (void)deallocSound
+{
+ @synchronized (self)
+ {
+ // NSLog(@"dealloc sound");
+ ALCcontext *context = NULL;
+ ALCdevice *device = NULL;
+
+
+
+ //Get active context
+ context = alcGetCurrentContext();
+
+
+
+ //Get device for active context
+ device = alcGetContextsDevice(context);
+
+
+
+ alcMakeContextCurrent(NULL);
+
+
+
+ //Release context
+ alcDestroyContext(context);
+
+
+
+ //Close device
+ alcCloseDevice(device);
+
+#ifdef __APPLE__
+ int error = alGetError();
+ if (error != AL_NO_ERROR)
+ {
+ NSLog(@"Error: Scene+Sound dealloc: alError %i soundNodes %i soundBuffers %@", error, soundNodes, [[SoundBuffer allBuffers] description]);
+ }
+#endif
+
+//#ifdef ALUT
+// NSLog(@"alutExit");
+// if (!alutExit())
+// NSLog(@"alutExit error %li", (long)alutGetError);
+//#endif
+ }
+}
+
+@end
+
+#endif
View
157 Audio/SceneNode+Sound.mm
@@ -0,0 +1,157 @@
+//
+// SceneNode+Sound.m
+// Core3D
+//
+// Created by CoreCode on 16.11.07.
+// Copyright 2007 - 2012 CoreCode. Licensed under the MIT License, see LICENSE.txt
+//
+
+
+#import "Core3D.h"
+
+
+int soundNodes;
+
+@implementation SceneNode (Sound)
+
+- (void)attachSoundNamed:(NSString *)n
+{
+#ifndef DISABLE_SOUND
+ if (globalSettings.soundEnabled)
+ {
+
+ [self deallocSound];
+
+ buffer = [SoundBuffer newSoundBufferNamed:n];
+
+ // Create some OpenAL Source Objects
+ alGenSources(1, &source);
+ soundNodes++;
+ if (alGetError() != AL_NO_ERROR)
+ fatal("Error generating sources! \n");
+
+ if (!source)
+ fatal("Error generating sources null! \n");
+ {
+ ALenum error = AL_NO_ERROR;
+
+ {
+ // Set Source Position
+ alSourcefv(source, AL_POSITION, position.data());
+
+ alSourcef(source, AL_REFERENCE_DISTANCE, 10.0f);
+
+ alSourcef(source, AL_MAX_DISTANCE, 800.0f);
+
+ alSourcef(source, AL_ROLLOFF_FACTOR, 0.3f);
+
+ alSourcef(source, AL_GAIN, 1.0f);
+
+ alSourcei(source, AL_BUFFER, buffer.buffer);
+ }
+
+ if ((error = alGetError()) != AL_NO_ERROR)
+ fatal("Error attaching buffer to source");
+ }
+ }
+#endif
+}
+
+- (void)setProperty:(int)property toValue:(float)value
+{
+#ifndef DISABLE_SOUND
+ if (source && globalSettings.soundEnabled)
+ alSourcef(source, property, value);
+#endif
+}
+
+- (void)updateSound
+{
+#ifndef DISABLE_SOUND
+ if (source && globalSettings.soundEnabled)
+ alSourcefv(source, AL_POSITION, position.data());
+#endif
+}
+
+- (void)setVolume:(float)inVolume
+{
+#ifndef DISABLE_SOUND
+ if (source && globalSettings.soundEnabled)
+ alSourcef(source, AL_GAIN, inVolume);
+#endif
+}
+
+- (void)setPitch:(float)inPitch
+{
+// if (source) cout << inPitch << endl;
+#ifndef DISABLE_SOUND
+ if (source && globalSettings.soundEnabled)
+ alSourcef(source, AL_PITCH, inPitch);
+#endif
+}
+
+- (void)setLooping:(BOOL)looping
+{
+#ifndef DISABLE_SOUND
+ if (source && globalSettings.soundEnabled)
+ alSourcei(source, AL_LOOPING, looping ? AL_TRUE : AL_FALSE);
+#endif
+}
+
+- (BOOL)isPlaying
+{
+#ifndef DISABLE_SOUND
+ if (source && globalSettings.soundEnabled)
+ {
+ ALint val;
+ alGetSourcei(source, AL_SOURCE_STATE, &val);
+ return (val == AL_PLAYING);
+ }
+ else
+ return NO;
+#endif
+}
+
+- (void)playSound
+{
+#ifndef DISABLE_SOUND
+ if (source && globalSettings.soundEnabled)
+ alSourcePlay(source);
+#endif
+}
+
+- (void)stopSound
+{
+#ifndef DISABLE_SOUND
+ if (source && globalSettings.soundEnabled)
+ alSourceStop(source);
+#endif
+}
+
+- (void)rewindSound
+{
+#ifndef DISABLE_SOUND
+ if (source && globalSettings.soundEnabled)
+ alSourceRewind(source);
+#endif
+}
+
+- (void)pauseSound
+{
+#ifndef DISABLE_SOUND
+ if (source && globalSettings.soundEnabled)
+ alSourcePause(source);
+#endif
+}
+
+- (void)deallocSound
+{
+#ifndef DISABLE_SOUND
+ if (source)
+ alDeleteSources(1, &source);
+ if (source)
+ soundNodes--;
+ [buffer release];
+#endif
+}
+@end
View
26 Audio/SoundBuffer.h
@@ -0,0 +1,26 @@
+//
+// SoundBuffer.h
+// Core3D
+//
+// Created by CoreCode on 25.05.11
+// Copyright 2011 - 2012 CoreCode. Licensed under the MIT License, see LICENSE.txt
+//
+
+@interface SoundBuffer : NSObject
+{
+
+ NSString *name;
+#ifndef DISABLE_SOUND
+ ALuint buffer;
+#endif
+}
+
++ (SoundBuffer *)newSoundBufferNamed:(NSString *)_name;
+- (SoundBuffer *)initWithContentsOfURL:(NSURL *)_url;
++ (NSArray *)allBuffers;
+
+@property (nonatomic, copy) NSString *name;
+#ifndef DISABLE_SOUND
+@property (nonatomic, readonly) ALuint buffer;
+#endif
+@end
View
295 Audio/SoundBuffer.mm
@@ -0,0 +1,295 @@
+//
+// SoundBuffer.mm
+// Core3D
+//
+// Created by CoreCode on 25.05.11
+// Copyright 2011 - 2012 CoreCode. Licensed under the MIT License, see LICENSE.txt
+//
+
+#import "Core3D.h"
+#import "Texture.h"
+
+
+#ifndef DISABLE_SOUND
+
+#ifdef ALUT
+ #include <AL/alut.h>
+#else
+#include <AudioToolbox/AudioToolbox.h>
+
+
+#endif
+
+#endif
+
+
+MutableDictionary *namedBuffers;
+
+
+#ifdef __APPLE__
+#ifndef DISABLE_SOUND
+#ifndef ALUT
+void *MyGetOpenALAudioData(CFURLRef inFileURL, ALsizei *outDataSize, ALenum *outDataFormat, ALsizei *outSampleRate);
+#endif
+#endif
+#endif
+
+@implementation SoundBuffer
+#ifndef DISABLE_SOUND
+
+@synthesize name, buffer;
+#else
+@synthesize name;
+#endif
+
++ (void)initialize
+{
+ if (!namedBuffers)
+ namedBuffers = new MutableDictionary;
+}
+
++ (NSArray *)allBuffers
+{
+ NSMutableArray *buffers = [NSMutableArray array];
+
+ MutableDictionary::const_iterator end = namedBuffers->end();
+ for (MutableDictionary::const_iterator it = namedBuffers->begin(); it != end; ++it)
+ [buffers addObject:it->second];
+
+
+ return buffers;
+}
+
++ (SoundBuffer *)newSoundBufferNamed:(NSString *)_name
+{
+ if (namedBuffers->count([_name UTF8String]))
+ {
+ SoundBuffer *cachedBuffer = (*namedBuffers)[[_name UTF8String]];
+
+ assert(cachedBuffer);
+
+ return [cachedBuffer retain];
+ }
+
+ for (NSString *ext in SND_EXTENSIONS)
+ {
+ NSURL *url = [[NSBundle mainBundle] URLForResource:_name withExtension:ext];
+ if (url)
+ {
+ SoundBuffer *snd = [(SoundBuffer *) [self alloc] initWithContentsOfURL:url];
+ (*namedBuffers)[[_name UTF8String]] = snd;
+
+ [snd setName:_name];
+ return snd;
+ }
+ }
+
+ NSLog(@"Warning: could not find sound named: %@", _name);
+
+ return nil;
+}
+
+- (SoundBuffer *)initWithContentsOfURL:(NSURL *)_url
+{
+ if ((self = [self init]))
+ {
+#ifndef DISABLE_SOUND
+#ifndef ALUT
+ // Create some OpenAL Buffer Objects
+ alGenBuffers(1, &buffer);
+ if (alGetError() != AL_NO_ERROR)
+ fatal("Error Generating Buffers: ");
+
+
+ {
+ ALenum error = AL_NO_ERROR;
+ ALenum format;
+ ALvoid *data;
+ ALsizei size;
+ ALsizei freq;
+
+
+ // get some audio data from a wave file
+ data = MyGetOpenALAudioData((CFURLRef) _url, &size, &format, &freq);
+
+ if (format != AL_FORMAT_MONO16)
+ {
+ NSDebugLog(@"Warning: audio file stereo, won't be 3D: %@", [[_url path] lastPathComponent]);
+ }
+
+ if ((error = alGetError()) != AL_NO_ERROR)
+ fatal("error loading %s: ", [[_url absoluteString] UTF8String]);
+
+
+ // Attach Audio Data to OpenAL Buffer
+ alBufferData(buffer, format, data, size, freq);
+
+ // Release the audio data
+ free(data);
+
+ if ((error = alGetError()) != AL_NO_ERROR)
+ printf("error unloading %s: ", [[_url absoluteString] UTF8String]);
+ }
+#else
+ NSString *p = [_url path];
+
+#ifdef WIN32
+ if ([p hasPrefix:@"/"]) p = [p substringFromIndex:1];
+ p = [p stringByReplacingOccurrencesOfString:@"/" withString:@"\\"];
+#endif
+ ALenum error = AL_NO_ERROR;
+ buffer = alutCreateBufferFromFile([p UTF8String]);
+
+
+ if ((error = alGetError()) != AL_NO_ERROR)
+ fatal("error loading %s: ", [p UTF8String]);
+
+ if (!buffer)
+ fatal("error loading no buffer %s: ", [p UTF8String]);
+
+#endif
+#endif
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ if (name)
+ {
+ namedBuffers->erase([name UTF8String]);
+ // NSLog(@"buf release %@", name );
+ }
+
+ [name release];
+
+#ifndef DISABLE_SOUND
+
+ int error = alGetError();
+ if (error != AL_NO_ERROR)
+ fatal("pre bufrel alError %i %i", error, buffer);
+
+ if (buffer)
+ alDeleteBuffers(1, &buffer);
+
+ error = alGetError();
+ if (error != AL_NO_ERROR)
+ fatal("bufrel alError %i %i", error, buffer);
+#endif
+
+ [super dealloc];
+}
+@end
+
+
+#ifndef DISABLE_SOUND
+#ifndef ALUT
+void *MyGetOpenALAudioData(CFURLRef inFileURL, ALsizei *outDataSize, ALenum *outDataFormat, ALsizei *outSampleRate)
+{
+ OSStatus err = noErr;
+ SInt64 theFileLengthInFrames = 0;
+ AudioStreamBasicDescription theFileFormat;
+ UInt32 thePropertySize = sizeof(theFileFormat);
+ ExtAudioFileRef extRef = NULL;
+ void *theData = NULL;
+ AudioStreamBasicDescription theOutputFormat;
+
+ // Open a file with ExtAudioFileOpen()
+ err = ExtAudioFileOpenURL(inFileURL, &extRef);
+ if (err)
+ {
+ printf("MyGetOpenALAudioData: ExtAudioFileOpenURL FAILED, Error = %ld\n", (long int) err);
+ if (extRef) ExtAudioFileDispose(extRef);
+ return theData;
+ }
+
+ // Get the audio data format
+ err = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &theFileFormat);
+ if (err)
+ {
+ printf("MyGetOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_FileDataFormat) FAILED, Error = %ld\n", (long int) err);
+ if (extRef) ExtAudioFileDispose(extRef);
+ return theData;
+ }
+ if (theFileFormat.mChannelsPerFrame > 2)
+ {
+ printf("MyGetOpenALAudioData - Unsupported Format, channel count is greater than stereo\n");
+ if (extRef) ExtAudioFileDispose(extRef);
+ return theData;
+ }
+#ifdef TARGET_OS_MAC
+#warning this code produces clicks at least on macos
+#endif
+ // Set the client format to 16 bit signed integer (native-endian) data
+ // Maintain the channel count and sample rate of the original source format
+ theOutputFormat.mSampleRate = theFileFormat.mSampleRate;
+ theOutputFormat.mChannelsPerFrame = theFileFormat.mChannelsPerFrame;
+
+ theOutputFormat.mFormatID = kAudioFormatLinearPCM;
+ theOutputFormat.mBytesPerPacket = 2 * theOutputFormat.mChannelsPerFrame;
+ theOutputFormat.mFramesPerPacket = 1;
+ theOutputFormat.mBytesPerFrame = 2 * theOutputFormat.mChannelsPerFrame;
+ theOutputFormat.mBitsPerChannel = 16;
+ theOutputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;
+
+ // Set the desired client (output) data format
+ err = ExtAudioFileSetProperty(extRef, kExtAudioFileProperty_ClientDataFormat, sizeof(theOutputFormat), &theOutputFormat);
+ if (err)
+ {
+ printf("MyGetOpenALAudioData: ExtAudioFileSetProperty(kExtAudioFileProperty_ClientDataFormat) FAILED, Error = %ld\n", (long int) err);
+ if (extRef) ExtAudioFileDispose(extRef);
+ return theData;
+ }
+
+ // Get the total frame count
+ thePropertySize = sizeof(theFileLengthInFrames);
+ err = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileLengthFrames, &thePropertySize, &theFileLengthInFrames);
+ if (err)
+ {
+ printf("MyGetOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_FileLengthFrames) FAILED, Error = %ld\n", (long int) err);
+ if (extRef) ExtAudioFileDispose(extRef);
+ return theData;
+ }
+
+
+ // Read all the data into memory
+ UInt32 theFramesToRead = (UInt32) theFileLengthInFrames;
+ UInt32 dataSize = theFramesToRead * theOutputFormat.mBytesPerFrame;
+ theData = malloc(dataSize);
+ if (theData)
+ {
+ AudioBufferList theDataBuffer;
+ theDataBuffer.mNumberBuffers = 1;
+ theDataBuffer.mBuffers[0].mDataByteSize = dataSize;
+ theDataBuffer.mBuffers[0].mNumberChannels = theOutputFormat.mChannelsPerFrame;
+
+ theDataBuffer.mBuffers[0].mData = theData;
+
+ // Read the data into an AudioBufferList
+ err = ExtAudioFileRead(extRef, &theFramesToRead, &theDataBuffer);
+ if (err == noErr)
+ {
+ // success
+ *outDataSize = (ALsizei) dataSize;
+ *outDataFormat = (theOutputFormat.mChannelsPerFrame > 1) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16;
+ *outSampleRate = (ALsizei) theOutputFormat.mSampleRate;
+ }
+ else
+ {
+ // failure
+ free(theData);
+ theData = NULL; // make sure to return NULL
+ printf("MyGetOpenALAudioData: ExtAudioFileRead FAILED, Error = %ld\n", (long int) err);
+
+ if (extRef) ExtAudioFileDispose(extRef);
+ return theData;
+ }
+ }
+
+ // Dispose the ExtAudioFileRef, it is no longer needed
+ if (extRef) ExtAudioFileDispose(extRef);
+ return theData;
+}
+#endif
+#endif
View
41 CoreEngine/Camera.h
@@ -0,0 +1,41 @@
+//
+// Camera.h
+// Core3D
+//
+// Created by CoreCode on 21.11.07.
+// Copyright 2007 - 2012 CoreCode. Licensed under the MIT License, see LICENSE.txt
+//
+
+
+@interface Camera : SceneNode
+{
+ float fov, nearPlane, farPlane;
+
+ CGSize size;
+
+ matrix44f_c projectionMatrix;
+ matrix44f_c viewMatrix;
+ vector<matrix44f_c> modelViewMatrices;
+ vector3f relativeModeTargetFactor;
+}
+
+@property (assign, nonatomic) float fov;
+@property (assign, nonatomic) float nearPlane;
+@property (assign, nonatomic) float farPlane;
+@property (assign, nonatomic) matrix44f_c projectionMatrix;
+@property (assign, nonatomic) matrix44f_c viewMatrix;
+@property (assign, nonatomic) vector3f relativeModeTargetFactor;
+
+- (void)updateProjection;
+
+- (matrix44f_c)modelViewMatrix;
+
+- (void)push;
+- (void)pop;
+- (void)identity;
+- (void)scale:(float)_scale;
+- (void)translate:(vector3f)tra;
+- (void)rotate:(vector3f)rot withConfig:(axisConfigurationEnum)axisRotation;
+- (float)getAspectRatio;
+
+@end
View
181 CoreEngine/Camera.mm
@@ -0,0 +1,181 @@
+//
+// Camera.m
+// Core3D
+//
+// Created by CoreCode on 21.11.07.
+// Copyright 2007 - 2012 CoreCode. Licensed under the MIT License, see LICENSE.txt
+//
+
+
+#import "Core3D.h"
+
+
+@implementation Camera
+
+
+@synthesize fov, nearPlane, farPlane, projectionMatrix, viewMatrix, relativeModeTargetFactor;
+
+- (id)init
+{
+ if ((self = [super init]))
+ {
+ fov = 80.0f;
+ nearPlane = 0.5f;
+ farPlane = 14000.0f;
+ relativeModeTargetFactor = vector3f(1, 1, 1);
+
+ [self addObserver:self forKeyPath:@"fov" options:NSKeyValueObservingOptionNew context:NULL];
+ [self addObserver:self forKeyPath:@"nearPlane" options:NSKeyValueObservingOptionNew context:NULL];
+ [self addObserver:self forKeyPath:@"farPlane" options:NSKeyValueObservingOptionNew context:NULL];
+
+ modelViewMatrices.push_back(cml::identity_transform<4, 4>());
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ [self removeObserver:self forKeyPath:@"fov"];
+ [self removeObserver:self forKeyPath:@"nearPlane"];
+ [self removeObserver:self forKeyPath:@"farPlane"];
+
+ [super dealloc];
+}
+
+- (vector3f)getLookAt // TODO: get rid of this method and find a proper solution for what it is trying to solve
+{
+ axisConfigurationEnum stored = axisConfiguration;
+ axisConfiguration = kYXZRotation;
+ vector3f bla = [super getLookAt];
+ axisConfiguration = stored;
+ return bla;
+}
+
+- (void)reshapeNode:(CGSize)_size
+{
+ size = _size;
+ [self updateProjection];
+}
+
+- (void)transform
+{
+ [self rotate:-rotation withConfig:axisConfiguration]; // TODO: camera axis config broken
+ [self translate:-position];
+
+ if (relativeModeTarget != nil)
+ {
+ vector3f rot = component_mult3([relativeModeTarget rotation], relativeModeTargetFactor);
+ [self rotate:-rot withConfig:relativeModeAxisConfiguration];
+ [self translate:-[relativeModeTarget position]];
+ }
+
+ viewMatrix = modelViewMatrices.back();
+
+#ifndef DISABLE_SOUND
+ if (currentRenderPass.settings == kMainRenderPass)
+ {
+ static uint64_t frame = 666;
+
+ if (frame != globalInfo.frame) // once per frame, regardless of the number of main passes
+ {
+ vector3f pos = [relativeModeTarget position] + position;
+ alListenerfv(AL_POSITION, pos.data());
+
+ vector3f up = [self getUp];
+ vector3f forward = [self getLookAt];
+ ALfloat orientation[6] = {forward[0], forward[1], forward[2], up[0], up[1], up[2]};
+ alListenerfv(AL_ORIENTATION, orientation);
+
+ frame = globalInfo.frame;
+ }
+ }
+#endif
+}
+
+- (float)getAspectRatio
+{
+ return (float) (size.width / size.height);
+}
+
+- (void)updateProjection
+{
+ if (size.width && size.height)
+ matrix_perspective_yfov_RH(projectionMatrix, cml::rad(fov), (float) (size.width / size.height), nearPlane, farPlane, cml::z_clip_neg_one);
+ else
+ cml::identity_transform(projectionMatrix);
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
+{
+ [self updateProjection];
+}
+
+- (matrix44f_c)modelViewMatrix
+{
+ return modelViewMatrices.back();
+}
+
+- (void)identity
+{
+ cml::identity_transform(modelViewMatrices.back());
+}
+
+- (void)scale:(float)_scale
+{
+ matrix44f_c m;
+ matrix_uniform_scale(m, _scale);
+ modelViewMatrices.back() *= m;
+}
+
+- (void)translate:(vector3f)tra
+{
+ matrix44f_c m;
+ matrix_translation(m, tra);
+ modelViewMatrices.back() *= m;
+}
+
+- (void)rotate:(vector3f)rot withConfig:(axisConfigurationEnum)axisRotation
+{
+ // this allows us to configure per-node the rotation order and axis to ignore (which is mostly useful for target mode)
+ for (uint8_t i = 0; i < 3; i++)
+ {
+ uint8_t axis = (axisRotation >> (i * 2)) & 3;
+
+ if ((axis != kDisabledAxis) && (rot[axis] != 0))
+ matrix_rotate_about_local_axis(modelViewMatrices.back(), axis, cml::rad(rot[axis]));
+ }
+}
+
+- (void)push
+{
+ matrix44f_c m = modelViewMatrices.back();
+ modelViewMatrices.push_back(m);
+}
+
+- (void)pop
+{
+ modelViewMatrices.pop_back();
+}
+
+#ifdef __COCOTRON__
+// KVO broken
+- (void)setFov:(float)_fov
+{
+ [self updateProjection];
+ fov = _fov;
+}
+
+- (void)setNearPlane:(float)_nearPlane
+{
+ [self updateProjection];
+ nearPlane = _nearPlane;
+}
+
+- (void)setFarPlane:(float)_farPlane
+{
+ [self updateProjection];
+ farPlane = _farPlane;
+}
+#endif
+@end
View
30 CoreEngine/FBO.h
@@ -0,0 +1,30 @@
+//
+// FBO.h
+// Core3D
+//
+// Created by CoreCode on 20.11.10.
+// Copyright 2010 - 2012 CoreCode. Licensed under the MIT License, see LICENSE.txt
+//
+
+#import "Texture.h"
+
+
+@interface FBO : RenderTarget
+{
+ Texture *colorTexture;
+ Texture *depthTexture;
+ GLuint fbo;
+
+ BOOL disableDepthTexture;
+ BOOL disableColorTexture;
+}
+
+
+
+- (void)load;
+
+@property (nonatomic, readonly) Texture *colorTexture;
+@property (nonatomic, readonly) Texture *depthTexture;
+@property (nonatomic, assign) BOOL disableDepthTexture;
+@property (nonatomic, assign) BOOL disableColorTexture;
+@end
View
182 CoreEngine/FBO.mm
@@ -0,0 +1,182 @@
+//
+// FBO.m
+// Core3D
+//
+// Created by CoreCode on 20.11.10.
+// Copyright 2010 - 2012 CoreCode. Licensed under the MIT License, see LICENSE.txt
+//
+
+#import "Core3D.h"
+#import "FBO.h"
+
+
+@implementation FBO
+
+
+@synthesize disableDepthTexture;
+@synthesize disableColorTexture;
+@synthesize colorTexture, depthTexture;
+
+- (id)init
+{
+ [self doesNotRecognizeSelector:_cmd];
+ return nil;
+}
+
+- (void)initTextures
+{
+ depthTexture = [[Texture alloc] init];
+ colorTexture = [[Texture alloc] init];
+
+
+ [colorTexture setMinFilter:GL_NEAREST];
+ [colorTexture setMagFilter:GL_NEAREST];
+#ifdef GL_ES_VERSION_2_0
+ [colorTexture setInternalFormat:GL_RGBA];
+#else
+ [colorTexture setInternalFormat:GL_RGBA8];
+#endif
+ [colorTexture setFormat:GL_RGBA];
+ [colorTexture setWrapS:GL_CLAMP_TO_EDGE];
+ [colorTexture setWrapT:GL_CLAMP_TO_EDGE];
+#ifdef GL_ES_VERSION_2_0
+ [colorTexture setType:GL_UNSIGNED_SHORT_4_4_4_4];
+#else
+ [colorTexture setType:GL_UNSIGNED_BYTE];
+#endif
+
+
+ [depthTexture setMinFilter:GL_NEAREST];
+ [depthTexture setMagFilter:GL_NEAREST];
+ [depthTexture setInternalFormat:GL_DEPTH_COMPONENT24];
+ [depthTexture setFormat:GL_DEPTH_COMPONENT];
+ [depthTexture setWrapS:GL_CLAMP_TO_EDGE];
+ [depthTexture setWrapT:GL_CLAMP_TO_EDGE];
+#ifdef GL_ES_VERSION_2_0
+ [depthTexture setType:GL_UNSIGNED_SHORT];
+#else
+ [depthTexture setType:GL_UNSIGNED_BYTE];
+#endif
+}
+
+- (id)initWithFixedWidth:(float)_width andFixedHeight:(float)_height
+{
+ if ((self = [super initWithFixedWidth:_width andFixedHeight:_height]))
+ {
+ [self initTextures];
+
+ glGenFramebuffers(1, &fbo);
+ }
+ return self;
+}
+
+- (id)initWithWidthMultiplier:(float)_widthMultiplier andHeightMultiplier:(float)_heightMultiplier
+{
+ if ((self = [super initWithWidthMultiplier:_widthMultiplier andHeightMultiplier:_heightMultiplier]))
+ {
+ [self initTextures];
+
+ glGenFramebuffers(1, &fbo);
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ glDeleteFramebuffers(1, &fbo);
+ fbo = 0;
+
+ [colorTexture release];
+ [depthTexture release];
+
+ [super dealloc];
+}
+
+- (void)reshape:(CGSize)size
+{
+ if ((!disableColorTexture && !colorTexture) || (!disableDepthTexture && !depthTexture))
+ fatal("FBO has not been loaded");
+
+ if (fixedSize)
+ return;
+
+
+ [super reshape:size];
+
+ [self load];
+}
+
+- (void)load
+{
+ if (disableColorTexture)
+ {
+ [colorTexture release];
+ colorTexture = nil;
+ }
+ if (disableDepthTexture)
+ {
+ [depthTexture release];
+ depthTexture = nil;
+ }
+
+
+ [colorTexture setWidth:(size_t) bounds.width];
+ [colorTexture setHeight:(size_t) bounds.height];
+ [colorTexture load];
+
+
+ [depthTexture setWidth:(size_t) bounds.width];
+ [depthTexture setHeight:(size_t) bounds.height];
+ [depthTexture load];
+
+
+#ifndef TARGET_OS_IPHONE
+ [self bind];
+
+ // #warning re-evaulate FBO disabling
+
+ if (!disableColorTexture)
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, [colorTexture texName], 0);
+ else
+ {
+#ifndef GL_ES_VERSION_2_0
+ glDrawBuffer(GL_NONE);
+ glReadBuffer(GL_NONE);
+#else
+ printf("Warning: fixme?");
+#endif
+ }
+
+#ifdef TARGET_OS_IPHONE
+ GLuint _depthBuffer, oldRenderbuffer;
+ glGetIntegerv(GL_RENDERBUFFER_BINDING, (GLint *) &oldRenderbuffer);
+ glGenRenderbuffers(1, &_depthBuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, _depthBuffer);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, bounds.width, bounds.height);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthBuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, oldRenderbuffer);
+#else
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, [depthTexture texName], 0);
+#endif
+
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+ fatal("Error: couldn't setup FBO %04x", (unsigned int)glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+ [self unbind];
+#endif
+}
+
+- (void)bind
+{
+#ifndef TARGET_OS_IPHONE
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+#endif
+}
+
+- (void)unbind
+{
+#ifndef TARGET_OS_IPHONE
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+#endif
+}
+@end
View
25 CoreEngine/Light.h
@@ -0,0 +1,25 @@
+//
+// Light.h
+// Core3D
+//
+// Created by CoreCode on 22.11.07.
+// Copyright 2007 - 2012 CoreCode. Licensed under the MIT License, see LICENSE.txt
+//
+
+
+@interface Light : SceneNode
+{
+ vector4f lightDiffuseColor, lightSpecularColor, lightAmbientColor;
+ float linearAttenuation;
+}
+
+@property (assign, nonatomic) float linearAttenuation;
+@property (assign, nonatomic) vector4f lightDiffuseColor;
+@property (assign, nonatomic) vector4f lightSpecularColor;
+@property (assign, nonatomic) vector4f lightAmbientColor;
+
+CPPPROPERTYSUPPORT_V4_H(lightDiffuseColor)
+CPPPROPERTYSUPPORT_V4_H(lightSpecularColor)
+CPPPROPERTYSUPPORT_V4_H(lightAmbientColor)
+
+@end
View
34 CoreEngine/Light.mm
@@ -0,0 +1,34 @@
+//
+// Light.m
+// Core3D
+//
+// Created by CoreCode on 22.11.07.
+// Copyright 2007 - 2012 CoreCode. Licensed under the MIT License, see LICENSE.txt
+//
+
+
+#import "Core3D.h"
+
+
+@implementation Light
+
+@synthesize lightDiffuseColor, lightSpecularColor, lightAmbientColor, linearAttenuation;
+
+- (id)init
+{
+ if ((self = [super init]))
+ {
+ linearAttenuation = 0.0f;
+ lightAmbientColor = vector4f(0.0f, 0.0f, 0.0f, 1.0f);
+ lightDiffuseColor = vector4f(0.99f, 0.99f, 0.99f, 1.0f);
+ lightSpecularColor = vector4f(0.99f, 0.99f, 0.99f, 1.0f);
+ }
+ return self;
+}
+
+// for editor because bindings don't work for c++ properties
+CPPPROPERTYSUPPORT_V4_M(lightDiffuseColor, LightDiffuseColor)
+CPPPROPERTYSUPPORT_V4_M(lightSpecularColor, LightSpecularColor)
+CPPPROPERTYSUPPORT_V4_M(lightAmbientColor, LightAmbientColor)
+
+@end
View
92 CoreEngine/Mesh.h
@@ -0,0 +1,92 @@
+//
+// Mesh.h
+// Core3D
+//
+// Created by CoreCode on 16.11.07.
+// Copyright 2007 - 2012 CoreCode. Licensed under the MIT License, see LICENSE.txt
+//
+
+struct octree_node
+{
+ uint32_t firstFace;
+ uint32_t faceCount;
+ float aabbOriginX, aabbOriginY, aabbOriginZ;
+ float aabbExtentX, aabbExtentY, aabbExtentZ;
+ uint16_t childIndex1, childIndex2, childIndex3, childIndex4, childIndex5, childIndex6, childIndex7, childIndex8;
+};
+
+struct octree_struct // TODO: optimization: add optimized prefetch indices for glDrawRangeElements, convert to aabbCenter
+{
+ uint32_t magicWord;
+ uint32_t nodeCount;
+ uint32_t vertexCount;
+ struct octree_node rootnode;
+};
+
+#define _OFFSET_NODES(oct) ((char *)oct + sizeof(struct octree_struct) - sizeof(struct octree_node))
+#define _OFFSET_VERTICES(oct) (_OFFSET_NODES(oct) + oct->nodeCount * sizeof(struct octree_node))
+#define _OFFSET_FACES(oct) (_OFFSET_VERTICES(oct) + oct->vertexCount * ((oct->magicWord == 0x6D616C62) ? 6 : 8) * sizeof(float))
+#define _NODE_NUM(oct, x) (_OFFSET_NODES(oct) + (x) * sizeof(struct octree_node))
+#define _VERTEX_NUM(oct, x) (_OFFSET_VERTICES(oct) + (x) * ((oct->magicWord == 0x6D616C62) ? 6 : 8) * sizeof(float))
+#define _FACE_NUM(oct, x) (_OFFSET_FACES(oct) + (x) * 3 * sizeof(uint16_t))
+
+#define OFFSET_NODES (_OFFSET_NODES(octree))
+#define OFFSET_VERTICES (_OFFSET_VERTICES(octree))
+#define OFFSET_FACES (_OFFSET_FACES(octree))
+#define NODE_NUM(x) (_NODE_NUM(octree, x))
+#define VERTEX_NUM(x) (_VERTEX_NUM(octree, x))
+#define FACE_NUM(x) (_FACE_NUM(octree, x))
+
+
+@interface Mesh : SceneNode
+{
+ BOOL visible;
+ BOOL hasTransparency;
+ struct octree_struct *octree;
+
+ vector4f color, specularColor;
+ float shininess;
+ float contributionCullingDistance;
+ BOOL doubleSided, dontDepthtest;
+
+ uint16_t *pvsCells;
+ uint16_t *visibleNodeStack;
+ uint16_t visibleNodeStackTop;
+
+ Texture *texture;
+ NSNumber *_texQuality;
+
+ VBO *vbo;
+
+ GLenum srcBlend;
+ GLenum dstBlend;
+}
+
+@property (assign, nonatomic) GLenum srcBlend;
+@property (assign, nonatomic) GLenum dstBlend;
+@property (readonly, nonatomic) struct octree_struct *octree;
+@property (readonly, nonatomic) uint16_t *visibleNodeStack;
+@property (readonly, nonatomic) uint16_t visibleNodeStackTop;
+
+@property (assign, nonatomic) uint16_t *pvsCells;
+
+@property (assign, nonatomic) BOOL hasTransparency;
+@property (assign, nonatomic) vector4f color;
+@property (assign, nonatomic) vector4f specularColor;
+@property (assign, nonatomic) BOOL doubleSided;
+@property (assign, nonatomic) BOOL dontDepthtest;
+@property (assign, nonatomic) float shininess;
+@property (assign, nonatomic) float contributionCullingDistance;
+@property (nonatomic, retain) Texture *texture;
+
++ (struct octree_struct *)_loadOctreeFromFile:(NSURL *)file;
+- (id)initWithOctreeNamed:(NSString *)_name;
+- (id)initWithOctreeNamed:(NSString *)_name andTexureQuality:(NSNumber *)texQuality;
+- (id)initWithOctree:(NSURL *)file andName:(NSString *)_name;
+- (id)initWithOctree:(NSURL *)file andName:(NSString *)_name andTexureQuality:(NSNumber *)texQuality;
+- (void)cleanup;
+
+- (vector3f)center;
+- (vector3f)size;
+- (float)radius;
+@end
View
531 CoreEngine/Mesh.mm
@@ -0,0 +1,531 @@
+//
+//
+// Mesh.m
+// Core3D
+//
+// Created by CoreCode on 16.11.07.
+// Copyright 2007 - 2012 CoreCode. Licensed under the MIT License, see LICENSE.txt
+//
+
+
+#import "Core3D.h"
+
+
+#define RECURSION_THRESHOLD 1000
+#undef glEnableVertexAttribArray
+#undef glDisableVertexAttribArray
+#define MAGIC_UNTEXTURED 0x6D616C62
+#define MAGIC_TEXTURED 0xDEADBEEF
+#define BUFFER_STRIDE ((octree->magicWord == MAGIC_UNTEXTURED) ? 6 : 8)
+
+GLfloat frustum[6][4];
+uint16_t _visibleNodeStackTop;
+
+static void vfcTestOctreeNode(struct octree_struct *octree, uint16_t *visibleNodeStack, uint32_t nodeNum);
+static void vfcTestOctreeNodePVS(struct octree_struct *octree, uint16_t *visibleNodeStack, uint32_t nodeNum, bool potentiallyVisible, bool *PVS);
+
+@implementation Mesh
+
+
+@synthesize octree, color, specularColor, visibleNodeStack, visibleNodeStackTop, shininess, doubleSided, texture, hasTransparency, pvsCells, contributionCullingDistance, srcBlend, dstBlend, dontDepthtest;
+
++ (struct octree_struct *)_loadOctreeFromFile:(NSURL *)file
+{
+ octree_struct *_octree;
+ FILE *f;
+ NSString *p = [file path];
+
+#ifdef WIN32
+ if ([p hasPrefix:@"/"]) p = [p substringFromIndex:1];
+#endif
+ f = fopen([p UTF8String], "rb");
+
+ assert(f);
+
+ if ([[[file path] pathExtension] isEqualToString:@"octree"])
+ {
+ unsigned long fileSize;
+ size_t result;
+
+
+ fseek(f, 0, SEEK_END);
+ fileSize = (unsigned long) ftell(f);
+ rewind(f);
+
+
+ _octree = (octree_struct *) malloc(fileSize); // TODO: mmap instead allows swapping on iphone
+ assert(_octree);
+
+ result = fread(_octree, 1, fileSize, f);
+ assert(result == fileSize);
+ }
+ else if ([[[file path] pathExtension] isEqualToString:@"snz"])
+ {
+ // uint64_t micro = GetNanoseconds() / 1000;
+
+ _octree = (octree_struct *) UncompressedBufferFromSNZFile(f);
+
+
+ // uint64_t post = GetNanoseconds() / 1000;
+
+ // NSLog(@"decompressing %@ took %f", [file lastPathComponent], (post-micro) / 1000.0);
+ }
+ else
+ fatal("Error: the file named %s doesn't seem to be a valid octree", [[file absoluteString] UTF8String]);
+
+ fclose(f);
+
+ if ((_octree->magicWord != MAGIC_UNTEXTURED) && (_octree->magicWord != MAGIC_TEXTURED))
+ fatal("Error: the file named %s doesn't seem to be a valid octree", [[file absoluteString] UTF8String]);
+
+ return _octree;
+}
+
+- (id)init
+{
+ [self doesNotRecognizeSelector:_cmd];
+ return nil;
+}
+
+- (id)initWithOctreeNamed:(NSString *)_name
+{
+ NSString *octreeURL = [[NSBundle mainBundle] pathForResource:_name ofType:@"octree"];
+ NSString *snzURL = [[NSBundle mainBundle] pathForResource:_name ofType:@"octree.snz"];
+
+ if (!octreeURL && !snzURL)
+ fatal("Error: there is no octree named: %s", [_name UTF8String]);
+
+ return [self initWithOctree:(octreeURL ? [NSURL fileURLWithPath:octreeURL] : [NSURL fileURLWithPath:snzURL]) andName:_name];
+}
+
+- (id)initWithOctreeNamed:(NSString *)_name andTexureQuality:(NSNumber *)texQuality
+{
+ _texQuality = texQuality;
+ return [self initWithOctreeNamed:_name];
+}
+
+- (id)initWithOctree:(NSURL *)file andName:(NSString *)_name andTexureQuality:(NSNumber *)texQuality
+{
+ _texQuality = texQuality;
+ return [self initWithOctree:file andName:_name];
+}
+
+- (id)initWithOctree:(NSURL *)file andName:(NSString *)_name
+{
+ if ((self = [super init]))
+ {
+
+ name = [[NSString alloc] initWithString:_name];
+ octree = [Mesh _loadOctreeFromFile:file];
+
+ NSData *pvsData = [NSData dataWithContentsOfURL:[[[file URLByDeletingPathExtension] URLByDeletingPathExtension] URLByAppendingPathExtension:@"pvs"]];
+
+ if (pvsData)
+ {
+ pvsCells = (uint16_t *) malloc([pvsData length]);
+ [pvsData getBytes:pvsCells length:[pvsData length]];
+ // NSLog(@"mesh %@ gets pvs!", name);
+ }
+
+ contributionCullingDistance = 99999.9f;
+ shininess = 30.0f;
+ doubleSided = FALSE;
+ visible = YES;
+ srcBlend = GL_SRC_ALPHA;
+ dstBlend = GL_ONE_MINUS_SRC_ALPHA;
+
+ [self setColor:vector4f(1.0f, 1.0f, 1.0f, 1.0f)];
+ [self setSpecularColor:vector4f(1.0f, 1.0f, 1.0f, 1.0f)];
+
+#ifdef TARGET_OS_IPHONE
+ if (octree->vertexCount > 0xFFFF)
+ fatal("Error: only 0xFFFF vertices per object supported on iOS %s %i", [name UTF8String], octree->vertexCount);
+#endif
+
+ int indexSize = octree->vertexCount > 0xFFFF ? sizeof(uint32_t) : sizeof(uint16_t);
+
+ vbo = [[VBO alloc] init];
+
+ [vbo setIndexBuffer:OFFSET_FACES withSize:octree->rootnode.faceCount * 3 * indexSize];
+ [vbo setVertexBuffer:OFFSET_VERTICES withSize:octree->vertexCount * BUFFER_STRIDE * sizeof(float)];
+ [vbo setVertexAttribPointer:(const GLvoid *) 0
+ forIndex:VERTEX_ARRAY withSize:3 withType:GL_FLOAT shouldNormalize:GL_FALSE withStride:BUFFER_STRIDE * sizeof(float)];
+ [vbo setVertexAttribPointer:(const GLfloat *) (sizeof(float) * 3)
+ forIndex:NORMAL_ARRAY withSize:3 withType:GL_FLOAT shouldNormalize:GL_FALSE withStride:BUFFER_STRIDE * sizeof(float)];
+ if (octree->magicWord != MAGIC_UNTEXTURED)
+ [vbo setVertexAttribPointer:(const GLfloat *) (sizeof(float) * 6)
+ forIndex:TEXTURE_COORD_ARRAY withSize:2 withType:GL_FLOAT shouldNormalize:GL_FALSE withStride:BUFFER_STRIDE * sizeof(float)];
+ [vbo load];
+
+ if (octree->magicWord != MAGIC_UNTEXTURED)
+ {
+ texture = [Texture newTextureNamed:name];
+
+ if (!texture)
+ {
+ NSURL *p = [[[file URLByDeletingPathExtension] URLByDeletingPathExtension] URLByAppendingPathExtension:@"png"];
+ NSURL *d = [[[file URLByDeletingPathExtension] URLByDeletingPathExtension] URLByAppendingPathExtension:@"dds"];
+ if ([[NSFileManager defaultManager] fileExistsAtPath:[p path]])
+ texture = [(Texture *) [Texture alloc] initWithContentsOfURL:p];
+ else if ([[NSFileManager defaultManager] fileExistsAtPath:[d path]])
+ texture = [(Texture *) [Texture alloc] initWithContentsOfURL:d];
+ }
+
+ if (_texQuality)
+ [texture setQuality:[_texQuality shortValue]];
+ else
+ [texture setQuality:$defaulti(kTextureQualityKey)];
+
+ [texture load];
+ }
+ else
+ {
+ NSDebugLog(@"Info: %@ is an untextured mesh", _name);
+ }
+
+ assert([self size].length() > 0.0001);
+
+ visibleNodeStack = (uint16_t *) calloc(1, octree->nodeCount * sizeof(uint16_t));
+
+ [self cleanup];
+ }
+
+ return self;
+}
+
+- (vector3f)center
+{
+ struct octree_node const *const n1 = (struct octree_node *) NODE_NUM(0);
+ vector3f extent = vector3f(n1->aabbExtentX, n1->aabbExtentY, n1->aabbExtentZ);
+ vector3f origin = vector3f(n1->aabbOriginX, n1->aabbOriginY, n1->aabbOriginZ);
+
+ return vector3f(origin + extent / 2.0);
+}
+
+- (vector3f)size
+{
+ struct octree_node const *const n1 = (struct octree_node *) NODE_NUM(0);
+ vector3f extent = vector3f(n1->aabbExtentX, n1->aabbExtentY, n1->aabbExtentZ);
+
+ return vector3f(extent / 2.0);
+}
+
+- (float)radius
+{
+ struct octree_node const *const n1 = (struct octree_node *) NODE_NUM(0);
+ vector3f extent = vector3f(n1->aabbExtentX, n1->aabbExtentY, n1->aabbExtentZ);
+ return extent.length() / 2.0f;
+}
+
+- (void)cleanup
+{
+#ifndef DEBUG
+ octree = (octree_struct *) realloc(octree, (sizeof(struct octree_struct) + (octree->nodeCount - 1) * sizeof(struct octree_node)));
+#endif
+}
+
+- (id)copyWithZone:(NSZone *)zone
+{
+ fatal("copying meshes currently not advised");
+ Mesh *octreeCopy = (Mesh *) NSCopyObject(self, 0, zone);
+
+ octreeCopy->name = [[NSString alloc] initWithString:name];
+ octreeCopy->visibleNodeStack = (uint16_t *) calloc(1, octree->nodeCount * sizeof(uint16_t));
+
+ return octreeCopy;
+}
+
+- (NSString *)description
+{
+ NSMutableString *desc = [NSMutableString stringWithString:@"Mesh: "];
+
+ [desc appendFormat:@"%@ (%p)\n Nodes/Vertices/Faces: %i / %i / %i\n", name, (void *) self, octree->nodeCount, octree->vertexCount, octree->rootnode.faceCount];
+ struct octree_node *n = (struct octree_node *) NODE_NUM(0);
+ [desc appendFormat:@" RootNode: firstFace: %i faceCount:%i\n origin:%f %f %f\n extent: %f %f %f\n children: %i %i %i %i %i %i %i %i\n", n->firstFace, n->faceCount, n->aabbOriginX, n->aabbOriginY, n->aabbOriginZ, n->aabbExtentX, n->aabbExtentY, n->aabbExtentZ, n->childIndex1, n->childIndex2, n->childIndex3, n->childIndex4, n->childIndex5, n->childIndex6, n->childIndex7, n->childIndex8];
+
+
+ if (0)
+ {
+ [desc appendFormat:@"NodeOffset:%p\n", (void *) OFFSET_NODES];
+ [desc appendFormat:@"VertexOffset:%p\n", (void *) OFFSET_VERTICES];
+ [desc appendFormat:@"FaceOffset:%p\n", (void *) OFFSET_FACES];
+
+ uint32_t i;
+ [desc appendString:@"Nodes:\n"];
+ for (i = 0; i < octree->nodeCount; i++)
+ {
+ struct octree_node *_n = (struct octree_node *) NODE_NUM(i);
+ [desc appendFormat:@"%i: firstFace: %i faceCount:%i origin:%f %f %f extent: %f %f %f children: %i %i %i %i %i %i %i %i\n", i, _n->firstFace, _n->faceCount, _n->aabbOriginX, _n->aabbOriginY, _n->aabbOriginZ, _n->aabbExtentX, _n->aabbExtentY, _n->aabbExtentZ, _n->childIndex1, _n->childIndex2, _n->childIndex3, _n->childIndex4, _n->childIndex5, _n->childIndex6, _n->childIndex7, _n->childIndex8];
+ }
+#ifdef DEBUG
+ [desc appendString:@"\nVertices:\n"];
+ for (i = 0; i < octree->vertexCount; i++)
+ {
+ float *v = (float *) VERTEX_NUM(i);
+ if (octree->magicWord == MAGIC_UNTEXTURED)
+ [desc appendFormat:@"%i: x: %f y: %f z: %f nx: %f ny: %f nz: %f\n", i, *v, *(v + 1), *(v + 2), *(v + 3), *(v + 4), *(v + 5)];
+ else
+ [desc appendFormat:@"%i: x: %f y: %f z: %f nx: %f ny: %f nz: %f tx: %f ty: %f tz: %f\n", i, *v, *(v + 1), *(v + 2), *(v + 3), *(v + 4), *(v + 5), *(v + 6), *(v + 7), *(v + 8)];
+ }
+ [desc appendString:@"\nFaces:\n"];
+ for (i = 0; i < octree->rootnode.faceCount; i++)
+ {
+ uint16_t *f = (uint16_t *) FACE_NUM(i);
+
+ [desc appendFormat:@"%i: v1: %u v2: %u v3: %u\n", i, *f, *(f + 1), *(f + 2)];
+ }
+#endif
+ }
+
+ //return [NSString stringWithString:[[super description] stringByAppendingString:desc]];
+ return [NSString stringWithString:desc];
+}
+
+- (void)renderNode
+{
+
+ renderPassEnum renderSettings = [currentRenderPass settings];
+
+ if (!globalSettings.disableCulling && (renderSettings & kRenderPassUpdateCulling)) // perform culling
+ {
+ visible = TRUE;
+
+ if (contributionCullingDistance < 10000.0f
+ && matrix_get_translation([currentCamera modelViewMatrix]).length() > contributionCullingDistance) // contribution culling
+ {
+ visible = FALSE;
+ }
+
+ if (visible) // view frustum and occlusion culling
+ {
+ _visibleNodeStackTop = 0;
+
+ extract_frustum_planes([currentCamera modelViewMatrix],
+ [currentCamera projectionMatrix],
+ frustum, cml::z_clip_neg_one, false);
+
+ if (pvsCells && renderSettings & kRenderPassUsePVS && currentRenderPass.currentPVSCell >= 0)
+ {
+ bool nodes[octree->nodeCount];
+ uint16_t startIndex = pvsCells[1 + currentRenderPass.currentPVSCell];
+ uint16_t stopIndex = pvsCells[1 + currentRenderPass.currentPVSCell + 1];
+
+
+ memset(nodes, 0, octree->nodeCount * sizeof(bool));
+
+
+
+ for (uint16_t index = startIndex; index < stopIndex; index++)
+ nodes[pvsCells[1 + globalInfo.pvsCells + 1 + index]] = 1;
+
+
+ vfcTestOctreeNodePVS(octree, visibleNodeStack, 0, nodes[0], &nodes[0]);
+ }
+ else
+ vfcTestOctreeNode(octree, visibleNodeStack, 0);
+
+
+ visibleNodeStackTop = _visibleNodeStackTop;
+
+ if (!visibleNodeStackTop)
+ {
+ visible = FALSE;
+ }
+ }
+ }
+
+ if (!visible)
+ {
+ // TODO: we really gotta find a more clever system that allows us to do culling once even for nodes that are attached *at multiple positions* for multiple passes, call update: cull: render:
+
+ return;
+ }
+
+
+#ifndef GL_ES_VERSION_2_0
+ #ifdef DEBUG
+ if (globalSettings.doWireframe)
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ #endif
+#endif
+
+ if (renderSettings & kRenderPassSetMaterial)
+ {
+ globalMaterial.color = color;
+ globalMaterial.specular = specularColor;
+ globalMaterial.shininess = shininess;
+
+ if (hasTransparency)
+ myBlendFunc(srcBlend, dstBlend);
+ }
+
+
+ myEnableBlendParticleCullDepthtestDepthwrite(hasTransparency && (renderSettings & kRenderPassSetMaterial), NO, !(doubleSided && (renderSettings & kRenderPassSetMaterial)), !dontDepthtest, YES);
+ [vbo bind];
+
+ if ((octree->magicWord != MAGIC_UNTEXTURED) && // textured
+ (renderSettings & kRenderPassUseTexture) && // and should use texture
+ (!globalSettings.disableTex)) // and texture not disabled
+ [texture bind];
+
+
+ assert(currentShader);
+ [currentShader prepare];
+
+
+ if (globalSettings.disableCulling) // no view frustum culling, render everthing with a single call
+ {
+#ifndef TARGET_OS_IPHONE
+ if (octree->vertexCount > 0xFFFF)
+ { glDrawElements(GL_TRIANGLES, octree->rootnode.faceCount * 3, GL_UNSIGNED_INT, (const GLuint *) 0); }
+ else
+#endif
+ {glDrawElements(GL_TRIANGLES, octree->rootnode.faceCount * 3, GL_UNSIGNED_SHORT, (const GLushort *) 0);}
+
+ globalInfo.renderedFaces += octree->rootnode.faceCount;
+ globalInfo.visitedNodes++;
+ globalInfo.drawCalls++;
+ /*DRAW_CALL*/
+ }
+ else
+ {
+ uint16_t i;
+ for (i = 0; i < visibleNodeStackTop;)
+ {
+ struct octree_node *n = (struct octree_node *) NODE_NUM(visibleNodeStack[i]);
+ uint32_t fc = n->faceCount;
+ uint32_t ff = n->firstFace;
+ uint16_t v = i + 1;
+ while (v < visibleNodeStackTop)
+ {
+ struct octree_node *nn = (struct octree_node *) NODE_NUM(visibleNodeStack[v]);
+
+ if (nn->firstFace != n->firstFace + n->faceCount) // TODO: allow for some draw call reduction at the expense of drawing invisible stuff
+ break;
+
+
+ fc += nn->faceCount;
+ n = nn;
+ v++;
+ }
+
+ i = v;
+#ifndef TARGET_OS_IPHONE
+ if (octree->vertexCount > 0xFFFF)
+ { glDrawElements(GL_TRIANGLES, fc * 3, GL_UNSIGNED_INT, (const GLuint *) 0 + (ff * 3)); }
+ else
+#endif
+ {glDrawElements(GL_TRIANGLES, fc * 3, GL_UNSIGNED_SHORT, (const GLushort *) 0 + (ff * 3));}
+
+ globalInfo.drawCalls++;
+ /*DRAW_CALL*/
+ globalInfo.renderedFaces += n->faceCount;
+ }
+ }
+
+
+#ifndef GL_ES_VERSION_2_0
+#ifdef DEBUG
+ if (globalSettings.doWireframe)
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+#endif
+#endif
+}
+
+// editor support
+- (void)setValue:(id)value forKey:(NSString *)key
+{
+ if ([key isEqualToString:@"color"])
+ {
+ vector4f v;
+ [value getValue:&v];
+ [self setColor:v];
+ }
+ else if ([key isEqualToString:@"specularColor"])
+ {
+ vector4f v;
+ [value getValue:&v];
+ [self setSpecularColor:v];
+ }
+ else [super setValue:value forKey:key];
+}
+
+- (void)dealloc
+{
+ // NSLog(@"dealloc mesh %@", [self description]);
+ free(pvsCells);
+ free(octree);
+ free(visibleNodeStack);
+ [texture release];
+
+ [vbo release];
+
+ [super dealloc];
+}
+@end
+
+static void vfcTestOctreeNode(struct octree_struct *octree, uint16_t *visibleNodeStack, uint32_t nodeNum) // TODO: optimization: VFC coherence (http://www.cescg.org/CESCG-2002/DSykoraJJelinek/index.html)
+{
+ struct octree_node const *const n = (struct octree_node *) NODE_NUM(nodeNum);
+ char result;
+
+ globalInfo.visitedNodes++;
+
+ if (n->faceCount == 0)
+ return;
+
+ result = AABoxInFrustum((const float (*)[4]) frustum, n->aabbOriginX, n->aabbOriginY, n->aabbOriginZ, n->aabbExtentX, n->aabbExtentY, n->aabbExtentZ);
+ if (result == kIntersecting)
+ {
+ if ((n->childIndex1 == 0xFFFF) || (n->faceCount < RECURSION_THRESHOLD))
+ visibleNodeStack[_visibleNodeStackTop++] = (uint16_t) nodeNum;
+ else
+ {
+ vfcTestOctreeNode(octree, visibleNodeStack, n->childIndex1);
+ vfcTestOctreeNode(octree, visibleNodeStack, n->childIndex2);
+ vfcTestOctreeNode(octree, visibleNodeStack, n->childIndex3);
+ vfcTestOctreeNode(octree, visibleNodeStack, n->childIndex4);
+ vfcTestOctreeNode(octree, visibleNodeStack, n->childIndex5);
+ vfcTestOctreeNode(octree, visibleNodeStack, n->childIndex6);
+ vfcTestOctreeNode(octree, visibleNodeStack, n->childIndex7);
+ vfcTestOctreeNode(octree, visibleNodeStack, n->childIndex8);
+ }
+ }
+ else if (result == kInside)
+ visibleNodeStack[_visibleNodeStackTop++] = (uint16_t) nodeNum;
+}
+
+static void vfcTestOctreeNodePVS(struct octree_struct *octree, uint16_t *visibleNodeStack, uint32_t nodeNum, bool potentiallyVisible, bool *PVS)
+{
+ struct octree_node const *const n = (struct octree_node *) NODE_NUM(nodeNum);
+ char result;
+
+ globalInfo.visitedNodes++;
+
+ if (n->faceCount == 0)
+ return;
+
+ result = AABoxInFrustum((const float (*)[4]) frustum, n->aabbOriginX, n->aabbOriginY, n->aabbOriginZ, n->aabbExtentX, n->aabbExtentY, n->aabbExtentZ);
+
+ if (result == kInside && potentiallyVisible)
+ visibleNodeStack[_visibleNodeStackTop++] = (uint16_t) nodeNum;
+ else if (result == kIntersecting || (result == kInside && !potentiallyVisible))
+ {
+ if (n->childIndex1 == 0xFFFF)
+ {
+ if (potentiallyVisible)
+ visibleNodeStack[_visibleNodeStackTop++] = (uint16_t) nodeNum;
+ }
+ else
+ {
+ vfcTestOctreeNodePVS(octree, visibleNodeStack, n->childIndex1, potentiallyVisible ? YES : PVS[n->childIndex1], PVS);
+ vfcTestOctreeNodePVS(octree, visibleNodeStack, n->childIndex2, potentiallyVisible ? YES : PVS[n->childIndex2], PVS);
+ vfcTestOctreeNodePVS(octree, visibleNodeStack, n->childIndex3, potentiallyVisible ? YES : PVS[n->childIndex3], PVS);
+ vfcTestOctreeNodePVS(octree, visibleNodeStack, n->childIndex4, potentiallyVisible ? YES : PVS[n->childIndex4], PVS);
+ vfcTestOctreeNodePVS(octree, visibleNodeStack, n->childIndex5, potentiallyVisible ? YES : PVS[n->childIndex5], PVS);
+ vfcTestOctreeNodePVS(octree, visibleNodeStack, n->childIndex6, potentiallyVisible ? YES : PVS[n->childIndex6], PVS);
+ vfcTestOctreeNodePVS(octree, visibleNodeStack, n->childIndex7, potentiallyVisible ? YES : PVS[n->childIndex7], PVS);
+ vfcTestOctreeNodePVS(octree, visibleNodeStack, n->childIndex8, potentiallyVisible ? YES : PVS[n->childIndex8], PVS);
+ }
+ }
+}
View
61 CoreEngine/RenderPass.h
@@ -0,0 +1,61 @@
+//
+// RenderPass.h
+// Core3D
+//
+// Created by CoreCode on 21.11.10.
+// Copyright 2010 - 2012 CoreCode. Licensed under the MIT License, see LICENSE.txt
+//
+
+
+typedef enum
+{
+ kRenderPassSetMaterial = 1,
+ kRenderPassUseTexture = 2,
+ kRenderPassUpdateCulling = 4,
+ kRenderPassUsePVS = 8,
+
+ kMainRenderPass = 15,
+ kAdditionalRenderPass = 0
+} renderPassEnum;
+
+@interface RenderPass : NSObject
+{
+ cml::matrix44d_c viewportMatrix;
+ renderPassEnum settings;
+ Camera *camera;
+ MutableLightArray *lights;
+ MutableSceneNodeArray *objects;
+ RenderTarget *renderTarget;
+ int autoresizingMask;
+ CGRect frame;
+ int16_t currentPVSCell;
+}
+
++ (RenderPass *)mainRenderPass;
++ (RenderPass *)shadowRenderPassWithSize:(int)size light:(Light *)light casters:(NSArray *)casters andMainCamera:(Camera *)mainCamera;
+- (id)initWithFrame:(CGRect)_frame andAutoresizingMask:(int)_mask;
+- (void)reshape:(CGSize)size;
+- (void)render;
+- (NSArray *)newListOfAllObjects;
+
+@property (retain, nonatomic) Camera *camera;
+@property (readonly, nonatomic) MutableLightArray *lights;
+@property (readonly, nonatomic) MutableSceneNodeArray *objects;
+@property (retain, nonatomic) RenderTarget *renderTarget;
+@property (readonly, nonatomic) cml::matrix44d_c viewportMatrix;
+
+@property (assign, nonatomic) renderPassEnum settings;
+@property (assign, nonatomic) int autoresizingMask;
+@property (assign, nonatomic) CGRect frame;
+@property (assign, nonatomic) int16_t currentPVSCell;
+
+@end
+
+
+//@protocol RenderTarget
+//
+//- (void)reshape:(CGSize)size;
+//- (void)bind;
+//- (void)unbind;
+//
+//@end
View
286 CoreEngine/RenderPass.mm
@@ -0,0 +1,286 @@
+//
+// RenderPass.m
+// Core3D
+//
+// Created by CoreCode on 21.11.10.
+// Copyright 2010 - 2012 CoreCode. Licensed under the MIT License, see LICENSE.txt
+//
+
+#import "Core3D.h"
+#import "RenderPass.h"
+#import "ShadowShader.h"
+#import "FocusingCamera.h"
+
+
+#undef glEnable
+#undef glDisable
+
+@implementation RenderPass
+
+@synthesize camera, lights, objects, renderTarget, autoresizingMask, frame, settings, viewportMatrix, currentPVSCell;
+
++ (RenderPass *)mainRenderPass
+{
+ RenderPass *rp = [[[RenderPass alloc] initWithFrame:CGRectMake(0, 0, [scene bounds].width, [scene bounds].height)
+ andAutoresizingMask:kCALayerWidthSizable | kCALayerHeightSizable] autorelease];
+ [rp setRenderTarget:[[[RenderTarget alloc] initWithWidthMultiplier:1.0 andHeightMultiplier:1.0] autorelease]];
+
+ Light *light = [[[Light alloc] init] autorelease];
+ [[rp lights] addObject:light];
+
+ [scene setMainRenderPass:rp];
+ [[scene renderpasses] addObject:rp];
+
+ return rp;
+}
+
++ (RenderPass *)shadowRenderPassWithSize:(int)size light:(Light *)light casters:(NSArray *)casters andMainCamera:(Camera *)mainCamera
+{
+ ShadowShader *ss = [[ShadowShader alloc] init];
+ [[ss children] addObjectsFromArray:casters];
+
+ RenderPass *sp = [[RenderPass alloc] initWithFrame:CGRectMake(0, 0, size, size) andAutoresizingMask:0];
+ sp.settings = kRenderPassUpdateCulling;
+ FocusingCamera *fc = [[FocusingCamera alloc] init];