/// <summary> /// box testaus. onko laatikko edes osittain ruudulla. jos on, palauta true. /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="z"></param> /// <param name="bb"></param> /// <returns></returns> public static bool BoxInFrustum(float x, float y, float z, BoundingVolume bb) { int q; for (q = 0; q < 6; q++) { if ((frustum[q, 0] * (x + bb.Min.X)) + (frustum[q, 1] * (y + bb.Min.Y)) + (frustum[q, 2] * (z + bb.Min.Z)) + frustum[q, 3] > 0) { continue; } if ((frustum[q, 0] * (x + bb.Max.X)) + (frustum[q, 1] * (y + bb.Min.Y)) + (frustum[q, 2] * (z + bb.Min.Z)) + frustum[q, 3] > 0) { continue; } if ((frustum[q, 0] * (x + bb.Max.X)) + (frustum[q, 1] * (y + bb.Min.Y)) + (frustum[q, 2] * (z + bb.Max.Z)) + frustum[q, 3] > 0) { continue; } if ((frustum[q, 0] * (x + bb.Min.X)) + (frustum[q, 1] * (y + bb.Min.Y)) + (frustum[q, 2] * (z + bb.Max.Z)) + frustum[q, 3] > 0) { continue; } if ((frustum[q, 0] * (x + bb.Min.X)) + (frustum[q, 1] * (y + bb.Max.Y)) + (frustum[q, 2] * (z + bb.Min.Z)) + frustum[q, 3] > 0) { continue; } if ((frustum[q, 0] * (x + bb.Max.X)) + (frustum[q, 1] * (y + bb.Max.Y)) + (frustum[q, 2] * (z + bb.Min.Z)) + frustum[q, 3] > 0) { continue; } if ((frustum[q, 0] * (x + bb.Max.X)) + (frustum[q, 1] * (y + bb.Max.Y)) + (frustum[q, 2] * (z + bb.Max.Z)) + frustum[q, 3] > 0) { continue; } if ((frustum[q, 0] * (x + bb.Min.X)) + (frustum[q, 1] * (y + bb.Max.Y)) + (frustum[q, 2] * (z + bb.Max.Z)) + frustum[q, 3] > 0) { continue; } // jos päästään tänne, objekti ei ole frustumissa return false; } // vertex ruudulla, objekti on näkyvä return true; }
public static bool ObjectInFrustum(Vector3 position, BoundingVolume bound) { return(ObjectInFrustum(position.X, position.Y, position.Z, bound)); }
/// <summary> /// lataa mesh tiedosto /// </summary> /// <param name="fileName"></param> /// <param name="xs"></param> /// <param name="ys"></param> /// <param name="zs"></param> public void Load(string fileName, float xs, float ys, float zs) { pathData.Clear(); ObjModel mesh = null; List <Vector3> _vertex = new List <Vector3>(); List <Vector3> _normal = new List <Vector3>(); List <Vector2> _uv = new List <Vector2>(); string dir = Settings.DataDir; if (fileName.Contains("\\")) { int l = fileName.LastIndexOf("\\"); dir = dir + fileName.Substring(0, l + 1); } else if (fileName.Contains("/")) { int l = fileName.LastIndexOf("/"); dir = dir + fileName.Substring(0, l + 1); } fileName = Settings.DataDir + fileName; bool path = false; // jos reitti using (System.IO.StreamReader file = new System.IO.StreamReader(fileName)) { // tiedosto muistiin string data = file.ReadToEnd(); data = data.Replace('\r', ' '); // pilko se string[] lines = data.Split('\n'); int numOfFaces = 0; for (int q = 0; q < lines.Length; q++) { string[] ln = lines[q].Split(' '); // pilko datat if (ln[0] == "f") { numOfFaces++; } } // lue kaikki datat objektiin ja indexit mesheihin for (int q = 0; q < lines.Length; q++) { string line = lines[q]; if (line.StartsWith("#")) { continue; } string[] ln = line.Split(' '); // pilko datat if (ln[0] == "v") // vertex x y z { float x = (Util.GetFloat(ln[1]) - mesh.Position.X) * xs; float y = (Util.GetFloat(ln[2]) - mesh.Position.Y) * ys; float z = (Util.GetFloat(ln[3]) - mesh.Position.Z) * zs; if (path) { pathData.Add(new Vector3(x, y, z)); } else { _vertex.Add(new Vector3(x, y, z)); } continue; } if (ln[0] == "vn") // normal x y z { _normal.Add(new Vector3(Util.GetFloat(ln[1]), Util.GetFloat(ln[2]), Util.GetFloat(ln[3]))); continue; } if (ln[0] == "vt") // texcoord U V { _uv.Add(new Vector2(Util.GetFloat(ln[1]), Util.GetFloat(ln[2]))); continue; } // uusi objekti if (ln[0] == "o" || ln[0] == "g") { if (mesh != null) { meshes.Add(mesh); // talteen } mesh = new ObjModel(ln[1]); mesh.material = material; // Nimessä voi olla ohjeita mitä muuta halutaan, esim: // * Path_reitti1 jolloin ei ladata objektia mutta reitti jota pitkin kamera/objektit voi kulkea. // * BBox_nimi/BSphere_nimi jolloin tämä onkin nimi-objektin bounding box/sphere. if (mesh.Name.Contains("Path_")) { path = true; } else if (mesh.Name.Contains("BBox_") || mesh.Name.Contains("BSphere_")) { // TODO: bbox_ bsphere_ } continue; } // materiaali if (ln[0] == "usemtl") { // jos kesken meshin materiaali vaihtuu, luodaan uusi obu johon loput facet if (lines[q - 1].StartsWith("f")) { meshes.Add(mesh); Vector3 tmpPos = mesh.Position; mesh = new ObjModel(mesh.Name); mesh.material = material; mesh.Position = tmpPos; // samaa objektia, niin sama Position } mesh.MaterialName = ln[1]; continue; } if (ln[0] == "f") { // ota talteen f rivi: // f vertex/uv/normal vertex/uv/normal vertex/uv/normal // eli esim: f 4/4/2 5/5/3 7/2/4 // tarkistetaan jos ilman texcoordei eli f 4/4 5/4 6/4 tai f 2//3 jne tai ilman / merkkejä. int dv = 0; for (int t = 0; t < line.Length; t++) { if (line[t] == '/') { dv++; } } if (line.Contains("//")) { dv = 0; // ei ole texindexei } line = line.Replace("//", " "); line = line.Replace("/", " "); string[] _ln = line.Split(' '); if (dv == 0 || dv == 3) // luultavasti nyt ei ole texturecoordinaatteja { mesh._vertexInd.Add(Int32.Parse(_ln[1]) - 1); mesh._vertexInd.Add(Int32.Parse(_ln[3]) - 1); mesh._vertexInd.Add(Int32.Parse(_ln[5]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[2]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[4]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[6]) - 1); } else // kaikki mukana { mesh._vertexInd.Add(Int32.Parse(_ln[1]) - 1); mesh._vertexInd.Add(Int32.Parse(_ln[4]) - 1); mesh._vertexInd.Add(Int32.Parse(_ln[7]) - 1); mesh._uvInd.Add(Int32.Parse(_ln[2]) - 1); mesh._uvInd.Add(Int32.Parse(_ln[5]) - 1); mesh._uvInd.Add(Int32.Parse(_ln[8]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[3]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[6]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[9]) - 1); } continue; } // materiaalitiedosto if (ln[0] == "mtllib") { try { // ladataan objektille materiaalitiedot (mesheille otetaan talteen materialname joka viittaa sitten näihin materiaaleihin) material = new Material(); material.Load(dir + ln[1], Texture.LoadTextures); } catch (Exception e) { Log.WriteDebugLine(e.ToString()); } } } if (mesh != null) { meshes.Add(mesh); } // pathille ei luoda objektia, se on vain kasa vertexejä if (path == false) { int cc = 0; vertices = new Vertex[numOfFaces * 3]; for (int m = 0; m < meshes.Count; m++) { meshes[m].vertices = new Vertex[meshes[m]._vertexInd.Count]; for (int q = 0; q < meshes[m]._vertexInd.Count; q++) { // mesh datat meshes[m].vertices[q].vertex = _vertex[meshes[m]._vertexInd[q]]; meshes[m].vertices[q].normal = _normal[meshes[m]._normalInd[q]]; if (meshes[m]._uvInd.Count != 0) { meshes[m].vertices[q].uv_or_color = new Vector4(_uv[meshes[m]._uvInd[q]].X, _uv[meshes[m]._uvInd[q]].Y, _uv[meshes[m]._uvInd[q]].X, _uv[meshes[m]._uvInd[q]].Y); } // pistetään myös objektille kaikki vertexit yhteen klimppiin. //TODO Miks? vie vaa muistia nii paljo, mesheissä kumminki nuo datat säilytetään. // jos tää on VAIN collisionia varten, siihe ny o helppo tehdä se et se menee objektin puun läpi // ni sit ei tartte tätä vertices[cc].vertex = _vertex[meshes[m]._vertexInd[q]]; vertices[cc].normal = _normal[meshes[m]._normalInd[q]]; if (meshes[m]._uvInd.Count != 0) { vertices[cc].uv_or_color = new Vector4(_uv[meshes[m]._uvInd[q]].X, _uv[meshes[m]._uvInd[q]].Y, _uv[meshes[m]._uvInd[q]].X, _uv[meshes[m]._uvInd[q]].Y); } cc++; } // index taulukko meshes[m].indices = new int[meshes[m]._vertexInd.Count]; for (int q = 0; q < meshes[m]._vertexInd.Count; q++) { meshes[m].indices[q] = q; } meshes[m].vbo = new VBO(); meshes[m].vbo.DataToVBO(meshes[m].vertices, meshes[m].indices); // meshin bounding volume meshes[m].Boundings = new BoundingVolume(); meshes[m].Boundings.CreateBoundingVolume(meshes[m]); // lataa glsl koodit string shader = material.GetMaterial(meshes[m].MaterialName).ShaderName; if (shader != "") { mesh.Shader = new GLSL(); mesh.Shader.Load(shader + ".vert", shader + ".frag"); } if (material.GetMaterial(meshes[m].MaterialName).Dissolve < 1.0f) { IsTranslucent = true; } } // koko objektin bounding volume IsRendObj = false; // childeissä rendattavat objektit, tässä ei ole rendattavaa, vain paikka Boundings = new BoundingVolume(); Boundings.CreateBoundingVolume(this); // lisätään objektille meshit childeiks for (int q = 0; q < meshes.Count; q++) { Add(meshes[q]); } Log.WriteDebugLine("Object: " + Name + " meshes: " + meshes.Count); } _vertex.Clear(); _normal.Clear(); _uv.Clear(); for (int q = 0; q < meshes.Count; q++) { meshes[q]._vertexInd.Clear(); meshes[q]._normalInd.Clear(); meshes[q]._uvInd.Clear(); } } }
public static bool ObjectInFrustum(float x, float y, float z, BoundingVolume bound) { if (bound == null) return true; switch (bound.Mode) { case BoundingVolume.TestMode.Box: // box if (BoxInFrustum(x, y, z, bound) == false) return false; break; case BoundingVolume.TestMode.Sphere: // sphere if (SphereInFrustum(x, y, z, bound.R) == 0) return false; break; } return true; }
public static bool ObjectInFrustum(Vector3 position, BoundingVolume bound) { return ObjectInFrustum(position.X, position.Y, position.Z, bound); }
/// <summary> /// lataa md5-animaatio. /// </summary> /// <param name="fileName"></param> /// <param name="anim"></param> public override void LoadAnim(string animName, string fileName) { if (fileName == null || fileName == "") return; Animation anim = new Animation(); anim.animName = animName; Buffer t = new Buffer(); MD5JointInfo[] jointInfos = null; MD5BaseFrameJoint[] baseFrame = null; float[] animFrameData = null; int numAnimatedComponents = 0; int frame_index; int i; using (System.IO.StreamReader file = new System.IO.StreamReader(Settings.DataDir + fileName)) { string line; while ((line = file.ReadLine()) != null) { if (line == "") continue; // Read number of joints if (ParseLine(ref t, line, "numFrames %d")) { /* Allocate memory for skeleton frames and bounding boxes */ anim.numFrames = t.ibuffer[0]; if (anim.numFrames > 0) { anim.bboxes = new MD5BoundingBox[anim.numFrames]; } } if (ParseLine(ref t, line, "numJoints %d")) { /* Allocate memory for joints of each frame */ anim.numJoints = t.ibuffer[0]; if (anim.numJoints > 0) { /* Allocate temporary memory for building skeleton frames */ jointInfos = new MD5JointInfo[anim.numJoints]; baseFrame = new MD5BaseFrameJoint[anim.numJoints]; } anim.skelFrames = new MD5Joint[anim.numFrames, anim.numJoints]; } if (ParseLine(ref t, line, "frameRate %d")) { anim.frameRate = t.ibuffer[0]; } if (ParseLine(ref t, line, "numAnimatedComponents %d")) { numAnimatedComponents = t.ibuffer[0]; if (numAnimatedComponents > 0) { /* Allocate memory for animation frame data */ animFrameData = new float[numAnimatedComponents]; } } if (line.Equals("hierarchy {")) { for (i = 0; i < anim.numJoints; ++i) { /* Read whole line */ line = file.ReadLine(); Cleanstring(ref line); /* Read joint info */ ParseLine(ref t, line, "%s %d %d %d"); jointInfos[i].name = t.sbuffer; jointInfos[i].parent = t.ibuffer[0]; jointInfos[i].flags = t.ibuffer[1]; jointInfos[i].startIndex = t.ibuffer[2]; } } if (line.Equals("bounds {")) { for (i = 0; i < anim.numFrames; ++i) { /* Read whole line */ line = file.ReadLine(); Cleanstring(ref line); /* Read bounding box */ ParseLine(ref t, line, "( %f %f %f ) ( %f %f %f )"); anim.bboxes[i].min.X = t.fbuffer[0]; anim.bboxes[i].min.Y = t.fbuffer[1]; anim.bboxes[i].min.Z = t.fbuffer[2]; anim.bboxes[i].max.X = t.fbuffer[3]; anim.bboxes[i].max.Y = t.fbuffer[4]; anim.bboxes[i].max.Z = t.fbuffer[5]; } } if (line.Equals("baseframe {")) { for (i = 0; i < anim.numJoints; ++i) { /* Read whole line */ line = file.ReadLine(); Cleanstring(ref line); /* Read base frame joint */ ParseLine(ref t, line, "( %f %f %f ) ( %f %f %f )"); if (t.fbuffer.Length == 6) { baseFrame[i].pos.X = t.fbuffer[0]; baseFrame[i].pos.Y = t.fbuffer[1]; baseFrame[i].pos.Z = t.fbuffer[2]; baseFrame[i].orient.X = t.fbuffer[3]; baseFrame[i].orient.Y = t.fbuffer[4]; baseFrame[i].orient.Z = t.fbuffer[5]; /* Compute the w component */ MathExt.ComputeW(ref baseFrame[i].orient); } } } if (ParseLine(ref t, line, "frame %d")) { frame_index = t.ibuffer[0]; /* Read frame data */ for (i = 0; i < numAnimatedComponents; ) { line = file.ReadLine(); if (line[0] == '}') break; Cleanstring(ref line); string[] splt = line.Split(' '); for (int ww = 0; ww < splt.Length; ww++) { animFrameData[i++] = float.Parse(splt[ww]); } } /* Build frame skeleton from the collected data */ BuildFrameSkeleton(ref jointInfos, ref baseFrame, ref animFrameData, frame_index, anim.numJoints, ref anim); } } anim.curFrame = 0; anim.nextFrame = 1; anim.lastTime = 0; anim.maxTime = 1.0f / anim.frameRate; /* Allocate memory for animated skeleton */ skeleton = new MD5Joint[anim.numJoints]; animated = true; Vector3 min = new Vector3(9999, 9999, 9999); Vector3 max = new Vector3(-9999, -9999, -9999); // laske bboxit for (int q = 0; q < anim.numFrames; q++) { if (anim.bboxes[q].min.X < min.X) min.X = anim.bboxes[q].min.X; if (anim.bboxes[q].min.Y < min.Y) min.Y = anim.bboxes[q].min.Y; if (anim.bboxes[q].min.Z < min.Z) min.Z = anim.bboxes[q].min.Z; if (anim.bboxes[q].max.X > max.X) max.X = anim.bboxes[q].max.X; if (anim.bboxes[q].max.Y > max.Y) max.Y = anim.bboxes[q].max.Y; if (anim.bboxes[q].max.Z > max.Z) max.Z = anim.bboxes[q].max.Z; } Boundings = new BoundingVolume(); Boundings.CreateBoundingVolume(this, min, max); Update(0); animations.Add(anim); Log.WriteDebugLine("Animation: " + fileName); UseAnimation(animName); } }
/// <summary> /// lataa mesh tiedosto /// </summary> /// <param name="fileName"></param> /// <param name="xs"></param> /// <param name="ys"></param> /// <param name="zs"></param> public void Load(string fileName, float xs, float ys, float zs) { pathData.Clear(); ObjModel mesh = null; List<Vector3> _vertex = new List<Vector3>(); List<Vector3> _normal = new List<Vector3>(); List<Vector2> _uv = new List<Vector2>(); string dir = Settings.DataDir; if (fileName.Contains("\\")) { int l = fileName.LastIndexOf("\\"); dir = dir + fileName.Substring(0, l + 1); } else if (fileName.Contains("/")) { int l = fileName.LastIndexOf("/"); dir = dir + fileName.Substring(0, l + 1); } fileName = Settings.DataDir + fileName; bool path = false; // jos reitti using (System.IO.StreamReader file = new System.IO.StreamReader(fileName)) { // tiedosto muistiin string data = file.ReadToEnd(); data = data.Replace('\r', ' '); // pilko se string[] lines = data.Split('\n'); int numOfFaces = 0; for (int q = 0; q < lines.Length; q++) { string[] ln = lines[q].Split(' '); // pilko datat if (ln[0] == "f") numOfFaces++; } // lue kaikki datat objektiin ja indexit mesheihin for (int q = 0; q < lines.Length; q++) { string line = lines[q]; if (line.StartsWith("#")) continue; string[] ln = line.Split(' '); // pilko datat if (ln[0] == "v") // vertex x y z { float x = (Util.GetFloat(ln[1]) - mesh.Position.X) * xs; float y = (Util.GetFloat(ln[2]) - mesh.Position.Y) * ys; float z = (Util.GetFloat(ln[3]) - mesh.Position.Z) * zs; if (path) pathData.Add(new Vector3(x, y, z)); else _vertex.Add(new Vector3(x, y, z)); continue; } if (ln[0] == "vn") // normal x y z { _normal.Add(new Vector3(Util.GetFloat(ln[1]), Util.GetFloat(ln[2]), Util.GetFloat(ln[3]))); continue; } if (ln[0] == "vt") // texcoord U V { _uv.Add(new Vector2(Util.GetFloat(ln[1]), Util.GetFloat(ln[2]))); continue; } // uusi objekti if (ln[0] == "o" || ln[0] == "g") { if (mesh != null) meshes.Add(mesh); // talteen mesh = new ObjModel(ln[1]); mesh.material = material; // Nimessä voi olla ohjeita mitä muuta halutaan, esim: // * Path_reitti1 jolloin ei ladata objektia mutta reitti jota pitkin kamera/objektit voi kulkea. // * BBox_nimi/BSphere_nimi jolloin tämä onkin nimi-objektin bounding box/sphere. if (mesh.Name.Contains("Path_")) { path = true; } else if (mesh.Name.Contains("BBox_") || mesh.Name.Contains("BSphere_")) { // TODO: bbox_ bsphere_ } continue; } // materiaali if (ln[0] == "usemtl") { // jos kesken meshin materiaali vaihtuu, luodaan uusi obu johon loput facet if (lines[q - 1].StartsWith("f")) { meshes.Add(mesh); Vector3 tmpPos = mesh.Position; mesh = new ObjModel(mesh.Name); mesh.material = material; mesh.Position = tmpPos; // samaa objektia, niin sama Position } mesh.MaterialName = ln[1]; continue; } if (ln[0] == "f") { // ota talteen f rivi: // f vertex/uv/normal vertex/uv/normal vertex/uv/normal // eli esim: f 4/4/2 5/5/3 7/2/4 // tarkistetaan jos ilman texcoordei eli f 4/4 5/4 6/4 tai f 2//3 jne tai ilman / merkkejä. int dv = 0; for (int t = 0; t < line.Length; t++) if (line[t] == '/') dv++; if (line.Contains("//")) dv = 0; // ei ole texindexei line = line.Replace("//", " "); line = line.Replace("/", " "); string[] _ln = line.Split(' '); if (dv == 0 || dv == 3) // luultavasti nyt ei ole texturecoordinaatteja { mesh._vertexInd.Add(Int32.Parse(_ln[1]) - 1); mesh._vertexInd.Add(Int32.Parse(_ln[3]) - 1); mesh._vertexInd.Add(Int32.Parse(_ln[5]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[2]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[4]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[6]) - 1); } else // kaikki mukana { mesh._vertexInd.Add(Int32.Parse(_ln[1]) - 1); mesh._vertexInd.Add(Int32.Parse(_ln[4]) - 1); mesh._vertexInd.Add(Int32.Parse(_ln[7]) - 1); mesh._uvInd.Add(Int32.Parse(_ln[2]) - 1); mesh._uvInd.Add(Int32.Parse(_ln[5]) - 1); mesh._uvInd.Add(Int32.Parse(_ln[8]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[3]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[6]) - 1); mesh._normalInd.Add(Int32.Parse(_ln[9]) - 1); } continue; } // materiaalitiedosto if (ln[0] == "mtllib") { try { // ladataan objektille materiaalitiedot (mesheille otetaan talteen materialname joka viittaa sitten näihin materiaaleihin) material = new Material(); material.Load(dir + ln[1], Texture.LoadTextures); } catch (Exception e) { Log.WriteDebugLine(e.ToString()); } } } if (mesh != null) meshes.Add(mesh); // pathille ei luoda objektia, se on vain kasa vertexejä if (path == false) { int cc = 0; vertices = new Vertex[numOfFaces * 3]; for (int m = 0; m < meshes.Count; m++) { meshes[m].vertices = new Vertex[meshes[m]._vertexInd.Count]; for (int q = 0; q < meshes[m]._vertexInd.Count; q++) { // mesh datat meshes[m].vertices[q].vertex = _vertex[meshes[m]._vertexInd[q]]; meshes[m].vertices[q].normal = _normal[meshes[m]._normalInd[q]]; if (meshes[m]._uvInd.Count != 0) meshes[m].vertices[q].uv_or_color = new Vector4(_uv[meshes[m]._uvInd[q]].X, _uv[meshes[m]._uvInd[q]].Y, _uv[meshes[m]._uvInd[q]].X, _uv[meshes[m]._uvInd[q]].Y); // pistetään myös objektille kaikki vertexit yhteen klimppiin. //TODO Miks? vie vaa muistia nii paljo, mesheissä kumminki nuo datat säilytetään. // jos tää on VAIN collisionia varten, siihe ny o helppo tehdä se et se menee objektin puun läpi // ni sit ei tartte tätä vertices[cc].vertex = _vertex[meshes[m]._vertexInd[q]]; vertices[cc].normal = _normal[meshes[m]._normalInd[q]]; if (meshes[m]._uvInd.Count != 0) vertices[cc].uv_or_color = new Vector4(_uv[meshes[m]._uvInd[q]].X, _uv[meshes[m]._uvInd[q]].Y, _uv[meshes[m]._uvInd[q]].X, _uv[meshes[m]._uvInd[q]].Y); cc++; } // index taulukko meshes[m].indices = new int[meshes[m]._vertexInd.Count]; for (int q = 0; q < meshes[m]._vertexInd.Count; q++) meshes[m].indices[q] = q; meshes[m].vbo = new VBO(); meshes[m].vbo.DataToVBO(meshes[m].vertices, meshes[m].indices); // meshin bounding volume meshes[m].Boundings = new BoundingVolume(); meshes[m].Boundings.CreateBoundingVolume(meshes[m]); // lataa glsl koodit string shader = material.GetMaterial(meshes[m].MaterialName).ShaderName; if (shader != "") { mesh.Shader = new GLSL(); mesh.Shader.Load(shader + ".vert", shader + ".frag"); } if (material.GetMaterial(meshes[m].MaterialName).Dissolve < 1.0f) IsTranslucent = true; } // koko objektin bounding volume IsRendObj = false; // childeissä rendattavat objektit, tässä ei ole rendattavaa, vain paikka Boundings = new BoundingVolume(); Boundings.CreateBoundingVolume(this); // lisätään objektille meshit childeiks for (int q = 0; q < meshes.Count; q++) { Add(meshes[q]); } Log.WriteDebugLine("Object: " + Name + " meshes: " + meshes.Count); } _vertex.Clear(); _normal.Clear(); _uv.Clear(); for (int q = 0; q < meshes.Count; q++) { meshes[q]._vertexInd.Clear(); meshes[q]._normalInd.Clear(); meshes[q]._uvInd.Clear(); } } }
/// <summary> /// lataa md5-animaatio. /// </summary> /// <param name="fileName"></param> /// <param name="anim"></param> public override void LoadAnim(string animName, string fileName) { if (fileName == null || fileName == "") { return; } Animation anim = new Animation(); anim.animName = animName; Buffer t = new Buffer(); MD5JointInfo[] jointInfos = null; MD5BaseFrameJoint[] baseFrame = null; float[] animFrameData = null; int numAnimatedComponents = 0; int frame_index; int i; using (System.IO.StreamReader file = new System.IO.StreamReader(Settings.DataDir + fileName)) { string line; while ((line = file.ReadLine()) != null) { if (line == "") { continue; } // Read number of joints if (ParseLine(ref t, line, "numFrames %d")) { /* Allocate memory for skeleton frames and bounding boxes */ anim.numFrames = t.ibuffer[0]; if (anim.numFrames > 0) { anim.bboxes = new MD5BoundingBox[anim.numFrames]; } } if (ParseLine(ref t, line, "numJoints %d")) { /* Allocate memory for joints of each frame */ anim.numJoints = t.ibuffer[0]; if (anim.numJoints > 0) { /* Allocate temporary memory for building skeleton frames */ jointInfos = new MD5JointInfo[anim.numJoints]; baseFrame = new MD5BaseFrameJoint[anim.numJoints]; } anim.skelFrames = new MD5Joint[anim.numFrames, anim.numJoints]; } if (ParseLine(ref t, line, "frameRate %d")) { anim.frameRate = t.ibuffer[0]; } if (ParseLine(ref t, line, "numAnimatedComponents %d")) { numAnimatedComponents = t.ibuffer[0]; if (numAnimatedComponents > 0) { /* Allocate memory for animation frame data */ animFrameData = new float[numAnimatedComponents]; } } if (line.Equals("hierarchy {")) { for (i = 0; i < anim.numJoints; ++i) { /* Read whole line */ line = file.ReadLine(); Cleanstring(ref line); /* Read joint info */ ParseLine(ref t, line, "%s %d %d %d"); jointInfos[i].name = t.sbuffer; jointInfos[i].parent = t.ibuffer[0]; jointInfos[i].flags = t.ibuffer[1]; jointInfos[i].startIndex = t.ibuffer[2]; } } if (line.Equals("bounds {")) { for (i = 0; i < anim.numFrames; ++i) { /* Read whole line */ line = file.ReadLine(); Cleanstring(ref line); /* Read bounding box */ ParseLine(ref t, line, "( %f %f %f ) ( %f %f %f )"); anim.bboxes[i].min.X = t.fbuffer[0]; anim.bboxes[i].min.Y = t.fbuffer[1]; anim.bboxes[i].min.Z = t.fbuffer[2]; anim.bboxes[i].max.X = t.fbuffer[3]; anim.bboxes[i].max.Y = t.fbuffer[4]; anim.bboxes[i].max.Z = t.fbuffer[5]; } } if (line.Equals("baseframe {")) { for (i = 0; i < anim.numJoints; ++i) { /* Read whole line */ line = file.ReadLine(); Cleanstring(ref line); /* Read base frame joint */ ParseLine(ref t, line, "( %f %f %f ) ( %f %f %f )"); if (t.fbuffer.Length == 6) { baseFrame[i].pos.X = t.fbuffer[0]; baseFrame[i].pos.Y = t.fbuffer[1]; baseFrame[i].pos.Z = t.fbuffer[2]; baseFrame[i].orient.X = t.fbuffer[3]; baseFrame[i].orient.Y = t.fbuffer[4]; baseFrame[i].orient.Z = t.fbuffer[5]; /* Compute the w component */ MathExt.ComputeW(ref baseFrame[i].orient); } } } if (ParseLine(ref t, line, "frame %d")) { frame_index = t.ibuffer[0]; /* Read frame data */ for (i = 0; i < numAnimatedComponents;) { line = file.ReadLine(); if (line[0] == '}') { break; } Cleanstring(ref line); string[] splt = line.Split(' '); for (int ww = 0; ww < splt.Length; ww++) { animFrameData[i++] = float.Parse(splt[ww]); } } /* Build frame skeleton from the collected data */ BuildFrameSkeleton(ref jointInfos, ref baseFrame, ref animFrameData, frame_index, anim.numJoints, ref anim); } } anim.curFrame = 0; anim.nextFrame = 1; anim.lastTime = 0; anim.maxTime = 1.0f / anim.frameRate; /* Allocate memory for animated skeleton */ skeleton = new MD5Joint[anim.numJoints]; animated = true; Vector3 min = new Vector3(9999, 9999, 9999); Vector3 max = new Vector3(-9999, -9999, -9999); // laske bboxit for (int q = 0; q < anim.numFrames; q++) { if (anim.bboxes[q].min.X < min.X) { min.X = anim.bboxes[q].min.X; } if (anim.bboxes[q].min.Y < min.Y) { min.Y = anim.bboxes[q].min.Y; } if (anim.bboxes[q].min.Z < min.Z) { min.Z = anim.bboxes[q].min.Z; } if (anim.bboxes[q].max.X > max.X) { max.X = anim.bboxes[q].max.X; } if (anim.bboxes[q].max.Y > max.Y) { max.Y = anim.bboxes[q].max.Y; } if (anim.bboxes[q].max.Z > max.Z) { max.Z = anim.bboxes[q].max.Z; } } Boundings = new BoundingVolume(); Boundings.CreateBoundingVolume(this, min, max); Update(0); animations.Add(anim); Log.WriteDebugLine("Animation: " + fileName); UseAnimation(animName); } }