Anim8or Community
General Category => Ongoing Anim8or Development => Topic started by: Steve on February 25, 2014, 01:13:45 am
-
As of build 1070 Anim8or supports user functions in ASL. The format is like normal functions:
<type> name ( <type> ident, <type> ident, ...)
{
<statements>
}
There is a new type void for functions that don't return a value and a new statement:
return <expr>;
As usual, return statements can only appear in functions and don't have the <expr> for void functions.
OK now the restrictions:
1. No forward declarations. Function headers must be followed by the definition in the form of a compound statement "{...}".
2. No recursion. Anim8or doesn't check for self-recursion yet (a last minute bug :(). If you try it be prepared for chaos. I plan on allowing recursion but it's quite a bit of work to do efficiently so it may take a while.
3. Functions must be declared before they are called.
4. There is no "main" function yet. Any statements that aren't in a function are gathered into the "main" function, no matter where they appear. Kind of whacky, I know, but this allows you to more easily add functions to existing scripts. I'll fix this shortly by supporting a "main" structure.
5. No array parameters. All parameters and function results are the predefined types: int, string, float, point2, point3, quaternion, float4x4, shape, meshdata, spline, material, attribute, texture, object, figure, sequence, scene, and tridata.
6. All parameters are passed by value. Remember: types that represent objects within Anim8or (shape, meshdata, material, etc.) are actually handles so any changes to the parameter within a function affect the same object as outside the function. In the future I hope to add support for an out modifier to return values through parameters as well as via the function result.
7. Function format parameter and local declarations are in a separate scope from global variables. Declarations within compound statements {} are still in the enclosing scope however. I hope to fix this soon as well but it could potentially break existing scripts. Let me know if you think this would be a big problem.
8. Not really function related, but you can use C++-style "//" comment delimiters now.
I'll post a couple of examples when I get a chance but hopefully this gives you something to start with!
-
Excellent! I will be sure to test this thoroughly :)
-
So far so good! I like the "//" comment delimiters ;)
Regarding #5 of the restrictions, do you intend to add arrays?
Regarding #7, I take it you meant that variables declared within an enclosing brackets (such as an if(){} statement), aside from within functions, are still accessible to the entire script. I've tested this and yeah it's a bit against the standard. I don't think it'll be too great of an issue for pre-existing scripts if this is fixed, since a lot of us never even declare variables within compound statements anyway. Personally, I didn't even know I could do so until recently, and most of the scripts by others that I've seen keep the variables outside. Whatever problems with backward compatibility it causes, I think it's worth having local scope, in my opinion.
I've written a few functions based from my AOBake script, and they work exactly as I expected them to. I've had no issues as of yet asides from the restrictions. I do have a few comments about ASL in general, if you don't mind my posting them here:
A "break" statement for compound statements would be...spectacular.
Apparently, changing the starting variable in the for statement, from within, does not affect the looping. I've tried it as a fix for not having a "break" statement, such as in the code below:
#command("object");
file $c;
int $i;
$c.open("$console", "w");
for $i = 0 to 10 do
{
$c.print("%d\n", $i);
if($i == 5)
$i = 10;
}
$c.close();
The above code does not break the loop when $i reaches 5.
Some happy functions:
/**
* @author Randall Bezant (aka Raxx)
* @attribution "Fast, Minimum Storage Ray/Triangle Intersection" by Tomas Moller and Ben Trumbore:
* http://www.cs.virginia.edu/~gfx/Courses/2003/ImageSynthesis/papers/Acceleration/Fast%20MinimumStorage%20RayTriangle%20Intersection.pdf
*
* @param <point3> $v0, $v1, $v2 - The three points of the colliding triangle in clockwise direction
* @param <point3> $rSource - Ray source point
* @param <point3> $rDir - Ray Direction
*
* @return point2 - If collision, returns the length along the ray direction (known as t),
* and collided indicator of 1 for a value of (1, t). Otherwise returns (0, 0). If t is negative,
* that means it collided in the opposite direction of the specified ray direction, behind the
* ray source.
*
* Single-sided ray/triangle intersection method. To get the point of intersection on the triangle,
* use this formula:
*
* pI = p + t*d
*
* pI: Point of intersection (point3)
* p: Ray source (point3)
* t: length along ray (float)
* d: Ray direction (point3)
*
*/
point2 $rayTriangleIntersect (point3 $V0, point3 $V1, point3 $V2, point3 $rSource, point3 $rDir)
{
// Determinant
point3 $pvec, $tvec, $qvec, $edge1, $edge2;
float $determinant, $triangleV, $triangleU;
$edge1 = $V1 - $V0;
$edge2 = $V2 - $V0;
$pvec = cross($rDir, $edge2);
$determinant = dot($edge1, $pvec);
if ($determinant < 0.000001)
return (0,0);
$tvec = $rSource - $V0;
$triangleU = dot($tvec, $pvec);
if($triangleU < 0.0 || $triangleU > $determinant)
return (0,0);
$qvec = cross($tvec, $edge1);
$triangleV = dot($rDir, $qvec);
if ($triangleV < 0.0 || $triangleU + $triangleV > $determinant)
return (0,0);
return (1, dot($edge2, $qvec) / $determinant);
}
/**
* @author Randall Bezant (aka Raxx)
*
* @param <int> $sPointIndex - The point index on the sphere
* @param <float> $sRadius - Radius of the sphere
*
* @return point3 - X,Y,Z of the point
*
* Generates the coordinate for an indicated point on a sphere
*/
point3 $uniformSpherePoint(int $sPointIndex, float $sRadius)
{
float $sY, $sR, $sPhi, $inc, $off;
$inc = PI*(3-sqrt(5));
$off = 2.0/$numSpherePoints;
$sY = $sPointIndex * $off - 1 + ($off/2);
$sR = sqrt(1 - $sY*$sY);
$sPhi = $sPointIndex * $inc;
return (cos($sPhi)*$sR, $sY + 0.05, sin($sPhi)*$sR)*$sRadius;
}
/**
* @author Randall Bezant (aka Raxx)
* @param <vector> $vector
*
* @return <Float4x4>
*
* Convert a directional vector to a transform matrix
*/
float4x4 $vectorToTransform(point3 $vector){
float $dot;
quaternion $quat;
$dot = dot((0,1,0), $vector);
if ($dot <= -1){
$quat = (0, 1, 0, 0);
} else if ($dot >= 1){
$quat = (0, 0, 0, 1);
} else {
$vector = cross((0, 1, 0), $vector);
$quat.x = $vector.x;
$quat.y = $vector.y;
$quat.z = $vector.z;
$quat.w = 1 + $dot;
$quat = normalize($quat);
}
return toFloat4x4($quat);
}
-
5. Yes I do plan on adding array parameters. There are a number of weird "features" (a.k.a. bugs) in the existing ASL implementation involving arrays that need to be fixed before I can add them. These "features" are thinks like you can assign an array to a scalar, and visa versa, ans Anim8or doesn't catch it. The result is not defined. Valid programs work correctly but invalid ones are not caught.
7. Yes, I mean supporting true C/C++ like scopes. I think it's worth doing and agree that any backwards compatibility issues should be minimal. I just wanted to point this out before I do the work in case anybody had any objections.
break is a good idea. I'll add it to the list of things to do.
The for semantics is something that I wasn't aware of (or had forgotten :)) I think your example should work as you intended so I'll fix that too.
Nice function examples :)
-
Found an easy fix for the for loop bug, raxx. Thanks for reporting it!
#098-005 - ASL for loops: assignment to control variable is overwritten by loop step code.
Status: Fixed for build 1071
-
Wow, Steve, this is awesome! What do you think about an #include type command or a linker type command that allows us to build libraries of functions in a separate file for easier reuse?
-
... What do you think about an #include type command or a linker type command that allows us to build libraries of functions in a separate file for easier reuse?
Yes, these ideas have crossed my mind a few times, too. After I get the overall language into better shape I'll look into it.