News | Forum | People | FAQ | Links | Search | Register | Log in
Mapping Help - Doom 3 Engine Edition
I thought it would be useful to have a mapping help thread dedicated to Doom 3 engine games only, as the regular thread seems to fill up very fast with Quake related posts.

So, apply here for Doom 3, Quake 4, Prey and ETQW related queries :}
I'll Start 
Glass sorting issues

I've been trying to create a glass material, or arrangement of different materials that will allow me to view multiple glass surfaces through each other with correct sorting.

I initially tried making several one-sided glass materials, all with vfp enabled but with different sort values in the hope that I could create a "window pane" by butting up two surfaces back-to-back, each with different sort values. In the case of a two-window setup, this window pane was duplicated, flipped and placed some distance away. The idea was that I would be able to view one window correctly through the other because the far window would always be showing a surface with a further sort value than the one facing me on the near window, regardless of which side of the window pane setup I was on.

Now this didn't work and with the help of Black Dog, I found that the problem was due to the vfp enabled surfaces stopping any other vfp surfaces behind them being drawn.

I can create an arrangement that does work, by having one of the materials vfp enabled and the other not. Now the funky thing is that the window surfaces always seem to sort correctly regardless of what sort values I set in my one-sided glass material as long as i can guarantee I can never be in a location where I'm looking through more than one vfp-enabled glass surface.

Why does this happen, does the additive alphablend of the glass surface make the arrangement always look the same regardless of whether the furthest surface is actually being drawn first? 
Good Idea On The Thread 
And I think the answer, Kinn, is that Doom3 is achieving sentience! 
Wow 
I read this, and I think "I thought mapping help was questions like 'how do I spawn in a monster when a door opens?'..." I obviously live in a simpler age =) 
Heh 
Well, game tech isn't growing any simpler that's for sure.

I had a brief spelunking expedition into some of the id maps to try to find areas where they might run into this problem. All the instances of seeing "glass-through-glass" I could find suffered from this problem, where the vfp glass in front would render the one behind invisible. However, you won't really notice this in game because the colour of the glass is set so dark that it becomes almost completely transparent, so a non-drawn glass surface becomes largely indistinguishable from an almost-transparent one, when viewed behind another glass surface.

This is fine when you want almost transparent glass, but what if (as in my case) you want a bit of texture to it? I guess I'll have to either be content with using the non-vfp versions, or I'll have to make use of the messy hack described in my earlier post. :/ 
Depth Testing 
I asked Rickmus. Here's the deal.

The scene is rendered without glass. This is stuffed in a buffer so it can be rendered as a texture later.

Special-sort transparency cases like glass then get rendered in reverse order so it overlaps properly, depth-buffer tested so it doesn't overlap what it's not supposed to, but the scene has already been captured. It's too expensive to recapture it after every transparent or VFP surface is rendered. So, through a pane of VFP glass you won't see another pane because that pane wasn't rendered yet when the scene was captured to the buffer used for distortion VFP's.

I feel all smart now, I should talk to RJ more often. 
Lunaran 
Awesome, thanks for asking - very useful info :) 
 
I noticed I have "frame" "1" set on the worldspawn entity in my map, and I have no idea why.

Looking back through all the archived versions of my map, I see that this has been set for well over a year, right back to the oldest version I have saved.

Any idea why this might be there and what it does? 
It's Supposed To Go On Animated Entities 
when you've got an imp or something spawned with an "anim" key because you want him to be in a certain anim right away, you can also have a "frame" key so it starts at a certain point in the anim.

you probably had a brush selected and clicked the little anim slider in the entity panel by mistake, so it automatically dropped that key onto worldspawn. it's harmless.

an 'origin' key on worldspawn, however, is not. avoid that at all costs, because it makes your map leak magically through nothing. 
Don't Change It! 
it will bring bad luck! ^_^; 
Ah Yes 
thanks Lunaran, I can see now how easy it would be to do that. I guess I can safely delete it

necros: on the other hand, it could be the source of the curse that's causing my map to take so long... ~_^ 
Curse?? 
I Cast Thread Necromancy, Like The Daemons Of The Elder World. 
Some quickies:

Doom 3
======

1) I've been making a lot of new materials lately. In the editor, I can quickly view changes to my existing images or materials with the commands "reloadimages" and "reloaddecls", but is there a way to load a brand new materal without having to exit and restart the editor?

2) Renderbumpflat. Lovely little command, but is there a way of using this without it exiting doom every single time? It's so annoying to have to restart doom to render out every single bloody normal map, especially when I'm constantly making changes. 
Fun With Angles 
Ugh. Anyone found this? To summarise - as part of a funky machine, i'm simply rotating a brush clockwise in the x-axis for a random amount of time. Then when it stops, I want to align it to one of 3 possible valves (corresponding to angular positions of (0,0,0), (90,0,0) and (270,0,0), depending on where it stopped, so that it rotates the least amount to reach a valve.

Should be simple. But I found that Doom stores angles in a funky way - e.g. when the rod *should* be at (180,0,0), its angles are actually stored as (0,180,180). In essence, the x-value of its angles field only ever has a range of 180 degrees (using anglemod360, that means the range is 0 <= x < 90, 270 <= x < 360), but the y and z will flip to 180 to compensate.

i've provided the relevant part of my script below in case anyone can spot if i'm doing anything particularly wrong. You'll have to excuse the formatting getting mullered...


void spinrod_spin(entity spinrod)
{
float rtime;
vector ang;

while(1)
{
rtime = 1 + sys.random(4);

spinrod.time(rtime);
spinrod.accelTime(0.5);
spinrod.decelTime(0.5);

spinrod.rotate('600 0 0');
sys.waitFor(spinrod);
sys.wait(0.5);

ang = anglemod360(spinrod.getAngles());
//sys.print(ang_x + "\n");
//sys.print(ang_y + "\n");
//sys.print(ang_z + "\n");
//sys.print("end\n");

//ok, the way angles are stored is a bit bollocksed up. in this case, a simple clockwise rotation in x does not result in what you'd expect...
//imagine dividing the rotation circle into 4 quadrants...
//from x = 0 to 90 (1st quadrant), everything is fine, but continuing clockwise past the 90 mark (into the 2nd quadrant), x decreases again to 0, whilst y and z are flipped to become 180..
//continuing clockwise into the 3rd quadrant, x becomes 360 and decreases towards 270. meanwhile y and z are still 180...
//continuing clockwise into the 4th quadrant, x now increases from 270 to 360, whilst y and z revert back to being 0.
//note that anglemod360 isn't mucking this up, because even without anglemod, the y and z 180-flip buggery still occurs.

//rotate the spinrod to the nearest valve, so as to avoid the minimum amount of rotation. FIXME - this is all bollocks because half the time it goes the bloody long way around (i.e. it spins in the opposite direction)
spinrod.time(1);
spinrod.accelTime(0.5);
spinrod.decelTime(0.5);

if (ang_x <= 90) //it's actually anywhere from 0 to 180
{
if (int(ang_y) == 0) //it's from 0 to 90
{
spinrod.rotateTo('90 0 0');
}
else //it's from 90 to 180, i.e. y and z are flipped to 180
{
//we don't have a valve in the 180 position; only at 0, 90 and 270
spinrod.rotateTo('90 0 0'); //uhh, just send it to 90 for the time being
}
}
else //it's actually anywhere from 180 to 360
{
if (int(ang_y) == 0) //it's from 270 to 360
{
spinrod.rotateTo('0 0 0');
}
else //it's from 180 to 270, i.e. y and z are flipped to 180
{
spinrod.rotateTo('270 0 0');
}
}

sys.waitFor(spinrod);
sys.wait(0.5);
}
}
 
I Had A Thought About This While Pooing. 
Didn't come up with anything clever though, except maybe you could try using
rotateDownTo and/or rotateUpTo instead of rotateTo. 
Angles 
i never really understood the problem, but i had major problems with angles too for something i was working on. i ended up making an invisible entity that flew around whilst maintaining a constant distance from the main object and then using a lookat function instead of rotation.

you may want to look into alternative methods of accomplishing your goal instead of relying on the (apparently?) buggy rotation stuff. 
Quirkiness 
czg: I never tried rotateUpTo and rotateDownTo to be honest. I'd have to take into account the craziness of the way the x-value of the angle alternately increases and decreases even as it moves constantly clockwise round the circle (remember, y and z keep flipping between 0 and 180 - even if i'm simply rotating in x) Depending on where it starts, rotateUpTo for example could send it either clockwise or anticlockwise. The results would be predictable however, so if I wanted my rod to always rotate clockwise to the next nearest valve, then i'd just have to figure out whether x is increasing or decreasing at the point where I start the rotation.

The problem has gone beyond what actually matters for the movement of my rod in this example to be honest - all my rod needs to do is adjust itself to one of three fixed orientations after it does the random spin - which it already does, because rotateTo will guarantee that it gets there, even if it sometimes goes the long way round. (which doesn't matter).

I just got a little carried away with trying to figure out the quirkiness of how angle values are stored, because I know this behaviour will bite me in the arse in the future whenever I do rotation stuff.

necros - heh, that sounds like a funky workaround. 
Kinn 
Might have to do with this, or then might not....
http://en.wikipedia.org/wiki/Gimbal_lock 
Bambuz 
funky - that Gimbal thing is interesting. In fact I was talking about this to a programmer at work and the first thing he said was "Gimbal lock" - but that might just have been his default comedy response to any poorly-explained problem with angles that a designer pesters him with.

I guess when getAngles() is called, it doesn't care about the history of how the entity has been rotating - it just calls the angles as it sees 'em.

Because a 180 degree rotation in x (and nothing else) results in the exact same end result as if you rotated 180 in y and then 180 in z (and nothing in x) - then Doom seems quite happy to return (0,180,180), instead of (180,0,0). 
Yeah 
it calculates the angles from the vectors or quaternions (how the stuff is really stored in the engine), so when there are multiple angle representations of a vector direction, you can get what you get... dunno. 
Quaternions 
are pure evil. T_T 
Kinn 
sounds like rotation order isn't XYZ. you could build the valve thing in the editor facing down the z-axis, rotate it first into the position you want in your script's main() (0 90 0 I think?) and then do all your rotation on z instead of x. this might only work in my head. 
Lunaran 
after a quick test, it looks like that would work - if i do the same rotation in the y-axis only, or the x-axis, then the angle value goes smoothly from 0 to 360 as I move clockwise.

still don't really understand why the x-axis should be different tho :{ 
Correction: 
if i do the same rotation in the y-axis only, or the x-axis

should read:

if i do the same rotation in the y-axis only, or the z-axis
Poles And Gimbal Lock 
The reason is probably what's called Gimbal Lock, although the name isn't very illustrative of the problem. The easiest way I can think of describing it is through FPS view angles.

Imagine you're running quake with some engine that lets you look 90 degrees up and down, and think about the unit vector describing the direction you are facing. Most of the time, there is a unique correspondence between this unit vector and the angle at which you are facing, each pair of pitch and yaw correspond to a different vector.

The only way that this does not hold is when you look straight up or straight down. Then regardless of how much you turn left or right, the vector describing the direction you're facing is the same, '0 0 1' or '0 0 -1'. This loss of a degree of freedom is what's called Gumbal Lock.

I'm guessing that when Doom3 represents angles it does it round the x-axis rather than the z-axis, although I've not really checked that out in theory or in the engine. The problem is a bit more complex than the illustration, as rotations in 3D have three degrees of freedom, not two. Quaternions represent these three degrees of freedom with 4 variables and 1 constraint, just like the 3D unit vectors describe pitch and yaw as 3 variables with 1 constraint. 
Arrgh 
That last bit is a little wonky, it's too late to be doing that kind of maths, probably best if you ignore it. 
Gumball Lock! 
that sounds delicious! 
Yeah 
I'm working with this now in another engine - it's a pain in the balls.

Basically the typical systems that use 0-360 are just so that stupid humans can understand what's happening.

Didn't post before because I hadn't got around to asking a programmer. 
Any Links To These Kinds Of Informaton? 
I remember when I was 14 asking my maths teacher if he knew how to plot a 3d image using maths, because I had made some simple scrolling doodles in BBC basic ! I figured out how to create a 3D effect, but were talking about black blocks with 16-colour lines, and you couldnt rotate the view... I never did get any further down that route (rabbit hole), as in "programming computers" TBH. 
Post A Reply:
Name:
Title:
Body:
message
question
exclamation
idea
flame
noflame
error
skull
beer
moon
pent
rocket
sheep
pacman
pig
cheese
worldcraft
gauntlet
crate
pitfall
pimp
smile
cool
sad
frown
oi
yay
tongue
evil
wink
neutral
q1
q2
q3
ut
hl
cs
doom
dkt
serious
cube
Website copyright © 2002-2017 John Fitzgibbons. All posts are copyright their respective authors.