Page 1 of 1

Script: Snap objects to ground

Posted: Sat Jul 18, 2015 10:54 am
by doc
I was looking for a way to automate a bit my workflow and I wrote these two functions that some might find useful.
So I decided to share them:

This function returns the "ground point" of the given position:
function getGroundPoint(%pos,%terrainOnly) 
{
	%mask = ($TypeMasks::GameBaseObjectType | $TypeMasks::PlayerObjectType | $TypeMasks::TerrainObjectType |
		$TypeMasks::StaticTSObjectType | $TypeMasks::StaticObjectType 
       | $TypeMasks::WaterObjectType |  $TypeMasks::DynamicObjectType
       |  $TypeMasks::RigidObjectType );
		
	if(%terrainOnly)
	{
		%mask = $TypeMasks::TerrainObjectType ;
	}
	
	%endPos = %pos;
	%endPos.z = -10000;
	%result = 0;
	%result = containerRayCast(%pos, %endPos, %mask);
	if(!%result)
	{
		%endPos.z = 10000;
		%result = containerRayCast(%pos, %endPos, %mask);
	}
	if(%result)
	   %retval = %pos.x SPC %pos.y SPC getWord(%result,3);
    else
	{
		warn("getGroundPoint(): RayCast can't find any object in range! Returning original position.");
		%retval = %pos;
	}
	return %retval;
}

And this one snaps a given object to the ground respecting its scale and preserving rotation:
function putOnGround(%obj)
{
	%transform = %obj.getTransform();
	%pos = getWords(%transform, 0, 2);
	%rot = getWords(%transform, 3, 6);
	%groundPos = getGroundPoint(%pos);
	%groundPos.z += %pos.z - getWord(%obj.getWorldBox(),2);
	%newTransform = %groundPos SPC %rot;
	%obj.setTransform(%newTransform);
}

here's some images to show the result:

The code is called from the console and is as simple as
putOnGround(myObject);
or
putOnGround(%obj);
before:
Image

after:
Image

and here with scale and rotated along an axis:

before:
Image

after:
Image

Re: Script: Snap objects to ground

Posted: Sat Jul 18, 2015 1:03 pm
by Dwarf King
I like that a lot! It comes handy when doing level design :D

Re: Script: Snap objects to ground

Posted: Sat Jul 18, 2015 1:16 pm
by doc
I'm glad you like it!
Technically it could also stack an object over another to make building blocks(see the rayCast mask).

Personally, I'll use it to spawn aircrafts directly on the carrier deck etc..

Re: Script: Snap objects to ground

Posted: Sat Jul 18, 2015 2:31 pm
by Duion
So you can snap objects of different sizes proper to the terrain and onto each other?
This sounds to me like the missing proper snapping function, if it works I would suggest to add it to the main repo as additional snapping option.

Re: Script: Snap objects to ground

Posted: Sat Jul 18, 2015 4:24 pm
by rlranft
Not to throw water on your fireworks, but terrain snapping for general object creation has been there forever:
T3D 1.2 -
Image
Just click that button to toggle this mode.

The part about snapping objects down on other objects is very nice, though. If the current snap were updated with that it would make things like placing objects on top of cave entrance geometry very easy.

All of that said - thank you for sharing! This script gives one the option of binding a key so that only the objects one wants to snap can be handled individually instead of wholesale based on editor snap mode.

Re: Script: Snap objects to ground

Posted: Sat Jul 18, 2015 6:04 pm
by doc
@ rlranft I already knew about the editor snapping function, but I wasn't sure if it would snap also in non-editor mode and/or on other shapes that are not a terrain. The point of the functions is to help me spawn (in my case)aircrafts over stuff like rigidShapes etc. by script and at random places.

For the cave I'd suggest to try by giving to castray a negative value and also change here:

Code: Select all

groundPos.z += getWord(%obj.getWorldBox(),2) - %pos.z; //inverted the order to snap to top

to make it snap from top(otherwise it would snap inside the shape).
I'm not sure tho if it wold work..

Re: Script: Snap objects to ground

Posted: Sat Jul 18, 2015 6:52 pm
by rlranft
Ah - no, I don't think the snap works outside of the editor.

But for the cave - I wasn't thinking inside as much as outside. When covering the hole in the terrain for the cave I usually use a model or collection of them, and because this script will snap to other objects it should be able to place "flavor" objects on top of this stuff.

As far as inside of a cave, that can be tricky - if your raycast starts from the "snapping" object's origin then it should work as is as long as you're inside the cave (because the object should be created by default at or near the camera) when you create the object. It would then be picking up the next object correctly (the cave) but you would then want to set the snapping object's position to the intersection point. Optionally, you could set the up vector to the face normal at the intersection point as well.

As I said - it's definitely a handy script, thanks for sharing.

Re: Script: Snap objects to ground

Posted: Sun Jul 19, 2015 3:42 am
by Dwarf King
The part about snapping objects down on other objects is very nice, though.
And that was what I found to be awesome. I often built bigger buildings/levels out of many pieces(big models cut into small pieces in Lightwave) and I really need this little feature to speed up the level building process :D

Re: Script: Snap objects to ground

Posted: Sun Jul 19, 2015 6:10 pm
by doc
I was wondering about what @
User avatar
rlranft
suggested..picking up the raycast contact point normal could also add the correct rotation to the object. Tomorrow I'll try to make some experiments but I'm not sure if I have the math to get the object rotation from the contact point normal..

Re: Script: Snap objects to ground

Posted: Thu Jul 23, 2015 3:15 pm
by rlranft
Aw hell, on one board or the other I am sure the rotation thing came up and some code was thrown around.... It was a few months back, pretty sure it was on the old GG boards, probably the T3D Pro forum, can't recall...