MEL nParticles stop rotation after collision - maya

I have a simple nParticles been created with initial orient and rotation with some expressions, and the issue is that on collision with the ground they keep on rotating. I followed a tutorial online and I don't have a lot of experience with expressions. I'm using these expressions in the creation:
nParticleShape1.InitialOrient = <<rand(360),rand(360),rand(360)>> ;
nParticleShape1.RotateFactor = <<rand(10),rand(10),rand(10)>> ;
and in the after runtime:
nParticleShape1.InitialOrient += nParticleShape1.RotateFactor ;
How can I make them stop rotating after the collision?

You can do it using a simple if-else runtime statement:
if (nParticleShape1.event >= 1) {
nParticleShape1.rotatePP = <<$x, $y, $z>> ;
//rotation at the moment of and after the collision event...
} else {
nParticleShape1.initialOrient += nParticleShape1.rotateFactor ;
} ;

Related

How do I remove a single life per collision of two 2D objects?

I am programming a game for fun and to get more familiar with C and GBA mode 3. Though, I have run into an issue.
I have these two blocks on the screen, one is the good guy, the other is the bad guy. When the good guy collides with the bad guy its supposed to remove a life. That is where the problem comes in.
I have this within a while loop that runs the game:
if (plyr_row < enemy_row + enemy_size && plyr_ row
+ plyr_size > enemy_row && plyr_col < enemy_col + enemy_size
&& plyr_size + plyr_col > enemy_col)
{
lives--;
}
The lives do go down, but a lot of lives are taken away while the player is making contact with the enemy. In other words, during contact, the lives drop really fast and I just want to remove one for each time they collide, how can I accomplish that?
You have to use a flag to remember, if a collision is currently happening or not. Something like:
int in_collision = 0; // global flag, initialized to 0 once at start
...
if (plyr_row < enemy_row + enemy_size &&
plyr_row + plyr_size > enemy_row &&
plyr_col < enemy_col + enemy_size &&
plyr_size + plyr_col > enemy_col) {
if (!in_collision) {
in_collision = 1;
lives--;
}
} else {
in_collision = 0;
}
Now, the running collision must stop before another life will be removed on the following collision.
The simplest solution is to maintain a flag IN_COLLISION. You want to remove a life when there is a collision and IN_COLLISION is false.
Then it's a matter of toggling it to true at the first collision detection and then to false when you are not colliding anymore.

Creating an If statement for an entire array

So here is my situation. I'm new to programming and I've just started making a very, very basic platform game. And I mean literally a game with platforms.
I've got my character in and jumping about and I've created my platforms as an array. This was so that I could put them all side by side at the bottom. Now there is other ways I can do this to get round the problem but I wanted to find out how to do it for an array.
So I've got my character falling with this
kirby.yVelocity += 1.0f
Which is all fine but I want his yVelocity to go to 0.0f when he hits any of the platforms in the array.
So I tried this piece of code
if (plat[i].drawRect.Intersects(kirby.drawRect))
{
kirby.yVelocity = 0.0f
}
which I thought would work but it gives me an error for the [i] saying that it isn't applicable in this context.
few notes:
kirby is my character name, drawRect is the definition for Rectangle, plat is my Platform array which consists of 13 platforms.
Thanks to anyone who can help
Update
The problem is any variation of plat.drawRect or plat[i].drawRect don't work. Here is all my code relating to the platform arrays.
struct Platform
{
public Texture2D txr;
public Rectangle drawRect;
}
Platform[] plat;
plat = new Platform[13];
for (int i = 0; i < plat.Length; i++)
{
plat[i].txr = Content.Load<Texture2D>("platform");
plat[i].drawRect = new Rectangle(i * plat[i].txr.Width, 460, plat[i].txr.Width, plat[i].txr.Height);`
}
for (int i = 0; i < plat.Length; i++)
{
spriteBatch.Draw(plat[i].txr, plat[i].drawRect, Color.White);
}
spriteBatch.End();
Seems like you have to add a for loop, to loop over the platforms. Maybe like this:
for(Platform : plat){
if (platform.drawRect.Intersects(kirby.drawRect)){
kirby.yVelocity = 0.0f;
}
}
Here, I'm assuming you're using Java and Platform is the class of your plat-array, which has class List<Platform>.

How to draw a polygon from a set of unordered points

Currently, I am using a convex hull algorithm to get the outer most points from a set of points randomly placed. What I aim to do is draw a polygon from the set of points returned by the convex hull however, when I try to draw the polygon it looks quite strange.
My question, how do I order the points so the polygon draws correctly?
Thanks.
EDIT:
Also, I have tried sorting using orderby(...).ThenBy(...) and I cant seem to get it working.
Have you tried the gift wrapping algorithm ( http://en.wikipedia.org/wiki/Gift_wrapping_algorithm)? This should return points in the correct order.
I had an issue where a random set of points were generated from which a wrapped elevation vector needed a base contour. Having read the link supplied by #user1149913 and found a sample of gift-wrapping a hull, the following is a sample of my implementation:
private static PointCollection CalculateContour (List<Point> points) {
// locate lower-leftmost point
int hull = 0;
int i;
for (i = 1 ; i < points.Count ; i++) {
if (ComparePoint(points[i], points[hull])) {
hull = i;
}
}
// wrap contour
var outIndices = new int[points.Count];
int endPt;
i = 0;
do {
outIndices[i++] = hull;
endPt = 0;
for (int j = 1 ; j < points.Count ; j++)
if (hull == endPt || IsLeft(points[hull], points[endPt], points[j]))
endPt = j;
hull = endPt;
} while (endPt != outIndices[0]);
// build countour points
var contourPoints = new PointCollection(points.Capacity);
int results = i;
for (i = 0 ; i < results ; i++)
contourPoints.Add(points[outIndices[i]]);
return contourPoints;
}
This is not a full solution but a guide in the right direction. I faced a very similar problem just recently and I found a reddit post with an answer (https://www.reddit.com/r/DnDBehindTheScreen/comments/8efeta/a_random_star_chart_generator/dxvlsyt/) suggesting to use Delaunay triangulation which basically returns a solution with all possible triangles made within the data points you have. Once you have all possible triangles, which by definition you know won't result on any overlapped lines, you can chose which lines you use which result on all nodes being connected.
I was coding my solution on python and fortunately there's lots of scientific libraries on python. I was working on a random sky chart generator which would draw constellations out of those stars. In order to get all possible triangles (and draw them, just for fun), before going into the algorithm to draw the actual constellations, all I had to do was this:
# 2D array of the coordinates of every star generated randomly before
points = list(points_dict.keys())
from scipy.spatial import Delaunay
tri = Delaunay(points)
# Draw the debug constellation with the full array of lines
debug_constellation = Constellation(quadrants = quadrants, name_display_style = config.constellation_name_display_style)
for star in available_stars:
debug_constellation.add_star(star)
for triangle in tri.simplices:
star_ids = []
for index in triangle:
star_ids.append(points_dict[points[index]].id)
debug_constellation.draw_segment(star_ids, is_closed = True)
# Code to generate the image follows below
You can see the full implementation here: fake_sky_chart_generator/fake_libs/constellation_algorithms/delaunay.py
This is the result:

Point in Polygon Algorithm

I saw the below algorithm works to check if a point is in a given polygon from this link:
int pnpoly(int nvert, float *vertx, float *verty, float testx, float testy)
{
int i, j, c = 0;
for (i = 0, j = nvert-1; i < nvert; j = i++) {
if ( ((verty[i]>testy) != (verty[j]>testy)) &&
(testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )
c = !c;
}
return c;
}
I tried this algorithm and it actually works just perfect. But sadly I cannot understand it well after spending some time trying to get the idea of it.
So if someone is able to understand this algorithm, please explain it to me a little.
Thank you.
The algorithm is ray-casting to the right. Each iteration of the loop, the test point is checked against one of the polygon's edges. The first line of the if-test succeeds if the point's y-coord is within the edge's scope. The second line checks whether the test point is to the left of the line (I think - I haven't got any scrap paper to hand to check). If that is true the line drawn rightwards from the test point crosses that edge.
By repeatedly inverting the value of c, the algorithm counts how many times the rightward line crosses the polygon. If it crosses an odd number of times, then the point is inside; if an even number, the point is outside.
I would have concerns with a) the accuracy of floating-point arithmetic, and b) the effects of having a horizontal edge, or a test point with the same y-coord as a vertex, though.
Edit 1/30/2022: I wrote this answer 9 years ago when I was in college. People in the chat conversation are indicating it's not accurate. You should probably look elsewhere. 🤷‍♂️
Chowlett is correct in every way, shape, and form.
The algorithm assumes that if your point is on the line of the polygon, then that is outside - for some cases, this is false. Changing the two '>' operators to '>=' and changing '<' to '<=' will fix that.
bool PointInPolygon(Point point, Polygon polygon) {
vector<Point> points = polygon.getPoints();
int i, j, nvert = points.size();
bool c = false;
for(i = 0, j = nvert - 1; i < nvert; j = i++) {
if( ( (points[i].y >= point.y ) != (points[j].y >= point.y) ) &&
(point.x <= (points[j].x - points[i].x) * (point.y - points[i].y) / (points[j].y - points[i].y) + points[i].x)
)
c = !c;
}
return c;
}
I changed the original code to make it a little more readable (also this uses Eigen). The algorithm is identical.
// This uses the ray-casting algorithm to decide whether the point is inside
// the given polygon. See https://en.wikipedia.org/wiki/Point_in_polygon#Ray_casting_algorithm
bool pnpoly(const Eigen::MatrixX2d &poly, float x, float y)
{
// If we never cross any lines we're inside.
bool inside = false;
// Loop through all the edges.
for (int i = 0; i < poly.rows(); ++i)
{
// i is the index of the first vertex, j is the next one.
// The original code uses a too-clever trick for this.
int j = (i + 1) % poly.rows();
// The vertices of the edge we are checking.
double xp0 = poly(i, 0);
double yp0 = poly(i, 1);
double xp1 = poly(j, 0);
double yp1 = poly(j, 1);
// Check whether the edge intersects a line from (-inf,y) to (x,y).
// First check if the line crosses the horizontal line at y in either direction.
if ((yp0 <= y) && (yp1 > y) || (yp1 <= y) && (yp0 > y))
{
// If so, get the point where it crosses that line. This is a simple solution
// to a linear equation. Note that we can't get a division by zero here -
// if yp1 == yp0 then the above if will be false.
double cross = (xp1 - xp0) * (y - yp0) / (yp1 - yp0) + xp0;
// Finally check if it crosses to the left of our test point. You could equally
// do right and it should give the same result.
if (cross < x)
inside = !inside;
}
}
return inside;
}
To expand on the "too-clever trick". We want to iterate over all adjacent vertices, like this (imagine there are 4 vertices):
i
j
0
1
1
2
2
3
3
0
My code above does it the simple obvious way - j = (i + 1) % num_vertices. However this uses integer division which is much much slower than all other operations. So if this is performance critical (e.g. in an AAA game) you want to avoid it.
The original code changes the order of iteration a bit:
i
j
0
3
1
0
2
1
3
2
This is still totally valid since we're still iterating over every vertex pair and it doesn't really matter whether you go clockwise or anticlockwise, or where you start. However now it lets us avoid the integer division. In easy-to-understand form:
int i = 0;
int j = num_vertices - 1; // 3
while (i < num_vertices) { // 4
{body}
j = i;
++i;
}
Or in very terse C style:
for (int i = 0, j = num_vertices - 1; i < num_vertices; j = i++) {
{body}
}
This might be as detailed as it might get for explaining the ray-tracing algorithm in actual code. It might not be optimized but that must always come after a complete grasp of the system.
//method to check if a Coordinate is located in a polygon
public boolean checkIsInPolygon(ArrayList<Coordinate> poly){
//this method uses the ray tracing algorithm to determine if the point is in the polygon
int nPoints=poly.size();
int j=-999;
int i=-999;
boolean locatedInPolygon=false;
for(i=0;i<(nPoints);i++){
//repeat loop for all sets of points
if(i==(nPoints-1)){
//if i is the last vertex, let j be the first vertex
j= 0;
}else{
//for all-else, let j=(i+1)th vertex
j=i+1;
}
float vertY_i= (float)poly.get(i).getY();
float vertX_i= (float)poly.get(i).getX();
float vertY_j= (float)poly.get(j).getY();
float vertX_j= (float)poly.get(j).getX();
float testX = (float)this.getX();
float testY = (float)this.getY();
// following statement checks if testPoint.Y is below Y-coord of i-th vertex
boolean belowLowY=vertY_i>testY;
// following statement checks if testPoint.Y is below Y-coord of i+1-th vertex
boolean belowHighY=vertY_j>testY;
/* following statement is true if testPoint.Y satisfies either (only one is possible)
-->(i).Y < testPoint.Y < (i+1).Y OR
-->(i).Y > testPoint.Y > (i+1).Y
(Note)
Both of the conditions indicate that a point is located within the edges of the Y-th coordinate
of the (i)-th and the (i+1)- th vertices of the polygon. If neither of the above
conditions is satisfied, then it is assured that a semi-infinite horizontal line draw
to the right from the testpoint will NOT cross the line that connects vertices i and i+1
of the polygon
*/
boolean withinYsEdges= belowLowY != belowHighY;
if( withinYsEdges){
// this is the slope of the line that connects vertices i and i+1 of the polygon
float slopeOfLine = ( vertX_j-vertX_i )/ (vertY_j-vertY_i) ;
// this looks up the x-coord of a point lying on the above line, given its y-coord
float pointOnLine = ( slopeOfLine* (testY - vertY_i) )+vertX_i;
//checks to see if x-coord of testPoint is smaller than the point on the line with the same y-coord
boolean isLeftToLine= testX < pointOnLine;
if(isLeftToLine){
//this statement changes true to false (and vice-versa)
locatedInPolygon= !locatedInPolygon;
}//end if (isLeftToLine)
}//end if (withinYsEdges
}
return locatedInPolygon;
}
Just one word about optimization: It isn't true that the shortest (and/or the tersest) code is the fastest implemented. It is a much faster process to read and store an element from an array and use it (possibly) many times within the execution of the block of code than to access the array each time it is required. This is especially significant if the array is extremely large. In my opinion, by storing each term of an array in a well-named variable, it is also easier to assess its purpose and thus form a much more readable code. Just my two cents...
The algorithm is stripped down to the most necessary elements. After it was developed and tested all unnecessary stuff has been removed. As result you can't undertand it easily but it does the job and also in very good performance.
I took the liberty to translate it to ActionScript-3:
// not optimized yet (nvert could be left out)
public static function pnpoly(nvert: int, vertx: Array, verty: Array, x: Number, y: Number): Boolean
{
var i: int, j: int;
var c: Boolean = false;
for (i = 0, j = nvert - 1; i < nvert; j = i++)
{
if (((verty[i] > y) != (verty[j] > y)) && (x < (vertx[j] - vertx[i]) * (y - verty[i]) / (verty[j] - verty[i]) + vertx[i]))
c = !c;
}
return c;
}
This algorithm works in any closed polygon as long as the polygon's sides don't cross. Triangle, pentagon, square, even a very curvy piecewise-linear rubber band that doesn't cross itself.
1) Define your polygon as a directed group of vectors. By this it is meant that every side of the polygon is described by a vector that goes from vertex an to vertex an+1. The vectors are so directed so that the head of one touches the tail of the next until the last vector touches the tail of the first.
2) Select the point to test inside or outside of the polygon.
3) For each vector Vn along the perimeter of the polygon find vector Dn that starts on the test point and ends at the tail of Vn. Calculate the vector Cn defined as DnXVn/DN*VN (X indicates cross product; * indicates dot product). Call the magnitude of Cn by the name Mn.
4) Add all Mn and call this quantity K.
5) If K is zero, the point is outside the polygon.
6) If K is not zero, the point is inside the polygon.
Theoretically, a point lying ON the edge of the polygon will produce an undefined result.
The geometrical meaning of K is the total angle that the flea sitting on our test point "saw" the ant walking at the edge of the polygon walk to the left minus the angle walked to the right. In a closed circuit, the ant ends where it started.
Outside of the polygon, regardless of location, the answer is zero.
Inside of the polygon, regardless of location, the answer is "one time around the point".
This method check whether the ray from the point (testx, testy) to O (0,0) cut the sides of the polygon or not .
There's a well-known conclusion here: if a ray from 1 point and cut the sides of a polygon for a odd time, that point will belong to the polygon, otherwise that point will be outside the polygon.
To expand on #chowlette's answer where the second line checks if the point is to the left of the line,
No derivation is given but this is what I worked out:
First it helps to imagine 2 basic cases:
the point is left of the line . / or
the point is right of the line / .
If our point were to shoot a ray out horizontally where would it strike the line segment. Is our point to the left or right of it? Inside or out? We know its y coordinate because it's by definition the same as the point. What would the x coordinate be?
Take your traditional line formula y = mx + b. m is the rise over the run. Here, instead we are trying to find the x coordinate of the point on that line segment that has the same height (y) as our point.
So we solve for x: x = (y - b)/m. m is rise over run, so this becomes run over rise or (yj - yi)/(xj - xi) becomes (xj - xi)/(yj - yi). b is the offset from origin. If we assume yi as the base for our coordinate system, b becomes yi. Our point testy is our input, subtracting yi turns the whole formula into an offset from yi.
We now have (xj - xi)/(yj - yi) or 1/m times y or (testy - yi): (xj - xi)(testy - yi)/(yj - yi) but testx isn't based to yi so we add it back in order to compare the two ( or zero testx as well )
I think the basic idea is to calculate vectors from the point, one per edge of the polygon. If vector crosses one edge, then the point is within the polygon. By concave polygons if it crosses an odd number of edges it is inside as well (disclaimer: although not sure if it works for all concave polygons).
This is the algorithm I use, but I added a bit of preprocessing trickery to speed it up. My polygons have ~1000 edges and they don't change, but I need to look up whether the cursor is inside one on every mouse move.
I basically split the height of the bounding rectangle to equal length intervals and for each of these intervals I compile the list of edges that lie within/intersect with it.
When I need to look up a point, I can calculate - in O(1) time - which interval it is in and then I only need to test those edges that are in the interval's list.
I used 256 intervals and this reduced the number of edges I need to test to 2-10 instead of ~1000.
Here's a php implementation of this:
<?php
class Point2D {
public $x;
public $y;
function __construct($x, $y) {
$this->x = $x;
$this->y = $y;
}
function x() {
return $this->x;
}
function y() {
return $this->y;
}
}
class Point {
protected $vertices;
function __construct($vertices) {
$this->vertices = $vertices;
}
//Determines if the specified point is within the polygon.
function pointInPolygon($point) {
/* #var $point Point2D */
$poly_vertices = $this->vertices;
$num_of_vertices = count($poly_vertices);
$edge_error = 1.192092896e-07;
$r = false;
for ($i = 0, $j = $num_of_vertices - 1; $i < $num_of_vertices; $j = $i++) {
/* #var $current_vertex_i Point2D */
/* #var $current_vertex_j Point2D */
$current_vertex_i = $poly_vertices[$i];
$current_vertex_j = $poly_vertices[$j];
if (abs($current_vertex_i->y - $current_vertex_j->y) <= $edge_error && abs($current_vertex_j->y - $point->y) <= $edge_error && ($current_vertex_i->x >= $point->x) != ($current_vertex_j->x >= $point->x)) {
return true;
}
if ($current_vertex_i->y > $point->y != $current_vertex_j->y > $point->y) {
$c = ($current_vertex_j->x - $current_vertex_i->x) * ($point->y - $current_vertex_i->y) / ($current_vertex_j->y - $current_vertex_i->y) + $current_vertex_i->x;
if (abs($point->x - $c) <= $edge_error) {
return true;
}
if ($point->x < $c) {
$r = !$r;
}
}
}
return $r;
}
Test Run:
<?php
$vertices = array();
array_push($vertices, new Point2D(120, 40));
array_push($vertices, new Point2D(260, 40));
array_push($vertices, new Point2D(45, 170));
array_push($vertices, new Point2D(335, 170));
array_push($vertices, new Point2D(120, 300));
array_push($vertices, new Point2D(260, 300));
$Point = new Point($vertices);
$point_to_find = new Point2D(190, 170);
$isPointInPolygon = $Point->pointInPolygon($point_to_find);
echo $isPointInPolygon;
var_dump($isPointInPolygon);
I modified the code to check whether the point is in a polygon, including the point is on an edge.
bool point_in_polygon_check_edge(const vec<double, 2>& v, vec<double, 2> polygon[], int point_count, double edge_error = 1.192092896e-07f)
{
const static int x = 0;
const static int y = 1;
int i, j;
bool r = false;
for (i = 0, j = point_count - 1; i < point_count; j = i++)
{
const vec<double, 2>& pi = polygon[i);
const vec<double, 2>& pj = polygon[j];
if (fabs(pi[y] - pj[y]) <= edge_error && fabs(pj[y] - v[y]) <= edge_error && (pi[x] >= v[x]) != (pj[x] >= v[x]))
{
return true;
}
if ((pi[y] > v[y]) != (pj[y] > v[y]))
{
double c = (pj[x] - pi[x]) * (v[y] - pi[y]) / (pj[y] - pi[y]) + pi[x];
if (fabs(v[x] - c) <= edge_error)
{
return true;
}
if (v[x] < c)
{
r = !r;
}
}
}
return r;
}

Loops' iterating in ANTLR

I'm trying to make a Pascal interpreter using ANTLR and currently have some troubles with processing loops while walking the AST tree.
For example for loop is parsed as:
parametricLoop
: FOR IDENTIFIER ASSIGN start = integerExpression TO end = integerExpression DO
statement
-> ^( PARAMETRIC_LOOP IDENTIFIER $start $end statement )
;
(variant with DOWNTO is ignored).
In what way can I make walker to repeat the loop's execution so much times as needed? I know that I should use input.Mark() and input.Rewind() for that. But exactly where should they be put? My current wrong variant looks so (target language is C#):
parametricLoop
:
^(
PARAMETRIC_LOOP
IDENTIFIER
start = integerExpression
{
Variable parameter = Members.variable($IDENTIFIER.text);
parameter.value = $start.result;
}
end = integerExpression
{
int end_value = $end.result;
if ((int)parameter.value > end_value) goto EndLoop;
parametric_loop_start = input.Mark();
}
statement
{
parameter.value = (int)parameter.value + 1;
if ((int)parameter.value <= end_value)
input.Rewind(parametric_loop_start);
)
{
EndLoop: ;
}
;
(Hope everything is understandable). The condition of repeating should be checked before the statement's first execution.
I tried to play with placing Mark and Rewind in different code blocks including #init and #after, and even put trailing goto to loops head, but each time loop either iterated one time or threw exceptions like Unexpected token met, for example ':=' (assignement). I have no idea, how to make that work properly and can't find any working example. Can anybody suggest a solution of this problem?
I haven't used ANTLR, but it seems to me that you are trying to execute the program while you're parsing it, but that's not really what parsers are designed for (simple arithmetic expressions can be executed during parsing, but as you have discovered, loops are problematic). I strongly suggest that you use the parsing only to construct the AST. So the parser code for parametricLoop should only construct a tree node that represents the loop, with child nodes representing the variables, conditions and body. Afterwards, in a separate, regular C# class (to which you provide the AST generated by the parser), you execute the code by traversing the tree in some manner, and then you have complete freedom to jump back and forth between the nodes in order to simulate the loop execution.
I work with ANTLR 3.4 and I found a solution which works with Class CommonTreeNodeStream.
Basically I splitted off new instances of my tree parser, which in turn analyzed all subtrees. My sample code defines a while-loop:
tree grammar Interpreter;
...
#members
{
...
private Interpreter (CommonTree node, Map<String, Integer> symbolTable)
{
this (new CommonTreeNodeStream (node));
...
}
...
}
...
stmt : ...
| ^(WHILE c=. s1=.) // ^(WHILE cond stmt)
{
for (;;)
{
Interpreter condition = new Interpreter (c, this.symbolTable);
boolean result = condition.cond ();
if (! result)
break;
Interpreter statement = new Interpreter (s1, this.symbolTable);
statement.stmt ();
}
}
...
cond returns [boolean result]
: ^(LT e1=expr e2=expr) {$result = ($e1.value < $e2.value);}
| ...
Just solved a similar problem, several points:
Seems you need to use BufferedTreeNodeStream instead of CommonTreeNodeStream, CommonTreeNodeStream never works for me (struggled long time to find out)
Use seek seems to be more clear to me
Here's my code for a list command, pretty sure yours can be easily changed to this style:
list returns [Object r]
: ^(LIST ID
{int e_index = input.Index;}
exp=.
{int s_index = input.Index;}
statements=.
)
{
int next = input.Index;
input.Seek(e_index);
object list = expression();
foreach(object o in (IEnumerable<object>)list)
{
model[$ID.Text] = o;
input.Seek(s_index);
$r += optional_block().ToString();
}
input.Seek(next);
}

Resources