Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

simple llRezObject question

Jeremy Bender
anachronistic iconoclast
Join date: 12 Aug 2006
Posts: 99
11-18-2006 15:38
This is a rather trivial, picky problem but one that amateur and beginning scripters like myself might run into so I am posting it here for an answer, but also as an aide to others struggling with very simple problems in scripting.

I am building a small fireplace and I want the fire to appear inside the firebox on touch. The fire itself has to be rotated 90 degrees through the x axis, and offset by a tiny bit (down and to), from the main prim. It was easy enough to do until I realised that I had to take into account the possibility that the fireplace might not be ressed at <0,0,0>.

To make this work no matter what the orientation of the fireplace, was unnecessarily complex, but I finally worked it out with one exception. No matter what I do I cannot seem to get the offset to work exactly right.

When the fireplace is rotated (see picture, hopefully attached), the fire is ressed at the correct orientation, but ever so slightly off-centre. Even though 99% of the time the only rotation anyone would give to a fireplace would be around the Z axis, if you rotate the fireplace though the X or Y axis, the effect becomes quite glaring. I simply can't sleep until I figure out why this is so. I know it's probably something really simple but I have tried a zillion combinations and can't see it.

A free fireplace to the first person to show me the dumb mistake. :)

CODE

// ===================================
// Fireplacer script by Jeremy Bender
// ===================================


integer _fireOn;
vector _currentPos;
rotation _currentRot;
rotation _fireRot;

default
{

on_rez(integer start_param)
{
llResetScript();
}

state_entry()
{
llWhisper(59,"poke");
_fireOn = FALSE;
}

touch_start(integer total_number)
{
if (_fireOn){
llWhisper(59,"poke");
_fireOn = FALSE;
}
else{
_currentRot = llGetRot();
_currentPos = llGetPos();
_fireRot = llEuler2Rot(<PI_BY_TWO, 0.0, 0.0>); //rotation needed for fire

llRezObject("firelog & grate w/fire", _currentPos + <-0.1,0.0,-0.925> * _currentRot, ZERO_VECTOR, _fireRot * _currentRot, 42);
_fireOn = TRUE;
}

}
}
Anti Antonelli
Deranged Toymaker
Join date: 25 Apr 2006
Posts: 1,091
11-18-2006 16:16
It's not a dumb mistake IMHO, although you might smack yourself on the forehead like I did when you see the problem :D The thing is, the offset vector (<-0.1,0.0,-0.925>;) is static, it offsets in the same direction at all times, when it really needs to rotate with the fireplace. Your offset is so small it ends up looking like a subtle mysterious problem, but imagine: if you were rezzing your fire 1 meter up in the Z direction, then tilted it as in the pic, the fire would still be 1 meter directly straight up from the origin and would look totally wrong; it should be 1 meter up and to the side.

There's a pointer to a solution on the Wiki rotation page

http://www.lslwiki.com/lslwiki/wakka.php?wakka=rotation

Look at the example for rotating around an arbitrary point, and think about the fact that you need to rez the fire and rather than applying a static offset, the offset needs to be derived from the rotation of the fireplace, the arbitrary point of rotation being the prim that rezzed the fire.

I worked through this recently but unfortunately my script applies an llSetPos and llSetRot to object that are already rezzed, and I'm not smart enough to figure out how to make the math work with a rezzer like you have. Maybe that will get you started though, unless someone comes along with some solid code for you. :)

And all that said - have you considered just hiding/unhiding the flame with llSetAlpha? Might be a quick solution for you.
Joannah Cramer
Registered User
Join date: 12 Apr 2006
Posts: 1,539
11-18-2006 16:16
From: Jeremy Bender
CODE

llRezObject("firelog & grate w/fire", _currentPos + <-0.1,0.0,-0.925> * _currentRot, ZERO_VECTOR, _fireRot * _currentRot, 42);

entirely random guess but try to swap

_fireRot * _currentRot

around to

_currentRot * _fireRot

(combining quaternions give different results depending on order of components)
Jeremy Bender
anachronistic iconoclast
Join date: 12 Aug 2006
Posts: 99
11-18-2006 23:15
From: Anti Antonelli
It's not a dumb mistake IMHO, although you might smack yourself on the forehead like I did when you see the problem :D The thing is, the offset vector (<-0.1,0.0,-0.925>;) is static, it offsets in the same direction at all times, when it really needs to rotate with the fireplace. ...
Thanks for this reply, I was already thinking along these lines and had read the rotations page in the wiki many times over. I had already tried all the possible multiplication orders (as per Johannah's suggestion) as well.

The problem is indeed the static offset, but even though I spent all evening trying various combinations I think now that this is simply an impossible task.

If I was just rotating and object and setting it's position in space I can see how it could be done and the wiki is fairly clear on that, but since the position and the rotation of the ressed object have to be specified both separately yet at the same time in the llRezObject function, I just don't see how it could be done.

The offset needs to be rotated, but the wiki formula for arbitrary rotation around a vector envisions doing them both together whereas the llRezObject function requires you to do it separately.

All the various ways in which the vector describing the offset, or the sum of that and the vector (position) of the fireplace, or the difference of the two can be rotated, either fail to produce the correct result or simply fail to do anything at all. What I had thought to be the most obvious choice, (adding the offset vector to the fireplace vector and multiplying by the current rotation), compiles but produces a dead script.

I can only think of two very clumsy workarounds.

- The fire could be passed its new position from the parent prim of the fireplace, and use it's own LLSetPos call to position itself after it has ressed.

- I coud also simply add yet another prim to the fireplace and have a sort of "poseball" located at the offset point.

The other solution as you mention, is to have the log and the grate and the fire already in the fireplace and then merely animate the texture on the firesheet. I was avoiding that because the fire with the grate and the log is nine prims and I thought it made sense to be able to save those prims, since the fireplace is already seven prims.

The real solution is simply to be able to define an offset in the local frame of the prim in question, which may be possible but I just don't see it. When simple rotations and vectors are this difficult, it's no wonder that a junky solution like the "poseball" is king. ;)
Haravikk Mistral
Registered User
Join date: 8 Oct 2005
Posts: 2,482
11-19-2006 05:13
Joannah Cramer's code snippet should be all that you need. To have your offset work for all rotations you need multiply the offset by the rotation of the object.
If this is not working, then there is something else affecting your object.

Is the fire rezzing script in the root prim of the object? If not then the rotation you probably want to use is llGetRootRotation()
_____________________
Computer (Mac Pro):
2 x Quad Core 3.2ghz Xeon
10gb DDR2 800mhz FB-DIMMS
4 x 750gb, 32mb cache hard-drives (RAID-0/striped)
NVidia GeForce 8800GT (512mb)
Jeremy Bender
anachronistic iconoclast
Join date: 12 Aug 2006
Posts: 99
12-04-2006 18:58
From: Haravikk Mistral
Joannah Cramer's code snippet should be all that you need. To have your offset work for all rotations you need multiply the offset by the rotation of the object.
If this is not working, then there is something else affecting your object....
Okay, so this thread is a bit old now but I resurrect it because:

a) I have been working all this time and it *still* doesn't work! (I am an idiot I guess) :p

b) I "kind of" solved it and the solution is even more mystifying than the original problem!

Essentially I made a test bed of simple prims with a simplified version of the script so as to test the rotation of the offset with no other junk to mess it up. I started off with the original solution I had worked out for the rotation before I even started this thread and was going to work through all the possible solution methodically until I found the right one.

Unfortunately, (sort of), it worked on the very first go and has worked perfectly ever since. :eek:

So I had it right all along, and the wiki had it right, and all the hints I got on this thread were essentially right, but the sad thing is the script still does not work in the actual fireplace. The same script with the same variables works in the test construction, but *not* in the fireplace and the curious thing is that there is only one difference between them. The fireplace rezzes a fire which is multiprim object, whereas the test construction rezzes a simgle sphere. WTF?

To confirm that the rezzed object being single or multi-prim is the only difference and indeed the cause of the problem, I put a single sphere inside my fireplace and changed only the name of the object to be rezzed so it would rez the sphere instead of the fire. Bingo. Now the fireplace works every single time. However, the second I replace the single sphere with the multiprim fire object again, it stops working.

Here is the code:

CODE

// ======================================
// rez-rot test script by Jeremy Bender
// ======================================

integer _rezzed;
vector _currPos;
vector _currOffset;
vector _currPosPlusOffset;
rotation _currentRot;
vector _pos2Rez;

default
{
on_rez(integer start_param)
{
llResetScript();
}

state_entry()
{
llWhisper(59,"poke");
_rezzed = FALSE;
}

touch_start(integer total_number)
{
if (_rezzed){
llWhisper(59,"poke");
_rezzed = FALSE;
}
else{
_currentRot = llGetRot();
_rezObjRot = llEuler2Rot(<PI_BY_TWO, 0.0, 0.0>);
_currPos = llGetPos();
_currOffset = <1.0, 0.0, -1.0>;
_currPosPlusOffset = llGetPos() + _currOffset;

_pos2Rez = _currPos - ((_currPos * _currentRot) - (_currPosPlusOffset * _currentRot));

llRezObject("pink object 1", _pos2Rez, ZERO_VECTOR, ZERO_ROTATION, 42);
_rezzed = TRUE;
}

}
}



I simply cannot see how the fact that the object being rezzed has more than one prim has anything to do with this and would appreciate it if someone could show me why it does. There is only one rotation, and a couple of vectors that describe the position of the parent object, the offset, and eventually the "_pos2Rez" or position to rez the object is calculated from that. The object being rezzed has absolutely nothing to do with any of these variables as far as I can see.

And it's not that the final rezzed fire is off-place because it's centre is not the same as the parent prim of the fire "prim-set's" centre, the whole thing is seven prims or so and all are within 0.1 of each other.

What happens is that if the prim being rezzed is a multiprim object, the formula above fails to rotate the offset of the object. Almost as if it knows that it's about to rez a multi-prim object even though the script cannot know this.

How can a script that has no knowledge of *what* it's about to rez, and only calculates a vector at which the rez is going to take place, act one way if the object eventually rezzed is a sphere and another way if it is a multiprim object?

Is the occult at work in SL? :confused: Argh!
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
12-04-2006 19:29
From: Jeremy Bender
Is the occult at work in SL? :confused: Argh!


You mean no one has told about the script gremlins yet?

Me, I am waiting for the shoe makers elves to join SL and finish my scripts for me at night!!!!!

EDIT: Well actually we do have one script elf here. His name is Newgate :)
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
12-05-2006 01:45
From: Jesse Barnett
You mean no one has told about the script gremlins yet?

Me, I am waiting for the shoe makers elves to join SL and finish my scripts for me at night!!!!!

EDIT: Well actually we do have one script elf here. His name is Newgate :)


I'm an OGRE, not an ELF!
I smell and I make people cry, no no no thats onions, I've just got layers
Tiarnalalon Sismondi
Registered User
Join date: 1 Jun 2006
Posts: 402
12-05-2006 05:53
From: Jeremy Bender
What happens is that if the prim being rezzed is a multiprim object, the formula above fails to rotate the offset of the object. Almost as if it knows that it's about to rez a multi-prim object even though the script cannot know this.

How can a script that has no knowledge of *what* it's about to rez, and only calculates a vector at which the rez is going to take place, act one way if the object eventually rezzed is a sphere and another way if it is a multiprim object?


Try switching your llRezObject for llRezAtRoot. Multiple prim objects are going to have a different 'center' than normal, and it won't be where the root prim is most of the time. The script doesn't know it's a multiprim object, SL does and this is what makes it rez funny.

llRezAtRoot solves this problem by always using the coordinates on the root prim for placing the whole object.

I've heard that there are supposed to be problems with llRezAtRoot, but I haven't had much of any to speak of and I've been using it extensively in my newest ships for the saucer separation sequence and MVAM.