View Issue Details

IDProjectCategoryView StatusLast Update
0004370Multi Theft Auto : San AndreasServerpublic2009-07-14 18:08
ReporterkarlozAssigned ToJax 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version 
Target VersionFixed in Version1.0 
Summary0004370: getObjectRotation() returns acumulated values for attached objects
Description

When you call getObjectRotation() on an object that is actually attached to other object, the function returns attachment offset but accumulate them in every call.

in the included code i create a car and an object attached to it with initial rotation rx=1,ry=1,rz=1

first time i call getObjectRotation() = 1,1,1
second time = 2,2,2
third time = 3,3,3

and so on..

object rotation doesnt changes

Additional Information

-- Example: test.lua --

-- Offsets
local x,y,z,rx,ry,rz= 0,-1.5,-0.1,1,1,1
local veh, base

function createArmedcar(player, cmd)
local lx,ly,lz = getElementPosition(player) -- get the position of the player
lx = lx + 5 -- add 5 units to the x position

veh = createVehicle( 422, lx, ly, lz) -- create a bobcat
base = createObject( 2985, 2,2,2) -- create a minigun_base object
attachElements ( base, veh,  x,y,z,rx,ry,rz) -- attach the base to the bobcat

end

function rotateIt(player, cmd, addZ)
if(addZ) then
rz=rz+addZ
--detachElements ( base )
attachElements ( base, veh, x,y,z,rx,ry,rz) --update offsets
end
end

function checkOffsets(player, cmd)
local a,b,c = getElementPosition(base)
local d,e,f = getObjectRotation(base)
if(a) then
outputDebugString("x:"..a..",y:"..b..",z:"..c.."rx:"..d..",ry:"..e..",rz:"..f)
else
outputDebugString("offsets:"..tostring(a))
end
end

addCommandHandler("bobcat", createArmedcar)
addCommandHandler("rotate", rotateIt)
addCommandHandler("check", checkOffsets)

TagsNo tags attached.

Relationships

parent of 0004405 closed Source patches Server Element Rotations 

Activities

Cazomino05

2009-05-26 22:20

reporter   ~~0009395

Last edited: 2009-05-26 22:23

This is actually not the real bug, the reason it increments is that the code above was commented out, Thus causing the function to increment each time.

The code above was supposed to reset the member variable storing the rotations with the real rotation of the object itself and therefore stop it incrementing.

to sum up what I have just posted:
"getObjectRotation" should not be returning relative positions in the first place, It should be returning the actual rotation which has caused this bug.

Edit:
The problem is in the server - deathmatch project
CObject.cpp
line 193

karloz

2009-06-01 00:22

viewer   ~~0009479

Last edited: 2009-06-01 00:23

I see, in CObject.cpp

if ( m_pAttachedTo )
{
    // TODO: fix this
    //m_vecRotation = m_pAttachedTo->GetRotation ();
    m_vecRotation += m_vecAttachedRotation;
}

but the real fix is at CElement

Actually CElement doesnt have Get/SetRotation functions, so you cant know if the function exists in m_pAttachedTo, thats why that code is commented out. As a fast fix [Get/Set]Roration virtual funtions should be added to CElement.

Current CElement::[Get/Set]Position doesnt check if element is attached, and most of attachable Elements need this. Non attachable Elements will evaluate if(m_pAttachedTo) => false

CElement.h

const CVector&              GetPosition             ( void );
void                        SetPosition             ( const CVector& vecPosition );

const CVector&              GetRotation             ( void );
void                        SetRotation             ( const CVector& vecRotatation );

CElement.cpp

const CVector& CElement::GetPosition ( void )
{
// Are we attached to something?
if ( m_pAttachedTo )
{
m_vecPosition = m_pAttachedTo->GetPosition () + m_vecAttachedPosition;
}

return m_vecPosition;

}

void CElement::SetPosition ( const CVector& vecPosition )
{
// If we're attached to something, dont change anything (attachment takes priority over moving here)
if ( m_pAttachedTo ) return;

// Different position?
if ( m_vecPosition != vecPosition )
{
    // Update our vectors
    m_vecLastPosition = m_vecPosition;
    m_vecPosition = vecPosition;
}

}

const CVector& CElement::GetRotation ( void )
{
// Are we attached to something?
if ( m_pAttachedTo )
{
m_vecPosition = m_pAttachedTo->GetRotation () + m_vecAttachedRotation;
}

return m_vecRotation;

}

void CElement::SetRotation ( const CVector& vecRotation )
{
// If we're attached to something, dont change anything (attachment takes priority over moving here)
if ( m_pAttachedTo ) return;

// Different rotation?
if ( m_vecRotation != vecRotation )
{
    // Set the new rotation
    m_vecRotation = vecRotation;
    //last rotation ??
}

}

this should work


Another related issue is this, in CPed (and derived class CPlayer)

inline float    GetRotation ( void )    { return m_fRotation; }
inline void     SetRotation ( float fRotation ) { m_fRotation = fRotation; }

If you attach something to a ped, the above GetRotation would fail
When Ped rotation changes, m_vecRotation doesnt

void CPed::SetRotation ( float fRotation )
{
// If we're attached to something, dont change anything (attachment takes priority over moving here)
if ( m_pAttachedTo ) return;

// Set the new rotation
m_fRotation = fRotation;
m_vecRotation.fZ= fRotation; 

}

m_vecRotation is not initialized in CPed constructor it should be initialized to 0 0 0

Linker should choose the correct GetRotation here:
m_vecPosition = m_pAttachedTo->GetRotation () + m_vecAttachedRotation;

When a ped is attached to an Element it rotates in X Y axes correctly but not
Z coordinate. I think in client Z coordinate is forced to this single fRotation

Cazomino05

2009-06-01 09:36

reporter   ~~0009481

"Actually CElement doesnt have Get/SetRotation functions, so you cant know if the function exists in m_pAttachedTo, thats why that code is commented out."

Hence why it isn't fixed yet if it was a simple job of un-commenting that line.

Issue History

Date Modified Username Field Change