public Page(long TableX, long TableZ) { isLoaded = false; isPreLoaded = false; tableX = TableX; tableZ = TableZ; numTiles = (long) ((float) Options.Instance.PageSize / Options.Instance.TileSize); pageNode = null; long size = Options.Instance.PageSize - 1; // Boundaries of this page // the middle page is at world coordinates 0,0 float factorX = size * Options.Instance.Scale.x; float factorZ = size * Options.Instance.Scale.z; iniX = (tableX + tableX - Options.Instance.World_Width) / 2.0f * factorX ; iniZ = (tableZ + tableZ - Options.Instance.World_Height) / 2.0f * factorZ ; float EndX = iniX + factorX; float EndZ = iniZ + factorZ; float MaxHeight = Data2DManager.Instance.GetMaxHeight(tableX, tableZ); float chgfactor = Options.Instance.Change_Factor; boundsExt = new AxisAlignedBox(); boundsExt.SetExtents( new Vector3(( float )( iniX ), 0, ( float )( iniZ )), new Vector3(( float )( EndX ), MaxHeight, ( float )( EndZ ) )); //Change Zone of this page boundsInt = new AxisAlignedBox(); boundsInt.SetExtents( new Vector3(( float )( iniX + chgfactor ), 0, ( float )( iniZ + chgfactor )), new Vector3(( float )( EndX - chgfactor ), MaxHeight, ( float )( EndZ - chgfactor ) )); neighbors = new Page[4]; for ( long i = 0; i < 4; i++ ) { neighbors[ i ] = null; } }
/// <summary> /// Internal method for locating a list of shadow casters which /// could be affecting the frustum for a given light. /// </summary> /// <remarks> /// Custom scene managers are encouraged to override this method to add optimizations, /// and to add their own custom shadow casters (perhaps for world geometry) /// </remarks> /// <param name="light"></param> /// <param name="camera"></param> protected virtual IList FindShadowCastersForLight(Light light, Camera camera) { shadowCasterList.Clear(); if (light.Type == LightType.Directional) { // Basic AABB query encompassing the frustum and the extrusion of it AxisAlignedBox aabb = new AxisAlignedBox(); Vector3[] corners = camera.WorldSpaceCorners; Vector3 min, max; Vector3 extrude = light.DerivedDirection * -shadowDirLightExtrudeDist; // do first corner min = max = corners[0]; min.Floor(corners[0] + extrude); max.Ceil(corners[0] + extrude); for (int c = 1; c < 8; ++c) { min.Floor(corners[c]); max.Ceil(corners[c]); min.Floor(corners[c] + extrude); max.Ceil(corners[c] + extrude); } aabb.SetExtents(min, max); if (shadowCasterAABBQuery == null) shadowCasterAABBQuery = CreateAABBRegionQuery(aabb); else shadowCasterAABBQuery.Box = aabb; // Execute, use callback shadowCasterQueryListener.Prepare(false, light.GetFrustumClipVolumes(camera), light, camera, shadowCasterList, shadowFarDistanceSquared); shadowCasterAABBQuery.Execute(shadowCasterQueryListener); } else { Sphere s = new Sphere(light.DerivedPosition, light.AttenuationRange); // eliminate early if camera cannot see light sphere if (camera.IsObjectVisible(s)) { // create or init a sphere region query if(shadowCasterSphereQuery == null) { shadowCasterSphereQuery = CreateSphereRegionQuery(s); } else { shadowCasterSphereQuery.Sphere = s; } // check if the light is within view of the camera bool lightInFrustum = camera.IsObjectVisible(light.DerivedPosition); List<PlaneBoundedVolume> volumeList = null; // Only worth building an external volume list if // light is outside the frustum if(!lightInFrustum) { volumeList = light.GetFrustumClipVolumes(camera); } // prepare the query and execute using the callback shadowCasterQueryListener.Prepare( lightInFrustum, volumeList, light, camera, shadowCasterList, shadowFarDistanceSquared); shadowCasterSphereQuery.Execute(shadowCasterQueryListener); } } return shadowCasterList; }
/// <summary> /// Sets the corners of the rectangle, in relative coordinates. /// </summary> /// <param name="left">Left position in screen relative coordinates, -1 = left edge, 1.0 = right edge.</param> /// <param name="top">Top position in screen relative coordinates, 1 = top edge, -1 = bottom edge.</param> /// <param name="right">Position in screen relative coordinates.</param> /// <param name="bottom">Position in screen relative coordinates.</param> public void SetCorners(float left, float top, float right, float bottom) { float[] data = new float[] { left, top, -1, left, bottom, -1, right, top, -1, right, bottom, -1 }; HardwareVertexBuffer buffer = vertexData.vertexBufferBinding.GetBuffer(POSITION); buffer.WriteData(0, buffer.Size, data, true); box = new AxisAlignedBox(); box.SetExtents(new Vector3(left, top, 0), new Vector3(right, bottom, 0)); }
/// <summary> /// Utility method for extruding a bounding box. /// </summary> /// <param name="box">Original bounding box, will be updated in-place.</param> /// <param name="lightPosition">4D light position in object space, when w=0.0f this /// represents a directional light</param> /// <param name="extrudeDistance">The distance to extrude.</param> protected virtual void ExtrudeBounds(AxisAlignedBox box, Vector4 lightPosition, float extrudeDistance) { Vector3 extrusionDir = Vector3.Zero; if (lightPosition.w == 0) { extrusionDir.x = -lightPosition.x; extrusionDir.y = -lightPosition.y; extrusionDir.z = -lightPosition.z; extrusionDir.Normalize(); extrusionDir *= extrudeDistance; box.SetExtents(box.Minimum + extrusionDir, box.Maximum + extrusionDir); } else { Vector3[] corners = box.Corners; Vector3 vmin = new Vector3(); Vector3 vmax = new Vector3(); for(int i = 0; i < 8; i++) { extrusionDir.x = corners[i].x - lightPosition.x; extrusionDir.y = corners[i].y - lightPosition.y; extrusionDir.z = corners[i].z - lightPosition.z; extrusionDir.Normalize(); extrusionDir *= extrudeDistance; Vector3 res = corners[i] + extrusionDir; if(i == 0) { vmin = res; vmax = res; } else { vmin.Floor(res); vmax.Ceil(res); } } box.SetExtents(vmin, vmax); } }