public override Transform Step(double time, LocationOptions options) { var dt = (float)(time - _time); var v = _vel * dt + 0.5f * _acc * dt * dt; if (Vec3.Dot(v, v) == 0.0) { return(base.Step(time, options)); } position = _pos + v; if (!options.RotationOptions.HasFlag(RotationOptions.AlignToVelocity)) { return(base.Step(time, options)); } v = _vel + _acc * dt; v.Normalize(); var n = new Vector3(local_orientation.v13, local_orientation.v23, local_orientation.v33); var u = new Vector3(v.x, v.y, v.z); var proj = u - Vector3.Dot(u, n) * n; var north = new Vector3(local_orientation.v12, local_orientation.v22, local_orientation.v32); var dot = Vector3.Dot(proj, north); var det = Vector3.Dot(n, Vector3.Cross(north, proj)); _euler.y = -(float)Math.Atan2(det, dot); return(base.Step(time, options)); }
public static NQuaternion GetDeltaQuaternionWithDirectionVectors(NVector3 a, NVector3 b) { var dot = NVector3.Dot(a, b); if (dot < -0.999999) { var cross = NVector3.Cross(a, b); if (cross.Length() < 0.000001) { cross = NVector3.Cross(NVector3.UnitY, a); } cross = NVector3.Normalize(cross); return(NQuaternion.CreateFromAxisAngle(cross, Pi)); } else if (dot > 0.999999) { return(new NQuaternion(0, 0, 0, 1)); } else { var xyz = NVector3.Cross(a, b); var w = (float)(Math.Sqrt(a.Length() * a.Length() + b.Length() * b.Length()) + dot); return(new NQuaternion(xyz.X, xyz.Y, xyz.Z, w)); } }
/// <summary> /// Find the closest point to the origin. /// </summary> /// <param name="W">Simplex</param> /// <returns>Closest point on simplex to origin.</returns> public Vector ClosestPoint(Simplex W) { Vector d = new Vector(); if (W.count >= 2) { d = W.B.MinkowskiPoint - W.A.MinkowskiPoint; } switch (W.count) { case 0: return(new Vector(0, 0)); case 1: return(W.A.MinkowskiPoint); case 2: return(W.A.MinkowskiPoint - (((d * W.A.MinkowskiPoint) / (d * d)) * d)); case 3: { Vector3 W1 = new Vector3((float)W.A.MinkowskiPoint.X, (float)W.A.MinkowskiPoint.Y, 0); Vector3 W2 = new Vector3((float)W.B.MinkowskiPoint.X, (float)W.B.MinkowskiPoint.Y, 0); Vector3 W3 = new Vector3((float)W.C.MinkowskiPoint.X, (float)W.C.MinkowskiPoint.Y, 0); Vector3 n = Vector3.Cross((W2 - W1), (W3 - W1)); Vector3 result = Vector3.Multiply(((Vector3.Multiply(n, W1)) / (Vector3.Multiply(n, n))), n); return(new Vector(result.X, result.Y)); } } return(new Vector(0, 0)); }
public MeshNormalsFallback(Schema2.Mesh mesh) { foreach (var srcPrim in mesh.Primitives) { var accessor = srcPrim.GetVertexAccessor("POSITION"); if (accessor == null) { continue; } var positions = accessor.AsVector3Array(); foreach (var srcTri in srcPrim.GetTriangleIndices()) { var a = positions[srcTri.A]; var b = positions[srcTri.B]; var c = positions[srcTri.C]; var d = XYZ.Cross(b - a, c - a); AddWeightedNormal(a, d); AddWeightedNormal(b, d); AddWeightedNormal(c, d); } } }
public override RayCastResult Intersection(Ray ray, float nowbest) { if (ray.OriginObject == this) { return(null); } { (bool happened, Float mint) = BoundBox.Intersection(ray); if (!happened || mint > nowbest) // 未相交 或 当前最小解已不是最优 { return(null); } } Float u, v, t_tmp = 0; Vector3f pvec = Vector3f.Cross(ray.Direction, e2); // S1 Float det = Vector3f.Dot(e1, pvec); Float det_inv = 1.0f / det; Vector3f tvec = ray.Origin - v0; // S u = Vector3f.Dot(tvec, pvec) * det_inv; if (u < 0 || u > 1) { return(null); } Vector3f qvec = Vector3f.Cross(tvec, e1); // S2 v = Vector3f.Dot(ray.Direction, qvec) * det_inv; if (v < 0 || u + v > 1) { return(null); } t_tmp = Vector3f.Dot(e2, qvec) * det_inv; if (t_tmp < 0) { return(null); } RayCastResult result = new RayCastResult(); result.distance = t_tmp; result.obj = this; result.coords = ray.Origin + t_tmp * ray.Direction; result.uv = new Vector2f(u, v); result.normal = Tools.UVMerge(u, v, n0, n1, n2); result.internalPoint = (Vector3f.Dot(result.normal, ray.Direction) > 0); if (result.internalPoint) { result.normal = -result.normal; } return(result); }
/** * Gets the face normal * * @return face normal */ public Vector3d getNormal() { Point3d p1 = v1.getPosition(); Point3d p2 = v2.getPosition(); Point3d p3 = v3.getPosition(); Vector3d xy, xz, normal; xy = new Vector3d(p2.X - p1.X, p2.Y - p1.Y, p2.Z - p1.Z); xz = new Vector3d(p3.X - p1.X, p3.Y - p1.Y, p3.Z - p1.Z); /*normal = new Vector3d(); * normal.cross(xy, xz); * normal.normalize();*/ normal = Vector3d.Normalize(Vector3d.Cross(xy, xz)); return(normal); }
private static IFlowField GenerateFlowField() { var f = new SimpleFlowField(50, 1, 50, new Vector3(25, 0.5f, 25)); //Start random f.Randomize(1); //Swirl around center //Half the field is a swirl (basically just concentric circles) while the other half has a slight bias to spiral inwards towards the center f.Func(pos => Vector3.Lerp(pos / 5, Vector3.Normalize(Vector3.Cross(pos, Vector3.UnitY)), pos.X > 0.5f ? 0.75f : 0.9f), 0.85f); //Keep it flat on the plane f.ClampXZ(); //Clean NaN values f.Clean(); return(f); }
//----------------------------------CONSTRUCTORS---------------------------------// /** * Constructor for a line. The line created is the intersection between two planes * * @param face1 face representing one of the planes * @param face2 face representing one of the planes */ public Line(Face face1, Face face2) { Vector3d normalFace1 = face1.getNormal(); Vector3d normalFace2 = face2.getNormal(); //direction: cross product of the faces normals //direction = new Vector3d(); //direction.cross(normalFace1, normalFace2); direction = Vector3d.Cross(normalFace1, normalFace2); //if direction lenght is not zero (the planes aren't parallel )... if (!(direction.Length() < TOL)) { //getting a line point, zero is set to a coordinate whose direction //component isn't zero (line intersecting its origin plan) point = new Point3d(); float d1 = -(normalFace1.X * face1.v1.X + normalFace1.Y * face1.v1.Y + normalFace1.Z * face1.v1.Z); float d2 = -(normalFace2.X * face2.v1.X + normalFace2.Y * face2.v1.Y + normalFace2.Z * face2.v1.Z); if (Math.Abs(direction.X) > TOL) { point.X = 0; point.Y = (d2 * normalFace1.Z - d1 * normalFace2.Z) / direction.X; point.Z = (d1 * normalFace2.Y - d2 * normalFace1.Y) / direction.X; } else if (Math.Abs(direction.Y) > TOL) { point.X = (d1 * normalFace2.Z - d2 * normalFace1.Z) / direction.Y; point.Y = 0; point.Z = (d2 * normalFace1.X - d1 * normalFace2.X) / direction.Y; } else { point.X = (d2 * normalFace1.Y - d1 * normalFace2.Y) / direction.Z; point.Y = (d1 * normalFace2.X - d2 * normalFace1.X) / direction.Z; point.Z = 0; } } direction = Vector3d.Normalize(direction); }
public override void Initialize() { Vector3 v1 = Helper.GetPerpendicularVector(normal); Vector3 v2 = Vector3.Cross(v1, normal); v1 *= 0.5f; v2 *= 0.5f; vertices = new Vector3[] // Position | Normal { -v1 - v2, normal, -v1 + v2, normal, v1 - v2, normal, v1 + v2, normal, }; indices = new uint[] { 0, 2, 1, 2, 3, 1 }; vertexArray = GL.GenVertexArray(); GL.BindVertexArray(vertexArray); vertexBuffer = GL.GenBuffer(); GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer); GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * sizeof(float) * 3, vertices, BufferUsageHint.StaticDraw); GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 0); GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 3 * sizeof(float)); GL.EnableVertexAttribArray(0); GL.EnableVertexAttribArray(1); elementBuffer = GL.GenBuffer(); GL.BindBuffer(BufferTarget.ElementArrayBuffer, elementBuffer); GL.BufferData(BufferTarget.ElementArrayBuffer, indices.Length * sizeof(uint), indices, BufferUsageHint.StaticDraw); UpdateTransformMatrix(); }
virtual public Transform Step(double time, LocationOptions options) { Clamp(options); var up = new Vector3(normal.x, normal.y, -normal.z); Vector3 east = new Vector3(local_orientation.v11, local_orientation.v21, local_orientation.v31);; Vector3 north; if (options.RotationOptions.HasFlag(RotationOptions.AlignToSurface)) { east = Vector3.Normalize(east - (Vector3.Dot(east, up) * up)); north = Vector3.Cross(east, up); } else { north = new Vector3(-local_orientation.v12, -local_orientation.v22, -local_orientation.v32); } var m = new Matrix4x4(east.X, east.Y, east.Z, 0, up.X, up.Y, up.Z, 0, north.X, north.Y, north.Z, 0, 0, 0, 0, 1); var qm = Quaternion.CreateFromRotationMatrix(m); var r = qm * Rotation; return(new Transform { Pos = { X = (float)position.x, Y = (float)position.y, Z = (float)position.z }, Rot = r }); }
/// <summary> /// Form new simplex and test in which external Voronoi region the origin lies. /// </summary> /// <param name="W">Simplex</param> /// <param name="w">New point in CSO surface</param> /// <returns>New smallest simplex <paramref name="W"/> containing <paramref name="w"/> and closest point to origin.</returns> public Simplex BestSimplex(Simplex W, ShapePoint w) { Simplex result = new Simplex(); switch (W.count) { case 0: { result.A = w; result.count = 1; break; } case 1: { Simplex line = new Simplex(); line.A = w; line.B = W.A; line.count = 2; Vector closest = ClosestToSegment(new Vector(0, 0), w.MinkowskiPoint, W.A.MinkowskiPoint); if (closest == w.MinkowskiPoint) { result.A = w; result.count = 1; } else { result.A = W.A; result.B = w; result.count = 2; } break; } case 2: { Vector d = new Vector(0, 0) - w.MinkowskiPoint; // d.negate(); AO = O - A; O = origin (0, 0) Vector e1 = W.A.MinkowskiPoint - w.MinkowskiPoint; // AB = B - A Vector e2 = W.B.MinkowskiPoint - w.MinkowskiPoint; Vector3 e1_3D = new Vector3((float)e1.X, (float)e1.Y, 0); Vector3 e2_3D = new Vector3((float)e2.X, (float)e2.Y, 0); Vector3 u1 = Vector3.Cross(e1_3D, Vector3.Cross(e1_3D, e2_3D)); Vector3 v1 = Vector3.Cross(Vector3.Cross(e1_3D, e2_3D), e2_3D); if (Vector.Multiply(d, e1) < 0 && Vector.Multiply(d, e2) < 0) { result.A = w; result.count = 1; } else if (Vector.Multiply(d, e1) > 0 && (d.X * u1.X + d.Y * u1.Y + 0 * u1.Z) > 0) { result.A = W.A; result.B = w; result.count = 2; } else if (Vector.Multiply(d, e2) > 0 && (d.X * v1.X + d.Y * v1.Y + 0 * v1.Z) > 0) { result.A = W.B; result.B = w; result.count = 2; } else if ((d.X * u1.X + d.Y * u1.Y + 0 * u1.Z < 0) && (d.X * v1.X + d.Y * v1.Y + 0 * v1.Z < 0)) { result.A = W.A; result.B = W.B; result.C = w; result.count = 3; } else { result = W; } break; } } return(result); }
public static MashTrigle[] LoadModel(string filePath, bool negativeZ = false) { string[] lines = File.ReadAllLines(filePath); List <MashTrigle> mashes = new List <MashTrigle>(); List <Vector3f> v = new List <Vector3f>() { new Vector3f() }; Dictionary <int, List <PW_Trigle> > faceList = new Dictionary <int, List <PW_Trigle> >(); List <Vector2f> vt = new List <Vector2f>() { new Vector2f() }; List <Vector3f> vn = new List <Vector3f>() { new Vector3f() }; MashTrigle nobj = null; List <PW_Trigle> trigles = new List <PW_Trigle>(); for (int linecount = 0; linecount < lines.Length; linecount++) { string line = lines[linecount]; if (string.IsNullOrWhiteSpace(line) || line.StartsWith('#')) { continue; } float p0 = 0.0f, p1 = 0.0f, p2 = 0.0f; string[] parts = line.Split(LineSplitChars, StringSplitOptions.RemoveEmptyEntries); switch (parts[0].ToLower()) { case "v": #region v if (parts.Length != 4) { throw new Exception($"line {linecount} : 缺少参数的行,请求3个,实际为{parts.Length - 1}个"); } if (!Float.TryParse(parts[1], out p0)) { throw new Exception($"line {linecount} : 不能转换的数据 {parts[1]}"); } if (!Float.TryParse(parts[2], out p1)) { throw new Exception($"line {linecount} : 不能转换的数据 {parts[2]}"); } if (!Float.TryParse(parts[3], out p2)) { throw new Exception($"line {linecount} : 不能转换的数据 {parts[3]}"); } if (negativeZ) { v.Add(new Vector3f(p0, p1, -p2)); } else { v.Add(new Vector3f(p0, p1, p2)); } #endregion break; case "vt": #region vt if (parts.Length != 3 && parts.Length != 4) { throw new Exception($"line {linecount} : 缺少参数的行,请求2或3个,实际为{parts.Length - 1}个"); } if (!Float.TryParse(parts[1], out p0)) { throw new Exception($"line {linecount} : 不能转换的数据 {parts[1]}"); } if (!Float.TryParse(parts[2], out p1)) { throw new Exception($"line {linecount} : 不能转换的数据 {parts[2]}"); } vt.Add(new Vector2f(p0, p1)); #endregion break; case "vn": #region vn if (parts.Length != 4) { throw new Exception($"line {linecount} : 缺少参数的行,请求3个,实际为{parts.Length - 1}个"); } if (!Float.TryParse(parts[1], out p0)) { throw new Exception($"line {linecount} : 不能转换的数据 {parts[1]}"); } if (!Float.TryParse(parts[2], out p1)) { throw new Exception($"line {linecount} : 不能转换的数据 {parts[2]}"); } if (!Float.TryParse(parts[3], out p2)) { throw new Exception($"line {linecount} : 不能转换的数据 {parts[3]}"); } if (negativeZ) { vn.Add(Vector3f.Normalize(new Vector3f(p0, p1, -p2))); } else { vn.Add(Vector3f.Normalize(new Vector3f(p0, p1, p2))); } #endregion break; case "vp": break; case "g": #region g if (trigles != null && trigles.Count > 0) { if (nobj == null) { nobj = new MashTrigle(); } nobj.SetTrigles(Smooth(trigles, v, vt, faceList)); mashes.Add(nobj); } nobj = new MashTrigle(); trigles = new List <PW_Trigle>(); #endregion break; case "f": #region f if (parts.Length < 4) { throw new Exception($"line {linecount} : 缺少参数的行,请求至少为3个,实际为{parts.Length - 1}个"); } int pointcount = parts.Length - 1; int[] vidx = new int[pointcount], vtidx = new int[pointcount], vnidx = new int[pointcount]; // 分割顶点信息 for (int i = 0; i < pointcount; i++) { string pinfo = parts[i + 1]; string[] infos = pinfo.Split(PInfoSplitChars); vidx[i] = int.Parse(infos[0]); int tmp; if (infos.Length > 1 && int.TryParse(infos[1], out tmp)) { vtidx[i] = tmp; } else { vtidx[i] = 0; //-1; } if (infos.Length > 2 && int.TryParse(infos[1], out tmp)) { vnidx[i] = tmp; } else { vnidx[i] = 0; //-1; } } // 生成三角形面 for (int i = 2; i < pointcount; i++) { PW_Trigle face = new PW_Trigle(); face.v0 = vidx[0]; face.v1 = vidx[i - 1]; face.v2 = vidx[i]; { //normal Vector3f e1 = v[face.v1] - v[face.v0], e2 = v[face.v2] - v[face.v0]; face.Normal = Vector3f.Normalize(Vector3f.Cross(e1, e2)); } { //sp //if (vtidx[0] != -1) { face.vt0 = vtidx[0]; //} //if (vtidx[i - 1] != -1) { face.vt1 = vtidx[i - 1]; //} //if (vtidx[i] != -1) { face.vt2 = vtidx[i]; //} } trigles.Add(face); if (!faceList.ContainsKey(face.v0)) { faceList[face.v0] = new List <PW_Trigle>(); } faceList[face.v0].Add(face); if (!faceList.ContainsKey(face.v1)) { faceList[face.v1] = new List <PW_Trigle>(); } faceList[face.v1].Add(face); if (!faceList.ContainsKey(face.v2)) { faceList[face.v2] = new List <PW_Trigle>(); } faceList[face.v2].Add(face); } #endregion break; } } if (trigles != null && trigles.Count > 0) { if (nobj == null) { nobj = new MashTrigle(); } nobj.SetTrigles(Smooth(trigles, v, vt, faceList)); mashes.Add(nobj); } return(mashes.ToArray()); }
private void CreateGeometry() { // Create box Geometry box = new Geometry(OptixContext); box.PrimitiveCount = 1; box.BoundingBoxProgram = new OptixProgram(OptixContext, boxPath, "box_bounds");; box.IntersectionProgram = new OptixProgram(OptixContext, boxPath, "box_intersect");; box["boxmin"].Set(-2.0f, 0.0f, -2.0f); box["boxmax"].Set(2.0f, 7.0f, 2.0f); Geometry chull = null; if (mTutorial >= 9) { chull = new Geometry(OptixContext); chull.PrimitiveCount = 1u; chull.BoundingBoxProgram = new OptixProgram(OptixContext, shaderPath, "chull_bounds"); chull.IntersectionProgram = new OptixProgram(OptixContext, shaderPath, "chull_intersect"); uint nsides = 6; float radius = 1; Vector3 xlate = new Vector3(-1.4f, 0, -3.7f); BufferDesc desc = new BufferDesc() { Width = nsides + 2u, Type = BufferType.Input, Format = Format.Float4 }; Buffer chullBuffer = new Buffer(OptixContext, desc); float angle = 0.0f; BufferStream stream = chullBuffer.Map(); for (uint i = 0; i < nsides; i++) { angle = (float)i / (float)nsides * (float)Math.PI * 2.0f; float x = (float)Math.Cos(angle); float y = (float)Math.Sin(angle); stream.Write <Vector4>(Utils.CreatePlane(new Vector3(x, 0, y), new Vector3(x * radius, 0, y * radius) + xlate)); } float min = 0.02f; float max = 3.5f; angle = 5.0f / (float)nsides * (float)Math.PI * 2.0f; stream.Write <Vector4>(Utils.CreatePlane(new Vector3(0, -1, 0), new Vector3(0, min, 0) + xlate)); stream.Write <Vector4>(Utils.CreatePlane(new Vector3((float)Math.Cos(angle), 0.7f, (float)Math.Sin(angle)), new Vector3(0, max, 0) + xlate)); chullBuffer.Unmap(); chull["planes"].Set(chullBuffer); chull["chull_bbmin"].Set(-radius + xlate.X, min + xlate.Y, -radius + xlate.Z); chull["chull_bbmax"].Set(radius + xlate.X, max + xlate.Y, radius + xlate.Z); } // Floor geometry Geometry parallelogram = new Geometry(OptixContext); parallelogram.PrimitiveCount = 1; parallelogram.BoundingBoxProgram = new OptixProgram(OptixContext, parrallelPath, "bounds");; parallelogram.IntersectionProgram = new OptixProgram(OptixContext, parrallelPath, "intersect");; Vector3 anchor = new Vector3(-64.0f, 0.01f, -64.0f); Vector3 v1 = new Vector3(128.0f, 0.0f, 0.0f); Vector3 v2 = new Vector3(0.0f, 0.0f, 128.0f); Vector3 normal = Vector3.Normalize(Vector3.Cross(v2, v1)); v1 *= 1.0f / (v1.LengthSquared()); v2 *= 1.0f / (v2.LengthSquared()); float d = Vector3.Dot(normal, anchor); Vector4 plane = new Vector4(normal, d); parallelogram["plane"].Set(ref plane); parallelogram["v1"].Set(ref v1); parallelogram["v2"].Set(ref v2); parallelogram["anchor"].Set(ref anchor); string boxMtrlName = mTutorial >= 8 ? "box_closest_hit_radiance" : "closest_hit_radiance"; string floorMtrlName = mTutorial >= 4 ? "floor_closest_hit_radiance" : "closest_hit_radiance"; Material boxMtrl = new Material(OptixContext); boxMtrl.SetSurfaceProgram(0, new SurfaceProgram(OptixContext, RayHitType.Closest, shaderPath, boxMtrlName)); if (mTutorial >= 3) { boxMtrl.SetSurfaceProgram(1, new SurfaceProgram(OptixContext, RayHitType.Any, shaderPath, "any_hit_shadow")); } boxMtrl["Ka"].Set(0.3f, 0.3f, 0.3f); boxMtrl["Kd"].Set(0.6f, 0.7f, 0.8f); boxMtrl["Ks"].Set(0.8f, 0.9f, 0.8f); boxMtrl["phong_exp"].Set(88.0f); boxMtrl["reflectivity_n"].Set(0.2f, 0.2f, 0.2f); Material floorMtrl = new Material(OptixContext); floorMtrl.SetSurfaceProgram(0, new SurfaceProgram(OptixContext, RayHitType.Closest, shaderPath, floorMtrlName)); if (mTutorial >= 3) { floorMtrl.SetSurfaceProgram(1, new SurfaceProgram(OptixContext, RayHitType.Any, shaderPath, "any_hit_shadow")); } floorMtrl["Ka"].Set(0.3f, 0.3f, 0.1f); floorMtrl["Kd"].Set(194 / 255.0f * .6f, 186 / 255.0f * .6f, 151 / 255.0f * .6f); floorMtrl["Ks"].Set(0.4f, 0.4f, 0.4f); floorMtrl["reflectivity"].Set(0.1f, 0.1f, 0.1f); floorMtrl["reflectivity_n"].Set(0.05f, 0.05f, 0.05f); floorMtrl["phong_exp"].Set(88.0f); floorMtrl["tile_v0"].Set(0.25f, 0, .15f); floorMtrl["tile_v1"].Set(-.15f, 0, 0.25f); floorMtrl["crack_color"].Set(0.1f, 0.1f, 0.1f); floorMtrl["crack_width"].Set(0.02f); Material glassMtrl = null; if (chull != null) { glassMtrl = new Material(OptixContext); glassMtrl.SetSurfaceProgram(0, new SurfaceProgram(OptixContext, RayHitType.Closest, shaderPath, "glass_closest_hit_radiance")); glassMtrl.SetSurfaceProgram(1, new SurfaceProgram(OptixContext, RayHitType.Any, shaderPath, mTutorial > 9 ? "glass_any_hit_shadow" : "any_hit_shadow")); Vector3 extinction = new Vector3(.80f, .89f, .75f); glassMtrl["importance_cutoff"].Set(1e-2f); glassMtrl["cutoff_color"].Set(0.34f, 0.55f, 0.85f); glassMtrl["fresnel_exponent"].Set(3.0f); glassMtrl["fresnel_minimum"].Set(0.1f); glassMtrl["fresnel_maximum"].Set(1.0f); glassMtrl["refraction_index"].Set(1.4f); glassMtrl["refraction_color"].Set(1.0f, 1.0f, 1.0f); glassMtrl["reflection_color"].Set(1.0f, 1.0f, 1.0f); glassMtrl["refraction_maxdepth"].Set(100); glassMtrl["reflection_maxdepth"].Set(100); glassMtrl["extinction_constant"].Set((float)Math.Log(extinction.X), (float)Math.Log(extinction.Y), (float)Math.Log(extinction.Z)); glassMtrl["shadow_attenuation"].Set(0.4f, 0.7f, 0.4f); } GeometryInstance boxInst = new GeometryInstance(OptixContext); boxInst.Geometry = box; boxInst.AddMaterial(boxMtrl); GeometryInstance parallelInst = new GeometryInstance(OptixContext); parallelInst.Geometry = parallelogram; parallelInst.AddMaterial(floorMtrl); GeometryGroup group = new GeometryGroup(OptixContext); group.AddChild(boxInst); group.AddChild(parallelInst); if (chull != null) { GeometryInstance chullInst = new GeometryInstance(OptixContext); chullInst.Geometry = chull; chullInst.AddMaterial(glassMtrl); group.AddChild(chullInst); } group.Acceleration = new Acceleration(OptixContext, AccelBuilder.Bvh, AccelTraverser.Bvh); OptixContext["top_object"].Set(group); OptixContext["top_shadower"].Set(group); }
public override void Initialize() { //Vector3 v1 = Helper.GetPerpendicularVector(normal); //Vector3 v2 = Vector3.Cross(v1, normal); //v1 *= 0.5f; //v2 *= 0.5f; //vertices = new Vector3[] // Position | Normal //{ // -v1 - v2, normal, // -v1 + v2, normal, // v1 - v2, normal, // v1 + v2, normal, //}; // //indices = new uint[] //{ // 0, 2, 1, // 2, 3, 1 //}; List <Vector3> vertexList = new List <Vector3>(); List <uint> triangleList = new List <uint>(); void AddTriangle(uint a, uint b, uint c) { triangleList.Add(a); triangleList.Add(b); triangleList.Add(c); } Vector3 v1 = Helper.GetPerpendicularVector(normal); Vector3 v2 = Vector3.Cross(v1, normal); vertexList.Add(new Vector3(0f, 0f, 0f)); for (int i = 0; i < steps; ++i) { float angle = ((float)i / steps) * MathF.PI * 2f; vertexList.Add(v1 * MathF.Cos(angle) + v2 * MathF.Sin(angle)); } for (uint i = 1; i < steps - 1; ++i) { AddTriangle(0, i, i + 1); } AddTriangle(0, steps - 1, 1); // Add normals to vertex list for (int i = vertexList.Count - 1; i >= 0; --i) { Vector3 vert = vertexList[i]; vertexList.Insert(i + 1, normal); } vertices = vertexList.ToArray(); indices = triangleList.ToArray(); vertexArray = GL.GenVertexArray(); GL.BindVertexArray(vertexArray); vertexBuffer = GL.GenBuffer(); GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer); GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * sizeof(float) * 3, vertices, BufferUsageHint.StaticDraw); GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 0); GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 3 * sizeof(float)); GL.EnableVertexAttribArray(0); GL.EnableVertexAttribArray(1); elementBuffer = GL.GenBuffer(); GL.BindBuffer(BufferTarget.ElementArrayBuffer, elementBuffer); GL.BufferData(BufferTarget.ElementArrayBuffer, indices.Length * sizeof(uint), indices, BufferUsageHint.StaticDraw); UpdateTransformMatrix(); }