private static void IntersectSphere (int idx, Sphere sphere, Ray ray) { Vector3 L = sphere.pos - ray.O; float tca = Vector3.Dot (L, ray.D); if (tca < 0) return; float d2 = Vector3.Dot (L, L) - tca * tca; if (d2 > sphere.r) return; float thc = (float)Math.Sqrt (sphere.r - d2); float t0 = tca - thc; float t1 = tca + thc; if (t0 > 0) { if (t0 > ray.t) return; ray.N = Vector3.Normalize (ray.O + t0 * ray.D - sphere.pos); ray.objIdx = idx; ray.t = t0; } else { if ((t1 > ray.t) || (t1 < 0)) return; ray.N = Vector3.Normalize (sphere.pos - (ray.O + t1 * ray.D)); ray.objIdx = idx; ray.t = t1; } }
public Scene () { // define geometry plane1 = new Sphere (0.0f, -4999.0f, 0.0f, 4998.5f * 4998.5f); // bottom plane plane2 = new Sphere (0.0f, 0.0f, -5000.0f, 4993.0f * 4993f); // back plane for (int i = 0; i < 3; i++) { sphere [i] = new Sphere (-0.8f + i * 0.8f, 0, -2, 0.3f * 0.3f); sphere [i + 3] = new Sphere (-0.8f + i * 0.8f, -0.8f, -2, 0.5f * 0.5f); } light = new Sphere (2.7f, 1.7f, -0.5f, LIGHTSIZE * LIGHTSIZE); // load skybox skybox = new float[2500 * 1250 * 3]; // use this instead of the WinFileIO for linux support using (var f = new BinaryReader(File.OpenRead("../../assets/sky_15.raw"))) { var bytes = f.ReadBytes (2500 * 650 * 4 * 3); for (var i = 0; i < bytes.Length/sizeof(float); i++) { skybox [i] = BitConverter.ToSingle (bytes, i*sizeof(float)); } } //WinFileIO wf = new WinFileIO (skybox); //wf.OpenForReading ("../../assets/sky_15.raw"); //wf.Read (2500 * 650 * 4 * 3); for (int i = 2500 * 650 * 3; i < (2500 * 1250 * 3); i++) skybox [i] = 0; //wf.Dispose (); }
public Scene() { // define geometry plane1 = new Sphere( 0.0f, -4999.0f, 0.0f, 4998.5f * 4998.5f ); // bottom plane plane2 = new Sphere( 0.0f, 0.0f, -5000.0f, 4993.0f * 4993f ); // back plane for( int i = 0; i < 3; i++ ) { sphere[i] = new Sphere( -0.8f + i * 0.8f, 0, -2, 0.3f * 0.3f ); sphere[i + 3] = new Sphere( -0.8f + i * 0.8f, -0.8f, -2, 0.5f * 0.5f ); } light = new Sphere( 2.7f, 1.7f, -0.5f, LIGHTSIZE * LIGHTSIZE ); // load skybox skybox = new float[2500 * 1250 * 3]; WinFileIO wf = new WinFileIO( skybox ); wf.OpenForReading( "../../assets/sky_15.raw" ); wf.Read( 2500 * 650 * 4 * 3 ); for( int i = 2500 * 650 * 3; i < (2500 * 1250 * 3); i++ ) skybox[i] = 0; wf.Dispose(); }
private static void IntersectSphere4(int idx, Sphere sphere, Ray4 ray) { Vector<float> Lx4 = new Vector<float>(sphere.pos.X) - ray.Ox4; Vector<float> Ly4 = new Vector<float>(sphere.pos.Y) - ray.Oy4; Vector<float> Lz4 = new Vector<float>(sphere.pos.Z) - ray.Oz4; // calculate dot product between L and ray.D Vector<float> tca4 = Lx4 * ray.Dx4 + Ly4 * ray.Dy4 + Lz4 * ray.Dz4; Vector<int> mask1 = Vector.LessThan(tca4, Vector<float>.Zero); Vector<float> LdotL = Lx4 * Lx4 + Ly4 * Ly4 + Lz4 * Lz4; Vector<float> d2 = LdotL - tca4 * tca4; Vector<int> mask2 = Vector.GreaterThan(d2, new Vector<float>(sphere.r)); Vector<int> mask = Vector.BitwiseOr(mask1, mask2); // if a ray satisfies both masks, the normal stays the same Vector<float> thc4 = Vector.SquareRoot(new Vector<float>(sphere.r) - d2); Vector<float> t0 = tca4 - thc4; Vector<float> t1 = tca4 + thc4; Vector<int> mask_t0gt0 = Vector.GreaterThan(t0, Vector<float>.Zero); Vector<int> mask_t0gtrayt = Vector.GreaterThan(t0, ray.t4); Vector<int> mask_t1gtrt_or_t1lt0 = Vector.BitwiseOr(Vector.GreaterThan(t1, ray.t4), Vector.LessThan(t1, Vector<float>.Zero)); // calculate the (unnormalized) normals ray.Nx4 = Vector.ConditionalSelect(mask, ray.Nx4, Vector.ConditionalSelect(mask_t0gt0, Vector.ConditionalSelect(mask_t0gtrayt, ray.Nx4, ray.Ox4 + t0 * ray.Dx4 - new Vector<float>(sphere.pos.X)), Vector.ConditionalSelect(mask_t1gtrt_or_t1lt0, ray.Nx4, new Vector<float>(sphere.pos.X) - (ray.Ox4 + t1 * ray.Dx4)))); ray.Ny4 = Vector.ConditionalSelect(mask, ray.Ny4, Vector.ConditionalSelect(mask_t0gt0, Vector.ConditionalSelect(mask_t0gtrayt, ray.Ny4, ray.Oy4 + t0 * ray.Dy4 - new Vector<float>(sphere.pos.Y)), Vector.ConditionalSelect(mask_t1gtrt_or_t1lt0, ray.Ny4, new Vector<float>(sphere.pos.Y) - (ray.Oy4 + t1 * ray.Dy4)))); ray.Nz4 = Vector.ConditionalSelect(mask, ray.Nz4, Vector.ConditionalSelect(mask_t0gt0, Vector.ConditionalSelect(mask_t0gtrayt, ray.Nz4, ray.Oz4 + t0 * ray.Dz4 - new Vector<float>(sphere.pos.Z)), Vector.ConditionalSelect(mask_t1gtrt_or_t1lt0, ray.Nz4, new Vector<float>(sphere.pos.Z) - (ray.Oz4 + t1 * ray.Dz4)))); // normalize the normals Vector<float> length = Vector.SquareRoot(ray.Nx4 * ray.Nx4 + ray.Ny4 * ray.Ny4 + ray.Nz4 * ray.Nz4); ray.Nx4 /= length; ray.Ny4 /= length; ray.Nz4 /= length; // get the objIdxs ray.objIdx4 = Vector.ConditionalSelect(mask, ray.objIdx4, Vector.ConditionalSelect(mask_t0gt0, Vector.ConditionalSelect(mask_t0gtrayt, ray.objIdx4, new Vector<int>(idx)), Vector.ConditionalSelect(mask_t1gtrt_or_t1lt0, ray.objIdx4, new Vector<int>(idx)))); ray.t4 = Vector.ConditionalSelect(mask, ray.t4, Vector.ConditionalSelect(mask_t0gt0, Vector.ConditionalSelect(mask_t0gtrayt, ray.t4, t0), Vector.ConditionalSelect(mask_t1gtrt_or_t1lt0, ray.t4, t1))); }
public Vector3 Bounce(Vector3 direction, float distance, Sphere sphere, Vector3 origin) { Vector3 sphereNorm = Vector3.Normalize((direction * distance + origin) - sphere.position); return(Vector3.Normalize(direction - (sphereNorm * (Vector3.Dot(direction, sphereNorm)) * 2))); }
/// <summary> /// Respawns the balls and empties the grid lists /// </summary> /// <param name="sameSeed"> If set to true, the same seed as previous spawn will be used </param> public static void RestartScene(bool sameSeed, int scene) { grid = new Dictionary <int, List <int> >(); particles = new Sphere[numberOfPoints]; for (int i = 0; i < voxels * voxels * voxels; i++) { grid.Add(i, new List <int>()); } int count = 0; int val = 50; float step = dim / 50; if (scene > 1 && scene < 5) { float minX; float minY; float minZ; float maxX; float maxY; float maxZ; float stepSize = 0.02f; if (scene == 3) { minX = 0f; minY = 0.9f; minZ = 0f; maxX = 0.98f; maxY = 0.98f; maxZ = 0.98f; } else if (scene == 2) { minX = 0f; minY = 0.53f; minZ = 0.79f; maxX = 0.25f; maxY = 1f; maxZ = 0.98f; } else { stepSize = 0.03f; minX = 0f; minY = 0f; minZ = 0f; maxX = 0.15f; maxY = 0.3f; maxZ = 0.98f; } numberOfPoints = 2000; particles = new Sphere[numberOfPoints]; grid = new Dictionary <int, List <int> >(); for (int i = 0; i < voxels * voxels * voxels; i++) { grid.Add(i, new List <int>()); } for (float x = minX; x < maxX; x += stepSize) { for (float y = minY; y < maxY; y += stepSize) { for (float z = minZ; z < maxZ; z += stepSize) { if (count < numberOfPoints) { particles[count] = new Sphere(count, new Vector3(x, y, z), Vector3.Zero); particles[count].color = new Vector3(0.5f, 0, 0); particles[count].Mass = 0.3f; particles[count].NetForce = new Vector3(0, 0, 0); currentPoints++; } count++; } } } } else { for (int i = 0; i <= val; i++) { for (int j = 0; j < val; j++) { for (int k = 1; k < val; k++) { if (count < numberOfPoints) { if (scene == 1) { particles[count] = new Sphere(count, new Vector3(step * k, 1 - step * 3.0f * j - 0.08f, step * i), Vector3.Zero, 0.01f);; } else if (scene == 0) { particles[count] = new Sphere(count, new Vector3(step * 1.5f * j + 0.03f, step * k, step * i), Vector3.Zero, 0.01f); } particles[count].color = new Vector3(0.5f, 0, 0); particles[count].Mass = 0.3f; particles[count].NetForce = new Vector3(0, 0, 0); if (count > 396) { particles[count].verbose = false; } currentPoints++; } count++; } } } } }