} //places Model at start of list public bool addModel(OpenGLModel mod, int idx) { if (mod == null) { return(false); } ml.Insert(idx, mod); return(true); } //place Models with transparent textures last
public bool Save(OpenGLModel model, IOStream os) { try { saveJF3D(model, os); return(true); } catch (Exception e) { Console.WriteLine("Error:" + e.ToString()); return(false); } }
/** Clones a pre-loaded model. * Use addModel() to add into the render scene. */ public OpenGLModel CloneModel(String fn) { OpenGLModel mod = mtl.Get(fn); if (mod == null) { return(null); } mod.refcnt++; return((OpenGLModel)mod.Clone()); }
public bool Save(OpenGLModel model, String filename) { try { File fos = new File(filename); saveJF3D(model, fos); fos.Close(); return(true); } catch (Exception e) { Console.WriteLine("Error:" + e.ToString()); return(false); } }
/** * Clones deep enough so that the cloned object will include seperate GLObjects, but share vertex, vertex point, * and animation data (except for the frame position). */ public OpenGLModel Clone() { OpenGLModel c = new OpenGLModel((Matrix4x4)m.Clone()); int objs = ol.Size(); for (int a = 0; a < objs; a++) { c.ol.Add((OpenGLObject)ol.Get(a).Clone()); } c.textures = textures; return(c); }
private void saveJF3D(OpenGLModel model, IOStream os) { baos = new ByteArrayStream(); tmp = new byte[8]; int size; writeuint32(MAGIC); writeuint32(VERSION); writeuint32(ID_MODEL); size = 0; int tcnt = model.textures.Size(); for (int a = 0; a < tcnt; a++) { size += model.textures.Get(a).Length + 1; } writeuint32(size); writeuint32(tcnt); for (int a = 0; a < tcnt; a++) { writeString(model.textures.Get(a)); } for (int o = 0; o < model.ol.Size(); o++) { OpenGLObject obj = model.ol.Get(o); writeuint32(ID_OBJECT); int vcnt = obj.GetVertexCount() * 3; int pcnt = obj.GetPolyCount(); size = obj.GetName().Length + 1 + 4 + (4 * 3) + (4 + (vcnt * 4)) + (4 + (pcnt * 4)); writeuint32(size); writeString(obj.GetName()); writeuint32(obj.GetType()); writefloat(obj.GetOrigin().x); writefloat(obj.GetOrigin().y); writefloat(obj.GetOrigin().z); writeuint32(vcnt / 3); float[] xyz = obj.GetVertexBuffer(); for (int a = 0; a < vcnt; a++) { writefloat(xyz[a]); } switch (obj.GetType()) { case GL_TRIANGLES: writeuint32(pcnt / 3); break; case GL_QUADS: writeuint32(pcnt / 4); break; } int[] pts = obj.GetPolyBuffer(); for (int a = 0; a < pcnt; a++) { writeuint32(pts[a]); } int maps = obj.GetUVMaps().Size(); if (maps == 0) { Console.WriteLine("GL_JF3D:Warning:No UVMaps found for object:" + obj.GetName()); } for (int m = 0; m < maps; m++) { OpenGLUVMap map = obj.GetUVMaps().Get(m); writeuint32(ID_UVMAP); int uvcnt = map.GetUVCount() * 2; size = map.GetName().Length + 1 + 4 + (4 + (uvcnt * 4)); writeuint32(size); writeString(map.GetName()); writeuint32(map.GetTextureIndex()); writeuint32(uvcnt / 2); float[] uv = map.GetBuffer(); for (int a = 0; a < uvcnt; a++) { writefloat(uv[a]); } } } os.Write(baos.GetData().ToArray()); }
private OpenGLModel loadJF3D(IOStream fis) { datapos = 0; fis.Open(OpenMode.ReadOnly); data = fis.ReadAll().ToArray(); int magic = readuint32(); if (magic != MAGIC) { throw new Exception("GL_JF3D:Not JF3D file"); } int version = readuint32(); if (version < VERSION) { throw new Exception("GL_JF3D:Bad version"); } int fcnt, pcnt, vcnt, uvcnt; OpenGLUVMap map; while (!eof()) { int head_id = readuint32(); int head_len = readuint32(); skip = head_len; int head_ver = head_id & 0xffff; head_id &= 0x7fff0000; switch (head_id) { case ID_MODEL: if (model != null) { throw new Exception("GL_JF3D:Multiple Model chunks found"); } model = new OpenGLModel(); fcnt = readuint32(); for (int a = 0; a < fcnt; a++) { String txt = readString(); model.textures.Add(txt); // Console.WriteLine("Texture=" + txt); } if (head_ver > 0) { //future reserved } break; case ID_OBJECT: obj = new OpenGLObject(); model.AddObject(obj); obj.SetName(readString()); obj.SetType(readuint32()); obj.GetOrigin().x = readfloat(); obj.GetOrigin().y = readfloat(); obj.GetOrigin().z = readfloat(); vcnt = readuint32(); //vertex count for (int v = 0; v < vcnt; v++) { float fx = readfloat(); float fy = readfloat(); float fz = readfloat(); obj.AddVertex(new float[] { fx, fy, fz }); } pcnt = readuint32(); //poly count switch (obj.GetType()) { case GL_TRIANGLES: pcnt *= 3; break; case GL_QUADS: pcnt *= 4; break; default: Console.WriteLine("GL_JF3D:Error Unknown GL Type:" + obj.GetType()); return(null); } for (int p = 0; p < pcnt; p++) { int pt = readuint32(); if (pt >= vcnt) { Console.WriteLine("Error:Poly includes invalid vertex !!!"); } obj.AddPoly(new int[] { pt }); } break; case ID_UVMAP: map = obj.CreateUVMap(); map.SetName(readString()); map.SetTextureIndex(readuint32()); uvcnt = readuint32(); if (uvcnt != obj.GetVertexCount()) { Console.WriteLine("Warning:UVMAP size != vertex count"); } for (int i = 0; i < uvcnt; i++) { float u = readfloat(); float v = readfloat(); map.Add(new float[] { u, v }); } break; default: break; } if (skip > 0) { datapos += skip; } } return(model); }
public void UnloadModel(OpenGLModel mod) { mod.refcnt--; }
public void removeModel(OpenGLModel mod) { ml.Remove(mod); }
} //place Models with transparent textures last public int indexOfModel(OpenGLModel mod) { return(ml.IndexOf(mod)); }
public bool addModel(OpenGLModel mod) { return(addModel(mod, 0)); } //places Model at start of list
private OpenGLModel loadBlend(IOStream fis) { setData(fis.ReadAll().ToArray()); if (data.Length < 12) { throw new Exception("GL_BLEND:File too small"); } model = new OpenGLModel(); //load signature (12 bytes) "BLENDER_V100" if (!new String(data, 0, 7).Equals("BLENDER")) { throw new Exception("Not a blender file"); } switch ((char)data[7]) { case '-': x64 = true; break; case '_': x64 = false; break; default: throw new Exception("GL_BLEND:Unknown bit size"); } switch ((char)data[8]) { case 'v': le = true; break; case 'V': le = false; break; default: throw new Exception("GL_BLEND:Unknown Endianness"); } String version = new String(data, 9, 3); // Console.WriteLine("Blender file version:" + version); int ver = Int32.ValueOf(version); if (ver < 263) { throw new Exception("Error:Blender file too old, can not read."); } datapos = 12; //skip main header //first phase - read raw chunks while (!eof()) { BlendChunk chunk = new BlendChunk(this); chunk.filepos = datapos; chunk.read(); BlendChunk ochunk = chunks.Get(chunk.ptr); if (ochunk != null) { if (!haveDups) { Console.WriteLine("Warning:This file contains duplicate BHeads."); haveDups = true; } ochunk.dup = true; while (ochunk.nextdup != null) { ochunk = ochunk.nextdup; } ochunk.nextdup = chunk; } else { chunks.Set(chunk.ptr, chunk); } } int chunkCnt = chunks.Size(); BlendChunk[] chunkArray = chunks.Values(); BlendChunk raw; //2nd phase - parse DNA chunk for (int i = 0; i < chunkCnt; i++) { if (chunkArray[i].id == ID_DNA1) { raw = chunkArray[i]; setData(raw.raw); //SDNA String SDNA = readString(4); if (!SDNA.Equals("SDNA")) { throw new Exception("Bad DNA Struct:SDNA"); } //NAME String NAME = readString(4); if (!NAME.Equals("NAME")) { throw new Exception("Bad DNA Struct:NAME"); } int nr_names = readuint32(); for (int a = 0; a < nr_names; a++) { String str = readString(); // Console.WriteLine("name=" + str); names.Add(str); } //align pointer datapos += 3; datapos &= 0x7ffffffc; //TYPE String TYPE = readString(4); if (!TYPE.Equals("TYPE")) { throw new Exception("Bad DNA Struct:TYPE"); } int nr_types = readuint32(); for (int a = 0; a < nr_types; a++) { String str = readString(); // Console.WriteLine("type=" + str); types.Add(str); } //align pointer datapos += 3; datapos &= 0x7ffffffc; //TLEN String TLEN = readString(4); if (!TLEN.Equals("TLEN")) { throw new Exception("Bad DNA Struct:TLEN"); } for (int a = 0; a < nr_types; a++) { typelen.Add(readuint16()); } //align pointer datapos += 3; datapos &= 0x7ffffffc; //STRC String STRC = readString(4); if (!STRC.Equals("STRC")) { throw new Exception("Bad DNA Struct:STRC"); } int nr_structs = readuint32(); for (int a = 0; a < nr_structs; a++) { BlendStruct s = new BlendStruct(); s.typeidx = readuint16(); s.nr = readuint16(); s.name = types.Get(s.typeidx); // Console.WriteLine("Struct:" + s.name + "==" + a); for (int b = 0; b < s.nr; b++) { BlendMember m = new BlendMember(); m.typelenidx = readuint16(); m.nameidx = readuint16(); m.name = names.Get(m.nameidx); m.typelen = typelen.Get(m.typelenidx); m.size = calcMemberSize(m); // Console.WriteLine(" Member:" + m.name + "=" + m.Length); s.members.Add(m); } structs.Add(s); } break; } } //3nd phase - now look for objects and piece together chunks for (int i = 0; i < chunkCnt; i++) { if (chunkArray[i].id == ID_SC) { setData(chunkArray[i].raw); BlendScene OpenGLScene = new BlendScene(this); OpenGLScene.read(); long ptr = OpenGLScene.last; while (ptr != 0) { BlendChunk chunk = findChunkByPtr(ptr); if (chunk == null) { break; } setData(chunk.raw); BlendBase _base = new BlendBase(this); _base.read(); chunk = findChunkByPtr(_base.bobject); if (chunk.id == ID_OB) { readObject(chunk); } ptr = _base.prev; } } } return(model); }
private OpenGLModel load3ds(IOStream fis) { OpenGLObject obj = null; int head_id; int head_len; int _siz; float[] _float; int[] _pts; bool done_vertex = false; bool done_pts = false; int vertexidx = -1; int vertexcnt = -1; String name; List <OpenGL3DS_Material> matlist; //materials (objects refer to material name) List <String> objlist; //object names (keyframe data refers to object name) String objname = ""; int objidx = -1; OpenGL3DS_Material mat; String matname = "", fn; int a, b, keys, u32; bool ok; int u16; OpenGLTranslate trans; OpenGLRotate rot; OpenGLScale scale; OpenGLModel mod; OpenGLUVMap map; int mapidx = -1; int skip = 0; int parent; int frameno; int s; datapos = 0; fis.Open(OpenMode.ReadOnly); data = fis.ReadAll().ToArray(); matlist = new List <OpenGL3DS_Material>(); objlist = new List <String>(); mod = new OpenGLModel(); while (!eof()) { head_id = readuint16(); head_len = readuint32(); if (head_len == -1) { break; //this does happen in some files } if (head_len < 6) { throw new Exception("head_len < 6 (" + head_len + ")"); //bad file } head_len -= 6; switch (head_id) { case 0x4d4d: //main chunk break; case 0x3d3d: //mesh chunk break; case 0xafff: //material chunk matname = ""; break; case 0xa000: //material chunk name matname = readname(head_len); break; case 0xa200: //texture details break; case 0xa300: //texture filename mat = new OpenGL3DS_Material(); fn = readname(head_len); mat.name = matname; mat.filename = fn; matlist.Add(mat); break; case 0x4000: //object chunk objname = readname(-1); //don't skip the whole chunk if (debug) { Console.WriteLine("obj=" + objname); } done_vertex = false; done_pts = false; break; case 0x4100: //triangular object chunk break; case 0x4110: //vertex list of a polygon skip = head_len; if (done_vertex) { Console.WriteLine("Warning : 2 vertex lists found for 1 object?"); break; } obj = new OpenGLObject(); obj.SetType(GL_TRIANGLES); //3ds only supports triangles obj.SetName(objname); mapidx = -1; mod.ol.Add(obj); objlist.Add(objname); _siz = readuint16(); skip -= 2; vertexidx = obj.GetVertexCount() * 3; vertexcnt = _siz; if (_siz == 0) { break; } _float = new float[_siz * 3]; for (a = 0; a < _siz; a++) { for (b = 0; b < 3; b++) { _float[a * 3 + b] = readfloat(); skip -= 4; } if (debug) { // Console.WriteLine(String.format("v=%3.3f,%3.3f,%3.3f", _float[a*3+0] , _float[a*3+1] , _float[a*3+2])); } } obj.AddVertex(_float); _float = null; done_vertex = true; break; case 0x4120: //Points list _siz = readuint16(); skip = _siz * 2 * 4; if (!done_vertex) { Console.WriteLine("Warning : pts list before vertex list?"); break; } if (done_pts) { Console.WriteLine("Warning : 2 pts lists found for 1 object?"); break; } if (_siz == 0) { break; } _pts = new int[3]; //p1,p2,p3,flgs per triangle for (a = 0; a < _siz; a++) { for (b = 0; b < 3; b++) { _pts[b] = (short)readuint16(); skip -= 2; } readuint16(); //skip flgs skip -= 2; obj.AddPoly(_pts); if (debug) { Console.WriteLine("p=" + _pts[0] + "," + _pts[1] + "," + _pts[2]); } } _pts = null; done_pts = true; break; case 0x4130: //object material name name = readname(head_len); mapidx++; map = obj.CreateUVMap(); map.SetName("uvmap" + mapidx); if (obj != null) { //find name in matlist ok = false; for (a = 0; a < matlist.Size(); a++) { if (matlist.Get(a).name.Equals(name)) { int idx = mod.AddTexture(matlist.Get(a).filename); map.SetTextureIndex(idx); ok = true; break; } } // if (!ok) throw new Exception("0x4130 : object material name not found in list : " + name); } if (debug) { Console.WriteLine("mat=" + map.GetTextureIndex()); } break; case 0x4140: //texture vertex list (UV) _siz = readuint16(); skip = _siz * 2 * 4; if (!done_vertex) { Console.WriteLine("Warning:Texture coords (UV) list before vertex list"); break; } if (_siz != vertexcnt) { Console.WriteLine("Warning:texture list siz != vertex list siz"); break; } if (_siz == 0) { break; } _float = new float[2]; for (a = 0; a < _siz; a++) { _float[0] = readfloat(); //U fis okay skip -= 4; _float[1] = 1.0f - readfloat(); //V must be inverted skip -= 4; obj.AddUV(_float, mapidx); if (debug) { // Console.WriteLine(String.format("t=%3.3f,%3.3f", _float[0] , _float[1])); } } _float = null; break; case 0x4160: //obj matrix //read in 3x3 matrix and show for now s = 0; //padding to convert to 4x4 matrix for (a = 0; a < 3 * 3; a++) { u32 = readuint32(); if ((a > 0) && (a % 3 == 0)) { s++; } //not sure what this matrix fis for??? But I don't seem to need it // obj.m.m[a+s] = readfloat(); // if (debug) Console.WriteLine("m=" + obj.m.m[a+s]); } obj.GetOrigin().x = readfloat(); obj.GetOrigin().y = readfloat(); obj.GetOrigin().z = readfloat(); if (debug) { Console.WriteLine("pos=" + obj.GetOrigin().x + "," + obj.GetOrigin().y + "," + obj.GetOrigin().z); } break; case 0xb000: //keyframe header break; case 0xb002: //object node chunk objidx = -1; break; case 0xb010: //keyframe object name name = readname(-1); readuint16(); //f1 readuint16(); //f2 parent = readuint16(); //parent //find name in objlist objidx = 0; ok = false; for (a = 0; a < objlist.Size(); a++) { if (objlist.Get(a).Equals(name)) { ok = true; break; } objidx++; } if (!ok) { objidx = -1; } else { obj = mod.ol.Get(objidx); if (parent != 65535) { obj.SetParent(parent); } obj = null; } //Console.WriteLine("0xb010 : name=" + name + ":objidx=" + objidx + ":parent=" + parent); break; case 0xb020: //keyframe pos skip = head_len; if (objidx == -1) { break; } obj = mod.ol.Get(objidx); u16 = readuint16(); //flgs skip -= 2; u32 = readuint32(); //r1 skip -= 4; u32 = readuint32(); //r2 skip -= 4; keys = readuint32(); //keys skip -= 4; _float = new float[3]; for (a = 0; a < keys; a++) { frameno = readuint32(); //frame # skip -= 4; u16 = readuint16(); //flgs skip -= 2; u32 = 0; if ((u16 & _3DS_FLG_TENSION) != 0) { u32++; } if ((u16 & _3DS_FLG_CONTINUITY) != 0) { u32++; } if ((u16 & _3DS_FLG_BIAS) != 0) { u32++; } if ((u16 & _3DS_FLG_EASE_TO) != 0) { u32++; } if ((u16 & _3DS_FLG_EASE_FROM) != 0) { u32++; } if (u32 > 0) { datapos += u32 * 4; //all ignored skip -= u32 * 4; } trans = new OpenGLTranslate(); for (b = 0; b < 3; b++) { _float[b] = readfloat(); skip -= 4; } trans.x = _float[0]; trans.y = _float[1]; trans.z = _float[2]; //Console.WriteLine("pos["+frameno+"]:"+pos.x+","+pos.y+","+pos.z+":flgs="+u16); obj.GetTranslateMap().Set(frameno, trans); if (obj.GetMaxFrameCount() < frameno) { obj.SetMaxFrameCount(frameno); } } _float = null; obj = null; break; case 0xb021: //keyframe rotate skip = head_len; if (objidx == -1) { break; } obj = mod.ol.Get(objidx); u16 = readuint16(); //flgs skip -= 2; u32 = readuint32(); //r1 skip -= 4; u32 = readuint32(); //r2 skip -= 4; keys = readuint32(); //keys skip -= 4; _float = new float[4]; for (a = 0; a < keys; a++) { frameno = readuint32(); //frame # skip -= 4; u16 = readuint16(); //flgs skip -= 2; u32 = 0; if ((u16 & _3DS_FLG_TENSION) != 0) { u32++; } if ((u16 & _3DS_FLG_CONTINUITY) != 0) { u32++; } if ((u16 & _3DS_FLG_BIAS) != 0) { u32++; } if ((u16 & _3DS_FLG_EASE_TO) != 0) { u32++; } if ((u16 & _3DS_FLG_EASE_FROM) != 0) { u32++; } if (u32 > 0) { datapos += u32 * 4; //all ignored skip -= u32 * 4; } rot = new OpenGLRotate(); for (b = 0; b < 4; b++) { _float[b] = readfloat(); skip -= 4; } rot.angle = _float[0] * 57.2957795f; //convert to degrees rot.x = _float[1]; rot.y = _float[2]; rot.z = _float[3]; //Console.WriteLine("rot["+frameno+"]:"+rot.angle+","+rot.x+","+rot.y+","+rot.z+":flgs="+u16); obj.GetRotateMap().Set(frameno, rot); if (obj.GetMaxFrameCount() < frameno) { obj.SetMaxFrameCount(frameno); } } _float = null; obj = null; break; case 0xb022: //keyframe scale skip = head_len; if (objidx == -1) { break; } obj = mod.ol.Get(objidx); u16 = readuint16(); //flgs skip -= 2; u32 = readuint32(); //r1 skip -= 4; u32 = readuint32(); //r2 skip -= 4; keys = readuint32(); //keys skip -= 4; _float = new float[3]; for (a = 0; a < keys; a++) { frameno = readuint32(); //frame # skip -= 4; u16 = readuint16(); //flgs skip -= 2; u32 = 0; if ((u16 & _3DS_FLG_TENSION) != 0) { u32++; } if ((u16 & _3DS_FLG_CONTINUITY) != 0) { u32++; } if ((u16 & _3DS_FLG_BIAS) != 0) { u32++; } if ((u16 & _3DS_FLG_EASE_TO) != 0) { u32++; } if ((u16 & _3DS_FLG_EASE_FROM) != 0) { u32++; } if (u32 > 0) { datapos += u32 * 4; //all ignored skip -= u32 * 4; } scale = new OpenGLScale(); for (b = 0; b < 3; b++) { _float[b] = readfloat(); skip -= 4; } scale.x = _float[0]; scale.y = _float[1]; scale.z = _float[2]; //Console.WriteLine("scale["+frameno+"]:"+scale.x+","+scale.y+","+scale.z+":flgs="+u16); obj.GetScaleMap().Set(frameno, scale); if (obj.GetMaxFrameCount() < frameno) { obj.SetMaxFrameCount(frameno); } } _float = null; obj = null; break; default: skip = head_len; break; } if (skip > 0) { datapos += skip; skip = 0; } } //setup any lights _siz = mod.ol.Size(); for (a = 0; a < _siz; a++) { obj = mod.ol.Get(a); } //delete temp lists matlist.Clear(); objlist.Clear(); return(mod); }