nuclear@0: //#include nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@0: #include "sceneloader.h" nuclear@0: #include "3dschunks.h" nuclear@0: #include "typedefs.h" nuclear@0: nuclear@0: using std::ifstream; nuclear@0: using std::string; nuclear@0: nuclear@0: namespace SceneLoader { nuclear@0: GraphicsContext *gc; nuclear@0: dword ReadCounter; nuclear@0: Material *mat; nuclear@0: dword MatCount; nuclear@0: nuclear@0: bool eof = false; nuclear@0: nuclear@0: string datapath = ""; nuclear@0: nuclear@0: string SceneFileName; nuclear@0: string ObjectName; nuclear@0: nuclear@0: bool SaveNormalFile = false; nuclear@0: } nuclear@0: nuclear@0: using namespace SceneLoader; nuclear@0: nuclear@0: struct ChunkHeader { nuclear@0: ChunkID id; nuclear@0: dword size; nuclear@0: }; nuclear@0: nuclear@0: struct Percent { nuclear@0: int IntPercent; nuclear@0: float FloatPercent; nuclear@0: nuclear@0: Percent(int p = 0) {IntPercent = p; FloatPercent = (float)p / 100.0f; } nuclear@0: Percent(float p) {FloatPercent = p; IntPercent = (int)(p * 100.0f); } nuclear@0: }; nuclear@0: nuclear@0: struct TexMap { nuclear@0: string filename; nuclear@0: TextureType type; nuclear@0: float intensity; nuclear@0: float rotation; nuclear@0: Vector2 offset; nuclear@0: Vector2 scale; nuclear@0: }; nuclear@0: nuclear@0: const dword HeaderSize = 6; nuclear@0: nuclear@0: enum {OBJ_MESH, OBJ_PTLIGHT, OBJ_SPLIGHT, OBJ_CAMERA, OBJ_CURVE}; nuclear@0: nuclear@0: // local function prototypes nuclear@0: byte ReadByte(HANDLE file); nuclear@0: word ReadWord(HANDLE file); nuclear@0: dword ReadDword(HANDLE file); nuclear@0: float ReadFloat(HANDLE file); nuclear@0: Vector3 ReadVector(HANDLE file, bool FlipYZ = true); nuclear@0: string ReadString(HANDLE file); nuclear@0: Color ReadColor(HANDLE file); nuclear@0: Percent ReadPercent(HANDLE file); nuclear@0: ChunkHeader ReadChunkHeader(HANDLE file); nuclear@0: void SkipChunk(HANDLE file, const ChunkHeader &chunk); nuclear@0: void SkipBytes(HANDLE file, dword bytes); nuclear@0: nuclear@0: int ReadObject(HANDLE file, const ChunkHeader &ch, void **obj); nuclear@0: int ReadLight(HANDLE file, const ChunkHeader &ch, Light **lt); nuclear@0: Material ReadMaterial(HANDLE file, const ChunkHeader &ch); nuclear@0: TexMap ReadTextureMap(HANDLE file, const ChunkHeader &ch); nuclear@0: nuclear@0: Material *FindMaterial(string name); nuclear@0: nuclear@0: bool LoadNormalsFromFile(const char *fname, Scene *scene); nuclear@0: void SaveNormalsToFile(const char *fname, Scene *scene); nuclear@0: nuclear@0: nuclear@0: void SceneLoader::SetGraphicsContext(GraphicsContext *gfx) { nuclear@0: gc = gfx; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: void SceneLoader::SetDataPath(const char *path) { nuclear@0: datapath = path; nuclear@0: } nuclear@0: nuclear@0: void SceneLoader::SetNormalFileSaving(bool enable) { nuclear@0: SaveNormalFile = enable; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: nuclear@0: //////////////////////////////////////// nuclear@0: // --==( function LoadScene )==-- // nuclear@0: // ---------------------------------- // nuclear@0: // Creates a Scene instance and loads // nuclear@0: // the data from specified file // nuclear@0: //////////////////////////////////////// nuclear@0: nuclear@0: bool SceneLoader::LoadScene(const char *fname, Scene **scene) { nuclear@0: if(!gc) return false; nuclear@0: nuclear@0: if(!LoadMaterials(fname, &mat)) return false; nuclear@0: nuclear@0: //ifstream file(fname); nuclear@0: //if(!file.is_open()) return false; nuclear@0: HANDLE file = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); nuclear@0: assert(file != NULL); nuclear@0: eof = false; nuclear@0: nuclear@0: SceneFileName = string(fname); nuclear@0: nuclear@0: ChunkHeader chunk; nuclear@0: Scene *scn = new Scene(gc); // new scene instance nuclear@0: nuclear@0: chunk = ReadChunkHeader(file); nuclear@0: if(chunk.id != Chunk_3DSMain) { nuclear@0: CloseHandle(file); nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: //while(!file.eof()) { nuclear@0: while(!eof) { nuclear@0: nuclear@0: chunk = ReadChunkHeader(file); nuclear@0: nuclear@0: void *objptr; nuclear@0: int type; nuclear@0: nuclear@0: switch(chunk.id) { nuclear@0: case Chunk_Main_3DEditor: nuclear@0: break; // dont skip nuclear@0: nuclear@0: case Chunk_Edit_AmbientColor: nuclear@0: scn->SetAmbientLight(ReadColor(file)); nuclear@0: break; nuclear@0: nuclear@0: case Chunk_Edit_Fog: nuclear@0: // **TODO** find out chunk structure nuclear@0: break; nuclear@0: nuclear@0: case Chunk_Edit_Object: nuclear@0: type = ReadObject(file, chunk, &objptr); nuclear@0: switch(type) { nuclear@0: case OBJ_MESH: nuclear@0: { nuclear@0: Object *object = (Object*)objptr; nuclear@0: scn->AddObject(object); nuclear@0: } nuclear@0: break; nuclear@0: nuclear@0: case OBJ_CAMERA: nuclear@0: { nuclear@0: Camera *cam = (Camera*)objptr; nuclear@0: scn->AddCamera(cam); nuclear@0: } nuclear@0: break; nuclear@0: nuclear@0: case OBJ_PTLIGHT: nuclear@0: { nuclear@0: PointLight *lt = (PointLight*)objptr; nuclear@0: scn->AddLight(lt); nuclear@0: } nuclear@0: break; nuclear@0: nuclear@0: case OBJ_SPLIGHT: nuclear@0: { nuclear@0: SpotLight *lt = (SpotLight*)objptr; nuclear@0: scn->AddLight(lt); nuclear@0: } nuclear@0: break; nuclear@0: nuclear@0: case OBJ_CURVE: nuclear@0: { nuclear@0: CatmullRomSpline *spline = (CatmullRomSpline*)objptr; nuclear@0: scn->AddCurve(spline); nuclear@0: } nuclear@0: break; nuclear@0: } nuclear@0: nuclear@0: break; nuclear@0: nuclear@0: default: nuclear@0: SkipChunk(file, chunk); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: CloseHandle(file); nuclear@0: nuclear@0: nuclear@0: // check if there is a normals file in the same dir and load them, or else calculate them nuclear@0: if(!LoadNormalsFromFile((SceneFileName + string(".normals")).c_str(), scn)) { nuclear@0: std::list::iterator objiter = scn->GetObjectsList()->begin(); nuclear@0: while(objiter != scn->GetObjectsList()->end()) { nuclear@0: (*objiter++)->GetTriMesh()->CalculateNormals(); nuclear@0: } nuclear@0: if(SaveNormalFile) SaveNormalsToFile((SceneFileName + string(".normals")).c_str(), scn); nuclear@0: } nuclear@0: nuclear@0: *scene = scn; nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: nuclear@0: bool SceneLoader::LoadObject(const char *fname, const char *ObjectName, Object **obj) { nuclear@0: if(!gc) return false; nuclear@0: nuclear@0: if(!LoadMaterials(fname, &mat)) return false; nuclear@0: nuclear@0: //ifstream file(fname); nuclear@0: //if(!file.is_open()) return false; nuclear@0: HANDLE file = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); nuclear@0: assert(file != NULL); nuclear@0: eof = false; nuclear@0: nuclear@0: ChunkHeader chunk = ReadChunkHeader(file); nuclear@0: if(chunk.id != Chunk_3DSMain) { nuclear@0: CloseHandle(file); nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: while(!eof) { nuclear@0: nuclear@0: chunk = ReadChunkHeader(file); nuclear@0: nuclear@0: void *objptr; nuclear@0: int type; nuclear@0: nuclear@0: switch(chunk.id) { nuclear@0: case Chunk_Main_3DEditor: nuclear@0: break; // dont skip nuclear@0: nuclear@0: case Chunk_Edit_Object: nuclear@0: type = ReadObject(file, chunk, &objptr); nuclear@0: if(type == OBJ_MESH) { nuclear@0: Object *object = (Object*)objptr; nuclear@0: if(!strcmp(object->name.c_str(), ObjectName)) { nuclear@0: object->GetTriMesh()->CalculateNormals(); nuclear@0: *obj = object; nuclear@0: CloseHandle(file); nuclear@0: return true; nuclear@0: } nuclear@0: } nuclear@0: break; nuclear@0: nuclear@0: default: nuclear@0: SkipChunk(file, chunk); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: CloseHandle(file); nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: nuclear@0: bool FindChunk(HANDLE file, word ChunkID) { nuclear@0: nuclear@0: ChunkHeader chunk = ReadChunkHeader(file); nuclear@0: nuclear@0: while(chunk.id != ChunkID) { nuclear@0: SkipChunk(file, chunk); nuclear@0: chunk = ReadChunkHeader(file); nuclear@0: } nuclear@0: nuclear@0: return chunk.id == ChunkID; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: nuclear@0: bool SceneLoader::LoadMaterials(const char *fname, Material **materials) { nuclear@0: if(!materials) return false; nuclear@0: nuclear@0: //ifstream file(fname); nuclear@0: //if(!file.is_open()) return false; nuclear@0: HANDLE file = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); nuclear@0: assert(file != NULL); nuclear@0: eof = false; nuclear@0: nuclear@0: ChunkHeader chunk; nuclear@0: nuclear@0: chunk = ReadChunkHeader(file); nuclear@0: if(chunk.id != Chunk_3DSMain) { nuclear@0: CloseHandle(file); nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: if(!FindChunk(file, Chunk_Main_3DEditor)) { nuclear@0: CloseHandle(file); nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: std::vector mats; nuclear@0: nuclear@0: while(!eof) { nuclear@0: nuclear@0: chunk = ReadChunkHeader(file); nuclear@0: nuclear@0: if(chunk.id == Chunk_Edit_Material) { nuclear@0: Material mat = ReadMaterial(file, chunk); nuclear@0: mats.push_back(mat); nuclear@0: } else { nuclear@0: SkipChunk(file, chunk); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: MatCount = (dword)mats.size(); nuclear@0: nuclear@0: if(*materials) delete [] *materials; nuclear@0: Material *m = new Material[MatCount]; nuclear@0: nuclear@0: for(dword i=0; i 0.0f) mat.SpecularEnable = true; nuclear@0: break; nuclear@0: nuclear@0: case Chunk_Mat_SpecularIntensity: nuclear@0: p = ReadPercent(file); nuclear@0: mat.Specular.r *= p.FloatPercent; nuclear@0: mat.Specular.g *= p.FloatPercent; nuclear@0: mat.Specular.b *= p.FloatPercent; nuclear@0: break; nuclear@0: nuclear@0: case Chunk_Mat_Transparency: nuclear@0: p = ReadPercent(file); nuclear@0: mat.Alpha = 1.0f - p.FloatPercent; nuclear@0: break; nuclear@0: nuclear@0: case Chunk_Mat_SelfIllumination: nuclear@0: p = ReadPercent(file); nuclear@0: mat.Emissive = Color(p.FloatPercent); nuclear@0: break; nuclear@0: nuclear@0: case Chunk_Mat_TextureMap: nuclear@0: case Chunk_Mat_TextureMap2: nuclear@0: case Chunk_Mat_OpacityMap: nuclear@0: case Chunk_Mat_SelfIlluminationMap: nuclear@0: map = ReadTextureMap(file, chunk); nuclear@0: mat.SetTexture(gc->texman->LoadTexture((datapath + map.filename).c_str()), map.type); nuclear@0: break; nuclear@0: nuclear@0: case Chunk_Mat_ReflectionMap: nuclear@0: map = ReadTextureMap(file, chunk); nuclear@0: mat.SetTexture(gc->texman->LoadTexture((datapath + map.filename).c_str()), map.type); nuclear@0: mat.EnvBlend = map.intensity; nuclear@0: break; nuclear@0: nuclear@0: case Chunk_Mat_BumpMap: nuclear@0: map = ReadTextureMap(file, chunk); nuclear@0: mat.SetTexture(gc->texman->LoadTexture((datapath + map.filename).c_str()), map.type); nuclear@0: mat.BumpIntensity = map.intensity; nuclear@0: break; nuclear@0: nuclear@0: default: nuclear@0: SkipChunk(file, chunk); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: return mat; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: nuclear@0: nuclear@0: nuclear@0: //////////////////////////////////////////////////// nuclear@0: byte ReadByte(HANDLE file) { nuclear@0: byte val; nuclear@0: dword numread; nuclear@0: ReadFile(file, &val, sizeof(byte), &numread, NULL); nuclear@0: if(numread < sizeof(byte)) eof = true; nuclear@0: ReadCounter++; nuclear@0: return val; nuclear@0: } nuclear@0: nuclear@0: word ReadWord(HANDLE file) { nuclear@0: word val; nuclear@0: dword numread; nuclear@0: ReadFile(file, &val, sizeof(word), &numread, NULL); nuclear@0: if(numread < sizeof(word)) eof = true; nuclear@0: ReadCounter += sizeof(word); nuclear@0: return val; nuclear@0: } nuclear@0: nuclear@0: dword ReadDword(HANDLE file) { nuclear@0: dword val; nuclear@0: dword numread; nuclear@0: ReadFile(file, &val, sizeof(dword), &numread, NULL); nuclear@0: if(numread < sizeof(dword)) eof = true; nuclear@0: ReadCounter += sizeof(dword); nuclear@0: return val; nuclear@0: } nuclear@0: nuclear@0: float ReadFloat(HANDLE file) { nuclear@0: float val; nuclear@0: dword numread; nuclear@0: ReadFile(file, &val, sizeof(float), &numread, NULL); nuclear@0: if(numread < sizeof(float)) eof = true; nuclear@0: ReadCounter += sizeof(float); nuclear@0: return val; nuclear@0: } nuclear@0: /* nuclear@0: byte ReadByte(HANDLE file) { nuclear@0: byte val; nuclear@0: file.read((char*)&val, 1); nuclear@0: ReadCounter++; nuclear@0: return val; nuclear@0: } nuclear@0: nuclear@0: word ReadWord(HANDLE file) { nuclear@0: word val; nuclear@0: file.read((char*)&val, sizeof(word)); nuclear@0: ReadCounter += sizeof(word); nuclear@0: return val; nuclear@0: } nuclear@0: nuclear@0: dword ReadDword(HANDLE file) { nuclear@0: dword val; nuclear@0: file.read((char*)&val, sizeof(dword)); nuclear@0: ReadCounter += sizeof(dword); nuclear@0: return val; nuclear@0: } nuclear@0: nuclear@0: float ReadFloat(HANDLE file) { nuclear@0: float val; nuclear@0: file.read((char*)&val, sizeof(float)); nuclear@0: ReadCounter += sizeof(float); nuclear@0: return val; nuclear@0: } nuclear@0: */ nuclear@0: Vector3 ReadVector(HANDLE file, bool FlipYZ) { nuclear@0: Vector3 vector; nuclear@0: vector.x = ReadFloat(file); nuclear@0: if(!FlipYZ) vector.y = ReadFloat(file); nuclear@0: vector.z = ReadFloat(file); nuclear@0: if(FlipYZ) vector.y = ReadFloat(file); nuclear@0: return vector; nuclear@0: } nuclear@0: nuclear@0: string ReadString(HANDLE file) { nuclear@0: string str; nuclear@0: char c; nuclear@0: while(c = (char)ReadByte(file)) { nuclear@0: str.push_back(c); nuclear@0: } nuclear@0: str.push_back('\0'); nuclear@0: ReadCounter++; nuclear@0: nuclear@0: return str; nuclear@0: } nuclear@0: /* nuclear@0: string ReadString(HANDLE file) { nuclear@0: string str; nuclear@0: char c; nuclear@0: while(c = file.get()) { nuclear@0: str.push_back(c); nuclear@0: ReadCounter++; nuclear@0: } nuclear@0: str.push_back('\0'); nuclear@0: ReadCounter++; nuclear@0: nuclear@0: return str; nuclear@0: } nuclear@0: */ nuclear@0: nuclear@0: Color ReadColor(HANDLE file) { nuclear@0: ChunkHeader chunk = ReadChunkHeader(file); nuclear@0: if(chunk.id < 0x0010 || chunk.id > 0x0013) return Color(-1.0f, -1.0f, -1.0f); nuclear@0: nuclear@0: Color color; nuclear@0: nuclear@0: if(chunk.id == Chunk_Color_Byte3 || chunk.id == Chunk_Color_GammaByte3) { nuclear@0: byte r = ReadByte(file); nuclear@0: byte g = ReadByte(file); nuclear@0: byte b = ReadByte(file); nuclear@0: color = Color(r, g, b); nuclear@0: } else { nuclear@0: color.r = ReadFloat(file); nuclear@0: color.g = ReadFloat(file); nuclear@0: color.b = ReadFloat(file); nuclear@0: } nuclear@0: nuclear@0: return color; nuclear@0: } nuclear@0: nuclear@0: Percent ReadPercent(HANDLE file) { nuclear@0: ChunkHeader chunk = ReadChunkHeader(file); nuclear@0: Percent p; nuclear@0: if(chunk.id != Chunk_PercentInt && chunk.id != Chunk_PercentFloat) return p; nuclear@0: nuclear@0: if(chunk.id == Chunk_PercentInt) { nuclear@0: p = Percent(ReadWord(file)); nuclear@0: } else { nuclear@0: p = Percent(ReadFloat(file)); nuclear@0: } nuclear@0: nuclear@0: return p; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: ChunkHeader ReadChunkHeader(HANDLE file) { nuclear@0: ChunkHeader chunk; nuclear@0: chunk.id = (ChunkID)ReadWord(file); nuclear@0: chunk.size = ReadDword(file); nuclear@0: return chunk; nuclear@0: } nuclear@0: nuclear@0: void SkipChunk(HANDLE file, const ChunkHeader &chunk) { nuclear@0: //file.ignore(chunk.size - HeaderSize); nuclear@0: SetFilePointer(file, chunk.size - HeaderSize, 0, FILE_CURRENT); nuclear@0: ReadCounter += chunk.size - HeaderSize; nuclear@0: } nuclear@0: nuclear@0: void SkipBytes(HANDLE file, dword bytes) { nuclear@0: SetFilePointer(file, bytes, 0, FILE_CURRENT); nuclear@0: ReadCounter += bytes; nuclear@0: } nuclear@0: nuclear@0: Material *FindMaterial(string name) { nuclear@0: dword i=0; nuclear@0: while(i < MatCount) { nuclear@0: if(mat[i].name == name) return &mat[i]; nuclear@0: i++; nuclear@0: } nuclear@0: nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: ///////////////////// Read Object Function ////////////////////// nuclear@0: int ReadObject(HANDLE file, const ChunkHeader &ch, void **obj) { nuclear@0: if(!obj || !gc) return -1; nuclear@0: nuclear@0: ReadCounter = HeaderSize; // reset the global read counter nuclear@0: nuclear@0: string name = ReadString(file); nuclear@0: nuclear@0: ChunkHeader chunk; nuclear@0: chunk = ReadChunkHeader(file); nuclear@0: if(chunk.id == Chunk_Obj_TriMesh) { nuclear@0: // object is a trimesh... load it nuclear@0: Vertex *varray; nuclear@0: Triangle *tarray; nuclear@0: dword VertexCount=0, TriCount=0; nuclear@0: Material mat; nuclear@0: Base base; nuclear@0: Vector3 translation; nuclear@0: nuclear@0: bool curve = true; nuclear@0: nuclear@0: dword ObjChunkSize = ch.size; nuclear@0: nuclear@0: while(ReadCounter < ObjChunkSize) { // make sure we only read subchunks of this object chunk nuclear@0: //assert(!file.eof()); nuclear@0: assert(!eof); nuclear@0: chunk = ReadChunkHeader(file); nuclear@0: nuclear@0: switch(chunk.id) { nuclear@0: case Chunk_TriMesh_VertexList: nuclear@0: VertexCount = (dword)ReadWord(file); nuclear@0: varray = new Vertex[VertexCount]; nuclear@0: nuclear@0: for(dword i=0; iname = name; nuclear@0: for(dword i=0; iAddControlPoint(varray[i].pos); nuclear@0: } nuclear@0: nuclear@0: *obj = spline; nuclear@0: return OBJ_CURVE; nuclear@0: } else { nuclear@0: nuclear@0: base.i.Normalize(); nuclear@0: base.j.Normalize(); nuclear@0: base.k.Normalize(); nuclear@0: Matrix3x3 RotXForm = base.CreateRotationMatrix(); nuclear@0: RotXForm.OrthoNormalize(); nuclear@0: nuclear@0: for(dword i=0; iname = name; nuclear@0: object->GetTriMesh()->SetData(varray, tarray, VertexCount, TriCount); nuclear@0: object->material = mat; nuclear@0: object->SetRotation(RotXForm); nuclear@0: object->SetTranslation(translation.x, translation.y, translation.z); nuclear@0: *obj = object; nuclear@0: nuclear@0: return OBJ_MESH; nuclear@0: } nuclear@0: } else { nuclear@0: nuclear@0: if(chunk.id == Chunk_Obj_Light) { nuclear@0: nuclear@0: dword ObjChunkSize = ch.size; nuclear@0: nuclear@0: Vector3 pos = ReadVector(file); nuclear@0: Color color = ReadColor(file); nuclear@0: nuclear@0: Vector3 SpotTarget; nuclear@0: float InnerCone, OuterCone; nuclear@0: bool spot = false; nuclear@0: bool att = false; nuclear@0: bool CastShadows = false; nuclear@0: float AttEnd = 10000.0f; nuclear@0: float Intensity = 1.0f; nuclear@0: nuclear@0: while(ReadCounter < ObjChunkSize) { nuclear@0: nuclear@0: chunk = ReadChunkHeader(file); nuclear@0: nuclear@0: switch(chunk.id) { nuclear@0: case Chunk_Light_SpotLight: nuclear@0: spot = true; nuclear@0: SpotTarget = ReadVector(file); nuclear@0: InnerCone = ReadFloat(file) / 180.0f; nuclear@0: OuterCone = ReadFloat(file) / 180.0f; nuclear@0: break; nuclear@0: nuclear@0: case Chunk_Light_Attenuation: nuclear@0: att = true; nuclear@0: break; nuclear@0: nuclear@0: case Chunk_Light_AttenuationEnd: nuclear@0: AttEnd = ReadFloat(file); nuclear@0: break; nuclear@0: nuclear@0: case Chunk_Light_Intensity: nuclear@0: Intensity = ReadFloat(file); nuclear@0: break; nuclear@0: nuclear@0: case Chunk_Spot_CastShadows: nuclear@0: CastShadows = true; nuclear@0: break; nuclear@0: nuclear@0: default: nuclear@0: SkipChunk(file, chunk); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: Light *light; nuclear@0: if(spot) { nuclear@0: light = new TargetSpotLight(pos, SpotTarget, InnerCone, OuterCone); nuclear@0: } else { nuclear@0: light = new PointLight(pos); nuclear@0: } nuclear@0: light->SetColor(color); nuclear@0: light->SetShadowCasting(CastShadows); nuclear@0: light->SetIntensity(Intensity); nuclear@0: light->name = name; nuclear@0: nuclear@0: *obj = light; nuclear@0: return spot ? OBJ_SPLIGHT : OBJ_PTLIGHT; nuclear@0: } nuclear@0: nuclear@0: if(chunk.id == Chunk_Obj_Camera) { nuclear@0: Camera *cam = new Camera; nuclear@0: Vector3 pos = ReadVector(file); nuclear@0: Vector3 targ = ReadVector(file); nuclear@0: float roll = ReadFloat(file); nuclear@0: float FOV = ReadFloat(file); nuclear@0: nuclear@0: Vector3 up = VECTOR3_J; nuclear@0: Vector3 view = targ - pos; nuclear@0: up.Rotate(view.Normalized(), roll); nuclear@0: nuclear@0: cam->SetCamera(pos, targ, up); nuclear@0: cam->name = name; nuclear@0: cam->SetFOV(DEGTORAD(FOV) / 1.33333f); nuclear@0: nuclear@0: *obj = cam; nuclear@0: return OBJ_CAMERA; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: return -1; // should have already left by now, if not something is wrong nuclear@0: } nuclear@0: nuclear@0: nuclear@0: //////////////////////////////////////////////////////////////////////////////// nuclear@0: // functions to save/load normals from file nuclear@0: nuclear@0: void WriteByte(HANDLE file, byte val) { nuclear@0: dword junk; nuclear@0: WriteFile(file, &val, sizeof(byte), &junk, 0); nuclear@0: } nuclear@0: nuclear@0: void WriteDword(HANDLE file, dword val) { nuclear@0: dword junk; nuclear@0: WriteFile(file, &val, sizeof(dword), &junk, 0); nuclear@0: assert(junk == sizeof(dword)); nuclear@0: } nuclear@0: nuclear@0: void WriteFloat(HANDLE file, float val) { nuclear@0: dword junk; nuclear@0: WriteFile(file, &val, sizeof(float), &junk, 0); nuclear@0: assert(junk == sizeof(float)); nuclear@0: } nuclear@0: nuclear@0: void WriteString(HANDLE file, string str) { nuclear@0: dword junk; nuclear@0: for(dword i=0; i<(dword)str.size(); i++) { nuclear@0: WriteFile(file, &str[i], sizeof(char), &junk, 0); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: nuclear@0: void SaveNormalsToFile(const char *fname, Scene *scene) { nuclear@0: nuclear@0: HANDLE file = CreateFile(fname, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); nuclear@0: assert(file); nuclear@0: nuclear@0: WriteDword(file, (dword)scene->GetObjectsList()->size()); nuclear@0: nuclear@0: std::list::iterator objiter = scene->GetObjectsList()->begin(); nuclear@0: while(objiter != scene->GetObjectsList()->end()) { nuclear@0: WriteString(file, (*objiter)->name); nuclear@0: dword VertexCount = (*objiter)->GetTriMesh()->GetVertexCount(); nuclear@0: WriteDword(file, VertexCount); nuclear@0: nuclear@0: const Vertex *varray = (*objiter)->GetTriMesh()->GetVertexArray(); nuclear@0: for(dword i=0; iGetObjectsList()->size()) { // detect changes nuclear@0: CloseHandle(file); nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: while(SceneLoader::ReadCounter < FileSize) { nuclear@0: string name = ReadString(file); nuclear@0: dword VertexCount = ReadDword(file); nuclear@0: nuclear@0: Object *obj = scene->GetObject(name.c_str()); nuclear@0: if(!obj) { nuclear@0: CloseHandle(file); nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: if(VertexCount != obj->GetTriMesh()->GetVertexCount()) { // again detect changes nuclear@0: CloseHandle(file); nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: Vertex *varray = obj->GetTriMesh()->GetModVertexArray(); nuclear@0: for(dword i=0; i