Basic but working new planet drawable. Can be tested on ships by enabling BALL_WORLD in ShipEntity.m.

git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@2799 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
Jens Ayton 2009-11-29 14:36:22 +00:00
parent fd7cd71011
commit 7dcf2df39c
15 changed files with 48948 additions and 55 deletions

View File

@ -539,6 +539,11 @@
1A94E4FC0F348D5700F1B5D9 /* delayedReactToAttackAI.plist in Copy AIs */ = {isa = PBXBuildFile; fileRef = 1A94E4FB0F348D4300F1B5D9 /* delayedReactToAttackAI.plist */; };
1A95338B0C02089E004EBB58 /* material-defaults.plist in Copy Config */ = {isa = PBXBuildFile; fileRef = 1A9533890C02089E004EBB58 /* material-defaults.plist */; };
1A95338C0C02089E004EBB58 /* planetinfo.plist in Copy Config */ = {isa = PBXBuildFile; fileRef = 1A95338A0C02089E004EBB58 /* planetinfo.plist */; };
1AA7FCAB10C2B9BA0058FBED /* OOPlanetDrawable.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AA7FCA910C2B9BA0058FBED /* OOPlanetDrawable.h */; };
1AA7FCAC10C2B9BA0058FBED /* OOPlanetDrawable.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AA7FCAA10C2B9BA0058FBED /* OOPlanetDrawable.m */; };
1AA7FCAF10C2BA3B0058FBED /* OOPlanetData.c in Sources */ = {isa = PBXBuildFile; fileRef = 1AA7FCAD10C2BA3B0058FBED /* OOPlanetData.c */; };
1AA7FCB010C2BA3B0058FBED /* OOPlanetData.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AA7FCAE10C2BA3B0058FBED /* OOPlanetData.h */; };
1AA7FCD210C2BDDD0058FBED /* oolite-planet-temp.png in Resources */ = {isa = PBXBuildFile; fileRef = 1AA7FCD110C2BDDD0058FBED /* oolite-planet-temp.png */; };
1AA82C8A0CC10E700023B797 /* OOJSWorldScripts.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AA82C820CC10E3D0023B797 /* OOJSWorldScripts.m */; };
1AAB9A980D779F4500A9F424 /* OOCocoa.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AAB9A960D779F3C00A9F424 /* OOCocoa.m */; };
1AAF56170F1A198400A2F2E6 /* Comparison.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AAF56160F1A198400A2F2E6 /* Comparison.h */; };
@ -680,7 +685,7 @@
isa = PBXContainerItemProxy;
containerPortal = 1A0519340C7CCAC900BA5CCA /* DebugOXP.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 8D5B49AC048680CD000E48DA /* DebugOXP */;
remoteGlobalIDString = 8D5B49AC048680CD000E48DA;
remoteInfo = DebugOXP;
};
1A3042F310C16DA60056219D /* PBXContainerItemProxy */ = {
@ -1611,6 +1616,11 @@
1A94E4FB0F348D4300F1B5D9 /* delayedReactToAttackAI.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = delayedReactToAttackAI.plist; sourceTree = "<group>"; };
1A9533890C02089E004EBB58 /* material-defaults.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = "material-defaults.plist"; sourceTree = "<group>"; };
1A95338A0C02089E004EBB58 /* planetinfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = planetinfo.plist; sourceTree = "<group>"; };
1AA7FCA910C2B9BA0058FBED /* OOPlanetDrawable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOPlanetDrawable.h; sourceTree = "<group>"; };
1AA7FCAA10C2B9BA0058FBED /* OOPlanetDrawable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOPlanetDrawable.m; sourceTree = "<group>"; };
1AA7FCAD10C2BA3B0058FBED /* OOPlanetData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = OOPlanetData.c; sourceTree = "<group>"; };
1AA7FCAE10C2BA3B0058FBED /* OOPlanetData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOPlanetData.h; sourceTree = "<group>"; };
1AA7FCD110C2BDDD0058FBED /* oolite-planet-temp.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "oolite-planet-temp.png"; sourceTree = "<group>"; };
1AA82C810CC10E3D0023B797 /* OOJSWorldScripts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOJSWorldScripts.h; sourceTree = "<group>"; };
1AA82C820CC10E3D0023B797 /* OOJSWorldScripts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOJSWorldScripts.m; sourceTree = "<group>"; };
1AAB9A960D779F3C00A9F424 /* OOCocoa.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOCocoa.m; sourceTree = "<group>"; };
@ -1987,6 +1997,7 @@
1A35916B0C1C375400E52220 /* oolite-nebula-3.png */,
1A0365990D7CA0EE00B5F46F /* oolite-nebula-4.png */,
1A817C16106D123F00AA2F97 /* oolite-particle-blur.png */,
1AA7FCD110C2BDDD0058FBED /* oolite-planet-temp.png */,
1ACE208E0D805F78009F6957 /* oolite-scarred-metal-specular.png */,
1A35916A0C1C375400E52220 /* oolite-star-1.png */,
1A2318490B9D026D00EF0852 /* pod2_redux.png */,
@ -2832,6 +2843,10 @@
1A2A1CA90BD2914F00152975 /* OOMesh.m */,
1A1504490C12C50D0032F3E8 /* OOSkyDrawable.h */,
1A15044A0C12C50D0032F3E8 /* OOSkyDrawable.m */,
1AA7FCA910C2B9BA0058FBED /* OOPlanetDrawable.h */,
1AA7FCAA10C2B9BA0058FBED /* OOPlanetDrawable.m */,
1AA7FCAE10C2BA3B0058FBED /* OOPlanetData.h */,
1AA7FCAD10C2BA3B0058FBED /* OOPlanetData.c */,
);
name = Drawables;
sourceTree = "<group>";
@ -3087,6 +3102,8 @@
2B4CDFEC107B3D8400526C98 /* OOJSManifest.h in Headers */,
1AB9AE8B107F459B00B6F3CE /* OOPolygonSprite.h in Headers */,
1A6AA36510C13B1D00383767 /* SunEntity.h in Headers */,
1AA7FCAB10C2B9BA0058FBED /* OOPlanetDrawable.h in Headers */,
1AA7FCB010C2BA3B0058FBED /* OOPlanetData.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3232,6 +3249,7 @@
1A2123291051892D00530CDE /* slow-gpus.plist in Resources */,
2B13C520105D342D00AF4A7B /* oolite-nova-system.png in Resources */,
2B9A1089105D526200EE2AE6 /* javascript-errors.plist in Resources */,
1AA7FCD210C2BDDD0058FBED /* oolite-planet-temp.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3441,6 +3459,8 @@
1AB9AE8C107F459B00B6F3CE /* OOPolygonSprite.m in Sources */,
1A6A963310AEEC5D0065D0F3 /* AIGraphViz.m in Sources */,
1A6AA36610C13B1D00383767 /* SunEntity.m in Sources */,
1AA7FCAC10C2B9BA0058FBED /* OOPlanetDrawable.m in Sources */,
1AA7FCAF10C2BA3B0058FBED /* OOPlanetData.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -23,6 +23,9 @@ MA 02110-1301, USA.
*/
#define BALL_WORLD 0
#import "ShipEntity.h"
#import "ShipEntityAI.h"
#import "ShipEntityScriptMethods.h"
@ -49,6 +52,10 @@ MA 02110-1301, USA.
#endif
#import "OOMesh.h"
#if BALL_WORLD
#import "OOPlanetDrawable.h"
#endif
#import "Geometry.h"
#import "Octree.h"
#import "OOColor.h"
@ -1320,7 +1327,7 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
- (OOEquipmentType *) newMissile
{
ShipEntity *missile = nil;
OOEquipmentType *missileType;
OOEquipmentType *missileType = nil;
BOOL isMissileType = NO;
id value;
@ -3356,6 +3363,27 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
}
#if BALL_WORLD
- (void)drawEntity2:(BOOL)immediate :(BOOL)translucent
{
if (no_draw_distance < zero_distance)
{
// Don't draw.
return;
}
if ([UNIVERSE wireframeGraphics]) GLDebugWireframeModeOn();
OOPlanetDrawable *ball = [OOPlanetDrawable planetWithTextureName:@"oolite-planet-temp.png" radius:[[self mesh] collisionRadius] eccentricity:0];
if (translucent) [ball renderTranslucentParts];
else [ball renderOpaqueParts];
if ([UNIVERSE wireframeGraphics]) GLDebugWireframeModeOff();
}
#endif
- (void)drawEntity:(BOOL)immediate :(BOOL)translucent
{
NSEnumerator *subEntityEnum = nil;
@ -3369,7 +3397,11 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
}
// Draw self.
#if BALL_WORLD
[self drawEntity2:immediate :translucent];
#else
[super drawEntity:immediate :translucent];
#endif
#ifndef NDEBUG
// Draw bounding boxes if we have to before going for the subentities.

View File

@ -50,6 +50,9 @@ OOINLINE OOMatrix OOMatrixFromOrientationAndPosition(Quaternion orientation, Vec
OOINLINE OOMatrix OOMatrixFromBasisVectorsAndPosition(Vector i, Vector j, Vector k, Vector position) INLINE_CONST_FUNC;
OOINLINE OOMatrix OOMatrixFromBasisVectors(Vector i, Vector j, Vector k) INLINE_CONST_FUNC;
OOINLINE OOMatrix OOMatrixForScale(OOScalar sx, OOScalar sy, OOScalar sz) INLINE_CONST_FUNC;
OOINLINE OOMatrix OOMatrixForScaleUniform(OOScalar s) INLINE_CONST_FUNC;
OOINLINE OOMatrix OOMatrixForRotationX(OOScalar angle) INLINE_CONST_FUNC;
OOINLINE OOMatrix OOMatrixForRotationY(OOScalar angle) INLINE_CONST_FUNC;
OOINLINE OOMatrix OOMatrixForRotationZ(OOScalar angle) INLINE_CONST_FUNC;
@ -66,6 +69,9 @@ OOMatrix OOMatrixForBillboard(Vector bbPos, Vector eyePos) CONST_FUNC;
OOINLINE OOMatrix OOMatrixTranslate(OOMatrix m, Vector offset) INLINE_CONST_FUNC;
OOINLINE OOMatrix OOMatrixTranslateComponents(OOMatrix m, OOScalar dx, OOScalar dy, OOScalar dz) INLINE_CONST_FUNC;
OOINLINE OOMatrix OOMatrixScale(OOMatrix m, OOScalar sx, OOScalar sy, OOScalar sz) INLINE_CONST_FUNC;
OOINLINE OOMatrix OOMatrixScaleUniform(OOMatrix m, OOScalar s) INLINE_CONST_FUNC;
OOINLINE OOMatrix OOMatrixRotateX(OOMatrix m, OOScalar angle) INLINE_CONST_FUNC;
OOINLINE OOMatrix OOMatrixRotateY(OOMatrix m, OOScalar angle) INLINE_CONST_FUNC;
OOINLINE OOMatrix OOMatrixRotateZ(OOMatrix m, OOScalar angle) INLINE_CONST_FUNC;
@ -234,6 +240,36 @@ OOINLINE OOMatrix OOMatrixTranslate(OOMatrix m, Vector offset)
}
OOINLINE OOMatrix OOMatrixForScale(OOScalar sx, OOScalar sy, OOScalar sz)
{
return OOMatrixConstruct
(
sx, 0, 0, 0,
0, sy, 0, 0,
0, 0, sz, 0,
0, 0, 0, 1
);
}
OOINLINE OOMatrix OOMatrixForScaleUniform(OOScalar s)
{
return OOMatrixForScale(s, s, s);
}
OOINLINE OOMatrix OOMatrixScale(OOMatrix m, OOScalar sx, OOScalar sy, OOScalar sz)
{
return OOMatrixMultiply(m, OOMatrixForScale(sx, sy, sz));
}
OOINLINE OOMatrix OOMatrixScaleUniform(OOMatrix m, OOScalar s)
{
return OOMatrixScale(m, s, s, s);
}
OOINLINE OOMatrix OOMatrixRotateX(OOMatrix m, OOScalar angle)
{
return OOMatrixMultiply(m, OOMatrixForRotationX(angle));

View File

@ -28,47 +28,7 @@ MA 02110-1301, USA.
*/
#import "OOCocoa.h"
#if OOLITE_MAC_OS_X
// Apple OpenGL includes...
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <OpenGL/glext.h>
#elif OOLITE_SDL
// SDL OpenGL includes...
// prevent the including of SDL_opengl.h loading a previous version of glext.h
#define NO_SDL_GLEXT
// GL_GLEXT_PROTOTYPES must be defined for the Linux build to use shaders.
#if OOLITE_LINUX
#ifndef GL_GLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES
#define __DEFINED_GL_GLEXT_PROTOTYPES
#endif // GL_GLEXT_PROTOTYPES
#endif // OOLITE_LINUX && !OOLITE_WINDOWS
// the standard SDL_opengl.h
#include <SDL_opengl.h>
// include an up-to-date version of glext.h
#include <GL/glext.h>
#ifdef __DEFINED_GL_GLEXT_PROTOTYPES
#undef GL_GLEXT_PROTOTYPES
#undef __DEFINED_GL_GLEXT_PROTOTYPES
#endif
#else // Not OS X or SDL
#error OOOpenGL.h: unknown target!
#endif
#import "OOOpenGLOnly.h"
#define NULL_SHADER ((GLhandleARB)0)

66
src/Core/OOOpenGLOnly.h Normal file
View File

@ -0,0 +1,66 @@
/*
OOOpenGL.h
Do whatever is appropriate to get gl.h, glu.h and glext.h included.
Oolite
Copyright (C) 2004-2008 Giles C Williams and contributors
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
#if OOLITE_MAC_OS_X
// Apple OpenGL includes...
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <OpenGL/glext.h>
#elif OOLITE_SDL
// SDL OpenGL includes...
// prevent the including of SDL_opengl.h loading a previous version of glext.h
#define NO_SDL_GLEXT
// GL_GLEXT_PROTOTYPES must be defined for the Linux build to use shaders.
#if OOLITE_LINUX
#ifndef GL_GLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES
#define __DEFINED_GL_GLEXT_PROTOTYPES
#endif // GL_GLEXT_PROTOTYPES
#endif // OOLITE_LINUX && !OOLITE_WINDOWS
// the standard SDL_opengl.h
#include <SDL_opengl.h>
// include an up-to-date version of glext.h
#include <GL/glext.h>
#ifdef __DEFINED_GL_GLEXT_PROTOTYPES
#undef GL_GLEXT_PROTOTYPES
#undef __DEFINED_GL_GLEXT_PROTOTYPES
#endif
#else // Not OS X or SDL
#error OOOpenGL.h: unknown target!
#endif

48276
src/Core/OOPlanetData.c Normal file

File diff suppressed because it is too large Load Diff

31
src/Core/OOPlanetData.h Normal file
View File

@ -0,0 +1,31 @@
/*
OOPlanetData.h
For Oolite
This file was automatically generated by tools/icosmesh. Do not modify.
This data may be used freely.
*/
#import "OOOpenGLOnly.h"
#define kOOPlanetDataLevels 6
typedef struct
{
unsigned vertexCount;
unsigned faceCount;
GLenum type;
const void *indices; // faceCount * 3
} OOPlanetDataLevel;
extern const OOPlanetDataLevel kPlanetData[kOOPlanetDataLevels];
#define kOOPlanetDataVertexCount 10446
extern const GLfloat kOOPlanetVertices[kOOPlanetDataVertexCount * 3];
extern const GLfloat kOOPlanetTexCoords[kOOPlanetDataVertexCount * 2];

View File

@ -0,0 +1,65 @@
/*
OOPlanetDrawable.h
Draw a ball, such as might be used to represent a planet.
Oolite
Copyright (C) 2004-2009 Giles C Williams and contributors
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
#import "OODrawable.h"
#import "OOMaths.h"
@class OOMaterial;
@interface OOPlanetDrawable: OODrawable
{
@private
OOMaterial *_material;
BOOL _isAtmosphere;
float _radius;
float _eccentricity;
OOMatrix _transform;
unsigned _lod;
}
+ (id) planetWithTextureName:(NSString *)textureName radius:(float)radius eccentricity:(float)eccentricity;
+ (id) atmosphereWithRadius:(float)radius eccentricity:(float)eccentricity;
- (id) initAsAtmosphere;
- (NSString *) textureName;
- (void) setTextureName:(NSString *)textureName;
// Radius, in game metres.
- (float) radius;
- (void) setRadius:(float)radius;
// Eccentricity, [0..1).
- (float) eccentricity;
- (void) setEccentricity:(float)eccentricity;
// Level of detail, [0..1]. Granularity is implementation-defined.
- (float) levelOfDetail;
- (void) setLevelOfDetail:(float)lod;
- (void) calculateLevelOfDetailForViewDistance:(float)distance;
@end

342
src/Core/OOPlanetDrawable.m Normal file
View File

@ -0,0 +1,342 @@
/*
OOPlanetDrawable.m
Oolite
Copyright (C) 2004-2009 Giles C Williams and contributors
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
#import "OOPlanetDrawable.h"
#import "OOPlanetData.h"
#import "OOSingleTextureMaterial.h"
#import "OOOpenGL.h"
#import "OOMacroOpenGL.h"
#import "Universe.h"
#ifndef NDEBUG
#import "Entity.h"
#import "OODebugGLDrawing.h"
#endif
#define LOD_GRANULARITY ((float)(kOOPlanetDataLevels - 1))
@interface OOPlanetDrawable (Private)
- (void) recalculateTransform;
- (void) debugDrawNormals;
@end
@implementation OOPlanetDrawable
+ (id) planetWithTextureName:(NSString *)textureName radius:(float)radius eccentricity:(float)eccentricity
{
OOPlanetDrawable *result = [[[self alloc] init] autorelease];
[result setTextureName:textureName];
[result setRadius:radius];
[result setEccentricity:eccentricity];
return result;
}
+ (id) atmosphereWithRadius:(float)radius eccentricity:(float)eccentricity
{
OOPlanetDrawable *result = [[[self alloc] initAsAtmosphere] autorelease];
[result setRadius:radius];
[result setEccentricity:eccentricity];
return result;
}
- (id) init
{
if ((self = [super init]))
{
_radius = 1.0f;
_eccentricity = 0.0f;
[self recalculateTransform];
[self setLevelOfDetail:0.5f];
}
return self;
}
- (id) initAsAtmosphere
{
if ((self = [self init]))
{
_isAtmosphere = YES;
[self setTextureName:@"oolite-temp-atmosphere.png"];
}
return self;
}
- (void) dealloc
{
[_material release];
[super dealloc];
}
- (NSString *) textureName
{
return [_material name];
}
- (void) setTextureName:(NSString *)textureName
{
if (![textureName isEqual:[self textureName]])
{
[_material release];
_material = [[OOSingleTextureMaterial alloc] initWithName:textureName configuration:nil];
}
}
- (float) radius
{
return _radius;
}
- (void) setRadius:(float)radius
{
_radius = fabsf(radius);
[self recalculateTransform];
}
- (float) eccentricity
{
return _eccentricity;
}
- (void) setEccentricity:(float)eccentricity
{
_eccentricity = OOClamp_0_1_f(eccentricity);
[self recalculateTransform];
}
- (float) levelOfDetail
{
return (float)_lod / LOD_GRANULARITY;
}
- (void) setLevelOfDetail:(float)lod
{
if (lod < 0.0f) _lod = 0;
else _lod = roundf(lod * LOD_GRANULARITY);
}
- (void) calculateLevelOfDetailForViewDistance:(float)distance
{
// FIXME
[self setLevelOfDetail:1.0f];
}
- (void) renderOpaqueParts
{
assert(_lod < kOOPlanetDataLevels);
BOOL shaders = NO;//[UNIVERSE shaderEffectsLevel] > SHADERS_OFF;
const OOPlanetDataLevel *data = &kPlanetData[_lod];
OO_ENTER_OPENGL();
OOGL(glPushAttrib(GL_ENABLE_BIT));
OOGL(glShadeModel(GL_SMOOTH));
if (_isAtmosphere)
{
OOGL(glEnable(GL_BLEND));
}
else
{
OOGL(glDisable(GL_BLEND));
}
[_material apply];
// Scale the ball.
glPushMatrix();
GLMultOOMatrix(_transform);
OOGL(glEnable(GL_LIGHTING));
OOGL(glEnable(GL_TEXTURE_2D));
OOGL(glDisableClientState(GL_COLOR_ARRAY));
OOGL(glDisableClientState(GL_INDEX_ARRAY));
OOGL(glDisableClientState(GL_EDGE_FLAG_ARRAY));
OOGL(glEnableClientState(GL_VERTEX_ARRAY));
OOGL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
OOGL(glVertexPointer(3, GL_FLOAT, 0, kOOPlanetVertices));
OOGL(glTexCoordPointer(2, GL_FLOAT, 0, kOOPlanetTexCoords));
if (!shaders)
{
// FIXME: instead of GL_RESCALE_NORMAL, consider copying and transforming the vertex array for each planet.
glEnable(GL_RESCALE_NORMAL);
OOGL(glEnableClientState(GL_NORMAL_ARRAY));
OOGL(glNormalPointer(GL_FLOAT, 0, kOOPlanetVertices));
}
OOGL(glDrawElements(GL_TRIANGLES, data->faceCount * 3, data->type, data->indices));
glPopMatrix();
#ifndef NDEBUG
if (gDebugFlags & DEBUG_DRAW_NORMALS) [self debugDrawNormals];
#endif
[OOMaterial applyNone];
OOGL(glPopAttrib());
}
- (void) renderTranslucentParts
{
[self renderOpaqueParts];
}
- (BOOL) hasOpaqueParts
{
return !_isAtmosphere;
}
- (BOOL) hasTranslucentParts
{
return _isAtmosphere;
}
- (GLfloat) collisionRadius
{
return _radius;
}
- (GLfloat) maxDrawDistance
{
// FIXME
return INFINITY;
}
- (BoundingBox) boundingBox
{
// FIXME: take eccentricity into account for y.
return (BoundingBox){{ -_radius, -_radius, -_radius }, { _radius, _radius, _radius }};
}
- (void) setBindingTarget:(id<OOWeakReferenceSupport>)target
{
[_material setBindingTarget:target];
}
- (void) dumpSelfState
{
[super dumpSelfState];
OOLog(@"dumpState.planetDrawable", @"radius: %g", [self radius]);
OOLog(@"dumpState.planetDrawable", @"eccentricity: %g", [self eccentricity]);
OOLog(@"dumpState.planetDrawable", @"LOD: %g", [self levelOfDetail]);
}
- (void) recalculateTransform
{
// FIXME: teh eccentricities
_transform = OOMatrixForScaleUniform(_radius);
}
#ifndef NDEBUG
- (void) debugDrawNormals
{
OODebugWFState state;
OO_ENTER_OPENGL();
state = OODebugBeginWireframe(NO);
const OOPlanetDataLevel *data = &kPlanetData[_lod];
unsigned i;
OOGLBEGIN(GL_LINES);
for (i = 0; i < data->vertexCount; i++)
{
/* Fun sphere facts: the normalized coordinates of a point on a sphere at the origin
is equal to the object-space normal of the surface at that point.
Furthermore, we can construct the binormal (a vector pointing westward along the
surface) as the cross product of the normal with the Y axis. (This produces
singularities at the pole, but there have to be singularities according to the
Hairy Ball Theorem.) The tangent (a vector north along the surface) is then the
inverse of the cross product of the normal and binormal.
(This comment courtesy of the in-development planet shader.)
*/
Vector v = make_vector(kOOPlanetVertices[i * 3], kOOPlanetVertices[i * 3 + 1], kOOPlanetVertices[i * 3 + 2]);
Vector n = v;
v = OOVectorMultiplyMatrix(v, _transform);
glColor3f(0.0f, 1.0f, 1.0f);
GLVertexOOVector(v);
GLVertexOOVector(vector_add(v, vector_multiply_scalar(n, _radius * 0.05)));
Vector b = cross_product(n, kBasisYVector);
Vector t = vector_flip(true_cross_product(n, b));
glColor3f(1.0f, 1.0f, 0.0f);
GLVertexOOVector(v);
GLVertexOOVector(vector_add(v, vector_multiply_scalar(t, _radius * 0.03)));
glColor3f(0.0f, 1.0f, 0.0f);
GLVertexOOVector(v);
GLVertexOOVector(vector_add(v, vector_multiply_scalar(b, _radius * 0.03)));
}
OOGLEND();
OODebugEndWireframe(state);
}
#endif
@end

View File

@ -19,6 +19,7 @@ static inline BOOL IsPolarVector(Vector v)
- (void) rotate; // a = b, b = c, c = a
- (void) generateTextureCoordinates; // Requires that any polar coordinate is in [0].
- (void) fixUpWinding;
@end
@ -55,6 +56,9 @@ static NSString *VertexDescription(Vertex v)
if (IsPolarVector(_vertices[2].v)) [self rotate];
if (IsPolarVector(_vertices[1].v)) [self rotate];
// Ensure winding is consistent.
[self fixUpWinding];
[self generateTextureCoordinates];
}
@ -188,4 +192,26 @@ static NSString *VertexDescription(Vertex v)
return [NSArray arrayWithObjects:subTris count:4];
}
- (void) fixUpWinding
{
// Construct vectors from v0 to v1 and v0 to v2.
Vector ab = VectorSubtract(_vertices[1].v, _vertices[0].v);
Vector ac = VectorSubtract(_vertices[2].v, _vertices[0].v);
// Take their cross product.
Vector cross = VectorCross(ab, ac);
// For a correctly-wound triangle, this should point inwards.
// Since our corner vectors point generally outwards, the dot product of
// any of these with cross should be negative.
if (VectorDot(cross, _vertices[0].v) > 0)
{
// If not, we swap v1 and v2.
Vertex temp = _vertices[1];
_vertices[1] = _vertices[2];
_vertices[2] = temp;
}
}
@end

View File

@ -1,2 +0,0 @@
typedef float GLfloat;
typedef unsigned GLuint;

View File

@ -0,0 +1,10 @@
typedef float GLfloat;
typedef unsigned long GLenum;
typedef unsigned char GLubyte;
typedef unsigned short GLushort;
typedef unsigned long GLuint;
#define GL_UNSIGNED_BYTE 0x1401
#define GL_UNSIGNED_SHORT 0x1403
#define GL_UNSIGNED_INT 0x1405

View File

@ -39,6 +39,17 @@ static inline double VectorDot(Vector u, Vector v)
}
static inline Vector VectorCross(Vector u, Vector v)
{
return (Vector)
{
u.y * v.z - v.y * u.z,
u.z * v.x - v.z * u.x,
u.x * v.y - v.x * u.y
};
}
static inline double VectorMagnitude(Vector v)
{
return sqrt(VectorDot(v, v));

View File

@ -50,7 +50,7 @@
1A675F6110B466AF00786F5F /* generatemesh.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = generatemesh.c; sourceTree = "<group>"; };
1A675F6610B466CE00786F5F /* OOPlanetData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = OOPlanetData.c; path = build/Debug/OOPlanetData.c; sourceTree = "<group>"; };
1A675F6710B466CE00786F5F /* OOPlanetData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OOPlanetData.h; path = build/Debug/OOPlanetData.h; sourceTree = "<group>"; };
1A675F7610B4684900786F5F /* OOOpenGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOOpenGL.h; sourceTree = "<group>"; };
1A675F7610B4684900786F5F /* OOOpenGLOnly.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOOpenGLOnly.h; sourceTree = "<group>"; };
1A67605410B479D200786F5F /* JAIcosTriangle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JAIcosTriangle.h; sourceTree = "<group>"; };
1A67605510B479D200786F5F /* JAIcosTriangle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JAIcosTriangle.m; sourceTree = "<group>"; };
1A67605710B479EA00786F5F /* icosmesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = icosmesh.h; sourceTree = "<group>"; };
@ -109,7 +109,7 @@
children = (
08FB7796FE84155DC02AAC07 /* main.m */,
1A67605710B479EA00786F5F /* icosmesh.h */,
1A675F7610B4684900786F5F /* OOOpenGL.h */,
1A675F7610B4684900786F5F /* OOOpenGLOnly.h */,
1A67605410B479D200786F5F /* JAIcosTriangle.h */,
1A67605510B479D200786F5F /* JAIcosTriangle.m */,
1A67608E10B4897B00786F5F /* JAVertexSet.h */,

View File

@ -67,6 +67,8 @@ static void WritePrelude(FILE *header, FILE *source);
static void WriteVertices(FILE *header, FILE *source, JAVertexSet *vertices);
static void WriteMeshForTriangles(FILE *source, unsigned level, NSArray *triangles, JAVertexSet *vertices, unsigned *faceCount, unsigned *maxVertex);
static void WriteMesh(FILE *source, unsigned level, JAIcosMesh *mesh);
static const char *SizeEnumeratorForMaximum(unsigned maxValue);
static const char *SizeTypeForMaximum(unsigned maxValue);
int main (int argc, const char * argv[])
@ -114,7 +116,7 @@ int main (int argc, const char * argv[])
for (i = 0; i < kLevels; i++)
{
if (i != 0) fprintf(source, ",\n");
fprintf(source, "\t%u, %u, kFaceIndicesLevel%u", maxIndex[i], faceCount[i], i);
fprintf(source, "\t{ %u, %u, %s, kFaceIndicesLevel%u }", maxIndex[i], faceCount[i], SizeEnumeratorForMaximum(maxIndex[i]), i);
}
fprintf(source, "\n};\n");
@ -150,7 +152,7 @@ static void WritePrelude(FILE *header, FILE *source)
"\tThis data may be used freely.\n"
"*/\n"
"\n"
"#import \"OOOpenGL.h\"\n"
"#import \"OOOpenGLOnly.h\"\n"
"\n"
"\n"
"#define kOOPlanetDataLevels %u\n"
@ -160,7 +162,8 @@ static void WritePrelude(FILE *header, FILE *source)
"{\n"
"\tunsigned vertexCount;\n"
"\tunsigned faceCount;\n"
"\tconst GLuint *indices; // faceCount * 3\n"
"\tGLenum type;\n"
"\tconst void *indices; // faceCount * 3\n"
"} OOPlanetDataLevel;\n"
"\n"
"\n"
@ -184,10 +187,11 @@ static void WriteVertices(FILE *header, FILE *source, JAVertexSet *vertices)
{
unsigned i, count = vertices.count;
fprintf(header, "\n\nextern const GLfloat kOOPlanetVertices[%u];\n", count * 3);
fprintf(header, "\nextern const GLfloat kOOPlanetTexCoords[%u];\n", count * 2);
fprintf(header, "\n\n#define kOOPlanetDataVertexCount %u\n\n", count);
fprintf(header, "extern const GLfloat kOOPlanetVertices[kOOPlanetDataVertexCount * 3];\n");
fprintf(header, "extern const GLfloat kOOPlanetTexCoords[kOOPlanetDataVertexCount * 2];\n");
fprintf(source, "\n\n/* Shared vertex array\n %u vertices\n*/\nconst GLfloat kOOPlanetVertices[%u] =\n{\n", count, count * 3);
fprintf(source, "\n\n/* Shared vertex array\n %u vertices\n*/\nconst GLfloat kOOPlanetVertices[kOOPlanetDataVertexCount * 3] =\n{\n", count);
NSArray *data = [vertices positionArray];
for (i = 0; i < count; i++)
{
@ -195,7 +199,7 @@ static void WriteVertices(FILE *header, FILE *source, JAVertexSet *vertices)
fprintf(source, "\t%+.8ff, %+.8ff, %+.8ff", [[data objectAtIndex:i * 3] doubleValue], [[data objectAtIndex:i * 3 + 1] doubleValue], [[data objectAtIndex:i * 3 + 2] doubleValue]);
}
fprintf(source, "\n};\n\n/* Shared texture coordinate array\n %u pairs\n*/\nconst GLfloat kOOPlanetTexCoords[%u] =\n{\n", count, count * 2);
fprintf(source, "\n};\n\n/* Shared texture coordinate array\n %u pairs\n*/\nconst GLfloat kOOPlanetTexCoords[kOOPlanetDataVertexCount * 2] =\n{\n", count);
data = [vertices texCoordArray];
for (i = 0; i < count; i++)
{
@ -223,7 +227,7 @@ static void WriteMesh(FILE *source, unsigned level, JAIcosMesh *mesh)
unsigned i, count = mesh.faceCount;
NSArray *indices = [mesh indexArray];
fprintf(source, "\n\n/* Level %u index array\n %u faces\n*/\nstatic const GLuint kFaceIndicesLevel%u[%u] =\n{\n", level, count, level, count * 3);
fprintf(source, "\n\n/* Level %u index array\n %u faces\n*/\nstatic const %s kFaceIndicesLevel%u[%u] =\n{\n", level, count, SizeTypeForMaximum(mesh.maxIndex), level, count * 3);
for (i = 0; i < count; i++)
{
if (i != 0) fprintf(source, ",\n");
@ -284,3 +288,19 @@ void VectorToCoords0_1(Vector v, double *latitude, double *longitude)
if (latitude != NULL) *latitude = 1.0 - (*latitude / M_PI + 0.5);
if (longitude != NULL) *longitude = 1.0 - (*longitude / (M_PI * 2.0) + 0.5);
}
static const char *SizeEnumeratorForMaximum(unsigned maxValue)
{
if (maxValue <= UCHAR_MAX) return "GL_UNSIGNED_BYTE";
if (maxValue <= USHRT_MAX) return "GL_UNSIGNED_SHORT";
return "GL_UNSIGNED_INT";
}
static const char *SizeTypeForMaximum(unsigned maxValue)
{
if (maxValue <= UCHAR_MAX) return "GLubyte";
if (maxValue <= USHRT_MAX) return "GLushort";
return "GLuint";
}