GUI Scripting: RenderDef
This page is part of a series. See GUI Scripting Language for overview.
Introduction
A renderDef allows dynamic projection of a 3D model, in its own separate world, onto a 2D surface. The orientation of the model can be dynamically and programmatically controlled. The only use of a renderDef in the core is for the compass that can be shown in the HUD, and whose orientation changes automatically as the player faces in different directions.
Of the Properties in Common, only a few are needed, such as the rect and making the background transparent. User variables will probably not be needed, but GUI:: Parameters will be vital to control the orientation of the model from a script.
Additional Properties Specific to RenderDefs
® = A property known as a "register", that can be altered at runtime by binding it to a GUI:: parameter, or in a "set" or "transition" script command. Other properties cannot be so altered.
Vector3of4 = A list of 4 floats (comma-separated in a Property declaration), but only the first 3 elements matter. This is a workaround for lack of vector3 parsing support by GUI script. By convention, use "0" or "1" as fourth element.
RenderDef Properties – Used in TDM Core
Lightcolor vector3of4 ®
Color of the light. Elements in range 0 to 1. This is RGB, not RGBA. Default is 1,1,1,1 (white).
lightColor 1, 1, 1, 1
Lightorigin vector3of4 ®
Position of the light. Default is -128,0,0,1.
lightOrigin -50, 0, 50, 0
Model "path_to_model_file"
Model (.ase or .lwo file, not model def) to render. For simple models, this is as a func_static entity.
model "models/darkmod/player_equipment/compass.ase"
Modelorigin vector3of4 ®
Position of the model. Default 0,0,0,0.
modelOrigin 0, 0, 0, 1
Modelrotate vector3of4 ®
Rotation by Euler angles (-180 to 180 or equivalently 0 to 360 degrees). Vector elements are respectively pitch, yaw, and roll. See "Additional Notes" below for more. Default 0,0,0,0.
modelRotate ("gui::modelPitch"), ("gui::modelYaw"), ("gui::modelRoll"), 1 // controlled by playertools script; see example below.
Needsrender bool
Dirty flag. If 1 (true), something changed so the scene must be rendered again. Default is 0 (false).
needsRender 1
Noshadows bool
If 1 (true), prevents the model from casting a shadow, just like the familiar spawnarg on any entity. Default is 1 (true).
noshadows 1
Viewoffset vector3of4 ®
Position of the camera. Default -128,0,0,1
viewOffset -10, 0, 6, 1
Render Def Properties – Not Used in TDM Core
These appear to be intended for Articulated Figure models. Specifically, given the Animclass name, find the entityDef. Then look for its "model" specification. From that, find the modelDef, and within that, the md5animation matching the "anim_name".
Anim "anim_name"
Animation to play.
Animclass "class_name"
entityDef to grab the animation from.
Compass HUD Example
The tdm_gui01.pk4\guis\playertools\compass.gui by Drumple and greebo:
windowDef Desktop { rect 500, 290, 140, 180 backcolor 0 ,0 ,0 ,0 visible "gui::CompassVisible" nocursor 1 renderDef compassModel { rect 0, 0, 140, 180 visible 1 backcolor 0, 0, 0, 0 model "models/darkmod/player_equipment/compass.ase" needsRender 1 modelRotate ("gui::modelPitch"), ("gui::modelYaw"), ("gui::modelRoll"), 1 modelOrigin 0, 0, 0, 1 viewOffset -10, 0, 6, 1 lightOrigin -50, 0, 50, 0 lightColor 1, 1, 1, 1 noshadows 1 } } // Desktop
Then, in tdm_playertools.script, there is code that creates an overlay for the compass in the HUD and, when the compass is visible, updates its image every frame. The latter, which takes the player’s orientation and calculates the GUI Parameters "modelPitch", "modelYaw", and "modelRoll", is:
... #define COMPASS_MIN_PITCH -75 #define COMPASS_MAX_PITCH 40 void playertools_compass::updateCompass(entity userEntity) // userEntity is the player { _playerAngles = userEntity.getViewAngles(); float yaw = _playerAngles_y - 90; // Clamp the pitch to [COMPASS_MIN_PITCH .. COMPASS_MAX_PITCH] float playerPitchClamped = _playerAngles_x; if (playerPitchClamped > 0) { playerPitchClamped = COMPASS_MAX_PITCH * playerPitchClamped/90; } else { playerPitchClamped = COMPASS_MIN_PITCH * -playerPitchClamped/90; } float modelPitch = playerPitchClamped * sys.sin(yaw); float modelRoll = playerPitchClamped * sys.cos(yaw); userEntity.setGuiFloat(_overlayHandle, "modelYaw", -_playerAngles_y); userEntity.setGuiFloat(_overlayHandle, "modelPitch", modelPitch); userEntity.setGuiFloat(_overlayHandle, "modelRoll", modelRoll); } ...
Additional Notes
ModelRotate and Pitch, Yaw, and Roll
Think in terms of an airplane model, with origin at its center of gravity, and its own relative axes passing through the origin. Namely:
- x axis extends along the length of the plane. So forwards/backwards.
- y axis is perpendicular to that and right/left (wing-aligned).
- z axis is perpendicular to those axes and up/down (ceiling/floor aligned)
When the plane is on ground and facing north (compass angle 0), its axes are aligned with the world coordinates. Then, to describe a different orientation, 3 consecutive rotations about each of the plane's axes is done. The order that these are applied very much matters, and is:
- About the z-axis, called "yaw". (Other terms are pan or azimuth or heading). After this rotation, the plane's x/y axes are usually no longer aligned with the world x/y axes.
- About the y-axis, called "pitch". (Other terms are elevation or tilt). After this rotation, the plane's x/y/z axes are usually no longer aligned with the world x/y/z axes.
- About the x-axis, called "roll". This is "fall over sideways".
This is described in TDM’s Angles.h thusly:
idAngles uses the "yaw, pitch, roll" convention, in which the yaw rotation occurs first, then pitch occurs relative to the yawed axes, and finally roll occurs relative to the yawed and pitched axes. Also known as the "zyx" convention.
Unfortunately, the vector elements for idAngles and so ModelRotate must be entered in a different order:
- pitch
- yaw
- roll
For a fuller understanding, a good resource is D. Rose, "Rotations in Three-Dimensions: Euler Angles and Rotation Matrices - Part 1", Feb., 2015.
Light Bug, Now Fixed
Note bug 4569, discovered by Durandall. Lightcolor and lightorigin were ignored starting in TDM 1.08. Functionality was restored in 2.07.