// ( v -- v' ) public override void Execute(Interpreter interp) { dynamic v = interp.StackPop(); Vector4Item result = new Vector4Item(Vector4.Normalize(v.Vector4Value)); interp.StackPush(result); }
// ( Canvas color -- ) public override void Execute(Interpreter interp) { Vector4Item color = (Vector4Item)interp.StackPop(); CanvasItem canvas = (CanvasItem)interp.StackPop(); canvas.ClearPixels(color.Vector4Value); }
StackItem multiply(MatrixItem l, Vector4Item r) { return(new Vector4Item( Vector4.Dot(l.GetRow(0), r.Vector4Value), Vector4.Dot(l.GetRow(1), r.Vector4Value), Vector4.Dot(l.GetRow(2), r.Vector4Value), Vector4.Dot(l.GetRow(3), r.Vector4Value))); }
// ( Canvas x y color -- ) public override void Execute(Interpreter interp) { Vector4Item color = (Vector4Item)interp.StackPop(); dynamic y = interp.StackPop(); dynamic x = interp.StackPop(); CanvasItem canvas = (CanvasItem)interp.StackPop(); canvas.WritePixel(x.IntValue, y.IntValue, color.Vector4Value); }
StackItem multiply(MatrixItem l, RayItem r) { Vector4Item origin = new Vector4Item(r.Origin); Vector4Item direction = new Vector4Item(r.Direction); Vector4Item newOrigin = (Vector4Item)multiply(l, origin); Vector4Item newDirection = (Vector4Item)multiply(l, direction); return(new RayItem(newOrigin.Vector4Value, newDirection.Vector4Value)); }
public bool ApproxEqual(dynamic rhs, double tolerance) { Vector4Item r = (Vector4Item)rhs; Vector4 l_val = this.Vector4Value; Vector4 r_val = r.Vector4Value; bool result = Math.Abs(l_val.X - r_val.X) < tolerance && Math.Abs(l_val.Y - r_val.Y) < tolerance && Math.Abs(l_val.Z - r_val.Z) < tolerance && Math.Abs(l_val.W - r_val.W) < tolerance; return(result); }
// ( v1 v2 -- v ) public override void Execute(Interpreter interp) { dynamic v2 = interp.StackPop(); dynamic v1 = interp.StackPop(); Vector4 a = v1.Vector4Value; Vector4 b = v2.Vector4Value; Vector4Item result = new Vector4Item( a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X, 0); interp.StackPush(result); }
void normal_at(Interpreter interp, SphereItem s, Vector4Item p) { // ( -- object_point ) interp.StackPush(s); interp.Run("'transform' REC@ INVERSE"); interp.StackPush(p); interp.Run("*"); // ( object_point -- object_normal ) interp.Run("0 0 0 Point -"); // ( object_normal -- world_normal ) interp.StackPush(s); interp.Run("'transform' REC@ INVERSE TRANSPOSE SWAP * 0 'W' <REC! NORMALIZE"); }
// ( world point -- bool ) public override void Execute(Interpreter interp) { Vector4Item point = (Vector4Item)interp.StackPop(); WorldItem world = (WorldItem)interp.StackPop(); interp.StackPush(world.PointLight.GetValue("position")); interp.StackPush(point); interp.Run("- DUP MAGNITUDE SWAP NORMALIZE"); dynamic direction = interp.StackPop(); dynamic distance = interp.StackPop(); interp.StackPush(world); interp.StackPush(point); interp.StackPush(direction); interp.Run("Ray INTERSECT-WORLD HIT"); dynamic h = interp.StackPop(); interp.StackPush(get_result(h, distance)); }
ArrayItem intersections(Interpreter interp, SphereItem sphere, RayItem ray) { // Compute sphere_to_ray interp.StackPush(ray); interp.Run("'origin' REC@ 0 0 0 Point -"); Vector4Item sphere_to_ray = (Vector4Item)interp.StackPop(); // Compute a interp.StackPush(ray); interp.Run("'direction' REC@ DUP DOT"); DoubleItem a = (DoubleItem)interp.StackPop(); // Compute b interp.StackPush(sphere_to_ray); interp.StackPush(ray); interp.Run("'direction' REC@ DOT 2 *"); DoubleItem b = (DoubleItem)interp.StackPop(); // Compute c interp.StackPush(sphere_to_ray); interp.Run("DUP DOT 1 -"); DoubleItem c = (DoubleItem)interp.StackPop(); float discriminant = b.FloatValue * b.FloatValue - 4.0f * a.FloatValue * c.FloatValue; ArrayItem result = new ArrayItem(); if (discriminant < 0) { return(result); } else { double t1 = (-b.FloatValue - Math.Sqrt(discriminant)) / 2.0f / a.FloatValue; double t2 = (-b.FloatValue + Math.Sqrt(discriminant)) / 2.0f / a.FloatValue; result.Add(new IntersectionItem(t1, sphere)); result.Add(new IntersectionItem(t2, sphere)); return(result); } }
StackItem divide(Vector4Item l, ScalarItem r) { return(new Vector4Item(Vector4.Divide(l.Vector4Value, r.FloatValue))); }
public bool IsEqual(dynamic rhs) { Vector4Item r = (Vector4Item)rhs; return(this.Vector4Value == r.Vector4Value); }
// ( material light point eyev normalv in_shadow -- lighting ) public override void Execute(Interpreter interp) { dynamic in_shadow = interp.StackPop(); dynamic normalv = interp.StackPop(); dynamic eyev = interp.StackPop(); dynamic point = interp.StackPop(); dynamic light = interp.StackPop(); dynamic material = interp.StackPop(); // Effective color interp.StackPush(material); interp.StackPush(light); interp.Run("'intensity' REC@ SWAP 'color' REC@ *"); dynamic effective_color = interp.StackPop(); // lightv interp.StackPush(point); interp.StackPush(light); interp.Run("'position' REC@ SWAP - NORMALIZE"); dynamic lightv = interp.StackPop(); // Ambient contribution interp.StackPush(effective_color); interp.StackPush(material); interp.Run("'ambient' REC@ *"); dynamic ambient = interp.StackPop(); // light_dot_normal interp.StackPush(lightv); interp.StackPush(normalv); interp.Run("DOT"); dynamic light_dot_normal = interp.StackPop(); // black interp.Run("0 0 0 Color"); Vector4Item black = (Vector4Item)interp.StackPop(); Vector4Item diffuse = black; Vector4Item specular = black; if (light_dot_normal.FloatValue > 0) { // Compute diffuse interp.StackPush(effective_color); interp.StackPush(light_dot_normal); interp.StackPush(material); interp.Run("'diffuse' REC@ * *"); diffuse = (Vector4Item)interp.StackPop(); // reflect_dot_eye interp.StackPush(eyev); interp.StackPush(normalv); interp.StackPush(lightv); interp.Run("NEGATE SWAP REFLECT DOT"); dynamic reflect_dot_eye = interp.StackPop(); if (reflect_dot_eye.FloatValue <= 0) { specular = black; } else { // Compute specular contribution interp.StackPush(reflect_dot_eye); interp.StackPush(material); interp.Run("'shininess' REC@ POW"); // factor interp.StackPush(light); interp.StackPush(material); interp.Run("'specular' REC@ SWAP 'intensity' REC@ * *"); specular = (Vector4Item)interp.StackPop(); } } // Compute result if (in_shadow.BoolValue) { interp.StackPush(ambient); } else { interp.StackPush(ambient); interp.StackPush(diffuse); interp.StackPush(specular); interp.Run("+ +"); } }
StackItem plus(Vector4Item l, Vector4Item r) { return(new Vector4Item(l.Vector4Value + r.Vector4Value)); }
StackItem minus(Vector4Item l, Vector4Item r) { return(new Vector4Item(l.Vector4Value - r.Vector4Value)); }
StackItem negate(Vector4Item item) { return(new Vector4Item(Vector4.Negate(item.Vector4Value))); }
// Multiply options StackItem multiply(Vector4Item l, ScalarItem r) { return(new Vector4Item(Vector4.Multiply(r.FloatValue, l.Vector4Value))); }
StackItem multiply(ScalarItem l, Vector4Item r) { return(multiply(r, l)); }
// Hadamard multiplication StackItem multiply(Vector4Item l, Vector4Item r) { return(new Vector4Item(l.X * r.X, l.Y * r.Y, l.Z * r.Z, l.W * r.W)); }