Oolite 1.91.0.7646-241128-10e222e
Loading...
Searching...
No Matches
OOMesh(Private) Category Reference
+ Inheritance diagram for OOMesh(Private):
+ Collaboration diagram for OOMesh(Private):

Instance Methods

(id) - initWithName:cacheKey:materialDictionary:shadersDictionary:smooth:shaderMacros:shaderBindingTarget:scaleFactor:cacheWriteable:
 
(BOOL) - loadData:scaleFactor:
 
(void) - checkNormalsAndAdjustWinding
 
(void) - generateFaceTangents
 
(void) - calculateVertexNormalsAndTangentsWithFaceRefs:
 
(void) - calculateVertexTangentsWithFaceRefs:
 
(void) - deleteDisplayLists
 
(NSDictionary *) - modelData
 
(BOOL) - setModelFromModelData:name:
 
(void) - getNormal:andTangent:forVertex:inSmoothGroup:
 
(BOOL) - setUpVertexArrays
 
(void) - calculateBoundingVolumes
 
(void) - rescaleByFactor:
 
(void) - debugDrawNormals
 
(void) - setRetainedObject:forKey:
 
(void *) - allocateBytesWithSize:count:key:
 
(BOOL) - allocateVertexBuffersWithCount:
 
(BOOL) - allocateNormalBuffersWithCount:
 
(BOOL) - allocateFaceBuffersWithCount:
 
(BOOL) - allocateVertexArrayBuffersWithCount:
 
(void) - renameTexturesFrom:to:
 
(id) - mutableCopyWithZone: [implementation]
 
(void) - resetGraphicsState [implementation]
 
(BoundingBox) - boundingBox [implementation]
 
- Instance Methods inherited from <OOGraphicsResetClient>

Class Methods

(static float) + FaceArea [implementation]
 
(static float) + FaceAreaCorrect [implementation]
 

Detailed Description

Definition at line 130 of file OOMesh.m.

Method Documentation

◆ allocateBytesWithSize:count:key:

- (void *) allocateBytesWithSize: (size_t) size
count: (NSUInteger) count
key: (NSString *) key 

Extends class OOMesh.

Definition at line 1792 of file OOMesh.m.

2141 :(size_t)size count:(NSUInteger)count key:(NSString *)key
2142{
2143 if (count == 0) { count=1; }
2144 size *= count;
2145 void *bytes = malloc(size);
2146 if (bytes != NULL)
2147 {
2148 Scribble(bytes, size);
2149 NSData *holder = [NSData dataWithBytesNoCopy:bytes length:size freeWhenDone:YES];
2150 [self setRetainedObject:holder forKey:key];
2151 }
2152 return bytes;
2153}
#define Scribble(bytes, size)
Definition OOMesh.m:2134
unsigned count
voidpf void uLong size
Definition ioapi.h:134

◆ allocateFaceBuffersWithCount:

- (BOOL) allocateFaceBuffersWithCount: (NSUInteger) count

Extends class OOMesh.

Definition at line 1792 of file OOMesh.m.

2171 :(NSUInteger)count
2172{
2173 _faces = [self allocateBytesWithSize:sizeof *_faces count:faceCount key:@"faces"];
2174 return _faces != NULL;
2175}

◆ allocateNormalBuffersWithCount:

- (BOOL) allocateNormalBuffersWithCount: (NSUInteger) count

Extends class OOMesh.

Definition at line 1792 of file OOMesh.m.

2163 :(NSUInteger)count
2164{
2165 _normals = [self allocateBytesWithSize:sizeof *_normals count:vertexCount key:@"normals"];
2166 _tangents = [self allocateBytesWithSize:sizeof *_tangents count:vertexCount key:@"tangents"];
2167 return _normals != NULL && _tangents != NULL;
2168}

◆ allocateVertexArrayBuffersWithCount:

- (BOOL) allocateVertexArrayBuffersWithCount: (NSUInteger) count

Extends class OOMesh.

Definition at line 1792 of file OOMesh.m.

2178 :(NSUInteger)count
2179{
2180 _displayLists.indexArray = [self allocateBytesWithSize:sizeof *_displayLists.indexArray count:count * 3 key:@"indexArray"];
2181 _displayLists.textureUVArray = [self allocateBytesWithSize:sizeof *_displayLists.textureUVArray count:count * 6 key:@"textureUVArray"];
2182 _displayLists.vertexArray = [self allocateBytesWithSize:sizeof *_displayLists.vertexArray count:count * 3 key:@"vertexArray"];
2183 _displayLists.normalArray = [self allocateBytesWithSize:sizeof *_displayLists.normalArray count:count * 3 key:@"normalArray"];
2184 _displayLists.tangentArray = [self allocateBytesWithSize:sizeof *_displayLists.tangentArray count:count * 3 key:@"tangentArray"];
2185
2186 return _faces != NULL &&
2187 _displayLists.indexArray != NULL &&
2188 _displayLists.textureUVArray != NULL &&
2189 _displayLists.vertexArray != NULL &&
2190 _displayLists.normalArray != NULL &&
2191 _displayLists.tangentArray != NULL;
2192}

◆ allocateVertexBuffersWithCount:

- (BOOL) allocateVertexBuffersWithCount: (NSUInteger) count

Extends class OOMesh.

Definition at line 1792 of file OOMesh.m.

2156 :(NSUInteger)count
2157{
2158 _vertices = [self allocateBytesWithSize:sizeof *_vertices count:vertexCount key:@"vertices"];
2159 return _vertices != NULL;
2160}

◆ boundingBox

- (BoundingBox) boundingBox
implementation

Extends class OOMesh.

Definition at line 1792 of file OOMesh.m.

2049{
2050 return boundingBox;
2051}
BoundingBox boundingBox()
Definition OOMesh.m:2048

◆ calculateBoundingVolumes

- (void) calculateBoundingVolumes

Extends class OOMesh.

Definition at line 1792 of file OOMesh.m.

1983{
1985
1987 float d_squared, length_longest_axis, length_shortest_axis;
1988 GLfloat result;
1989
1990 result = 0.0f;
1991 if (vertexCount) bounding_box_reset_to_vector(&boundingBox, _vertices[0]);
1992 else bounding_box_reset(&boundingBox);
1993
1994 for (i = 0; i < vertexCount; i++)
1995 {
1996 d_squared = magnitude2(_vertices[i]);
1997 if (d_squared > result) result = d_squared;
1998 bounding_box_add_vector(&boundingBox, _vertices[i]);
1999 }
2000
2001 length_longest_axis = boundingBox.max.x - boundingBox.min.x;
2002 if (boundingBox.max.y - boundingBox.min.y > length_longest_axis)
2003 length_longest_axis = boundingBox.max.y - boundingBox.min.y;
2004 if (boundingBox.max.z - boundingBox.min.z > length_longest_axis)
2005 length_longest_axis = boundingBox.max.z - boundingBox.min.z;
2006
2007 length_shortest_axis = boundingBox.max.x - boundingBox.min.x;
2008 if (boundingBox.max.y - boundingBox.min.y < length_shortest_axis)
2009 length_shortest_axis = boundingBox.max.y - boundingBox.min.y;
2010 if (boundingBox.max.z - boundingBox.min.z < length_shortest_axis)
2011 length_shortest_axis = boundingBox.max.z - boundingBox.min.z;
2012
2013 d_squared = (length_longest_axis + length_shortest_axis) * (length_longest_axis + length_shortest_axis) * 0.25; // square of average length
2014 maxDrawDistance = d_squared * NO_DRAW_DISTANCE_FACTOR * NO_DRAW_DISTANCE_FACTOR; // no longer based on the collision radius
2015
2016 collisionRadius = sqrtf(result);
2017
2019}
#define NO_DRAW_DISTANCE_FACTOR
Definition Entity.h:46
#define OOJS_PROFILE_EXIT_VOID
#define OOJS_PROFILE_ENTER
uint32_t OOMeshVertexCount
Definition OOMesh.h:59
float x

◆ calculateVertexNormalsAndTangentsWithFaceRefs:

- (void) calculateVertexNormalsAndTangentsWithFaceRefs: (VertexFaceRef *) faceRefs

Extends class OOMesh.

Definition at line 1739 of file OOMesh.m.

1749 :(VertexFaceRef *)faceRefs
1750{
1752
1753 NSParameterAssert(faceRefs != NULL);
1754
1755 NSUInteger i,j;
1756 float triangle_area[faceCount];
1757
1758 NSAssert1(_normals != NULL && _tangents != NULL, @"Normal/tangent buffers not allocated in %s", __PRETTY_FUNCTION__);
1759
1760 for (i = 0 ; i < faceCount; i++)
1761 {
1762 triangle_area[i] = FaceArea(_faces[i].vertex, _vertices);
1763 }
1764 for (i = 0; i < vertexCount; i++)
1765 {
1766 Vector normal_sum = kZeroVector;
1767 Vector tangent_sum = kZeroVector;
1768
1769 VertexFaceRef *vfr = &faceRefs[i];
1770 NSUInteger fIter, fCount = VFRGetCount(vfr);
1771 for (fIter = 0; fIter < fCount; fIter++)
1772 {
1773 j = VFRGetFaceAtIndex(vfr, fIter);
1774
1775 float t = triangle_area[j]; // weight sum by area
1776 normal_sum = vector_add(normal_sum, vector_multiply_scalar(_faces[j].normal, t));
1777 tangent_sum = vector_add(tangent_sum, vector_multiply_scalar(_faces[j].tangent, t));
1778 }
1779
1780 normal_sum = vector_normal_or_fallback(normal_sum, kBasisZVector);
1781 tangent_sum = vector_subtract(tangent_sum, vector_multiply_scalar(normal_sum, dot_product(tangent_sum, normal_sum)));
1782 tangent_sum = vector_normal_or_fallback(tangent_sum, kBasisXVector);
1783
1784 _normals[i] = normal_sum;
1785 _tangents[i] = tangent_sum;
1786 }
1787
1789}
static NSUInteger VFRGetCount(VertexFaceRef *vfr)
static NSUInteger VFRGetFaceAtIndex(VertexFaceRef *vfr, NSUInteger index)
const Vector kZeroVector
Definition OOVector.m:28
const Vector kBasisZVector
Definition OOVector.m:31
const Vector kBasisXVector
Definition OOVector.m:29
static float FaceArea(GLuint *vertIndices, Vector *vertices)
Definition OOMesh.m:1739

◆ calculateVertexTangentsWithFaceRefs:

- (void) calculateVertexTangentsWithFaceRefs: (VertexFaceRef *) faceRefs

Extends class OOMesh.

Definition at line 1792 of file OOMesh.m.

1808 :(VertexFaceRef *)faceRefs
1809{
1811
1812 NSParameterAssert(faceRefs != NULL);
1813
1814 /* This is conceptually broken.
1815 At the moment, it's calculating one tangent per "input" vertex. It should
1816 be calculating one tangent per "real" vertex, where a "real" vertex is
1817 defined as a combination of position, normal, material and texture
1818 coordinates.
1819 Currently, we don't have a format with unique "real" vertices.
1820 This basically means explicit-normal models without explicit tangents
1821 can't usefully be normal mapped.
1822 I don't intend to do anything about this pre-MSNR, although it might be
1823 possible to fix it by moving tangent generation to the same stage as
1824 smooth-grouped normal generation.
1825 -- Ahruman 2010-05-22
1826 */
1827 NSUInteger i,j;
1828 float triangle_area[faceCount];
1829 for (i = 0 ; i < faceCount; i++)
1830 {
1831 triangle_area[i] = FaceAreaCorrect(_faces[i].vertex, _vertices);
1832 }
1833 for (i = 0; i < vertexCount; i++)
1834 {
1835 Vector tangent_sum = kZeroVector;
1836
1837 VertexFaceRef *vfr = &faceRefs[i];
1838 NSUInteger fIter, fCount = VFRGetCount(vfr);
1839 for (fIter = 0; fIter < fCount; fIter++)
1840 {
1841 j = VFRGetFaceAtIndex(vfr, fIter);
1842
1843 float t = triangle_area[j]; // weight sum by area
1844 tangent_sum = vector_add(tangent_sum, vector_multiply_scalar(_faces[j].tangent, t));
1845 }
1846
1847 tangent_sum = vector_subtract(tangent_sum, vector_multiply_scalar(_normals[i], dot_product(_normals[i], tangent_sum)));
1848 tangent_sum = vector_normal_or_fallback(tangent_sum, kBasisXVector);
1849
1850 _tangents[i] = tangent_sum;
1851 }
1852
1854}
static float FaceAreaCorrect(GLuint *vertIndices, Vector *vertices)
Definition OOMesh.m:1792

◆ checkNormalsAndAdjustWinding

- (void) checkNormalsAndAdjustWinding

Extends class OOMesh.

Definition at line 341 of file OOMesh.m.

1648{
1650
1651 Vector calculatedNormal;
1653
1654 NSParameterAssert(_normalMode != kNormalModeExplicit);
1655
1656 for (i = 0; i < faceCount; i++)
1657 {
1658 Vector v0, v1, v2, norm;
1659 v0 = _vertices[_faces[i].vertex[0]];
1660 v1 = _vertices[_faces[i].vertex[1]];
1661 v2 = _vertices[_faces[i].vertex[2]];
1662 norm = _faces[i].normal;
1663
1664 calculatedNormal = normal_to_surface(v2, v1, v0);
1665 if (vector_equal(norm, kZeroVector))
1666 {
1667 norm = vector_flip(calculatedNormal);
1668 _faces[i].normal = norm;
1669 }
1670
1671 /* FIXME: for 2.0, either require explicit normals for every model
1672 or change to: if (dot_product(norm, calculatedNormal) < 0.0f)
1673 -- Ahruman 2010-01-23
1674 */
1675 if (norm.x * calculatedNormal.x < 0 || norm.y * calculatedNormal.y < 0 || norm.z * calculatedNormal.z < 0)
1676 {
1677 // normal lies in the WRONG direction!
1678 // reverse the winding
1679 int v0 = _faces[i].vertex[0];
1680 _faces[i].vertex[0] = _faces[i].vertex[2];
1681 _faces[i].vertex[2] = v0;
1682
1683 GLfloat f0 = _faces[i].s[0];
1684 _faces[i].s[0] = _faces[i].s[2];
1685 _faces[i].s[2] = f0;
1686
1687 f0 = _faces[i].t[0];
1688 _faces[i].t[0] = _faces[i].t[2];
1689 _faces[i].t[2] = f0;
1690 }
1691 }
1692
1694}
uint32_t OOMeshFaceCount
Definition OOMesh.h:60
@ kNormalModeExplicit
Definition OOMesh.m:80

◆ debugDrawNormals

- (void) debugDrawNormals

Extends class OOMesh.

Definition at line 1792 of file OOMesh.m.

2056{
2057 GLuint i;
2058 Vector v, n, t, b;
2059 float length, blend;
2060 GLfloat color[3];
2061 OODebugWFState state;
2062
2064
2065 state = OODebugBeginWireframe(NO);
2066
2067 // Draw
2068 OOGLBEGIN(GL_LINES);
2069 for (i = 0; i < _displayLists.count; ++i)
2070 {
2071 v = _displayLists.vertexArray[i];
2072 n = _displayLists.normalArray[i];
2073 t = _displayLists.tangentArray[i];
2074 b = true_cross_product(n, t);
2075
2076 // Draw normal
2077 length = magnitude2(n);
2078 blend = fabs(length - 1) * 5.0;
2079 color[0] = MIN(blend, 1.0f);
2080 color[1] = 1.0f - color[0];
2081 color[2] = color[1];
2082 glColor3fv(color);
2083
2084 glVertex3f(v.x, v.y, v.z);
2085 scale_vector(&n, 5.0f);
2086 n = vector_add(n, v);
2087 glVertex3f(n.x, n.y, n.z);
2088
2089 // Draw tangent
2090 glColor3f(1.0f, 1.0f, 0.0f);
2091 t = vector_add(v, vector_multiply_scalar(t, 3.0f));
2092 glVertex3f(v.x, v.y, v.z);
2093 glVertex3f(t.x, t.y, t.z);
2094
2095 // Draw bitangent
2096 glColor3f(0.0f, 1.0f, 0.0f);
2097 b = vector_add(v, vector_multiply_scalar(b, 3.0f));
2098 glVertex3f(v.x, v.y, v.z);
2099 glVertex3f(b.x, b.y, b.z);
2100 }
2101 OOGLEND();
2102
2103 OODebugEndWireframe(state);
2104}
void OODebugEndWireframe(OODebugWFState state)
OODebugWFState OODebugBeginWireframe(BOOL ignoreZ)
#define OO_ENTER_OPENGL()
#define MIN(A, B)
Definition OOMaths.h:111
#define OOGLBEGIN
Definition OOOpenGL.h:253
#define OOGLEND
Definition OOOpenGL.h:254

◆ deleteDisplayLists

- (void) deleteDisplayLists

Extends class OOMesh.

Definition at line 341 of file OOMesh.m.

977{
978 if (listsReady)
979 {
981
982 OOGL(glDeleteLists(displayList0, materialCount));
983 listsReady = NO;
984 }
985}
#define OOGL(statement)
Definition OOOpenGL.h:251

◆ FaceArea

+ (static float) FaceArea (GLuint *) vertIndices
(Vector *) vertices 
implementation

Extends class OOMesh.

Definition at line 1739 of file OOMesh.m.

1740{
1741 /* Calculate areas using Heron's formula. */
1742 float a2 = distance2(vertices[vertIndices[0]], vertices[vertIndices[1]]);
1743 float b2 = distance2(vertices[vertIndices[1]], vertices[vertIndices[2]]);
1744 float c2 = distance2(vertices[vertIndices[2]], vertices[vertIndices[0]]);
1745 return sqrt((2.0f * (a2 * b2 + b2 * c2 + c2 * a2) - (a2 * a2 + b2 * b2 +c2 * c2)) * 0.0625f);
1746}

◆ FaceAreaCorrect

+ (static float) FaceAreaCorrect (GLuint *) vertIndices
(Vector *) vertices 
implementation

Extends class OOMesh.

Definition at line 1792 of file OOMesh.m.

1793{
1794 /* Calculate area of triangle.
1795 The magnitude of the cross product of two vectors is the area of
1796 the parallelogram they span. The area of a triangle is half the
1797 area of a parallelogram sharing two of its sides.
1798 Since we only use the area of the triangle as a weight factor,
1799 constant terms are irrelevant, so we don't bother halving the
1800 value.
1801 */
1802 Vector AB = vector_subtract(vertices[vertIndices[1]], vertices[vertIndices[0]]);
1803 Vector AC = vector_subtract(vertices[vertIndices[2]], vertices[vertIndices[0]]);
1804 return magnitude(true_cross_product(AB, AC));
1805}

◆ generateFaceTangents

- (void) generateFaceTangents

Extends class OOMesh.

Definition at line 341 of file OOMesh.m.

1698{
1700
1702 for (i = 0; i < faceCount; i++)
1703 {
1704 OOMeshFace *face = _faces + i;
1705
1706 /* Generate tangents, i.e. vectors that run in the direction of the s
1707 texture coordinate. Based on code I found in a forum somewhere and
1708 then lost track of. Sorry to whomever I should be crediting.
1709 -- Ahruman 2008-11-23
1710 */
1711 Vector vAB = vector_subtract(_vertices[face->vertex[1]], _vertices[face->vertex[0]]);
1712 Vector vAC = vector_subtract(_vertices[face->vertex[2]], _vertices[face->vertex[0]]);
1713 Vector nA = face->normal;
1714
1715 // projAB = aB - (nA . vAB) * nA
1716 Vector vProjAB = vector_subtract(vAB, vector_multiply_scalar(nA, dot_product(nA, vAB)));
1717 Vector vProjAC = vector_subtract(vAC, vector_multiply_scalar(nA, dot_product(nA, vAC)));
1718
1719 // delta s/t
1720 GLfloat dsAB = face->s[1] - face->s[0];
1721 GLfloat dsAC = face->s[2] - face->s[0];
1722 GLfloat dtAB = face->t[1] - face->t[0];
1723 GLfloat dtAC = face->t[2] - face->t[0];
1724
1725 if (dsAC * dtAB > dsAB * dtAC)
1726 {
1727 face->tangent = vector_normal(vector_subtract(vector_multiply_scalar(vProjAC, dtAB), vector_multiply_scalar(vProjAB, dtAC)));
1728 }
1729 else
1730 {
1731 face->tangent = vector_normal(vector_subtract(vector_multiply_scalar(vProjAB, dtAC), vector_multiply_scalar(vProjAC, dtAB)));
1732 }
1733 }
1734
1736}
Vector tangent
Definition OOMesh.h:71
GLuint vertex[3]
Definition OOMesh.h:68
Vector normal
Definition OOMesh.h:70
GLfloat t[3]
Definition OOMesh.h:73
GLfloat s[3]
Definition OOMesh.h:72

◆ getNormal:andTangent:forVertex:inSmoothGroup:

- (void) getNormal: (Vector *) outNormal
andTangent: (Vector *) outTangent
forVertex: (OOMeshVertexCount) v_index
inSmoothGroup: (OOMeshSmoothGroup) smoothGroup 

Extends class OOMesh.

Definition at line 1792 of file OOMesh.m.

1858 :(Vector *)outNormal andTangent:(Vector *)outTangent forVertex:(OOMeshVertexCount)v_index inSmoothGroup:(OOMeshSmoothGroup)smoothGroup
1859{
1861
1862 assert(outNormal != NULL && outTangent != NULL);
1863
1864 NSUInteger j;
1865 Vector normal_sum = kZeroVector;
1866 Vector tangent_sum = kZeroVector;
1867 for (j = 0; j < faceCount; j++)
1868 {
1869 if (_faces[j].smoothGroup == smoothGroup)
1870 {
1871 if ((_faces[j].vertex[0] == v_index)||(_faces[j].vertex[1] == v_index)||(_faces[j].vertex[2] == v_index))
1872 {
1873 float area = FaceArea(_faces[j].vertex, _vertices);
1874 normal_sum = vector_add(normal_sum, vector_multiply_scalar(_faces[j].normal, area));
1875 tangent_sum = vector_add(tangent_sum, vector_multiply_scalar(_faces[j].tangent, area));
1876 }
1877 }
1878 }
1879
1880 *outNormal = vector_normal_or_fallback(normal_sum, kBasisZVector);
1881 *outTangent = vector_normal_or_fallback(tangent_sum, kBasisXVector);
1882
1884}
uint16_t OOMeshSmoothGroup
Definition OOMesh.h:57

◆ initWithName:cacheKey:materialDictionary:shadersDictionary:smooth:shaderMacros:shaderBindingTarget:scaleFactor:cacheWriteable:

- (id) initWithName: (NSString *) name
cacheKey: (NSString *) cacheKey
materialDictionary: (NSDictionary *) materialDict
shadersDictionary: (NSDictionary *) shadersDict
smooth: (BOOL) smooth
shaderMacros: (NSDictionary *) macros
shaderBindingTarget: (id<OOWeakReferenceSupport>) object
scaleFactor: (float) scale
cacheWriteable: (BOOL) cacheWriteable 

Extends class OOMesh.

Definition at line 341 of file OOMesh.m.

873 :(NSString *)name
874 cacheKey:(NSString *)cacheKey
875materialDictionary:(NSDictionary *)materialDict
876 shadersDictionary:(NSDictionary *)shadersDict
877 smooth:(BOOL)smooth
878 shaderMacros:(NSDictionary *)macros
879shaderBindingTarget:(id<OOWeakReferenceSupport>)target
880 scaleFactor:(float)scale
881 cacheWriteable:(BOOL)cacheWriteable
882{
884
885 self = [super init];
886 if (self == nil) return nil;
887
888 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
889 _normalMode = smooth ? kNormalModeSmooth : kNormalModePerFace;
890 _cacheWriteable = cacheWriteable;
891
892#if OOMESH_PROFILE
893 _stopwatch = [[OOProfilingStopwatch alloc] init];
894#endif
895
896 if ([self loadData:name scaleFactor:scale])
897 {
898 [self calculateBoundingVolumes];
899 PROFILE(@"finished calculateBoundingVolumes (again\?\?)");
900
901 baseFile = [name copy];
902 baseFileOctreeCacheRef = [[NSString stringWithFormat:@"%@-%.3f", baseFile, scale] copy];
903
904 /* New in r3033: save the material-defining parameters here so we
905 can rebind the materials at any time.
906 -- Ahruman 2010-02-17
907 */
908 _materialDict = [materialDict copy];
909 _shadersDict = [shadersDict copy];
910 _cacheKey = [cacheKey copy];
911 _shaderMacros = [macros copy];
912 _shaderBindingTarget = [target weakRetain];
913
914 [self rebindMaterials];
915 PROFILE(@"finished material setup");
916
918 }
919 else
920 {
921 [self release];
922 self = nil;
923 }
924#if OOMESH_PROFILE
925 DESTROY(_stopwatch);
926#endif
927#if OO_MULTITEXTURE
928 if (EXPECT(self != nil))
929 {
930 _textureUnitCount = NSNotFound;
931 }
932#endif
933
934 [pool release];
935 return self;
936
938}
#define DESTROY(x)
Definition OOCocoa.h:77
#define EXPECT(x)
#define OOJS_PROFILE_EXIT
#define PROFILE(tag)
Definition OOMesh.m:97
@ kNormalModeSmooth
Definition OOMesh.m:79
@ kNormalModePerFace
Definition OOMesh.m:78
return nil
void registerClient:(id< OOGraphicsResetClient > client)
OOGraphicsResetManager * sharedManager()

◆ loadData:scaleFactor:

- (BOOL) loadData: (NSString *) filename
scaleFactor: (float) scale 

Extends class OOMesh.

Definition at line 341 of file OOMesh.m.

1162 :(NSString *)filename scaleFactor:(float)scale
1163{
1165
1166 NSScanner *scanner;
1167 NSDictionary *cacheData = nil;
1168 BOOL failFlag = NO;
1169 NSString *failString = @"***** ";
1170 unsigned i, j;
1171 NSMutableDictionary *texFileName2Idx = nil;
1172 NSString *cacheKey = nil;
1173 BOOL using_preloaded = NO;
1174
1175 cacheKey = [NSString stringWithFormat:@"%@:%u:%.3f", filename, _normalMode, scale];
1176 cacheData = [OOCacheManager meshDataForName:cacheKey];
1177 if (cacheData != nil)
1178 {
1179 if ([self setModelFromModelData:cacheData name:filename])
1180 {
1181 using_preloaded = YES;
1182 PROFILE(@"loaded from cache");
1183 OOLog(@"mesh.load.cached", @"Retrieved mesh \"%@\" from cache.", filename);
1184 }
1185 }
1186
1187 if (!using_preloaded)
1188 {
1189 OOLog(@"mesh.load.uncached", @"Mesh \"%@\" is not in cache, loading.", cacheKey);
1190
1191 NSCharacterSet *whitespaceCharSet = [NSCharacterSet whitespaceCharacterSet];
1192 NSCharacterSet *whitespaceAndNewlineCharSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
1193#if OOLITE_MAC_OS_X
1194 NSCharacterSet *newlineCharSet = [NSCharacterSet newlineCharacterSet];
1195#else
1196 static NSCharacterSet *newlineCharSet = nil;
1197 if (newlineCharSet == nil)
1198 {
1199 NSMutableCharacterSet *temp = [[whitespaceAndNewlineCharSet mutableCopy] autorelease];
1200 [temp formIntersectionWithCharacterSet:[whitespaceCharSet invertedSet]];
1201 newlineCharSet = [temp copy];
1202 }
1203#endif
1204
1205 texFileName2Idx = [NSMutableDictionary dictionary];
1206
1207 {
1208 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
1209 NSString *data = [ResourceManager stringFromFilesNamed:filename inFolder:@"Models" cache:NO];
1210 if (data == nil)
1211 {
1212 // Model not found
1213 OOLog(kOOLogMeshDataNotFound, @"***** ERROR: could not find %@", filename);
1214 OOStandardsError(@"Model file not found");
1215 return NO;
1216 }
1217
1218 // strip out comments and commas between values
1219 NSMutableArray *lines = [NSMutableArray arrayWithArray:[data componentsSeparatedByString:@"\n"]];
1220 for (i = 0; i < [lines count]; i++)
1221 {
1222 NSString *line = [lines objectAtIndex:i];
1223 NSArray *parts;
1224 //
1225 // comments
1226 //
1227 parts = [line componentsSeparatedByString:@"#"];
1228 line = [parts objectAtIndex:0];
1229 parts = [line componentsSeparatedByString:@"//"];
1230 line = [parts objectAtIndex:0];
1231 //
1232 // commas
1233 //
1234 line = [[line componentsSeparatedByString:@","] componentsJoinedByString:@" "];
1235 //
1236 [lines replaceObjectAtIndex:i withObject:line];
1237 }
1238
1239 data = [lines componentsJoinedByString:@"\n"];
1240 scanner = [NSScanner scannerWithString:data];
1241
1242 [scanner retain];
1243 [pool release];
1244 [scanner autorelease];
1245 }
1246
1247 PROFILE(@"finished preprocessing");
1248
1249 // get number of vertices
1250 //
1251 [scanner setScanLocation:0]; //reset
1252 if ([scanner scanString:@"NVERTS" intoString:NULL])
1253 {
1254 int n_v;
1255 if ([scanner scanInt:&n_v])
1256 vertexCount = n_v;
1257 else
1258 {
1259 failFlag = YES;
1260 failString = [NSString stringWithFormat:@"%@Failed to read value of NVERTS\n",failString];
1261 }
1262 }
1263 else
1264 {
1265 failFlag = YES;
1266 failString = [NSString stringWithFormat:@"%@Failed to read NVERTS\n",failString];
1267 }
1268
1269 if (![self allocateVertexBuffersWithCount:vertexCount])
1270 {
1271 OOLog(kOOLogAllocationFailure, @"***** ERROR: failed to allocate memory for model %@ (%u vertices).", filename, vertexCount);
1272 return NO;
1273 }
1274
1275 // get number of faces
1276 if ([scanner scanString:@"NFACES" intoString:NULL])
1277 {
1278 int n_f;
1279 if ([scanner scanInt:&n_f])
1280 {
1281 faceCount = n_f;
1282 }
1283 else
1284 {
1285 failFlag = YES;
1286 failString = [NSString stringWithFormat:@"%@Failed to read value of NFACES\n",failString];
1287 }
1288 }
1289 else
1290 {
1291 failFlag = YES;
1292 failString = [NSString stringWithFormat:@"%@Failed to read NFACES\n",failString];
1293 }
1294
1295 // Allocate face->vertex table.
1296 size_t faceRefSize = sizeof (VertexFaceRef) * vertexCount;
1297 VertexFaceRef *faceRefs = calloc(1, faceRefSize);
1298 if (faceRefs != NULL)
1299 {
1300 // use an NSData to effectively autorelease it.
1301 NSData *faceRefHolder = [NSData dataWithBytesNoCopy:faceRefs length:faceRefSize freeWhenDone:YES];
1302 if (faceRefHolder == nil)
1303 {
1304 free(faceRefs);
1305 faceRefs = NULL;
1306 }
1307 }
1308
1309 if (faceRefs == NULL || ![self allocateFaceBuffersWithCount:faceCount])
1310 {
1311 OOLog(kOOLogAllocationFailure, @"***** ERROR: failed to allocate memory for model %@ (%u vertices, %u faces).", filename, vertexCount, faceCount);
1312 return NO;
1313 }
1314
1315 // get vertex data
1316 if ([scanner scanString:@"VERTEX" intoString:NULL])
1317 {
1318 for (j = 0; j < vertexCount; j++)
1319 {
1320 float x, y, z;
1321 if (!failFlag)
1322 {
1323 if (![scanner scanFloat:&x]) failFlag = YES;
1324 if (![scanner scanFloat:&y]) failFlag = YES;
1325 if (![scanner scanFloat:&z]) failFlag = YES;
1326 if (!failFlag)
1327 {
1328 _vertices[j] = make_vector(x*scale, y*scale, z*scale);
1329 }
1330 else
1331 {
1332 failString = [NSString stringWithFormat:@"%@Failed to read a value for vertex[%d] in %@\n", failString, j, @"VERTEX"];
1333 }
1334 }
1335 }
1336 }
1337 else
1338 {
1339 failFlag = YES;
1340 failString = [NSString stringWithFormat:@"%@Failed to find VERTEX data\n",failString];
1341 }
1342
1343 // get face data
1344 if ([scanner scanString:@"FACES" intoString:NULL])
1345 {
1346 for (j = 0; j < faceCount; j++)
1347 {
1348 int r, g, b;
1349 float nx, ny, nz;
1350 int n_v;
1351 if (!failFlag)
1352 {
1353 // colors
1354 if (![scanner scanInt:&r]) failFlag = YES;
1355 if (![scanner scanInt:&g]) failFlag = YES;
1356 if (![scanner scanInt:&b]) failFlag = YES;
1357 if (!failFlag)
1358 {
1359 _faces[j].smoothGroup = r;
1360 }
1361 else
1362 {
1363 failString = [NSString stringWithFormat:@"%@Failed to read a color for face[%d] in FACES\n", failString, j];
1364 }
1365
1366 // normal
1367 if (![scanner scanFloat:&nx]) failFlag = YES;
1368 if (![scanner scanFloat:&ny]) failFlag = YES;
1369 if (![scanner scanFloat:&nz]) failFlag = YES;
1370 if (!failFlag)
1371 {
1372 _faces[j].normal = vector_normal(make_vector(nx, ny, nz));
1373 }
1374 else
1375 {
1376 failString = [NSString stringWithFormat:@"%@Failed to read a normal for face[%d] in FACES\n", failString, j];
1377 }
1378
1379 // vertices
1380 if ([scanner scanInt:&n_v])
1381 {
1382 if (n_v < 3)
1383 {
1384 failFlag = YES;
1385 failString = [NSString stringWithFormat:@"%@Face[%u] has fewer than three vertices.\n", failString, j];
1386 }
1387 else if (n_v > 3)
1388 {
1389 OOLogWARN(@"mesh.load.warning.nonTriangular", @"Face[%u] of %@ has %u vertices specified. Only the first three will be used.", j, baseFile, n_v);
1390 n_v = 3;
1391 }
1392 }
1393 else
1394 {
1395 failFlag = YES;
1396 failString = [NSString stringWithFormat:@"%@Failed to read number of vertices for face[%d] in FACES\n", failString, j];
1397 }
1398
1399 if (!failFlag)
1400 {
1401 int vi;
1402 for (i = 0; (int)i < n_v; i++)
1403 {
1404 if ([scanner scanInt:&vi])
1405 {
1406 _faces[j].vertex[i] = vi;
1407 if (faceRefs != NULL) VFRAddFace(&faceRefs[vi], j);
1408 }
1409 else
1410 {
1411 failFlag = YES;
1412 failString = [NSString stringWithFormat:@"%@Failed to read vertex[%d] for face[%d] in FACES\n", failString, i, j];
1413 }
1414 }
1415 }
1416 }
1417 }
1418 }
1419 else
1420 {
1421 failFlag = YES;
1422 failString = [NSString stringWithFormat:@"%@Failed to find FACES data\n",failString];
1423 }
1424
1425 // Get textures data.
1426 if ([scanner scanString:@"TEXTURES" intoString:NULL])
1427 {
1428 for (j = 0; j < faceCount; j++)
1429 {
1430 NSString *materialKey;
1431 float max_x, max_y;
1432 float s, t;
1433 if (!failFlag)
1434 {
1435 // materialKey
1436 //
1437 [scanner scanCharactersFromSet:whitespaceAndNewlineCharSet intoString:NULL];
1438 if (![scanner scanUpToCharactersFromSet:whitespaceCharSet intoString:&materialKey])
1439 {
1440 failFlag = YES;
1441 failString = [NSString stringWithFormat:@"%@Failed to read texture filename for face[%d] in TEXTURES\n", failString, j];
1442 }
1443 else
1444 {
1445 NSNumber *index = [texFileName2Idx objectForKey:materialKey];
1446 if (index != nil)
1447 {
1448 _faces[j].materialIndex = [index unsignedIntValue];
1449 }
1450 else
1451 {
1452 if (materialCount == kOOMeshMaxMaterials)
1453 {
1454 OOLog(kOOLogMeshTooManyMaterials, @"***** ERROR: model %@ has too many materials (maximum is %d)", filename, kOOMeshMaxMaterials);
1455 return NO;
1456 }
1457 _faces[j].materialIndex = materialCount;
1458 materialKeys[materialCount] = [materialKey retain];
1459 index = [NSNumber numberWithUnsignedInt:materialCount];
1460 [texFileName2Idx setObject:index forKey:materialKey];
1461 ++materialCount;
1462 }
1463 }
1464
1465 // texture size
1466 //
1467 if (!failFlag)
1468 {
1469 if (![scanner scanFloat:&max_x]) failFlag = YES;
1470 if (![scanner scanFloat:&max_y]) failFlag = YES;
1471 if (failFlag)
1472 failString = [NSString stringWithFormat:@"%@Failed to read texture size for max_x and max_y in face[%d] in TEXTURES\n", failString, j];
1473 }
1474
1475 // vertices
1476 //
1477 if (!failFlag)
1478 {
1479 for (i = 0; i < 3; i++)
1480 {
1481 if (![scanner scanFloat:&s]) failFlag = YES;
1482 if (![scanner scanFloat:&t]) failFlag = YES;
1483 if (!failFlag)
1484 {
1485 _faces[j].s[i] = s / max_x;
1486 _faces[j].t[i] = t / max_y;
1487 }
1488 else
1489 failString = [NSString stringWithFormat:@"%@Failed to read s t coordinates for vertex[%d] in face[%d] in TEXTURES\n", failString, i, j];
1490 }
1491 }
1492 }
1493 }
1494 }
1495 else
1496 {
1497 failFlag = YES;
1498 failString = [failString stringByAppendingString:@"Failed to find TEXTURES data (will use placeholder material)\n"];
1499 materialKeys[0] = @"_oo_placeholder_material";
1500 materialCount = 1;
1501
1502 for (j = 0; j < faceCount; j++)
1503 {
1504 _faces[j].materialIndex = 0;
1505 }
1506 }
1507
1508 if ([scanner scanString:@"NAMES" intoString:NULL])
1509 {
1510 unsigned int count;
1511 if (![scanner scanInt:(int *)&count])
1512 {
1513 failFlag = YES;
1514 failString = [failString stringByAppendingString:@"Expected count after NAMES\n"];
1515 }
1516 else
1517 {
1518 for (j = 0; j < count; j++)
1519 {
1520 NSString *name = nil;
1521 [scanner scanCharactersFromSet:whitespaceAndNewlineCharSet intoString:NULL];
1522 if (![scanner scanUpToCharactersFromSet:newlineCharSet intoString:&name])
1523 {
1524 failFlag = YES;
1525 failString = [failString stringByAppendingString:@"Expected file name\n"];
1526 }
1527 else
1528 {
1529 [self renameTexturesFrom:[NSString stringWithFormat:@"%u", j] to:name];
1530 }
1531 }
1532 }
1533 }
1534
1535 BOOL explicitTangents = NO;
1536
1537 // Get explicit normals.
1538 if ([scanner scanString:@"NORMALS" intoString:NULL])
1539 {
1540 _normalMode = kNormalModeExplicit;
1541 if (![self allocateNormalBuffersWithCount:vertexCount])
1542 {
1543 OOLog(kOOLogAllocationFailure, @"***** ERROR: failed to allocate memory for model %@ (%u vertices).", filename, vertexCount);
1544 return NO;
1545 }
1546
1547 for (j = 0; j < vertexCount; j++)
1548 {
1549 float x, y, z;
1550 if (!failFlag)
1551 {
1552 if (![scanner scanFloat:&x]) failFlag = YES;
1553 if (![scanner scanFloat:&y]) failFlag = YES;
1554 if (![scanner scanFloat:&z]) failFlag = YES;
1555 if (!failFlag)
1556 {
1557 _normals[j] = vector_normal(make_vector(x, y, z));
1558 }
1559 else
1560 {
1561 failString = [NSString stringWithFormat:@"%@Failed to read a value for vertex[%d] in %@\n", failString, j, @"NORMALS"];
1562 }
1563 }
1564 }
1565
1566 // Get explicit tangents (only together with vertices).
1567 if ([scanner scanString:@"TANGENTS" intoString:NULL])
1568 {
1569 for (j = 0; j < vertexCount; j++)
1570 {
1571 float x, y, z;
1572 if (!failFlag)
1573 {
1574 if (![scanner scanFloat:&x]) failFlag = YES;
1575 if (![scanner scanFloat:&y]) failFlag = YES;
1576 if (![scanner scanFloat:&z]) failFlag = YES;
1577 if (!failFlag)
1578 {
1579 _tangents[j] = vector_normal(make_vector(x, y, z));
1580 }
1581 else
1582 {
1583 failString = [NSString stringWithFormat:@"%@Failed to read a value for vertex[%d] in %@\n", failString, j, @"TANGENTS"];
1584 }
1585 }
1586 }
1587 }
1588 }
1589
1590 PROFILE(@"finished parsing");
1591
1592 if (IsLegacyNormalMode(_normalMode))
1593 {
1594 [self checkNormalsAndAdjustWinding];
1595 PROFILE(@"finished checkNormalsAndAdjustWinding");
1596 }
1597 if (!explicitTangents)
1598 {
1599 [self generateFaceTangents];
1600 PROFILE(@"finished generateFaceTangents");
1601 }
1602
1603 // check for smooth shading and recalculate normals
1604 if (_normalMode == kNormalModeSmooth)
1605 {
1606 if (![self allocateNormalBuffersWithCount:vertexCount])
1607 {
1608 OOLog(kOOLogAllocationFailure, @"***** ERROR: failed to allocate memory for model %@ (%u vertices).", filename, vertexCount);
1609 return NO;
1610 }
1611 [self calculateVertexNormalsAndTangentsWithFaceRefs:faceRefs];
1612 PROFILE(@"finished calculateVertexNormalsAndTangents");
1613
1614 }
1615 else if (IsPerVertexNormalMode(_normalMode) && !explicitTangents)
1616 {
1617 [self calculateVertexTangentsWithFaceRefs:faceRefs];
1618 PROFILE(@"finished calculateVertexTangents");
1619 }
1620
1621 // save the resulting data for possible reuse
1622 if (EXPECT(_cacheWriteable))
1623 {
1624 [OOCacheManager setMeshData:[self modelData] forName:cacheKey];
1625 PROFILE(@"saved to cache");
1626 }
1627
1628 if (failFlag)
1629 {
1630 OOLog(@"mesh.error", @"%@ ..... from %@ %@", failString, filename, (using_preloaded)? @"(from preloaded data)" :@"(from file)");
1631 }
1632 }
1633
1634 [self calculateBoundingVolumes];
1635 PROFILE(@"finished calculateBoundingVolumes");
1636
1637 // set up vertex arrays for drawing
1638 if (![self setUpVertexArrays]) return NO;
1639 PROFILE(@"finished setUpVertexArrays");
1640
1641 return YES;
1642
1644}
void OOStandardsError(NSString *message)
#define OOLogWARN(class, format,...)
Definition OOLogging.h:113
#define OOLog(class, format,...)
Definition OOLogging.h:88
NSString *const kOOLogAllocationFailure
Definition OOLogging.m:649
@ kOOMeshMaxMaterials
Definition OOMesh.h:53
static void VFRAddFace(VertexFaceRef *vfr, NSUInteger index)
static BOOL IsLegacyNormalMode(OOMeshNormalMode mode)
Definition OOMesh.m:188
static NSString *const kOOLogMeshTooManyMaterials
Definition OOMesh.m:85
static NSString *const kOOLogMeshDataNotFound
Definition OOMesh.m:84
struct VertexFaceRef VertexFaceRef
static BOOL IsPerVertexNormalMode(OOMeshNormalMode mode)
Definition OOMesh.m:210
float y
BOOL setUpVertexArrays()
Definition OOMesh.m:1887
void setMeshData:forName:(NSDictionary *inData,[forName] NSString *inShipName)
Definition OOMesh.m:2224
NSDictionary * meshDataForName:(NSString *inShipName)
Definition OOMesh.m:2218
NSString * stringFromFilesNamed:inFolder:cache:(NSString *fileName,[inFolder] NSString *folderName,[cache] BOOL useCache)
const char * filename
Definition ioapi.h:133
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque

◆ modelData

- (NSDictionary *) modelData

Extends class OOMesh.

Definition at line 341 of file OOMesh.m.

997{
999
1000 NSNumber *vertCnt = nil,
1001 *faceCnt = nil;
1002 NSData *vertData = nil,
1003 *normData = nil,
1004 *tanData = nil,
1005 *faceData = nil;
1006 NSArray *mtlKeys = nil;
1007 NSNumber *normMode = nil;
1008
1009 BOOL includeNormals = IsPerVertexNormalMode(_normalMode);
1010
1011 // Prepare cache data elements.
1012 vertCnt = [NSNumber numberWithUnsignedInt:vertexCount];
1013 faceCnt = [NSNumber numberWithUnsignedInt:faceCount];
1014
1015 vertData = [_retainedObjects objectForKey:@"vertices"];
1016 faceData = [_retainedObjects objectForKey:@"faces"];
1017 if (includeNormals)
1018 {
1019 normData = [_retainedObjects objectForKey:@"normals"];
1020 tanData = [_retainedObjects objectForKey:@"tangents"];
1021 }
1022
1023 if (materialCount != 0)
1024 {
1025 mtlKeys = [NSArray arrayWithObjects:materialKeys count:materialCount];
1026 }
1027 else
1028 {
1029 mtlKeys = [NSArray array];
1030 }
1031 normMode = [NSNumber numberWithUnsignedChar:_normalMode];
1032
1033 // Ensure we have all the required data elements.
1034 if (vertCnt == nil ||
1035 faceCnt == nil ||
1036 vertData == nil ||
1037 faceData == nil ||
1038 mtlKeys == nil ||
1039 normMode == nil)
1040 {
1041 return nil;
1042 }
1043
1044 if (includeNormals)
1045 {
1046 if (normData == nil || tanData == nil) return nil;
1047 }
1048
1049 // All OK; stick 'em in a dictionary.
1050 return [NSDictionary dictionaryWithObjectsAndKeys:
1051 vertCnt, @"vertex count",
1052 vertData, @"vertex data",
1053 faceCnt, @"face count",
1054 faceData, @"face data",
1055 mtlKeys, @"material keys",
1056 normMode, @"normal mode",
1057 /* NOTE: order matters. Since normData and tanData
1058 are last, if they're nil the dictionary will be
1059 built without them, which is desired behaviour.
1060 */
1061 normData, @"normal data",
1062 tanData, @"tangent data",
1063 nil];
1064
1066}

◆ mutableCopyWithZone:

- (id) mutableCopyWithZone: (NSZone *) zone
implementation

Extends class OOMesh.

Definition at line 341 of file OOMesh.m.

941 :(NSZone *)zone
942{
943 OOMesh *result = nil;
945
946 result = (OOMesh *)NSCopyObject(self, 0, zone);
947
948 if (result != nil)
949 {
950 [result->baseFile retain];
951 [result->baseFileOctreeCacheRef retain];
952 [result->octree retain];
953 [result->_retainedObjects retain];
954 [result->_materialDict retain];
955 [result->_shadersDict retain];
956 [result->_cacheKey retain];
957 [result->_shaderMacros retain];
958 [result->_shaderBindingTarget retain];
959
960 for (i = 0; i != kOOMeshMaxMaterials; ++i)
961 {
962 [result->materialKeys[i] retain];
963 [result->materials[i] retain];
964 }
965
966 // Reset unsharable GL state
967 result->listsReady = NO;
968
970 }
971
972 return result;
973}
uint8_t OOMeshMaterialCount
Definition OOMesh.h:58
uint8_t listsReady
Definition OOMesh.h:95

◆ renameTexturesFrom:to:

- (void) renameTexturesFrom: (NSString *) from
to: (NSString *) to 

Extends class OOMesh.

Definition at line 1792 of file OOMesh.m.

2195 :(NSString *)from to:(NSString *)to
2196{
2197 /* IMPORTANT: this has to be called before setUpMaterials..., so it can
2198 only be used during loading.
2199 */
2201 for (i = 0; i != materialCount; i++)
2202 {
2203 if ([materialKeys[i] isEqualToString:from])
2204 {
2205 [materialKeys[i] release];
2206 materialKeys[i] = [to copy];
2207 }
2208 }
2209}

◆ rescaleByFactor:

- (void) rescaleByFactor: (GLfloat) factor

Extends class OOMesh.

Definition at line 1792 of file OOMesh.m.

2022 :(GLfloat)factor
2023{
2024 // Rescale base vertices used for geometry calculations.
2026 Vector *vertex = NULL;
2027
2028 for (i = 0; i < vertexCount; i++)
2029 {
2030 vertex = &_vertices[i];
2031 *vertex = vector_multiply_scalar(*vertex, factor);
2032 }
2033
2034 // Rescale actual display vertices.
2035 for (i = 0; i < _displayLists.count; i++)
2036 {
2037 vertex = &_displayLists.vertexArray[i];
2038 *vertex = vector_multiply_scalar(*vertex, factor);
2039 }
2040
2041 [self calculateBoundingVolumes];
2042 DESTROY(octree);
2043 DESTROY(baseFile); // Avoid octree cache.
2044 DESTROY(baseFileOctreeCacheRef);
2045}

◆ resetGraphicsState

- (void) resetGraphicsState
implementation

Reimplemented from <OOGraphicsResetClient>.

Extends class OOMesh.

Definition at line 341 of file OOMesh.m.

989{
990 [self deleteDisplayLists];
991 [self rebindMaterials];
992 _textureUnitCount = NSNotFound;
993}

◆ setModelFromModelData:name:

- (BOOL) setModelFromModelData: (NSDictionary*) dict
name: (NSString *) fileName 

Extends class OOMesh.

Definition at line 341 of file OOMesh.m.

1069 :(NSDictionary *)dict name:(NSString *)fileName
1070{
1072
1073 NSData *vertData = nil,
1074 *normData = nil,
1075 *tanData = nil,
1076 *faceData = nil;
1077 NSArray *mtlKeys = nil;
1078 NSString *key = nil;
1079 unsigned i;
1080
1081 if (dict == nil || ![dict isKindOfClass:[NSDictionary class]]) return NO;
1082
1083 vertexCount = [dict oo_unsignedIntForKey:@"vertex count"];
1084 faceCount = [dict oo_unsignedIntForKey:@"face count"];
1085
1086 if (vertexCount == 0 || faceCount == 0) return NO;
1087
1088 // Read data elements from dictionary.
1089 vertData = [dict oo_dataForKey:@"vertex data"];
1090 faceData = [dict oo_dataForKey:@"face data"];
1091
1092 mtlKeys = [dict oo_arrayForKey:@"material keys"];
1093 _normalMode = [dict oo_unsignedCharForKey:@"normal mode"];
1094 BOOL includeNormals = IsPerVertexNormalMode(_normalMode);
1095
1096 // Ensure we have all the required data elements.
1097 if (vertData == nil ||
1098 faceData == nil ||
1099 mtlKeys == nil)
1100 {
1101 OOLog(@"mesh.load.error.badCacheData", @"Ignoring bad cache data for mesh \"%@\".", fileName);
1102 return NO;
1103 }
1104
1105 if (includeNormals)
1106 {
1107 normData = [dict oo_dataForKey:@"normal data"];
1108 tanData = [dict oo_dataForKey:@"tangent data"];
1109 if (normData == nil || tanData == nil)
1110 {
1111 OOLog(@"mesh.load.error.badCacheData", @"Ignoring bad normal/tangent cache data for mesh \"%@\".", fileName);
1112 return NO;
1113 }
1114 }
1115
1116 // Ensure data objects are of correct size.
1117 if ([vertData length] != sizeof *_vertices * vertexCount) return NO;
1118 if ([faceData length] != sizeof *_faces * faceCount) return NO;
1119 if (includeNormals)
1120 {
1121 if ([normData length] != sizeof *_normals * vertexCount) return NO;
1122 if ([tanData length] != sizeof *_tangents * vertexCount) return NO;
1123 }
1124
1125 // Retain data.
1126 _vertices = (Vector *)[vertData bytes];
1127 [self setRetainedObject:vertData forKey:@"vertices"];
1128 _faces = (OOMeshFace *)[faceData bytes];
1129 [self setRetainedObject:faceData forKey:@"faces"];
1130 if (includeNormals)
1131 {
1132 _normals = (Vector *)[normData bytes];
1133 [self setRetainedObject:normData forKey:@"normals"];
1134 _tangents = (Vector *)[tanData bytes];
1135 [self setRetainedObject:tanData forKey:@"tangents"];
1136 }
1137 else
1138 {
1139 _normals = NULL;
1140 _tangents = NULL;
1141 }
1142
1143 // Copy material keys.
1144 materialCount = [mtlKeys count];
1145 for (i = 0; i != materialCount; ++i)
1146 {
1147 key = [mtlKeys oo_stringAtIndex:i];
1148 if (key != nil) materialKeys[i] = [key copy];
1149 else
1150 {
1151 OOLog(@"mesh.load.error.badCacheData", @"Ignoring bad cache data for mesh \"%@\".", fileName);
1152 return NO;
1153 }
1154 }
1155
1156 return YES;
1157
1159}

◆ setRetainedObject:forKey:

- (void) setRetainedObject: (id) object
forKey: (NSString *) key 

Extends class OOMesh.

Definition at line 1792 of file OOMesh.m.

2108 :(id)object forKey:(NSString *)key
2109{
2110 assert(key != nil);
2111
2112 if (object != nil)
2113 {
2114 if (_retainedObjects == nil) _retainedObjects = [[NSMutableDictionary alloc] init];
2115 [_retainedObjects setObject:object forKey:key];
2116 }
2117}

◆ setUpVertexArrays

- (BOOL) setUpVertexArrays

Extends class OOMesh.

Definition at line 1792 of file OOMesh.m.

1888{
1890
1891 NSUInteger fi, vi, mi;
1892
1893 if (![self allocateVertexArrayBuffersWithCount:faceCount]) return NO;
1894
1895 // if smoothed, find any vertices that are between faces of different
1896 // smoothing groups and mark them as being on an edge and therefore NOT
1897 // smooth shaded
1898 BOOL is_edge_vertex[vertexCount];
1899 GLfloat smoothGroup[vertexCount];
1900 for (vi = 0; vi < vertexCount; vi++)
1901 {
1902 is_edge_vertex[vi] = NO;
1903 smoothGroup[vi] = -1;
1904 }
1905 if (_normalMode == kNormalModeSmooth)
1906 {
1907 for (fi = 0; fi < faceCount; fi++)
1908 {
1909 GLfloat rv = _faces[fi].smoothGroup;
1910 int i;
1911 for (i = 0; i < 3; i++)
1912 {
1913 vi = _faces[fi].vertex[i];
1914 if (smoothGroup[vi] < 0.0) // unassigned
1915 smoothGroup[vi] = rv;
1916 else if (smoothGroup[vi] != rv) // a different colour
1917 is_edge_vertex[vi] = YES;
1918 }
1919 }
1920 }
1921
1922
1923 // base model, flat or smooth shaded, all triangles
1924 int tri_index = 0;
1925 int uv_index = 0;
1926 int vertex_index = 0;
1927
1928 // Iterate over material names
1929 for (mi = 0; mi != materialCount; ++mi)
1930 {
1931 triangle_range[mi].location = tri_index;
1932
1933 for (fi = 0; fi < faceCount; fi++)
1934 {
1935 Vector normal, tangent;
1936
1937 if (_faces[fi].materialIndex == mi)
1938 {
1939 for (vi = 0; vi < 3; vi++)
1940 {
1941 int v = _faces[fi].vertex[vi];
1942 if (IsPerVertexNormalMode(_normalMode))
1943 {
1944 if (is_edge_vertex[v])
1945 {
1946 [self getNormal:&normal andTangent:&tangent forVertex:v inSmoothGroup:_faces[fi].smoothGroup];
1947 }
1948 else
1949 {
1950 NSAssert1(_normals != NULL && _tangents != NULL, @"Normal/tangent buffers not allocated in %s", __PRETTY_FUNCTION__);
1951
1952 normal = _normals[v];
1953 tangent = _tangents[v];
1954 }
1955 }
1956 else
1957 {
1958 normal = _faces[fi].normal;
1959 tangent = _faces[fi].tangent;
1960 }
1961
1962 // FIXME: avoid redundant vertices so index array is actually useful.
1963 _displayLists.indexArray[tri_index++] = vertex_index;
1964 _displayLists.normalArray[vertex_index] = normal;
1965 _displayLists.tangentArray[vertex_index] = tangent;
1966 _displayLists.vertexArray[vertex_index++] = _vertices[v];
1967 _displayLists.textureUVArray[uv_index++] = _faces[fi].s[vi];
1968 _displayLists.textureUVArray[uv_index++] = _faces[fi].t[vi];
1969 }
1970 }
1971 }
1972 triangle_range[mi].length = tri_index - triangle_range[mi].location;
1973 }
1974
1975 _displayLists.count = tri_index; // total number of triangle vertices
1976 return YES;
1977
1979}

The documentation for this category was generated from the following file: