Tutorial: Rotating Brush Models for QuakeWorld
I have something almost done that transparently supports origin brushes in the Worldcraft 3.3 Quake Adapter package without compiler support.
The preprocessing "nomapversion.exe" that strips out the "mapversion" field is being altered to locate origin brushes in entities and strip them out and substitute them with an origin field ("origin" "x y z").
This will make origin brushes with existing compilers available for playing around with in a quick way.
The preprocessing "nomapversion.exe" that strips out the "mapversion" field is being altered to locate origin brushes in entities and strip them out and substitute them with an origin field ("origin" "x y z").
This will make origin brushes with existing compilers available for playing around with in a quick way.
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
The preprocessor is done.
A couple of slight annoyances: txqbsp isn't, in fact, compatible even with the doors as-is. I think I had a super coincidence with the one time that it worked, I might have had the actual center @ 0,0,0 which is the only spot on the map that it may actually work with txqbsp.
And hmap2 doesn't like the texture alignments in Worldcraft 3.x (Valve 220 format) and some surfaces the textures aren't the same as in the editor. It also somehow crashes the editor upon compile (but I can work around that Still I'd like to find out why ...).
Haven't played around with the Half-Life compile tools yet, which already support all of this stuff anyway. I don't have whatever version of Visual Studio that is requierd to compile Zoner Tool's ... but since Zoner Tool's appears to support compiling via gcc and I have Cygwin all figured out now (I want to change some defaults and holy texture names and the hull size, of course )
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
I've done some more experimentation and it appears that hmap2 only messes up the texture alignment with "rotate_" brushes and otherwise so far appears to work completely fine with Valve 220 format.
I think I'm going to rapidly do something I said I'd never do in order to give it the kind of test it needs.
And since I now have defacto origin brush support, but it needs testing, I have a hilarious idea ...Note about Worldcraft 3.3 and hmap2 wrote:Something about hmap2 does crash Worldcraft 3.3 [probably something silly about Worldcraft], but that's fine for my purposes, I just wrote a little something to "encase" it to avoid the problem.
Besides, this little "encaser" is important because Worldcraft 3.3 doesn't support WAD2 and hmap2 doesn't support WAD3, but fortunately the Quake Adapter converts WAD2 to WAD3 so the "encaser" also changes .hlwad to .wad in worldspawn so I can transparently go about my business ...
I think I'm going to rapidly do something I said I'd never do in order to give it the kind of test it needs.
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Code note for NetQuake adaptations of this.
I ran into an annoying problem where after implementing Avirox's rotation support, backpacks from Enforcers and such would fall through the floor.
After examining the code, I have a have a small change that might even apply to the Quakeworld version.
I ran into an annoying problem where after implementing Avirox's rotation support, backpacks from Enforcers and such would fall through the floor.
After examining the code, I have a have a small change that might even apply to the Quakeworld version.
// ROTATE START
// rotate endpos back to world frame of reference
if (ent->v.solid == SOLID_BSP &&
(ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]) )
{
vec3_t a;
vec3_t forward, right, up;
vec3_t temp;
// Baker: note ... A couple of lines of this still needs done for non SOLID_BSP and SOLID_BSP without avelocity. At least in NetQuake for sure.
if (trace.fraction != 1)
{
VectorSubtract (vec3_origin, ent->v.angles, a);
AngleVectors (a, forward, right, up);
VectorCopy (trace.endpos, temp);
trace.endpos[0] = DotProduct (temp, forward);
trace.endpos[1] = -DotProduct (temp, right);
trace.endpos[2] = DotProduct (temp, up);
VectorCopy (trace.plane.normal, temp);
trace.plane.normal[0] = DotProduct (temp, forward);
trace.plane.normal[1] = -DotProduct (temp, right);
trace.plane.normal[2] = DotProduct (temp, up);
}
}
#if 1
// Non-Solid BSP and cases without avelocity.
else {
if (trace.fraction != 1)
VectorAdd (trace.endpos, offset, trace.endpos);
}
#endif
// ROTATE END
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Rotating doors ...
In Half-Life maps ...
Spawn flags appear to indicate the axis of rotation as such from hl_doors.qc from Avirox's QuakeLife.
Distance is maybe the degrees it opens it would seem.
Avirox has "hl_use" in the QuakeC quite a bit in the doors area, which appears to be for the "use" key in Half-Life.
In Half-Life maps ...
Code: Select all
{
"model" "*42"
"origin" "983 214 -64"
"healthvalue" "0"
"health" "0"
"lip" "0"
"wait" "-1"
"stopsnd" "0"
"movesnd" "0"
"dmg" "0"
"rendercolor" "0"
"renderamt" "0"
"rendermode" "0"
"renderfx" "0"
"_minlight" "0"
"distance" "60"
"speed" "180"
"targetname" "sine1"
"spawnflags" "98"
"classname" "func_door_rotating"
}
Code: Select all
if (self.spawnflags & DOOR_X_AXIS)
self.movedir_z = 1.0;
else if (self.spawnflags & DOOR_Y_AXIS)
self.movedir_x = 1.0;
else // Z_AXIS
self.movedir_y = 1.0;
// check for reverse rotation
if (self.spawnflags & DOOR_REVERSE)
self.movedir = '0 0 0' - self.movedir;
Code: Select all
float DOOR_REVERSE = 2;
float DOOR_X_AXIS = 64;
float DOOR_Y_AXIS = 128;
Code: Select all
self.pos1 = self.angles;
self.pos2 = self.angles + self.movedir * self.distance;
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Almost anti-climatically, I have rotating doors written in QuakeC.
Errr ... um ... well I ripped it from Avirox's work in QuakeLife but anyway the full implementation is now in hand.
1. entity definition
2. origin brush preprocessor (rips out origin brushes and substitutes origin coordinates into entity)
3. map compiler
4. the engine
5. the QuakeC
Maybe I can mellow out now. In the last 3-4 days, I've managed to successfully get a lot of things done. Only now do I realize being ripped away from all my projects back in February really affected my attitude. I had all these things I was in the middle of doing and then from out of nowhere .... SLAM ... zero time for months.
Errr ... um ... well I ripped it from Avirox's work in QuakeLife but anyway the full implementation is now in hand.
1. entity definition
2. origin brush preprocessor (rips out origin brushes and substitutes origin coordinates into entity)
3. map compiler
4. the engine
5. the QuakeC
Maybe I can mellow out now. In the last 3-4 days, I've managed to successfully get a lot of things done. Only now do I realize being ripped away from all my projects back in February really affected my attitude. I had all these things I was in the middle of doing and then from out of nowhere .... SLAM ... zero time for months.
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
I did this 2 days ago. Played several mods for hours. I just couldn't stop. That's why I love Quake.r00k wrote:Very true. Remember when we used to actually only play Quake?
QuakeWiki
getButterfly - WordPress Support Services
Roo Holidays
Fear not the dark, but what the dark hides.
getButterfly - WordPress Support Services
Roo Holidays
Fear not the dark, but what the dark hides.
Baker:
I looked back through world.c in Qrack and i'm using LordHavoc's early DP code,
if I place an ELSE before "//fix trace up by offset", as you have in your code:
then if I touch the backside of the door when its open I can walk through it and I am pushed out of it's radius.
I looked back through world.c in Qrack and i'm using LordHavoc's early DP code,
Code: Select all
trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end)
{
trace_t trace;
vec3_t offset, start_l, end_l;
hull_t *hull;
// fill in a default trace
memset (&trace, 0, sizeof(trace_t));
trace.fraction = 1;
trace.allsolid = true;
VectorCopy (end, trace.endpos);
// get the clipping hull
hull = SV_HullForEntity (ent, mins, maxs, offset);
VectorSubtract (start, offset, start_l);
VectorSubtract (end, offset, end_l);
// LordHavoc: enabling rotating bmodels
// rotate start and end into the models frame of reference
if (ent->v.solid == SOLID_BSP && (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]))
{
vec3_t forward, right, up;
vec3_t temp;
AngleVectors (ent->v.angles, forward, right, up);
VectorCopy (start_l, temp);
start_l[0] = DotProduct (temp, forward);
start_l[1] = -DotProduct (temp, right);
start_l[2] = DotProduct (temp, up);
VectorCopy (end_l, temp);
end_l[0] = DotProduct (temp, forward);
end_l[1] = -DotProduct (temp, right);
end_l[2] = DotProduct (temp, up);
}
// trace a line through the apropriate clipping hull
SV_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, &trace);
// LordHavoc: enabling rotating bmodels
// rotate endpos back to world frame of reference
if (ent->v.solid == SOLID_BSP && (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]))
{
vec3_t a;
vec3_t forward, right, up;
vec3_t temp;
if (trace.fraction != 1)
{
VectorNegate (ent->v.angles, a);
AngleVectors (a, forward, right, up);
VectorCopy (trace.endpos, temp);
trace.endpos[0] = DotProduct (temp, forward);
trace.endpos[1] = -DotProduct (temp, right);
trace.endpos[2] = DotProduct (temp, up);
VectorCopy (trace.plane.normal, temp);
trace.plane.normal[0] = DotProduct (temp, forward);
trace.plane.normal[1] = -DotProduct (temp, right);
trace.plane.normal[2] = DotProduct (temp, up);
}
}
// fix trace up by the offset
if (trace.fraction != 1)
VectorAdd (trace.endpos, offset, trace.endpos);
// did we clip the move?
if (trace.fraction < 1 || trace.startsolid)
trace.ent = ent;
return trace;
}
Code: Select all
#if 1
// Non-Solid BSP and cases without avelocity.
else {
if (trace.fraction != 1)
VectorAdd (trace.endpos, offset, trace.endpos);
}
#endif
exactly
Code: Select all
// set the abs box
// LordHavoc: enabling rotating bmodels
if (ent->v.solid == SOLID_BSP && (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]))
{
// expand for rotation
float max, v;
int i;
max = DotProduct(ent->v.mins, ent->v.mins);
v = DotProduct(ent->v.maxs, ent->v.maxs);
if (max < v)
max = v;
max = sqrt(max);
for (i=0 ; i<3 ; i++)
{
ent->v.absmin[i] = ent->v.origin[i] - max;
ent->v.absmax[i] = ent->v.origin[i] + max;
}
}
else
{
VectorAdd (ent->v.origin, ent->v.mins, ent->v.absmin);
VectorAdd (ent->v.origin, ent->v.maxs, ent->v.absmax);
}
My test implementation of rotation + rotation.qc I *can* walk through doors in DarkPlaces but not in an Avirox tutorial-modified engine (with or without that small extra modification I posted that keeps backpacks from falling through floors in NQ).
I'll see if I can finish a complete "package" this week for scrutiny.
R00k, I'm not quite sure what you are getting at (maybe I'm missing it) but adapting the Avirox-tutorial to NQ it was missing the original code (at least for NQ) for non-solid BSP which is all I added in with the ELSE clause.
I could post a before and after.
I'll see if I can finish a complete "package" this week for scrutiny.
R00k, I'm not quite sure what you are getting at (maybe I'm missing it) but adapting the Avirox-tutorial to NQ it was missing the original code (at least for NQ) for non-solid BSP which is all I added in with the ELSE clause.
I could post a before and after.
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
I downloaded your test map and qc in your .rar file
gamedir rotate
map rotate_example
the bridge is fine but the doors, ill open them go inside, turn left behind the door face back towards the starting spawn point then walk into the door, no clipping but then i get a big push in origin*forward. All because I put an ELSE in the code as you have.
using the SV_ClipMoveToEntity code (i posted earlier) without the ELSE in the last part
and your example works perfectly for me. I wasnt sure if that ELSE should actually be there.
gamedir rotate
map rotate_example
the bridge is fine but the doors, ill open them go inside, turn left behind the door face back towards the starting spawn point then walk into the door, no clipping but then i get a big push in origin*forward. All because I put an ELSE in the code as you have.
using the SV_ClipMoveToEntity code (i posted earlier) without the ELSE in the last part
and your example works perfectly for me. I wasnt sure if that ELSE should actually be there.