-
I've rewritten all the scripts and I've released them in another topic:
Magnet Tools Package (http://www.anim8or.com/smf/index.php?topic=1599.0)
Please refer to that topic for further discussion, thank you.
Consider this thread as locked.
[EDIT]
SCRIPT UPDATED: take a look to this post for the latest:
http://www.anim8or.com/smf/index.php?topic=1492.msg11109#msg11109 (http://www.anim8or.com/smf/index.php?topic=1492.msg11109#msg11109)
[/EDIT]
Hi all, that's my very first attempt at making a script. I've read somewhere that some 3D editors have a magnet tool. Honestly I never used one and I have no idea about the way it is intended to work, anyway, I tried to give a shot at it.
The idea by itself is simple, and the script I'm going to paste here below does compile without errors, but well, it simply doesn't work.
I took inspiration from the mirror script but I ended up with another way for exiting the script.
As with the mirror script, the CPU goes up 100% in my script, try it at your own risk.
I really don't know where I went wrong scripting, seems that moving the magnet shape around the screen doesn't make any difference, I think I'll have to debug it by outputting some values to a file.
As you will read in the code, only the first point of the "magnet" shape is used as reference. When this script gets fixed (if ever) it would be cool to use more than a point to model the "clay" shape, so that we could have some sort of "variable" magnet tool.
[EDIT]
I modified one line and actually now it works (well, no, it won't work as expected but it does work somehow).
Try this: add a large multifaceted sphere in an empty object, convert the sphere to a mesh and ensure it is named "mesh01", add another mesh and name it "magnet", then run the script. Moving around the magnet while the script is running will somehow modify the sphere.
The problem is that I am computing the distances checking each coordinate separately, which is too wrong... I'm trying to fix it.
[/EDIT]
[EDIT 2]
Cool! it works! and it's also quite easy to use... although it must be refined... try this, and notice that the script does not move the points as long as you keep the mouse button pressed to move the magnet. It does move the points only after that you release the mouse button. Enough for today, tomorrow I'll try to post a better version with some deeper instructions. Anyway, here below is the updated script, give it a try. The mesh "mesh01" must be centered at origin - for the moment...
[/EDIT 2]
/* magnet pseudo-tool
to stop the script change one of the shapes' names,
the while-loop goes on as long as both shapes are found */
#command("object");
shape $magnet; /* shape named "magnet" */
shape $clay; /* shape named "mesh01" */
point3 $clay_p; /* clay point */
point3 $mag_p; /* magnet location */
point3 $cur_p; /* currently modified clay point */
float $distance; /* actual distance between clay point and magnet location */
point3 $dist; /* coord distances between clay point and magnet location */
float $min_dist; /* min distance for modifying clay point */
float $max_dist; /* max distance for modifying clay point */
float $step; /* step of change */
int $continue; /* flag for exiting the loop */
int $i;
$min_dist = 2;
$max_dist = 10;
$step = 1;
$continue = 1;
while ( $continue ) {
$magnet = project.curObject.LookupShape("magnet");
$clay = project.curObject.LookupShape("mesh01");
if ( ($magnet != NULL) && ($clay != NULL) ) {
$clay.Open();
$mag_p = $magnet.loc;
for $i = 0 to $clay.GetNumPoints()-1 do {
$clay_p = $clay.GetPoint($i);
$cur_p = $clay_p;
$dist.x = $mag_p.x - $clay_p.x;
$dist.y = $mag_p.y - $clay_p.y;
$dist.z = $mag_p.z - $clay_p.z;
$distance = sqrt($dist.x * $dist.x + $dist.y * $dist.y + $dist.z * $dist.z);
if ( ($distance > $min_dist) && ($distance < $max_dist) ) {
if ( $mag_p.x > $clay_p.x ) {
$cur_p.x = $cur_p.x + $step;
} else {
$cur_p.x = $cur_p.x - $step;
}
if ( $mag_p.y > $clay_p.y ) {
$cur_p.y = $cur_p.y + $step;
} else {
$cur_p.y = $cur_p.y - $step;
}
if ( $mag_p.z > $clay_p.z ) {
$cur_p.z = $cur_p.z + $step;
} else {
$cur_p.z = $cur_p.z - $step;
}
}
$clay.SetPoint($i, $cur_p);
}
$clay.Close();
refresh();
} else {
$continue = 0; /* one or both shapes not found, exit loop */
}
}
Use this script at your will of course, feel free to. By my side I think I'll have to get a firmer grasp on ASL before getting to work things correctly.
-
It's seems like a great idea. But I think I need to be told how to use it :)
-
Oh, yes... forgot to explain. I don't know exactly if it would be so easy to use.
The idea is like this: you add a simple mesh (a cube for example) to the object and you name it "magnet", then you run the script. The script checks if the points of your object (the mesh named "mesh01") are in the range of attraction of the magnet. The points that fall in this range are moved step by step toward the magnet.
In other words, moving the magnet shape close to the surface of your mesh (either in the inside or in the outside) you bump its points in and out - at least that's the idea.
Tomorrow I'll dig it further to see if I can make it work.
Thanks for your interest headwax.
-
Oh well... (mumbling...)
I think that I've found where I mistaken my script. Moving the magnet shape around doesn't change the coords of its points, it changes the shape's displacement!
I'm on it, more to come.
[EDIT]
I've modified the script posted in the first message above but still it doesn't work as I expected, I'm on it again (eheheehh, I've managed to output some data to the console, debugging becomes simpler now ;) )
[/EDIT]
-
Ok, seems I got a deeper grip, I managed to make it work, see the updated script in the first post. Sorry for this mess of messages. Tomorrow I'll post a refined version of this script.
-
Nice little script there Francesco, It works now, might need another routine within the body to "repel" as its a bit hit and miss.
-
Thank you kreator, you gave me a good idea to further refine it, I'm on it and I'll post the result in a short while.
-
Here I am.
It came out quite a nice tool, please forgive me the autocelebration ;)
EDIT: I fixed the "all coords" part of the script and I have updated the zip file attached here. Details on the fix in this post (http://www.anim8or.com/smf/index.php?topic=1492.msg11419#msg11419).
WARNING: this script is experimental stuff and will make your cpu usage go up 100%, use this script at your own risk.
So then, here is the tutorial (well, sort of...):
http://francesco1978.altervista.org/magnet_tutorial.avi (http://francesco1978.altervista.org/magnet_tutorial.avi)
and attached to this post there is a zip file containing the script, a project and four bitmaps.
I used the material of the magnet shape to switch between attraction and repulsion, and also to limit the coordinates influenced by the magnet. The bitmaps are used to clearly show the script mode used at each time.
The project contains all the materials used by the script and a flat face mesh to make some experiments if you like.
Sorry if it seems all a bit messy, in particular the video tutorial, but it was the first time I used wink to make one.
So then, take a look to the archive attached here below, opening the project file should automatically load the bitmaps too - assuming that you open the project file from its folder containing the bitmaps.
Some details in the scripts comments.
Happy anim8ing, feel free to ask if something isn't clear enough.
EDIT: Here are the instructions reported by the readme.txt file as well as by the script's comments:
Magnet Pseudo-Tool by Francesco
Requisites:
- work in object mode;
- there must be a mesh named "MAGNET";
- there must be a mesh named "mesh01";
- there must be one or more of the following materials:
M_PULL, M_PULL_X, M_PULL_Y, M_PULL_Z
M_PUSH, M_PUSH_X, M_PUSH_Y, M_PUSH_Z
Usage:
- apply one of these materials to the magnet (depending if you want it
to attract or to repel the points of "mesh01", and depending on
which coordinates you want to modify);
- start the script;
- move the magnet around your mesh to modify it;
- resize the magnet to change its range of action;
- change the material of the magnet (one of the above mentioned)
to switch between attractive and repulsive magnet and to change
the affected coordinates;
To stop the script (pick your choice, all of them work):
- change the magnet's material to a unused one (I use "M_NONE" for my ease);
- change one of the meshes' names;
- delete one of the meshes;
Hints:
- make your magnet a spherical one (a dodecahedron will be fine);
- make the M_ materials halfway transparent;
- work in flat shaded view;
IMPORTANT: DO NOT ROTATE THE MESH NAMED "mesh01", BECAUSE IT WILL
MESS UP ALL THE SCRIPT'S EFFECT. You can translate it though,
and you can freely rotate the magnet.
-
Great work Francesco!
-
Thanks Kubajzz, I wish I were good at using it too... maybe some modeller here can show its opportunities, although I admit it could be improved a lot...
-
Francesco VERY COOL SCRIP!!! CONGRATULATIONS!! ;)
I have two sugestions for Future using your script OK... ::)
(http://img393.imageshack.us/img393/4201/magnettool01gc2.jpg)
and i think then is possible too... ::)
(http://img393.imageshack.us/img393/268/magnettool02yt3.jpg)
sorry my english ok?
Thank you for this script very cool!!
-
Hi Neirao, I'm very glad you liked it.
Although I didn't post in your topics I like very much your works, also the way you illustrate your ideas.
Also in this case your ideas are very nice, and actually they work sort of like the magnet script (just a bigger amount of computations, also because I fear that collision detection would be surface over surface and not point over point).
Maybe I'll take inspiration from them to improve the magnet script, but meanwhile I'd like to know the way you made all those examples... did you build them manually before rendering or did you use some other program's tools?
Just out of curiosity.
Thanks again, also to all the people that downloaded my work.
-
I'm a complete newb; I've got try it.
-
Well I'm going to use this right away... tomorrow. I'm still anticipating the rise of an anim8or that can match blender. I'm using anim8or for animating and blender for modeling because anim8or is so easy and simple and blender has a lot more useful tools.
-
i'm having trouble finding the script and video
the link at the top takes me to the avi link and that link takes me to an italian site
with no obvious page to go to.
-
Hi Francesco,
my examples i make manually using Anim8or and composer in CorelDraw
in this case i need get some imagens in web too..ok ;)
Thanks again!
-
@captaindrewi: if you didn't see the link at the bottom of that post maybe you weren't logged in, as for the video that's strange that you were redirected to my italian homepage, clicking the link should have asked you to save the file... Try right-click & "save as". Someone else had the same problem?
@neirao: obrigado! Thanks for the info :)
-
thanks francesco, i dont know how i missed the link at the bottom of the post.
got the script and video tutorial now.
very grateful for your help and gifts.
-
You're welcome Captaindrewi, I take the chance to say that I'll be glad to see the works made with the help of this tool (yours as well as anybody else's). I'm not really a modeler, hope somebody could make good use of it. As usual feel free to ask for improvements (meanwhile I'm giving a try to Neirao's suggestions).
-
Grazzie Francesco
I missed the link also, then I copy and paste in a new window and it worked.
thanks
-
Grazie a te per il tuo interesse, Dajean! *
I think I'll put the links in one of my website's pages though, also because I think internal linking it's more correct towards the people who are hosting my pages.
I've saw the video again... oh well, "tutorial" is a big word for that video... lots of time wandering with the mouse and no real explanation... maybe I'll remake it.
(* "Thanks to you for your interest Dajean!")
-
Cool script. I may try it out later....
-
i have managed to have a few goes,dont think i would have got very far without the vid.
the column of buttons on the left side of animator start blinking frenetically whilst using the script, cpu usage around 70%.
running on a vista laptop.a bit worrying but it didn't blow up!
it's a very exiting tool...fabulous work.
-
i have managed to have a few goes,dont think i would have got very far without the vid.
the column of buttons on the left side of animator start blinking frenetically whilst using the script, cpu usage around 70%.
running on a vista laptop.a bit worrying but it didn't blow up!
it's a very exiting tool...fabulous work.
I think you mean exciting...... unless of course you was quik to make an exit from of it :P
-
Yes just like the mirror script, this script makes the processor run like hell... I'll have to remark it in the post above and not only inside the script comments, thank you for the reminder. I use to keep the mouse button down for moving the magnet even if I'm not actually moving it, because the script stops and leaves a bit of relief to my poor 1.5GHz. I also use to turn it off when I'm dubious about the next modeling actions... that is more or less always, eheheh
Have fun and thanks again for the interest.
-
I've fixed the "all-coords" part of the script, which was quite wrong (see the attached picture to view the different results).
I'm also updating the package attached to this post (http://www.anim8or.com/smf/index.php?topic=1492.msg11109#msg11109).
Download it again if you like.
Have fun,
Francesco
-
Well done! I have to say this is a very nice looking script. It gives a nice sculpting quality which is great. I definitely want to try it out.
-
Thank you hihosilver, I look forward to see your works and to hear your advice.
-
Great Script Francesco ;D
Just one thing. Would it be possible to use any mesh as the MAGNET object?
This would be really helpful.
-
Yes, you can use the mesh you want, but it will behave as a sphere anyway. I guess you mean something like the cloth tool suggested by Neirao, well, I'm working on that, but I'm afraid you'll need quite a good machine to run that script.
-
Hi all,
here I am with a pre-release of my multi-magnet tool. In some way it does what Neirao suggested - that is, you can use any mesh as magnet and try to emboss or carve its shape over a finely faced surface. Sort of clothing, but really bumpy at this very stage.
In shorts: each vertex of the magnet becomes a magnet itself.
I was about to start from scratch with stuff like computing if a point falls here or there, when related to a magnet's face, but I think I need a firmer grasp on such things before writing the script.
Changing the spherical magnet into a bunch of smaller spherical magnets was easier and quicker to do, by modifying the original script, so here you have the first results in four files:
- an example picture;
- the "multimagnet" script;
- the "show ranges" script;
- a "multimagnet" project;
The "multimagnet" script is the one doing the work. If you already have the needed materials set in a project you can try it out at once (the needed materials are the same used by the "magnet script", they are in the "magnet project" I attached before in this thread).
The "show ranges" script can be used to display the range of action of your magnet. You only need a mesh named "MAGNET" to run this script. The script adds a sphere for each vertex of your magnet displaying the range of action of each vertex. When the script stops, all the added spheres remain selected, so, if you had nothing selected before running it, you can get rid of all the spheres hitting "DEL" on your keyboard.
The "multimagnet" project isn't really needed, but there you have the magnet I used in the example picture and the all-triangles sheet I use to test the magnet. I saved this project in the state it was when I took the screenshots below, if you care to know. I didn't attach the bitmaps this time, so I suggest you to paste the project in the same folder of those AXYZ pictures, if you want Anim8or to load them.
The picture:
1 - the magnet alone;
2, 3 - a sphere for each vertex' range;
4 - mesh01 and the magnet;
5 - range of action from another angle;
6 - result on mesh01 after fiddling around with M_PUSH_Z
An important detail: the range of action of each vertex is nothing more than its distance from the nearest neighbour. Hence, more points will give you a more detailed and less bumpy magnet. The "show ranges" script will show you exactly what you are dealing with.
Sorry if, again, it looks all messy, incomplete and not so clear with the explanations, but I'm in a hurry.
Let me know your opinion, if it sounds promising I can keep this script and continue working on it, otherwise I would switch to the "other way" (checking and changing mesh01 against each magnet's face).
Anyway, by the way, have fun,
Francesco
-
This is a really useful script ;D
Posting an example of what it can do.
-
Thank you odp04y, also for posting that example.
A side note: now that the surface of the magnet is made up of several small magnets, you should take care of approaching the magnet to the mesh step by step. If you intersect the two too quick some points of the mesh will fall in the "backside" of each magnet, and those points will be pulled instead of being pushed (or vice versa, it depends from the material you are using).
I look forward for your experiments with this script, people, and even more for your advice (otherwise I'll go on making this stuff the way I see fitting ;) ).
Thanks a lot to all of you for your attention, I'm really glad.
-
Francesco VERY COOL SCRIP!!! CONGRATULATIONS!! ;)
I have two sugestions for Future using your script OK... ::)
Somehow you always manage to make these awesome looking pictures that perfectly display your idea... :P
Anyway, reminds me of nCloth in Maya.
Great idea. (A carve script would be really awesome though)
-
First things first: the Multi-Magnet Script is pure crap - although the Showranges script is funny in my opinion.
I wonder why nobody suggested me to throw away that crap, but I think that Bamman62's parenthetical "(A carve script would be really awesome though)" would kindly mean the same, and I agree ;-)
So then, I struggled a lot and I came up with the Polimagnet script, that I share in a .a8s and a .jpg, both attached to this post.
So please go ahead and try clothing or carving something, but bear in mind what follows - I will remove all those limitations, but I need some of your help before doing that:
Limitations:
- the magnet must be a well formed, all-triangles mesh;
- you cannot rotate the magnet, you cannot rotate mesh01;
- you can only use "M_PUSH" materials (I seriously think that M_PULL modes are unneeded);
The juice in few words: the script checks if a point of mesh01 lies between magnet's origin and one of its faces. In such a case the point will be pushed away from magnet's origin till magnet's surface.
Notice that magnet's origin is not its pivot. You might want to manually set magnet's location to (0,0,0). Magnet's origin will be on world's origin then. I'm gonna fix that.
Temporary tweaks:
- you can modify the magnet or the mesh in point edit mode (you can also rotate them);
Final note: the script only cares about mesh01 points, hence mesh01 can have all sorts of facets (tri, quad, poly). But resulting faces could be messed up, up to you to use non-triangular facets (converting to subdivided could eventually fix that?).
Now the most important thing: I need some help with the transformation matrices for applying the rotations... somebody wants to give me advice? It's something I cannot grab my mind on.
-
I can't get it to work (i got a triangle faced mesh as MAGNET with M_PUSH material, neither are rotated, magnet script works but not this one) ???
-
Uhm, sorry but I have no real idea... I think I have to let the script output some debug information.
As for now I suggest you to check whether the magnet's origin is where you think it is.
Doubleclick the magnet and enter (0,0,0) as its location. If then it lies centered around world's (object's) origin, then the magnet's origin should be right.
If setting magnet's location to zero you happen to find it displaced away from object's origin, then enter point edit mode, select all points and bring them around the object's origin. Once you have done this, you can freely move the magnet.
I came to realise that there is no way to access pivot's position from within ASL, I cannot make this script easier to use until ASL allows me accessing pivot's position.
I am about to modify the script so that it creates a copy of the magnet and triangulates it, so that you will be able to use any kind of mesh as magnet.
I still need help with rotation matrix, I hope that someone could give me a quick insight on that and on its use.
[edit: here is a project whose magnet and mesh01 should work - I've just tested them. I attach a picture of another example, applied the magnet 4 times with M_PUSH_Z, wireframe, raw render, subdivided render. ]
-
You can access and change the object's pivot position in ASL. It is referred to as "orientation" as a quaternion type. You can construct a new quaternion of the rotation you desire and apply it to the whole object or you can can use the "toFloat4x4" and "Project" methods to change the orientation of the object on a point-by-point basis. See the chain maker script or the copy source mesh to target mesh scripts for examples of how the orientation can be manipulated.
-
Silly me, I was looking for a point3 just like the location... Sorry, my fault. Thank you NickE, also for the pointers.
-
Uhm... I fear that the pivot's position is not truly accessible from ASL... pivot's position and orientation are stored separately in projects files, that should be the same in ASL.
Please tell me if I'm banging my head or if I can extract pivot's position from orientation, I really need this.
-
The pivot point location and orientation aren't accessible.
Could you describe what you want to do exactly,maybe
you don't really need the pivot point.
As an example,if you want to calculate the true coordinates
of the points,you don't need it.
-
Hi Claude,
thanks for dropping in.
I need to know the pivot's position to make the polimagnet script more flexible and easy to use.
Currently, the script checks if a point of mesh01 falls in the "cone" (let me pass this term for clarity) built from a face of the magnet and its origin.
The thing I want to do is to build that "cone" from the pivot's position, so that users can easily modify the center of the magnet.
I'm about to make a sketch for clarity, this way I can clearly illustrate how the polimagnet script works - for the people that's interested in using it.
I attach the sketch here:
-
Francesco,
Thank you for the diagram. That helps me understand what you are attempting.
As far as I can tell, an object's position and orientation are a combination of three factors: the raw point coordinates retrieved by the GetPoints() function, the Location (loc), and the Orientation. When you move or rotate a whole object in the object editor, you are only changing the Location and the Orientation. When you move a point, you are changing the raw point coordinates relative to the current Location and Orientation. Whenever you need to know how one object's points relate to another object's points, both objects must be in the same coordinate system.
Below is some code that moves two meshes into the same coordinate system.
file $output;
string $fname;
$fname="$console";
$output.open($fname,"w");
object $curObject;
shape $shape, $shapes[0], $childShapes[1];
shape $source,$target;
int $i,$j,$havesource,$havetarget;
int $ii,$jj,$kk;
int $sourcenumpts,$sourcenumfaces,$sourcenumedges;
point3 $p,$sourcemin,$sourcemax,$sourcecenter,$sourceloc;
quaternion $sourceorientation,$zeroor;
float4x4 $sourcerotmat;
point3 $zeropoint;
float $sourcedepth,$sourcedepthoffset;
int $targetnumpts,$targetnumfaces,$targetnumedges;
point3 $targetmin,$targetmax,$targetcenter,$targetloc;
quaternion $targetorientation;
float4x4 $targetrotmat;
$zeropoint.x=0.0;
$zeropoint.y=0.0;
$zeropoint.z=0.0;
$zeroor.x=0.0;
$zeroor.y=0.0;
$zeroor.z=0.0;
$zeroor.w=1.0;
$curObject = project.curObject;
$curObject.GetShapes($childShapes);
$shapes.size = 0;
while ($childShapes.size > 0)
$shapes.push($childShapes.pop());
while ($shapes.size > 0) {
$shape = $shapes.pop();
if ($shape.GetKind() == SHAPE_KIND_MESH && $shape.name == "source")
{
$source=$shape;
$sourcenumpts=$source.GetNumPoints();
$sourcenumfaces=$source.GetNumFaces();
$sourcenumedges=$source.GetNumEdges();
$sourceloc=$source.loc;
$sourceorientation=$source.orientation;
$sourcerotmat=toFloat4x4($sourceorientation);
$havesource=1;
}
if ($shape.GetKind() == SHAPE_KIND_MESH && $shape.name == "target")
{
$target=$shape;
$targetnumpts=$target.GetNumPoints();
$targetnumfaces=$target.GetNumFaces();
$targetnumedges=$target.GetNumEdges();
$targetloc=$target.loc;
$targetorientation=$target.orientation;
$targetrotmat=toFloat4x4($targetorientation);
$havetarget=1;
}
}
if ($havesource==1 && $havetarget==1)
{
$output.print("Source Before:\n");
$output.print("Loc: (%0.2f,%0.2f,%0.2f)\n",$source.loc.x,$source.loc.y,$source.loc.z);
$output.print("Center: (%0.2f,%0.2f,%0.2f)\n",$sourcecenter.x,$sourcecenter.y,$sourcecenter.z);
$output.print("Min: (%0.2f,%0.2f,%0.2f) Max: (%0.2f,%0.2f,%0.2f)\n",$sourcemin.x,$sourcemin.y,$sourcemin.z,$sourcemax.x,$sourcemax.y,$sourcemax.z);
$output.print("Orientation (%0.2f,%0.2f,%0.2f,%0.2f)\n",$sourceorientation.x,$sourceorientation.y,$sourceorientation.z,$sourceorientation.w);
/* apply orientation and location to shapes */
for $ii = 0 to $sourcenumpts-1 do
{
$p=$source.GetPoint($ii);
$p=$sourcerotmat.Project($p)+$source.loc;
$source.SetPoint($ii,$p);
}
$source.loc=$zeropoint;
$source.orientation=$zeroor;
for $ii = 0 to $targetnumpts-1 do
{
$p=$target.GetPoint($ii);
$p=$targetrotmat.Project($p)+$target.loc;
$target.SetPoint($ii,$p);
}
$target.loc=$zeropoint;
$target.orientation=$zeroor;
/* get source stats */
$sourcemin.x=10000;
$sourcemin.y=10000;
$sourcemin.z=10000;
$sourcemax.x=-10000;
$sourcemax.y=-10000;
$sourcemax.z=-10000;
for $i=0 to $sourcenumpts-1 do
{
$p=$source.GetPoint($i);
if ($p.x < $sourcemin.x) $sourcemin.x=$p.x;
if ($p.y < $sourcemin.y) $sourcemin.y=$p.y;
if ($p.z < $sourcemin.z) $sourcemin.z=$p.z;
if ($p.x > $sourcemax.x) $sourcemax.x=$p.x;
if ($p.y > $sourcemax.y) $sourcemax.y=$p.y;
if ($p.z > $sourcemax.z) $sourcemax.z=$p.z;
}
$sourcecenter.x = 0.5 * ($sourcemax.x + $sourcemin.x);
$sourcecenter.y = 0.5 * ($sourcemax.y + $sourcemin.y);
$sourcecenter.z = 0.5 * ($sourcemax.z + $sourcemin.z);
$output.print("Source:\n");
$output.print("Points: %d, Faces: %d, Edges: %d\n",$sourcenumpts,$sourcenumfaces,$sourcenumedges);
$output.print("Loc: (%0.2f,%0.2f,%0.2f)\n",$source.loc.x,$source.loc.y,$source.loc.z);
$output.print("Center: (%0.2f,%0.2f,%0.2f)\n",$sourcecenter.x,$sourcecenter.y,$sourcecenter.z);
$output.print("Min: (%0.2f,%0.2f,%0.2f) Max: (%0.2f,%0.2f,%0.2f)\n",$sourcemin.x,$sourcemin.y,$sourcemin.z,$sourcemax.x,$sourcemax.y,$sourcemax.z);
$output.print("Orientation (%0.2f,%0.2f,%0.2f,%0.2f)\n",$sourceorientation.x,$sourceorientation.y,$sourceorientation.z,$sourceorientation.w);
/* get target stats */
$targetmin.x=10000;
$targetmin.y=10000;
$targetmin.z=10000;
$targetmax.x=-10000;
$targetmax.y=-10000;
$targetmax.z=-10000;
for $i=0 to $targetnumpts-1 do
{
$p=$target.GetPoint($i);
if ($p.x < $targetmin.x) $targetmin.x=$p.x;
if ($p.y < $targetmin.y) $targetmin.y=$p.y;
if ($p.z < $targetmin.z) $targetmin.z=$p.z;
if ($p.x > $targetmax.x) $targetmax.x=$p.x;
if ($p.y > $targetmax.y) $targetmax.y=$p.y;
if ($p.z > $targetmax.z) $targetmax.z=$p.z;
}
$targetcenter.x = 0.5 * ($targetmax.x + $targetmin.x);
$targetcenter.y = 0.5 * ($targetmax.y + $targetmin.y);
$targetcenter.z = 0.5 * ($targetmax.z + $targetmin.z);
$output.print("Target:\n");
$output.print("Points: %d, Faces: %d, Edges: %d\n",$targetnumpts,$targetnumfaces,$targetnumedges);
$output.print("Loc: (%0.2f,%0.2f,%0.2f)\n",$target.loc.x,$target.loc.y,$target.loc.z);
$output.print("Center: (%0.2f,%0.2f,%0.2f)\n",$targetcenter.x,$targetcenter.y,$targetcenter.z);
$output.print("Min: (%0.2f,%0.2f,%0.2f) Max: (%0.2f,%0.2f,%0.2f)\n",$targetmin.x,$targetmin.y,$targetmin.z,$targetmax.x,$targetmax.y,$targetmax.z);
$output.print("Orientation (%0.2f,%0.2f,%0.2f,%0.2f)\n",$targetorientation.x,$targetorientation.y,$targetorientation.z,$targetorientation.w);
} else {
$output.print("No source and/or target\n");
} /* end of have source or target if */
$output.close;
-
Actually the diagram shows what I already have done in the Polimagnet script attached some posts above (that is not the MultiMagnet scripts, sorry for this mess of names).
A little resume:
Magnet script --> a single spherical magnet;
MultiMagnet script --> a spherical magnet for each magnet's vertex (the "crap" script);
Polimagnet script --> the last one, the one that checks each vertex of mesh01 against each magnet's face;
Now I know that I cannot access pivot's position, thus I have to wait for the next ASL release before fixing that.
The other thing I needed to know was how to apply the rotation, I think that I can spill it out from your code NickE.
Thank you all for your support.
-
Hi Francesco,
your script is time in time better.. ;)
soon he will be perfect for to recognize collision with all object formats!
congratulations! :D
neirão
-
Thank you Neirao, I'm looking forward to see your renders, I believe you tested my script properly ;-)
People, I'm lost. The math behind bringing a point to one coord system to another is easy to me:
mesh1_pt_in_mesh2_coords = mesh1_pt - mesh1_location + mesh2_location
and back:
mesh1_pt = mesh1_pt_in_mesh2_coords + mesh1_location - mesh2_location
But this way all gets messed up as I rotate something.
Now, from NickE's script I learnt that with this code...
$sourcerotmat = toFloat4x4($source.orientation);
$p = $sourcerotmat.Project($p) + $source.loc;
...I am bringing the point to world's coordinates taking care of the rotation. Fine. But the reverse? How can I bring it back to original source's coordinates?
Help me. I feel like I'm lost in a glass of water (a large one for me, currently).
-
I'm afraid it's not possible to convert point location from the world coordinates into the local mesh coordinates...
You can get the "mesh --> global" transformation matrix using the "GetGlobalTransform()" or "toFloat4x4" functions, but there's no way to get the reversed matrices.
btw. the "GetGlobalTransform()" function is easier to use than "toFloat4x4", because it converts both orientation and position:
$transformMat = $YourShape.GetGlobalTransform();
$p = $transformMat.Project($p);
-
Good idea using global transformation, but sounds strange to me that I cannot do the inverse process.
I'm on it, I think I found the solution.
-
It's possible.You have to trick ASL into giving you the 16 elements of the matrix.Then,you calculate the inverse matrix
and apply it to the point coordinates.
Here's an example:
http://www.anim8or.com/smf/index.php?action=dlattach;topic=1309.0;attach=1725
-
Thank you for the hint Claude, I've come to the same solution in another flavour:
quaternion $mag_q, $clay_q;
$mag_q = $magnet.orientation;
$clay_q = $clay.orientation;
float4x4 $mag_rotmat, $clay_rotmat;
$mag_rotmat = toFloat4x4($mag_q);
$clay_rotmat = toFloat4x4($clay_q);
/* invert orientation quaternion for building inverse transformation */
$mag_q = ( -$mag_q.x, -$mag_q.y, -$mag_q.z, $mag_q.w);
$clay_q = ( -$clay_q.x, -$clay_q.y, -$clay_q.z, $clay_q.w);
float4x4 $mag_inv_rotmat, $clay_inv_rotmat;
$mag_inv_rotmat = toFloat4x4($mag_q);
$clay_inv_rotmat = toFloat4x4($clay_q);
...then...
/* translate clay point to magnet's coordinates */
$clay_p = $clay_rotmat.Project($clay_p) + $clay_l - $mag_l;
$clay_p = $mag_inv_rotmat.Project($clay_p);
...and back:
/* translate back clay point to clay's coordinates */
$clay_p = $mag_rotmat.Project($clay_p) - $clay_l + $mag_l;
$clay_p = $clay_inv_rotmat.Project($clay_p);
I attach the updated script here.
Now you can freely rotate the magnet or mesh01 while the script is running.
The single axis modes are (currently) tied to mesh01 axes, if somebody cares to know. I think I'll add an option for choosing the system onto which move the coordinates (clay's, magnet's or world's axes).
Thank you all for your attention and for your support, I really hope that you find this script useful, now that it's getting refined.
Reminder: the script still needs a well formed, all-triangle mesh as magnet.
If a magnet's face has more than three sides, only the triangle built on the first three edges is used; if a face is missing, points falling behind that face will not be pushed (nothing changes here respect to the first version of the polimagnet script, I've only added the ability to rotate the meshes).
The triangulate mesh script and the simplify mesh script are a must for using the polimagnet, thank you guys for sharing.
-
Have you consider the possibility of using the tridata structure
instead of the meshdata structure.If it's possible,you wouldn't
have to ask the user to triangulate himself.True?
Just a suggestion.
-
Thank you for the suggestion, is a really good one. Using the tridata will simplify the script too - I wasn't aware of this structure, I must have slipped on it in the specs.
Another note for who's interested in testing the polimagnet script: I've discovered that the script chokes on small meshes.
Scale up the magnet and mesh01 to avoid all those points left behind.
-
That script is full of crap. I hope that none of you has actually, carefully read the code, you would be laughing at me for ages... the good new is that I'm getting a deeper knowledge of ASL, and hopefully a serious version of all this stuff will be available soon.
(if you noticed the square root and the weird "is this the same point of that other?" section, don't stare at me so surprised. You couldn't be more surprised than me when I realised those absurdities... never speak about trying to break a for-loop)
-
Hi Francesco, forgive me for the delay in answering ;)
i make somes tests using the last "Polimagnet_2_script.a8s",
in your project work, but in others meshes no...
it better works in objects with "tips"..but not manys...
My tests:
(http://img513.imageshack.us/img513/9725/magnetji0.jpg)
but i dont know if i make something wrong in timer of runner script... ::)
For future too..
(http://img513.imageshack.us/img513/6983/magnet2vy6.jpg)
However congratulations for scripts! ;)
I wait that it is improved more still in the future
therefore will be of great utility for us Anim8or Users!
Thanks you Francesco! :D
sorry my english please..
Neirao-Brazil
-
Thank you very much for your experiments and for posting them Neirao.
The script has a serious bug that you can walk around by rotating both the mesh and the magnet and applying the magnet again.
You can safely put apart that script though, I'm almost done with the new version, which will be really more easy to use and hopefully also faster.
Thanks again Neirao, I really appreciate your support.
-
Hi to all the people that keep an eye to this topic.
Here I am with another release of the polimagnet. It is quite different from the previous versions so let's take it step by step.
- You can use any kind of mesh as magnet (that is, you don't need to triangulate it).
- I merged the sphere-magnet script with the polimagnet script.
- I added a control panel that gets created by the script itself, and also the needed materials get created by the script (that is, you can use this script on a plain new project).
So, right after you run the script on an empty project you get the following objects...
Image 1:
A - Panel frame
B - Mono/Poli toggle
C - All-directions switch
D, E, F - single axis switches
G - Push/pull ratio slider (the triangle thingie)
H - One of the following: Range tool (in Polimagnet mode) Spherical Magnet (in MonoMagnet mode).
As it is, you get all the panel in "inactive state" (everything is gray), and actually the script is stopped.
Image 2:
K - a mesh named "MAGNET"
L - a mesh named "mesh01"
I, J - the gray sphere get changed into two spheres, one inside the other. The green sphere pushes, the red one pulls. The ratio between the two is set by the triangle-slider mentioned above.
OK, let's see how does it work.
While the script is running (remember that you need both "MAGNET" and "mesh01" to let the script run continuously) you can:
- move and rotate the panel frame (all the attached objects will be rearranged at the next refresh)
- switch all the toggles (just grab them and move them up or down, they will be aligned correctly at the next refresh)
- change the ratio between the push/pull spheres (again, grab the triangle thingie and move it left-right)
Notice how the Mono/Poli toggle and the All-directions switch are at the bottom of the panel. Now the script is in monomagnet mode and in all-directions mode.
When you grab and move around the red sphere, the green one will be moved accordingly. For your ease, you can select them both and move or scale them together (but don't group them, it wouldn't work).
The result of applying the red/green monomagnet to a sheet of triangles can be seen in images 5~8.
Now take a look at image 3. The script is in Polimode, and the blue sphere marked with M is the range of action of the polimagnet.
Before describing how the polimagnet & bluerange work (images 9~12), notice the difference in the panel from image 3 and image 4: although the XYZ switches are down and should be in green in image 3, they are superseded by the all-directions switch and thus they are in gray. In image 4 they are active (green) because the all-dirs switch is off.
(and remember that the all-directions mode is really different from the XYZ modes used together)
Now, maybe you recall that I complained about not being able to access the pivot's location, because I needed it to become the centre of projection for the polimagnet.
Now the center of projection is the center of the blue sphere. Also, only the points (of "mesh01") and the faces (of "MAGNET") that fall inside of this blue sphere will be considered while the script is running.
In other words, you can use complex meshes and apply the magnet only in selected areas, while most of the points and faces (those that fall outside of the blue range) will be quickly skipped.
The result of applying the magnet and the range at the sheet of triangles can be seen in images 9~12. Although that was a quick test with a simple magnet, the script should work fine on more complex meshes.
In the diagram you can see the idea implemented by the script. The points marked in green project on a magnet's face and lie between the face and the center of the range, then those points will be pushed till the magnet's face.
The points marked in red will not be touched (one of them doesn't project on a face, the other one does not fall between the center and the face).
Is this stuff too complicated?
Well, I'm here to hear your advice to improve and simplify it. And to answer your questions, if you have any.
Final note: don't tell me that the script code is messy. That's a 1K lines function, if you know what I mean, it has to be messy ;)
-
hi Francesco congratulations for new script ;)
i try but no obtained make work..i think then i´m making something wrong...
is possible post the " FULL project.an8", in time for tests? ::)
thanks
neirao
-
The project wouldn't be of much use, all you need is in the script. Notice that the panel is put at coords (0 500 0), so you might have to hit F on the keyboard to adapt the view. I'm posting from my mobile phone right now, I'll add more hints later when I get back to my PC.
-
I know the script make all the itens...i saw..
but after i maker the "MAGNET" and "mesh01" i run script again i dont obtained make the displace work of right way..(like your imagens samples).
i think then im is maker something wrong..
sorry my english..
-
I don't really know what's going wrong Neirao, did you put the blue sphere around the magnet and mesh01? As I described in the diagram, only the points and the faces that fall inside of the blue sphere are considered by the script. I admit that this is absolutely not an userfriendly tool - I'm not really making honour to the Anim8or philosophy.
I'm a bit stuck. I've made several trials but the only good thing I've been able to do is to use the red pulling sphere to move out the inner mouth from an highly detailed woman's head, after having cut half part away (see picture).
I'm working on another experiment, if I get it right I'll post it here.
[Edit: reading your post again I think I misunderstood it before. The script is running and is changing the points, but you don't get the result you expect. Well I think that for getting the result you expect you have to play with it a bit. If you don't mind, attach a project with the mesh that is giving you problems and I'll have a look, and thanks again for your attention and your interest Neirao. ]
-
I wish somebody suggested me to use vectors and stuff like the cross product and the dot product... I'm rewriting everything.
I've found a way to switch all the various modes without using materials (as I did in the first versions), without using that panel (which can be funny but not truly more than funny), and without using attributes.
Have a nice weekend.
-
Sweet! I'm just now learning dot product and all that in pre-calc :p
It's good to know progress is being made on making this easier, and I'm sure it's a great learning opportunity for you as well!
-
You can bet on it, I'm learning a lot of new things.
Have good study hihosilver
-
So sweet... I am no modeller but I fell in love with the newborn script attached below...
The polimagnet 3 script of some posts above has been downloaded 9 times. I downloaded it once, so at least eight people had a try at it - assuming that nobody downloaded it twice (me, eventually :P). So let's speak frankly, there must be a good modeller capable to make something cool with these scripts, among those who keep an eye here.
The new one that I am attaching below is a simple spherical magnet just like the very frist script of this thread, but it has some interesting features added:
- all triangle faces of mesh01 get automatically subdivided as you enlarge them with the magnet
- all modes are switched by changing the magnet's name (simple and effective, you doubleclick on the magnet, you change its name and you have switched the mode while the script is running).
- it can cause Anim8or to crash (yes, this is a feature, not a bug ;))
no, seriously, I don't know why but it crashes if you try to move too much points at once.
Believe me it's fun, have a try, you will not crash anim8or if you move few points at once - but save your work and don't leave any important project open in anim8or.
I don't want to force you to open the script and read the comments, hence I'm reporting them here.
/*
To use this script you need a mesh named "mesh01", as usual.
the script subdivides only triangular facets, you do the math,
I suggest you to try with a division 3 geodesic (and remember to
do "build->convert to mesh").
As for the magnet, you need a sphere named in one of the following ways:
(use lowercases exactly as reported into the double quotes)
"mag" --> push mode, change all coordinates
"mag x" --> push mode, change x coords
"mag y" --> push mode, change y coords
"mag z" --> push mode, change z coords
"mag xy" --> push mode, change xy coords
"mag yz" --> push mode, change yz coords
"mag xz" --> push mode, change xz coords
Add a minus sign for switching to pull mode (useful for
rushing points together, eheheeh, no, seriously, if you
use a really small magnet you can use pull-mode for
fine-point-tuning without using point-edit mode)
"mag-" --> pull mode, change all coordinates
"mag-x" --> pull mode, change x coords
"mag-y" --> pull mode, change y coords
"mag-z" --> pull mode, change z coords
"mag-xy" --> pull mode, change xy coords
"mag-yz" --> pull mode, change yz coords
"mag-xz" --> pull mode, change xz coords
Exceeding characters will be ignored, as well as
non-exact entries, hence, for example:
"magnet" --> "mag" (push mode, all dirs)
"mag-xyy" --> "mag-" (pull mode, all dirs)
Careful with doubled spaces:
.1234567. << chars 4 and 5, doubled space
"mag xy" --> "mag" (push mode, all dirs)
To strop the script (pick one):
- delete the magnet
- change magnet's name to an invalid one
(remember that all names starting with "mag" are valid names)
- delete "mesh01"
- rename "mesh01"
Don't worry if you start seeing holes in your models, they're not holes.
For some reason, some faces are there but aren't visible. If you save the
project and reopen it, you get a couple of errors about missing materials
and everything will be fine, your model will be a fully faceted arlequin.
*/
Sorry for posting just a silly example, but I want you to post some interesting one. You can use this tool far better than me, I'm sure. I'm also sure that when you're done with the volume you could build a really cool low-poly model out of the tri-models that this tool allows you to make.
I believe in Anim8ors.
-
Stuff you can do with the magnet and the morph targets... see the animated gif below.
-
Other stuff you can do, this time with the polimagnet and again with the morph targets: icosahedron to dodecahedron, see attached gif.
-
And once again with the automagnet, a very quick draft: The Clay Brothers.
-
Nicely Done! I hope to experiment a bit with this tool when my thanksgiving break starts in a few days.
-
Looks fun :D.
Kinda like a sculpting tool.
-
Thank you guys for your appreciation.
In effect it is all about making some sculpting tool for bad modellers like me :P.
Now the idea would be to build a well edge-looped low-poly model on top of an all-triangle model like the ones I posted above, and then to use the polimagnet script to stick the low-poly model on the tri-model volume.
The problem on my side is that I have no grip on good edge-looping, but I'm studying.
As for the scripts themselves, I'm going to rewrite the polimagnet script. I will make it use vectors and the same naming convention of the automagnet, to improve speed and ease of use.
The automagnet has a problem though. When the script starts, it reads all mesh01 faces' areas to get the largest, and from there on it uses this area as reference for subdividing the others as you enlarge them.
When I was making the puppet I posted above, I subdivided the faces that compose its head and I realised that those newly-created small facets were no longer subdivided automatically. The reason is clear: they're not large enough, because the script checks for the largest face on mesh01 to be used as reference.
I think I will change it to get the average of all faces' areas to be used as reference, and if some mesh01 face is selected when the script starts, then the area of that face will be used as reference. Sort of telling it: "this is the largest face I want from here on".
Thanks again for your attention, don't forget to share your experiments and to tell me your advice about improving these scripts, your comments and critics are welcome.
-
I've rewritten all the scripts and I've released them in another topic:
Magnet Tools Package (http://www.anim8or.com/smf/index.php?topic=1599.0)
Please refer to that topic for further discussion, thank you.
Consider this thread as locked.