import "Object"
+#if defined(__EMSCRIPTEN__)
+#if !defined(_GLES2)
+#define _GLES2
+#endif
+#endif
+
+#if (defined(__ANDROID__) || defined(__ODROID__)) && !defined(_GLES)
+#define _GLES
+#endif
+
+#if !defined(_GLES) && !defined(_GLES2)
+#define USE_32_BIT_INDICES true
+#define indicesMember indices32
+#define uintindex uint32
+#else
+#define USE_32_BIT_INDICES false
+#define indicesMember indices
+#define uintindex uint16
+#endif
+
#define MAXNAMELEN 64
-// RGB Chunks
-#define RGB_FLOAT 0x0010
-#define RGB_BYTE 0x0011
-#define RGB_BYTE_GAMMA 0x0012
-#define RGB_FLOAT_GAMMA 0x0013
-
-// Amount Of Chunks
-#define AMOUNT_OF 0x0030
-
-#define MAIN3DS 0x4D4D
-#define EDIT3DS 0x3D3D
-#define EDIT_AMBIENT 0x2100
-#define EDIT_MATERIAL 0xAFFF
-#define EDIT_OBJECT 0x4000
-#define OBJ_HIDDEN 0x4010
-#define OBJ_TRIMESH 0x4100
-#define OBJ_LIGHT 0x4600
-#define OBJ_CAMERA 0x4700
-
-// Triangular Mesh Chunks
-#define TRI_VERTEXL 0x4110
-#define TRI_FACEL1 0x4120
-#define TRI_MATERIAL 0x4130
-#define TRI_MAPPINGCOORS 0x4140
-#define TRI_SMOOTHING 0x4150
-#define TRI_LOCAL 0x4160
-
-// Light Chunks
-#define LIT_SPOT 0x4610
-#define LIT_ONOFF 0x4620
-#define LIT_ATTENUATION 0x4625
-#define LIT_START 0x4659
-#define LIT_END 0x465A
-#define LIT_MULTIPLIER 0x465B
-
-// Camera Chunks
-#define CAM_SEECONE 0x4710
-#define CAM_RANGES 0x4720
-
-// Material Chunks
-#define MAT_NAME 0xA000
-#define MAT_AMBIENT 0xA010
-#define MAT_DIFFUSE 0xA020
-#define MAT_SPECULAR 0xA030
-#define MAT_SHININESS 0xA040
-#define MAT_SHINSTRENGTH 0xA041
-#define MAT_SHIN3PC 0xA042
-#define MAT_TRANSPARENCY 0xA050
-#define MAT_XPFALL 0xA052
-#define MAT_REFBLUR 0xA053
-#define MAT_SELFILLUM 0xA080
-#define MAT_DOUBLESIDED 0xA081
-#define MAT_ADDITIVE 0xA083
-#define MAT_SELFILPCT 0xA084
-#define MAT_WIRE 0xA085
-#define MAT_SUPERSMP 0xA086
-#define MAT_WIRETHICKNESS 0xA087
-#define MAT_FACEMAP 0xA088
-#define MAT_XPFALLIN 0xA08A
-#define MAT_PHONG 0xA08C
-#define MAT_WIREABS 0xA08E
-#define MAT_SHADING 0xA100
-#define MAT_MAPTEXTURE1 0xA200
-#define MAT_SPECULARMAP 0xA204
-#define MAT_MAPOPACITY 0xA210
-#define MAT_REFLECTIONMAP 0xA220
-#define MAT_BUMPMAP 0xA230
-
-// Map Chunks
-#define MAP_FILENAME 0xA300
-
-#define MAT_SHININESSMAP 0xA33C
-#define MAT_EMISSIVEMAP 0xA33D
-#define MAP_OPTIONS 0xA351
-#define MAP_1_U_SCALE 0xA354
-#define MAP_1_V_SCALE 0xA356
-#define MAP_U_OFFSET 0xA358
-#define MAP_V_OFFSET 0xA35A
-#define MAP_ROTATION 0xA35C
-
-#define MAP_OPTIONS_DECAL 0x0001 // (related to MAP_OPTIONS_DONTTILE)
-#define MAP_OPTIONS_MIRROR 0x0002
-#define MAP_OPTIONS_NEGATIVE 0x0008
-#define MAP_OPTIONS_DONTTILE 0x0010
-#define MAP_OPTIONS_SUMMEDFILTERING 0x0020
-#define MAP_OPTIONS_USEALPHA 0x0040
-#define MAP_OPTIONS_LUMORALPHATINT 0x0080
-#define MAP_OPTIONS_IGNOREALPHA 0x0100
-#define MAP_OPTIONS_RGBTINT 0x0200
-
-#define MAP_FILTERBLUR 0xA353
-#define MAP_1_U_SCALE 0xA354
-#define MAP_1_V_SCALE 0xA356
-#define MAP_U_OFFSET 0xA358
-#define MAP_V_OFFSET 0xA35A
-#define MAP_ROTATION 0xA35C
-
-#define MAP_LUMTINT1 0xA360
-#define MAP_LUMTINT2 0xA362
-
-#define MAP_TINTR 0xA364
-#define MAP_TINTG 0xA366
-#define MAP_TINTB 0xA368
-
-// Keyframer Chunks
-#define KEYFRAME3DS 0xB000
-#define FRM_AMBIENT 0xB001
-#define FRM_MESHINFO 0xB002
-#define FRM_CAMERA 0xB003
-#define FRM_CAMERATARGET 0xB004
-#define FRM_OMNILIGHT 0xB005
-#define FRM_SPOTLIGHTTARGET 0xB006
-#define FRM_SPOTLIGHT 0xB007
-#define FRM_FRAMES 0xB008
-#define FRM_PARAM 0xB010
-#define FRM_DUMMYNAME 0xB011
-#define FRM_PIVOT 0xB013
-#define FRM_TRACKPOS 0xB020
-#define FRM_TRACKROT 0xB021
-#define FRM_TRACKSCALE 0xB022
-#define FRM_TRACKFOV 0xB023
-#define FRM_TRACKROLL 0xB024
-#define FRM_TRACKCOLOR 0xB025
-#define FRM_TRACKMORPH 0xB026 // What does this do?
-#define FRM_TRACKHOTSPOT 0xB027
-#define FRM_TRACKFALLOFF 0xB028
-#define FRM_TRACKHIDE 0xB029
-#define FRM_HIERARCHY 0xB030
+static enum ChunkID3DS : uint16
+{
+ // RGB Chunks
+ RGB_FLOAT = 0x0010,
+ RGB_BYTE = 0x0011,
+ RGB_BYTE_GAMMA = 0x0012,
+ RGB_FLOAT_GAMMA = 0x0013,
+
+ // Amount Of Chunks
+ AMOUNT_OF = 0x0030,
+
+ MAIN3DS = 0x4D4D,
+ EDIT3DS = 0x3D3D,
+ EDIT_AMBIENT = 0x2100,
+ EDIT_MATERIAL = 0xAFFF,
+ EDIT_OBJECT = 0x4000,
+ OBJ_HIDDEN = 0x4010,
+ OBJ_TRIMESH = 0x4100,
+ OBJ_LIGHT = 0x4600,
+ OBJ_CAMERA = 0x4700,
+
+ // Triangular Mesh Chunks
+ TRI_VERTEXL = 0x4110,
+ TRI_FACEL1 = 0x4120,
+ TRI_MATERIAL = 0x4130,
+ TRI_MAPPINGCOORS = 0x4140,
+ TRI_SMOOTHING = 0x4150,
+ TRI_LOCAL = 0x4160,
+
+ // Light Chunks
+ LIT_SPOT = 0x4610,
+ LIT_ONOFF = 0x4620,
+ LIT_ATTENUATION = 0x4625,
+ LIT_START = 0x4659,
+ LIT_END = 0x465A,
+ LIT_MULTIPLIER = 0x465B,
+
+ // Camera Chunks
+ CAM_SEECONE = 0x4710,
+ CAM_RANGES = 0x4720,
+
+ // Material Chunks
+ MAT_NAME = 0xA000,
+ MAT_AMBIENT = 0xA010,
+ MAT_DIFFUSE = 0xA020,
+ MAT_SPECULAR = 0xA030,
+ MAT_SHININESS = 0xA040,
+ MAT_SHINSTRENGTH = 0xA041,
+ MAT_SHIN3PC = 0xA042,
+ MAT_TRANSPARENCY = 0xA050,
+ MAT_XPFALL = 0xA052,
+ MAT_REFBLUR = 0xA053,
+ MAT_SELFILLUM = 0xA080,
+ MAT_DOUBLESIDED = 0xA081,
+ MAT_ADDITIVE = 0xA083,
+ MAT_SELFILPCT = 0xA084,
+ MAT_WIRE = 0xA085,
+ MAT_SUPERSMP = 0xA086,
+ MAT_WIRETHICKNESS = 0xA087,
+ MAT_FACEMAP = 0xA088,
+ MAT_XPFALLIN = 0xA08A,
+ MAT_PHONG = 0xA08C,
+ MAT_WIREABS = 0xA08E,
+ MAT_SHADING = 0xA100,
+ MAT_MAPTEXTURE1 = 0xA200,
+ MAT_SPECULARMAP = 0xA204,
+ MAT_MAPOPACITY = 0xA210,
+ MAT_REFLECTIONMAP = 0xA220,
+ MAT_BUMPMAP = 0xA230,
+
+ // Map Chunks
+ MAP_FILENAME = 0xA300,
+
+ MAT_SHININESSMAP = 0xA33C,
+ MAT_EMISSIVEMAP = 0xA33D,
+
+ MAP_OPTIONS = 0xA351,
+ MAP_1_U_SCALE = 0xA354,
+ MAP_1_V_SCALE = 0xA356,
+ MAP_U_OFFSET = 0xA358,
+ MAP_V_OFFSET = 0xA35A,
+ MAP_ROTATION = 0xA35C,
+
+ MAP_FILTERBLUR = 0xA353,
+ MAP_1_U_SCALE = 0xA354,
+ MAP_1_V_SCALE = 0xA356,
+ MAP_U_OFFSET = 0xA358,
+ MAP_V_OFFSET = 0xA35A,
+ MAP_ROTATION = 0xA35C,
+
+ MAP_LUMTINT1 = 0xA360,
+ MAP_LUMTINT2 = 0xA362,
+
+ MAP_TINTR = 0xA364,
+ MAP_TINTG = 0xA366,
+ MAP_TINTB = 0xA368,
+
+ // Keyframer Chunks
+ KEYFRAME3DS = 0xB000,
+ FRM_AMBIENT = 0xB001,
+ FRM_MESHINFO = 0xB002,
+ FRM_CAMERA = 0xB003,
+ FRM_CAMERATARGET = 0xB004,
+ FRM_OMNILIGHT = 0xB005,
+ FRM_SPOTLIGHTTARGET = 0xB006,
+ FRM_SPOTLIGHT = 0xB007,
+ FRM_FRAMES = 0xB008,
+ FRM_PARAM = 0xB010,
+ FRM_DUMMYNAME = 0xB011,
+ FRM_PIVOT = 0xB013,
+ FRM_TRACKPOS = 0xB020,
+ FRM_TRACKROT = 0xB021,
+ FRM_TRACKSCALE = 0xB022,
+ FRM_TRACKFOV = 0xB023,
+ FRM_TRACKROLL = 0xB024,
+ FRM_TRACKCOLOR = 0xB025,
+ FRM_TRACKMORPH = 0xB026, // What does this do?
+ FRM_TRACKHOTSPOT = 0xB027,
+ FRM_TRACKFALLOFF = 0xB028,
+ FRM_TRACKHIDE = 0xB029,
+ FRM_HIERARCHY = 0xB030
+};
+
+static class MapOptions : uint32
+{
+ bool decal:1; // (related to dontTile)
+ bool mirror:1;
+ bool negative:1;
+ bool dontTile:1;
+ bool summedFiltering:1;
+ bool useAlpha:1;
+ bool lumOrAlphaTint:1;
+ bool ignoreAlpha:1;
+ bool rgbTint:1;
+};
typedef struct FileInfo FileInfo;
uint origIndices[3];
uint smoothGroups;
Material material;
- Vector3Df normal;
+ Vector3D normal;
+ double dots[3];
bool done:1;
} Face;
-struct FileInfo
+static struct FileInfo
{
File f;
DisplaySystem displaySystem;
Object rootObject;
- String fileName;
+ const String fileName;
- uint16 chunkId;
+ ChunkID3DS chunkId;
uint pos, end;
FileInfo * parent;
static float ReadFloat(File f)
{
- float floatValue;
+ float floatValue = 0;
f.Read(&floatValue, sizeof(float), 1);
BIGENDSWAP_DWORD(floatValue);
return floatValue;
static uint16 ReadWORD(File f)
{
- uint16 wordValue;
+ uint16 wordValue = 0;
f.Read(&wordValue, sizeof(uint16), 1);
BIGENDSWAP_WORD(wordValue);
return wordValue;
static uint ReadDWORD(File f)
{
- uint dwordValue;
+ uint dwordValue = 0;
f.Read(&dwordValue, sizeof(uint), 1);
BIGENDSWAP_DWORD(dwordValue);
return dwordValue;
childInfo.parent = info;
info->f.Seek(info->pos, start);
- childInfo.chunkId = ReadWORD(info->f);
+ childInfo.chunkId = (ChunkID3DS)ReadWORD(info->f);
length = ReadDWORD(info->f);
childInfo.pos += sizeof(uint16) + sizeof(uint);
{
if(info->chunkId == RGB_BYTE || info->chunkId == RGB_BYTE_GAMMA)
{
- byte value;
+ byte value = 0;
info->f.Getc((char *)&value); rgb->r = value / 255.0f;
info->f.Getc((char *)&value); rgb->g = value / 255.0f;
info->f.Getc((char *)&value); rgb->b = value / 255.0f;
if(face > b.face) return 1;
}
if(index == b.index) return 0;
- if(WELD_TRESHOLD)
+ if(WELD_TRESHOLD > 0)
{
if(value.x < b.value.x - WELD_TRESHOLD) return -1;
if(value.x > b.value.x + WELD_TRESHOLD) return 1;
class DestVertexInfo
{
int index, copyFromIndex;
- Vector3Df normal;
+ Vector3Df normal, tangent1, tangent2;
};
static void ComputeNormals(Mesh mesh, FileInfo * info, Object object)
{
Face * face = &faces[c];
Plane plane;
- plane.FromPointsf(mesh.vertices[face->indices[2]],
- mesh.vertices[face->indices[1]],
- mesh.vertices[face->indices[0]]);
+ uint * indices = face->indices;
+ Vector3D edges[3], rEdges[3];
+ computeNormalWeights(3, mVertices, indices, true, 0, face->dots, edges, rEdges);
+
+ plane.FromPointsf(mVertices[indices[2]], mVertices[indices[1]], mVertices[indices[0]]);
face->normal = { (float)plane.normal.x, (float)plane.normal.y, (float)plane.normal.z };
}
for(index = 0; index < nNewVertices; index++)
{
- int numShared = 0;
it.pointer = vertices[index];
if(it.pointer)
{
+ int numShared = 0;
+ double dotSum = 0;
DestVertexInfo vInfo = it.data;
- Vector3Df normal { };
+ Vector3D normal { };
+ Vector3D tangent1 { };
+ Vector3D tangent2 { };
SourceVertexInfo * inf = (SourceVertexInfo *)&(((AVLNode)it.pointer).key);
uint smoothing = inf->smoothGroups;
bool added = true;
}
// Optional code to compensate auto-welding with a limit angle cutoff between faces of same smoothing group
- if(SMOOTH_CUTOFF && WELD_TRESHOLD)
+ if(SMOOTH_CUTOFF && WELD_TRESHOLD > 0)
{
for(i : svInfo.faces)
{
{
bool valid = true;
- if(SMOOTH_CUTOFF && WELD_TRESHOLD)
+ if(SMOOTH_CUTOFF && WELD_TRESHOLD > 0)
{
int origIndexB = -1;
int k;
if(valid)
{
- normal.x += face->normal.x;
- normal.y += face->normal.y;
- normal.z += face->normal.z;
+ uint * indices = face->origIndices;
+ uint ix = vInfo.copyFromIndex;
+ uint ix0 = indices[0], ix1 = indices[1], ix2 = indices[2];
+ double dot = ix == ix0 ? face->dots[0] : ix == ix1 ? face->dots[1] : ix == ix2 ? face->dots[2] : 1;
+ if(ix != indices[0] && ix != indices[1] && ix != indices[2])
+ {
+ if(!mVertices[ix0].OnCompare(mVertices[ix])) dot = face->dots[0];
+ else if(!mVertices[ix1].OnCompare(mVertices[ix])) dot = face->dots[1];
+ else if(!mVertices[ix2].OnCompare(mVertices[ix])) dot = face->dots[2];
+ }
+ normal.x += face->normal.x * dot;
+ normal.y += face->normal.y * dot;
+ normal.z += face->normal.z * dot;
+
+ if(mesh.texCoords)
+ {
+ Vector3Df * p0 = &mVertices[ix0], * p1 = &mVertices[ix1], * p2 = &mVertices[ix2];
+ Pointf * t0 = &mesh->texCoords[ix0], * t1 = &mesh->texCoords[ix1], * t2 = &mesh->texCoords[ix2];
+ Vector3D v01 { (double)p1->x - (double)p0->x, (double)p1->y - (double)p0->y, (double)p1->z - (double)p0->z };
+ Vector3D v02 { (double)p2->x - (double)p0->x, (double)p2->y - (double)p0->y, (double)p2->z - (double)p0->z };
+
+ Vector3D t01 { (double)t1->x - (double)t0->x, (double)t1->y - (double)t0->y };
+ Vector3D t02 { (double)t2->x - (double)t0->x, (double)t2->y - (double)t0->y };
+ double f = dot / (t01.x * t02.y - t02.x * t01.y);
+
+ tangent1.x += f * (v01.x * t02.y - v02.x * t01.y);
+ tangent1.y += f * (v01.y * t02.y - v02.y * t01.y);
+ tangent1.z += f * (v01.z * t02.y - v02.z * t01.y);
+
+ tangent2.x += f * (v02.x * t01.x - v01.x * t02.x);
+ tangent2.y += f * (v02.y * t01.x - v01.y * t02.x);
+ tangent2.z += f * (v02.z * t01.x - v01.z * t02.x);
+ }
+
+ dotSum += dot;
numShared++;
added = true;
face->done = true;
}
}
}
- if(!SMOOTH_CUTOFF || !WELD_TRESHOLD) break;
+ if(!SMOOTH_CUTOFF || !(WELD_TRESHOLD > 0)) break;
}
- normal.Scale(normal, 1.0f / numShared);
+ // normal.Scale(normal, 1.0f / numShared);
+ normal.Scale(normal, 1.0 / dotSum);
+ normal.Normalize(normal);
+
+ //tangent1.Scale(tangent1, 1.0 / dotSum);
+ tangent1.Normalize(tangent1);
+
+ //tangent2.Scale(tangent2, 1.0 / dotSum);
+ tangent2.Normalize(tangent2);
+
if(vInfo.index == index)
- vInfo.normal.Normalize(normal);
+ {
+ vInfo.normal = { (float)normal.x, (float)normal.y, (float)normal.z };
+ vInfo.tangent1 = { (float)tangent1.x, (float)tangent1.y, (float)tangent1.z };
+ vInfo.tangent2 = { (float)tangent2.x, (float)tangent2.y, (float)tangent2.z };
+ }
// Auto welding/smoothing requires extra vertices because angle is too steep
- if(SMOOTH_CUTOFF && WELD_TRESHOLD)
+ if(SMOOTH_CUTOFF && WELD_TRESHOLD > 0)
{
SharedDestVertexInfo newSharedInfo = null;
int index;
*((void **)&mesh.texCoords) = null;
*((int *)&mesh.nVertices) = 0;
- mesh.Allocate( { vertices = true, normals = true, texCoords1 = oldTexCoords ? true : false }, nNewVertices, info->displaySystem);
+ mesh.Allocate( { vertices = true, normals = true, tangents = oldTexCoords ? true : false, texCoords1 = oldTexCoords ? true : false }, nNewVertices, info->displaySystem);
// Fill in the new vertices
for(index = 0; index < nNewVertices; index++)
// Duplicate vertex
mesh.normals[index] = vInfo ? vInfo.normal : { };
mesh.vertices[index] = oldVertices[vInfo ? vInfo.copyFromIndex : index];
+ if(mesh.tangents)
+ {
+ mesh.tangents[2*index+0] = vInfo ? vInfo.tangent1 : { };
+ mesh.tangents[2*index+1] = vInfo ? vInfo.tangent2 : { };
+ }
if(mesh.texCoords)
mesh.texCoords[index] = oldTexCoords[vInfo ? vInfo.copyFromIndex : index];
}
info->faces[i].done = false;
}
- mesh.Unlock({ normals = true });
+ mesh.Unlock({ normals = true, tangents = true });
// Free all the temporary stuff
PrimitiveSingle * triangle;
triangle = &mesh.primitives[mesh.nPrimitives++];
- if(mesh.AllocatePrimitive(triangle, { triangles, indices32bit = true }, 3))
+ if(mesh.AllocatePrimitive(triangle, { triangles, indices32bit = USE_32_BIT_INDICES }, 3))
{
- triangle->indices32[0] = face->indices[0];
- triangle->indices32[1] = face->indices[1];
- triangle->indices32[2] = face->indices[2];
- triangle->middle.Add(mesh.vertices[triangle->indices32[0]], mesh.vertices[triangle->indices32[1]]);
- triangle->middle.Add(triangle->middle, mesh.vertices[triangle->indices32[2]]);
+ triangle->indicesMember[0] = (uintindex)face->indices[0];
+ triangle->indicesMember[1] = (uintindex)face->indices[1];
+ triangle->indicesMember[2] = (uintindex)face->indices[2];
+ triangle->middle.Add(mesh.vertices[triangle->indicesMember[0]], mesh.vertices[triangle->indicesMember[1]]);
+ triangle->middle.Add(triangle->middle, mesh.vertices[triangle->indicesMember[2]]);
triangle->plane.FromPointsf(
- mesh.vertices[triangle->indices32[2]],
- mesh.vertices[triangle->indices32[1]],
- mesh.vertices[triangle->indices32[0]]);
+ mesh.vertices[triangle->indicesMember[2]],
+ mesh.vertices[triangle->indicesMember[1]],
+ mesh.vertices[triangle->indicesMember[0]]);
mesh.UnlockPrimitive(triangle);
}
}
else
{
- PrimitiveGroup group = mesh.AddPrimitiveGroup({ triangles, indices32bit = true }, faces.count * 3);
+ PrimitiveGroup group = mesh.AddPrimitiveGroup({ triangles, indices32bit = USE_32_BIT_INDICES }, faces.count * 3);
if(group)
{
c = 0;
if(object.flags.flipWindings)
{
- group.indices32[c*3] = face->indices[2];
- group.indices32[c*3+1] = face->indices[1];
- group.indices32[c*3+2] = face->indices[0];
+ group.indicesMember[c*3] = (uintindex)face->indices[2];
+ group.indicesMember[c*3+1] = (uintindex)face->indices[1];
+ group.indicesMember[c*3+2] = (uintindex)face->indices[0];
}
else
{
- group.indices32[c*3] = face->indices[0];
- group.indices32[c*3+1] = face->indices[1];
- group.indices32[c*3+2] = face->indices[2];
+ group.indicesMember[c*3] = (uintindex)face->indices[0];
+ group.indicesMember[c*3+1] = (uintindex)face->indices[1];
+ group.indicesMember[c*3+2] = (uintindex)face->indices[2];
}
face->done = true;
c++;
count++;
if(count)
{
- PrimitiveGroup group = mesh.AddPrimitiveGroup({ triangles, indices32bit = true }, count * 3);
+ PrimitiveGroup group = mesh.AddPrimitiveGroup({ triangles, indices32bit = USE_32_BIT_INDICES }, count * 3);
if(group)
{
for(c = 0; c<nFaces; c++)
Face * face = &info->faces[c];
if(!face->done)
{
- group.indices32[c*3] = face->indices[0];
- group.indices32[c*3+1] = face->indices[1];
- group.indices32[c*3+2] = face->indices[2];
+ group.indicesMember[c*3] = (uintindex)face->indices[0];
+ group.indicesMember[c*3+1] = (uintindex)face->indices[1];
+ group.indicesMember[c*3+2] = (uintindex)face->indices[2];
}
}
mesh.UnlockPrimitiveGroup(group);
{
uint bc = y * bw + x;
Color color = picture[bc].color;
- picture[bc] = { 255, { color.r, 255 - color.b, color.g } };
+ picture[bc] = { 255, { color.r, color.g, color.b } };
+ }
+ }
+ }
+ }
+ }
+ else if(info->parent->chunkId == MAT_SPECULARMAP)
+ {
+ // To avoid messing up the diffuse texture if same bitmap is specified by mistake...
+ char specName[MAX_LOCATION+5];
+ strcpy(specName, "SPEC:");
+ strcat(specName, location);
+ if(!mat.specularMap)
+ {
+ mat.specularMap = displaySystem.GetTexture(specName);
+ if(!mat.specularMap)
+ {
+ mat.specularMap = Bitmap { };
+ if(!mat.specularMap.Load(location, null, null) ||
+ !mat.specularMap.Convert(null, pixelFormat888, null) ||
+ !displaySystem.AddTexture(specName, mat.specularMap))
+ delete mat.specularMap;
+ if(mat.specularMap)
+ {
+ ColorAlpha * picture = (ColorAlpha *)mat.specularMap.picture;
+ int bw = mat.specularMap.width, bh = mat.specularMap.height;
+ int y, x;
+
+ for(y = 0; y < bh; y++)
+ for(x = 0; x < bw; x++)
+ {
+ uint bc = y * bw + x;
+ Color color = picture[bc].color;
+ picture[bc] = { 255, { color.r, color.g, color.b } };
}
}
}
}
case MAP_OPTIONS:
{
- uint16 options = ReadWORD(info->f);
- if(!(options & MAP_OPTIONS_DONTTILE)) mat.flags.tile = true;
+ MapOptions options = (MapOptions)ReadWORD(info->f);
+ if(!options.dontTile) mat.flags.tile = true;
break;
}
case MAP_1_U_SCALE:
{
uint16 shininess;
ReadChunks(ReadAmountOf, info, &shininess);
+ mat.reflectivity = shininess / 100.0f;
+ /*
mat.specular.r *= shininess / 100.0f;
mat.specular.g *= shininess / 100.0f;
mat.specular.b *= shininess / 100.0f;
+ */
break;
}
case MAT_SHININESS:
{ Kc, Kl, Kq, small, d });
*/
- light->flags.attenuation = true;
-
/*
#define MINLIGHT 0.08
light->Kq = 1/(light->end*light->end*MINLIGHT);
#define MINLIGHT 0.15f
// #define MINLIGHT 0.1
- light->Kl = (float)(1/(light->end*MINLIGHT));
+ //light->Kl = (float)(1/(light->end*MINLIGHT));
+ float c = 1.0, l = 0.005, q = 0.0005, small = 500, end = light->end;
+ light->Kc = (c + l * end + q * end * end) / small;
+ light->Kl = light->Kc * l/c;
+ light->Kq = light->Kc * q/c;
+ light->flags.attenuation = true;
break;
}
case LIT_START:
};
// Key Framer Chunks
-
-#define ACCFLAG_TENSION 0x00000001
-#define ACCFLAG_CONTINUITY 0x00000002
-#define ACCFLAG_BIAS 0x00000004
-#define ACCFLAG_EASETO 0x00000008
-#define ACCFLAG_EASEFROM 0x00000010
+static class AccelerationFlags : uint32
+{
+ bool tension:1, continuity:1, bias:1, easeTo:1, easeFrom:1;
+};
static bool ReadFrameInfoBlock(FileInfo * info, ObjectInfoBlock * block)
{
track.keys = new0 FrameKey[track.numKeys];
for(c = 0; c<track.numKeys; c++)
{
- uint16 accelerationFlags;
+ AccelerationFlags accelerationFlags;
FrameKey * key = track.keys + c;
key->frame = ReadDWORD(info->f);
- accelerationFlags = ReadWORD(info->f);
+ accelerationFlags = (AccelerationFlags)ReadWORD(info->f);
- if(accelerationFlags & ACCFLAG_TENSION)
+ if(accelerationFlags.tension)
key->tension = ReadFloat(info->f);
- if(accelerationFlags & ACCFLAG_CONTINUITY)
+ if(accelerationFlags.continuity)
key->continuity = ReadFloat(info->f);
- if(accelerationFlags & ACCFLAG_BIAS)
+ if(accelerationFlags.bias)
key->bias = ReadFloat(info->f);
- if(accelerationFlags & ACCFLAG_EASETO)
+ if(accelerationFlags.easeTo)
key->easeTo = ReadFloat(info->f);
- if(accelerationFlags & ACCFLAG_EASEFROM)
+ if(accelerationFlags.easeFrom)
key->easeFrom = ReadFloat(info->f);
switch(info->chunkId)
{
Vector3Df axis;
Angle angle = ReadFloat(info->f);
- Vector3Df fixedAxis;
+ Vector3D fixedAxis;
Read3DVertex(info->f, axis);
- fixedAxis.x = axis.x;
- fixedAxis.y = -axis.z;
- fixedAxis.z = axis.y;
+ fixedAxis = { axis.x, -axis.z, axis.y };
if(c > 0)
{
case FRM_MESHINFO:
{
ObjectInfoBlock block { };
- Object object;
+ Object object = null;
ReadChunks(ReadFrameInfoBlock, info, &block);
}
delete block.dummyName;
}
- object.parent = info->rootObject;
+ if(object)
+ object.parent = info->rootObject;
}
else
object = info->rootObject.Find(block.name);
case FRM_CAMERA:
{
ObjectInfoBlock block { };
- Object object;
+ Object object = null;
ReadChunks(ReadFrameInfoBlock, info, &block);
}
delete block.dummyName;
}
- object.parent = info->rootObject;
+ if(object)
+ object.parent = info->rootObject;
}
else
object = info->rootObject.Find(block.name);
case FRM_CAMERATARGET:
{
ObjectInfoBlock block { };
- Object object;
+ Object object = null;
char targetName[MAXNAMELEN];
ReadChunks(ReadFrameInfoBlock, info, &block);
}
delete block.dummyName;
}
- object.parent = info->rootObject;
+ if(object)
+ object.parent = info->rootObject;
}
else
object = info->rootObject.Find(targetName);
case FRM_SPOTLIGHT:
{
ObjectInfoBlock block { };
- Object object;
+ Object object = null;
ReadChunks(ReadFrameInfoBlock, info, &block);
}
delete block.dummyName;
}
- object.parent = info->rootObject;
+ if(object)
+ object.parent = info->rootObject;
}
else
object = info->rootObject.Find(block.name);
case FRM_SPOTLIGHTTARGET:
{
ObjectInfoBlock block { };
- Object object;
+ Object object = null;
char targetName[MAXNAMELEN];
ReadChunks(ReadFrameInfoBlock, info, &block);
{
object = Object { };
object.name = new char[strlen(block.dummyName) + strlen(model.name) + 2];
+ // TODO: When passing a String to a const String, use member if property is const String but member is String
sprintf(object.name, "%s.%s", model.name, block.dummyName);
object.flags = model.flags;
object.flags.ownMesh = false;
}
delete block.dummyName;
}
- object.parent = info->rootObject;
+ if(object)
+ object.parent = info->rootObject;
}
else
object = info->rootObject.Find(targetName);
{
class_property(extension) = "3ds";
- bool Load(Object object, char * fileName, DisplaySystem displaySystem)
+ bool Load(Object object, const char * fileName, DisplaySystem displaySystem)
{
bool result = false;
if(fileName)
info.f = FileOpen(fileName, read);
if(info.f)
{
- if(ReadChunks(ReadMain, &info, object) && info.rootObject.children.first)
+ // TOFIX: eC reorders that badly
+ // if(ReadChunks(ReadMain, &info, object) && info.rootObject.children.first)
+ if(ReadChunks(ReadMain, &info, object) && info.rootObject.firstChild)
{
object.flags.root = true;
object.SetMinMaxRadius(true);