GetAbsOrigin(): Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
No edit summary
 
 
(11 intermediate revisions by 6 users not shown)
Line 1: Line 1:
'''<code>GetAbsOrigin()</code>''' returns the world co-ordinates of the [[origin]] of any [[point]] or [[model]] entity as a [[vector]]. This is ''normally'' either the centre of the object, but for NPCs (to choose a prominent example) will be a point exactly half way between the soles of their feet when in the [[reference posture]], or wherever else the modeller has placed it.
{{LanguageBar|GetAbsOrigin()}}[[Category:Functions]][[Category:Networking]]
{{ent|GetAbsOrigin()}} returns the absolute (i.e., [[world]]-relative) [[origin]] of an entity as a [[vector]]. Its sister function '''<code>SetAbsOrigin()</code>''' changes it.
 
The origin is technically stored in local space (i.e., [[parent]]-relative). If an entity has a parent, the <code>Abs</code> functions perform extra calculations to get the position relative to the world. This value is cached and only recalculated if the origin has changed since the last time it was used. On the other hand, '''<code>GetLocalOrigin()</code>''' and '''<code>SetLocalOrigin()</code>''' work directly with the stored origin (<tt>m_vecOrigin</tt>) with no extra calculations, so if one entity is parented to another entity, the returned origin will be relative to the origin of its parent. <code>Get/SetLocalOrigin</code> should only be used when world space isn't important (e.g. an entity that can't be parented) or is undesirable while an entity is parented.


== Alternatives ==
== Alternatives ==
A different approach for finding the position of an entity can be useful, particularly when dealing with a [[brush entity]] which might not have a valid origin. Bear in mind that these alternatives are all significantly more [[expensive]] than the "vanilla" functions listed above.
; {{ent|Vector|WorldSpaceCenter()}}: Returns the centre of an entity's [[bounding box]].
; <code>void CollisionProp()->CalcNearestPoint(&vecWorldPt,*pVecNearestWorldPt)</code>
: Finds the nearest point on the entity's bounding box to <tt>vecWorldPt</tt>. Modifies <code>pVecNearestWorldPt</code> with the result instead of returning anything.


You may want to use a different method of finding an entity's location, particularly given the fact that <code>GetAbsOrigin()</code> will not work with [[brush]]es unless they are tied to an [[entity]] that creates one for them - which may well not mark the location of the object in any useful way!
== Cells ==
 
Starting with {{l4d|4}}<!--presumably-->, <code>CBaseEntity</code> transmits its origin in "cells." This splits the entity's local coordinate space up into cells of 32 units X/Y/Z, then uses that reduced range to compress the networked value to a mere 5 bits per ordinate. The index of the current cell also has to be networked, but it changes relatively infrequently.
{{todo|How many of these OBB functions work with vphysics?}}
 
;<code>WorldSpaceCenter()</code>
:Calculates the centre of an [[object-aligned bounding box]] in all three dimensions.
;<code>[[CollisionProp()]]->CalcNearestPoint( [[const]] Vector &vecWorldPt, Vector *pVecNearestWorldPt )</code>
:Calculates the nearest point to <code>vecWorldPt</code> of an [[object-aligned bounding box]].  
:{{note|Instead of returning a value, this function will modify whatever variable is passed for <code>pVecNearestWorldPt</code>.}}
 
{{todo|More...}}


[[Category:Functions]]
This system leads to a huge reduction in network traffic at the price of imprecision. The sensitivity of [[prediction]] requires the local player to be sent an uncompressed origin.
{{bugfix|In {{as}}, <code>CBasePlayer</code> assumes that an uncompressed origin will be sent… but does not actually send one. This leads to the client-side entity being stuck at the world origin.|Either network the origin yourself, or for a quick fix, override <code>ShouldRegenerateOriginFromCellBits()</code> and return <tt>true</tt>.}}

Latest revision as of 16:01, 18 July 2025

English (en)Translate (Translate)

GetAbsOrigin() returns the absolute (i.e., world-relative) origin of an entity as a vector. Its sister function SetAbsOrigin() changes it.

The origin is technically stored in local space (i.e., parent-relative). If an entity has a parent, the Abs functions perform extra calculations to get the position relative to the world. This value is cached and only recalculated if the origin has changed since the last time it was used. On the other hand, GetLocalOrigin() and SetLocalOrigin() work directly with the stored origin (m_vecOrigin) with no extra calculations, so if one entity is parented to another entity, the returned origin will be relative to the origin of its parent. Get/SetLocalOrigin should only be used when world space isn't important (e.g. an entity that can't be parented) or is undesirable while an entity is parented.

Alternatives

A different approach for finding the position of an entity can be useful, particularly when dealing with a brush entity which might not have a valid origin. Bear in mind that these alternatives are all significantly more expensive than the "vanilla" functions listed above.

Vector WorldSpaceCenter()
Returns the centre of an entity's bounding box.
void CollisionProp()->CalcNearestPoint(&vecWorldPt,*pVecNearestWorldPt)
Finds the nearest point on the entity's bounding box to vecWorldPt. Modifies pVecNearestWorldPt with the result instead of returning anything.

Cells

Starting with Left 4 Dead Left 4 Dead, CBaseEntity transmits its origin in "cells." This splits the entity's local coordinate space up into cells of 32 units X/Y/Z, then uses that reduced range to compress the networked value to a mere 5 bits per ordinate. The index of the current cell also has to be networked, but it changes relatively infrequently.

This system leads to a huge reduction in network traffic at the price of imprecision. The sensitivity of prediction requires the local player to be sent an uncompressed origin.

Icon-Bug.pngBug:In Alien Swarm, CBasePlayer assumes that an uncompressed origin will be sent… but does not actually send one. This leads to the client-side entity being stuck at the world origin.  [todo tested in ?]
Note.pngFix:Either network the origin yourself, or for a quick fix, override ShouldRegenerateOriginFromCellBits() and return true.