//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------ public ResourceItem Convert(object input, String collection) { if (input == null) return null; MeshObject obj = (MeshObject) input; MeshItem ret = new MeshItem(this._graphics); if (obj.Indexes == null) obj.Indexes = SystemCore.Environment.CreateUInt16Array(0); if (obj.Vertices == null) obj.Vertices = SystemCore.Environment.CreateFloat32Array(0); if (obj.Normals == null) obj.Normals = SystemCore.Environment.CreateFloat32Array(0); if (obj.UVs == null) obj.UVs = SystemCore.Environment.CreateFloat32Array(0); ret.Indexes = SystemCore.Environment.CreateUInt16ArrayFromArray(obj.Indexes); ret.Mesh = SystemCore.Environment.CreateFloat32Array((ulong) (obj.Vertices.Length + obj.Normals.Length + obj.UVs.Length)); ret.OffsetPosition = 0; ret.OffsetNormal = obj.Vertices.Length; ret.OffsetUv = obj.Vertices.Length + obj.Normals.Length; /*mesh data*/ for (int i = 0; i < obj.Vertices.Length; i++) ret.Mesh[i] = obj.Vertices[i]; for (int i = 0; i < obj.Normals.Length; i++) ret.Mesh[i + ret.OffsetNormal] = obj.Normals[i]; for (int i = 0; i < obj.UVs.Length; i++) ret.Mesh[i + ret.OffsetUv] = obj.UVs[i]; /*bounding volume*/ ret.ComputeBoundingVolume(); return ret; }
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------ public bool Test(CullInfo cullInfo, Node node, MeshItem meshItem) { float x = meshItem.BoundingVolume.Center.Elements[0]; float y = meshItem.BoundingVolume.Center.Elements[1]; float z = meshItem.BoundingVolume.Center.Elements[2]; /*First: we transform our coordinate into eye coordinates from model-view.*/ float xp = x * cullInfo.ModelView[0] + y * cullInfo.ModelView[4] + z * cullInfo.ModelView[8] + cullInfo.ModelView[12]; float yp = x * cullInfo.ModelView[1] + y * cullInfo.ModelView[5] + z * cullInfo.ModelView[9] + cullInfo.ModelView[13]; float zp = x * cullInfo.ModelView[2] + y * cullInfo.ModelView[6] + z * cullInfo.ModelView[10] + cullInfo.ModelView[14]; /*then we transform the furthest away vertex to mv to comute sphere radius*/ float xv = meshItem.Mesh[meshItem.BoundingVolume.VertexIndex * 3]; float yv = meshItem.Mesh[meshItem.BoundingVolume.VertexIndex * 3 + 1]; float zv = meshItem.Mesh[meshItem.BoundingVolume.VertexIndex * 3 + 2]; float xpv = xv * cullInfo.ModelView[0] + yv * cullInfo.ModelView[4] + zv * cullInfo.ModelView[8] + cullInfo.ModelView[12]; float ypv = xv * cullInfo.ModelView[1] + yv * cullInfo.ModelView[5] + zv * cullInfo.ModelView[9] + cullInfo.ModelView[13]; float zpv = xv * cullInfo.ModelView[2] + yv * cullInfo.ModelView[6] + zv * cullInfo.ModelView[10] + cullInfo.ModelView[14]; /*now we compute the radius*/ float r = Math.Sqrt((xp - xpv) * (xp - xpv) + (yp - ypv) * (yp - ypv) + (zp - zpv) * (zp - zpv)); if (xp + r < -this._regionX) return false; if (xp - r > this._regionX) return false; if (yp + r < -this._regionY) return false; if (yp - r > this._regionY) return false; return true; }
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------ public bool Test(CullInfo cullInfo, Node node, MeshItem meshItem) { float x = meshItem.BoundingVolume.Center.Elements[0]; float y = meshItem.BoundingVolume.Center.Elements[1]; float z = meshItem.BoundingVolume.Center.Elements[2]; /*First: we transform our coordinate into eye coordinates from model-view.*/ float xp = x * cullInfo.ModelView[0] + y * cullInfo.ModelView[4] + z * cullInfo.ModelView[8] + cullInfo.ModelView[12]; float yp = x * cullInfo.ModelView[1] + y * cullInfo.ModelView[5] + z * cullInfo.ModelView[9] + cullInfo.ModelView[13]; float zp = x * cullInfo.ModelView[2] + y * cullInfo.ModelView[6] + z * cullInfo.ModelView[10] + cullInfo.ModelView[14]; /*then we transform the furthest away vertex to mv to comute sphere radius*/ float xv = meshItem.Mesh[meshItem.BoundingVolume.VertexIndex * 3]; float yv = meshItem.Mesh[meshItem.BoundingVolume.VertexIndex * 3 + 1]; float zv = meshItem.Mesh[meshItem.BoundingVolume.VertexIndex * 3 + 2]; float xpv = xv * cullInfo.ModelView[0] + yv * cullInfo.ModelView[4] + zv * cullInfo.ModelView[8] + cullInfo.ModelView[12]; float ypv = xv * cullInfo.ModelView[1] + yv * cullInfo.ModelView[5] + zv * cullInfo.ModelView[9] + cullInfo.ModelView[13]; float zpv = xv * cullInfo.ModelView[2] + yv * cullInfo.ModelView[6] + zv * cullInfo.ModelView[10] + cullInfo.ModelView[14]; /*now we compute the radius*/ float r = Math.Sqrt((xp - xpv) * (xp - xpv) + (yp - ypv) * (yp - ypv) + (zp - zpv) * (zp - zpv)); /*Now - we apply the "plane equation" of each clip plane to see how far from the clip plane our point is. The clip planes are directed: positive number distances mean we are INSIDE our viewing area by some distance; negative means outside. So ... if we are outside by less than -r, the ENTIRE sphere is out of bounds. We are not visible! We do the near clip plane, then sides, then far, in an attempt to try the planes that will eliminate the most geometry first...half the world is behind the near clip plane, but not much is behind the far clip plane on sunny day.*/ if ((xp * cullInfo.NearClip [0] + yp * cullInfo.NearClip [1] + zp * cullInfo.NearClip [2] + cullInfo.NearClip [3] + r) < 0) return false; if ((xp * cullInfo.BotClip [0] + yp * cullInfo.BotClip [1] + zp * cullInfo.BotClip [2] + cullInfo.BotClip [3] + r) < 0) return false; if ((xp * cullInfo.TopClip [0] + yp * cullInfo.TopClip [1] + zp * cullInfo.TopClip [2] + cullInfo.TopClip [3] + r) < 0) return false; if ((xp * cullInfo.LeftClip [0] + yp * cullInfo.LeftClip [1] + zp * cullInfo.LeftClip [2] + cullInfo.LeftClip [3] + r) < 0) return false; if ((xp * cullInfo.RightClip[0] + yp * cullInfo.RightClip[1] + zp * cullInfo.RightClip[2] + cullInfo.RightClip[3] + r) < 0) return false; if ((xp * cullInfo.FarClip [0] + yp * cullInfo.FarClip [1] + zp * cullInfo.FarClip [2] + cullInfo.FarClip [3] + r) < 0) return false; return true; }
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------ private void RenderLight(ShaderGroup lightShader, LightComponent component, MeshItem lightVolume) { LightItem light = (LightItem) this._library.GetResource(component.LightHandle); if(light == null) return; float intensity = (float) light.Properties["intensity"]; /*update sphere scale matrix*/ this._scaleMatrix.Elements[0] = intensity * 2; this._scaleMatrix.Elements[5] = intensity * 2; this._scaleMatrix.Elements[10] = intensity * 2; this._scaleMatrix.Elements[15] = 1.0f; this._vMatrix.MultiplyM2(component.Parent.World, this._mvMatrix); this._mvMatrix.MultiplyM2(this._scaleMatrix, this._mvMatrix); Vector3 pos = this._mvMatrix.TransformV(new Vector3(new float[] {0.0f, 0.0f, 0.0f})); /*check view occlusion*/ this.UpdateCullInfo(this._mvMatrix); /*test for view occlusion*/ if (this._occluder != null && !this._occluder.Test(this._cullInfo, null, lightVolume)) return; /*bind shader, mesh and buffers*/ lightShader.ShaderBinder.BindLight(pos, light, this._mvMatrix, this._pMatrix); this._context.DrawElements(WebGLE.Triangles, this._lightSphereVolume.Indexes.Length, WebGLE.UnsignedShortT, 0); }
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------ public bool DealocateMesh(MeshItem mesh) { this._context.DeleteBuffer(mesh.IndexBuffer); this._context.DeleteBuffer(mesh.MeshBuffer); return true; }
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------ public bool AllocateMesh(MeshItem mesh) { /*vertex position buffer*/ IBuffer meshBuffer = this._context.CreateBuffer(); this._context.BindBuffer(WebGLE.ArrayBuffer, meshBuffer); this._context.BufferData(WebGLE.ArrayBuffer, mesh.Mesh, WebGLE.StaticDraw); /*index buffer*/ IBuffer indexBuffer = this._context.CreateBuffer(); this._context.BindBuffer(WebGLE.ElementArrayBuffer, indexBuffer); this._context.BufferData(WebGLE.ElementArrayBuffer, mesh.Indexes, WebGLE.StaticDraw); mesh.IndexBuffer = indexBuffer; mesh.MeshBuffer = meshBuffer; return true; }
public void BindLightMesh(MeshItem lightVolume) { if (this._parent.LightPassShader == null) return; /*bind the vbo's*/ this._graphics.BindBuffer(WebGLE.ArrayBuffer, lightVolume.MeshBuffer); this._graphics.VertexAttribPointer(_parent.LightPassShader.Attributes["aVertexPosition"], 3, WebGLE.FloatT, false, 0, lightVolume.OffsetPosition * 4); this._graphics.BindBuffer(WebGLE.ElementArrayBuffer, lightVolume.IndexBuffer); }
public void BindGeometryMesh(MeshItem mesh) { if (this._parent.GeometryPassShader == null) return; this._graphics.BindBuffer(WebGLE.ArrayBuffer, mesh.MeshBuffer); this._graphics.VertexAttribPointer(this._parent.GeometryPassShader.Attributes["aVertexPosition"], 3, WebGLE.FloatT, false, 0, mesh.OffsetPosition * 4); this._graphics.VertexAttribPointer(this._parent.GeometryPassShader.Attributes["aNormalPosition"], 3, WebGLE.FloatT, false, 0, mesh.OffsetNormal * 4); this._graphics.VertexAttribPointer(this._parent.GeometryPassShader.Attributes["aUVPosition"], 2, WebGLE.FloatT, false, 0, mesh.OffsetUv * 4); /*index array*/ this._graphics.BindBuffer(WebGLE.ElementArrayBuffer, mesh.IndexBuffer); }