Jump to content

Rapid prim movement


WayneScott
 Share

You are about to reply to a thread that has been inactive for 1622 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

I want a steam engine with a particular aesthetic, and couldn't find it on the MP, so I started building it ... which is half the fun anyway :)

I have it built, and started scripting the moving parts. I'm cutting myself a fair bit of slack by having the flywheel attached to a 'hidden' camshaft (i.e. there is no camshaft, but you can't tell that because it's enclosed) but I really want a visible piston shaft, with noticeable movement.

Given that I've scripted the rest of the moving parts to permit me to vary the speed (which is all just llTargetOmega() anyway), the ability to change the rate that the cylindrical prim (piston shaft) is moving back and forth along it's axis is a must.

I've moved prims in the past, using llSetPos(), but that doesn't let me control the rate of movement. Research has turned up llSetKeyframedMotion() and llMoveToTarget() ... but I don't see any way to control the rate of movement with them suitably.

I'd appreciate it if someone could point me in the right direction, or even tell me what I want is impossible because it's 4 am and my brain is starting to leak out of my ears.

On that note, I'm going to bed. TIA for any assistance :)

 

 

Link to comment
Share on other sites

llSetKeyframedMotion and llMoveToTarget are useful for moving entire objects but the goal here seems to be moving parts of an object, for which the PRIM_POS_LOCAL parameter of llSetLinkPrimitiveParamsFast() is most suited. To control the speed of motion you'll vary the distance moved per update, the number of timer()-triggered updates per second, or both.

Keep in mind that, like llSetPos(), each update is a separate function call and a separate message from sim to viewer, which means a lot more lag than the simple fire-and-forget llTargetOmega(), so it's good practice to keep that timer as slow as possible while maintaining acceptably smooth motion.

A relatively recent thread has some potentially relevant sample code for a different application of oscillating motion.

[EDIT: I have only a vague sense of the object under development, but you may be satisfied using texture animation to "move" which of several "piston shaft" positions is opaque. That can be a whole lot less laggy and the speed is easily controlled by the rate parameter of llSetTextureAnim().]

Edited by Qie Niangao
  • Thanks 1
Link to comment
Share on other sites

In order to have both the reciprocating motion of a piston rod and the proper motion of the coupling and connecting rods you are going to have to learn puppeteering. This is done by using llSetLinkPrimitiveParamsFast to move the components several times a second. I have a steam engine where the wheels rotate, the coupling rods move with them, and puffs of steam occur four times each wheel revolution. All the positions of the components were worked out and are stored in lists so that there is no need to do any calculations whilst in motion. The locomotive moves by a pre-calculated amount for each change which is the fraction of the wheel circumference divided by the number of spokes, since each animation frame is based on the driving wheels rotating enough for one spoke to move to the next spoke position.

 

ETA Qie's point about the timer interval is important, in order to have a smooth-looking locomotive from the inside of the attached carriage you will need a quite fast timer,

Edited by Profaitchikenz Haiku
  • Thanks 1
Link to comment
Share on other sites

The design challenge here is how to relate the rotary motion of the wheel to the reciprocal motion of the camshaft.  Unlike in RL, where the camshaft's forward thrust drives the wheel, you'll have to translate the smooth rotation of the wheel into the pulsing movement of the shaft -- whose velocity changes as the sine of the rotational angle of the wheel.  My mind isn't up to the mathematics on a Saturday morning, but I would be inclined to model the problem in a set of integral steps -- a loop -- in which you calculate the position and rotation of the camshaft with every 10 or 20 degree rotation of the wheel and then apply it new values of PRIM_POS_LOCAL and PRIM_ROT_LOCAL with llSetLinkPrimitiveParamsFast.

Edit:   What Prof said ^^  ;)

Edited by Rolig Loon
  • Thanks 1
Link to comment
Share on other sites

I wrote a long reply, and then my browser crashed ... and I want to get back to the code so I'll go with a shorter version.

The device in question is a small, not more than 2 meters long, almost opulent looking object which you would see in a fairly luxurious steampunk setting. So it's a static engine and I don't have to worry about the issues that would be noticeable with something large like a locomotive (eg the surges at startup, etc).

The motion of the piston shaft is, at this stage, a little less than 0.5 meters and represents the only linear motion on the entire linkset. I would have loved to include a camshaft and connecting rod (having seen some amazing engines in-world) I decided that the script load represented by that was just too much. And, to be honest, the mental toll of trying to synchronise the motions of piston, conrod, and camshaft would definitely be beyond me.

 

6 hours ago, Qie Niangao said:

llSetKeyframedMotion and llMoveToTarget are useful for moving entire objects but the goal here seems to be moving parts of an object, for which the PRIM_POS_LOCAL parameter of llSetLinkPrimitiveParamsFast() is most suited. To control the speed of motion you'll vary the distance moved per update, the number of timer()-triggered updates per second, or both.

[EDIT: I have only a vague sense of the object under development, but you may be satisfied using texture animation to "move" which of several "piston shaft" positions is opaque. That can be a whole lot less laggy and the speed is easily controlled by the rate parameter of llSetTextureAnim().]

 

6 hours ago, Profaitchikenz Haiku said:

In order to have both the reciprocating motion of a piston rod and the proper motion of the coupling and connecting rods you are going to have to learn puppeteering. This is done by using llSetLinkPrimitiveParamsFast to move the components several times a second.

 

 

6 hours ago, Rolig Loon said:

 I would be inclined to model the problem in a set of integral steps -- a loop -- in which you calculate the position and rotation of the camshaft with every 10 or 20 degree rotation of the wheel and then apply it new values of PRIM_POS_LOCAL and PRIM_ROT_LOCAL with llSetLinkPrimitiveParamsFast.

Edit:   What Prof said ^^  ;)

 

6 hours ago, KT Kingsley said:

Qie mentions llSetTextureAnim. Maybe using this function in frame mode might work here if, say, 16 256 x 256 frames would make an acceptable effect.

 

We definitely have a consensus :)  I'll look at the use of llSetLinkPrimitiveParamsFast().

I may have to fall back on a texture animation, although I don't want to as the piston shaft I've made is specifically designed to have 'physical' features to make the motion more apparent, and I'd have to remove them and it would detract from the build.

 

Thanks everyone for your very helpful advice. :D

Link to comment
Share on other sites

7 hours ago, Lucia Nightfire said:

a single animation using bone translation

 

This is how the steam engines in the train simulators are done, yes.

Looking at the OP's more detailed description, a static power plant is going to be much easier than a railway engine as there is no need to adjust the inworld position. Texture animation to simulate the piston rod is a possibility of the engine is always running at constant speed and there is sufficient framework around to prevent an observer wandering around to view it from a different persective. Thing Grandfather clock, where the pendulum is only visible through the glass in the door at the front.

Link to comment
Share on other sites

I mentioned Animesh in the thread cited above, but it was for (what at least seemed to be) a low land-impact decoration, so I dismissed that option as impractical for that application. In contrast the object here is likely to need nearly the minimum Animesh land impact, but the complexity is that the speed of the moving parts needs to be continuously adjustable by the user; maybe this could be adequately reflected in Animesh by a range of different-speed animations, or maybe in a sequence of script-timed static poses (but that's back to timer() events). Anyway, it would be a project.

Just for clarity, the animated texture thing I suggested is not a flat image of a piston moving back and forth. Rather it's using texture animation to affect which part of a mesh is opaque, where each part is a full-formed piston (or whatever is moving around). So a single frame of the animation has stripes corresponding to the striped UV map, each stripe corresponding to one of the pistons; the full texture is a sequence of those frames, and played as looped, ping-pong cel animation to look like a single piston moving back and forth. Like llTargetOmega() this uses zero script time (for a set speed), but it does dramatically constrain the complexity of the piston's surface texture, and multiplies the geometric complexity of the moving part by as many "frames" as it takes to look like smooth motion (fine for a simple piston, but a problem for a complex moving shape).

Link to comment
Share on other sites

10 hours ago, Lucia Nightfire said:

The entire application could be done with rigged mesh and a single animation using bone translation

This can be achieved with rotation only also, assuming both wheel and piston are one single piece and with a nice animation setup of constraints. This limits the build's size adjustability though and for resizing, if needed, a different set of animesh parts would be required

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1622 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...