Rotate_objects With Mismatched Vis Connection
#10562 posted by necros on 2010/11/25 04:39:03
don't know the exact terminology for this, but essentially, bmodels are attached to vis areas to determine whether they are visible or not. if the player can't see any of the vis areas that the bmodel it attached to, the bmodel isn't drawn.
essentially what happens is that the rotate_object is somehow linked to the vis area at the origin and not with the vis area that the bmodel is actually located in.
so you get a rotate_object that flickers in and out of existence (or just plain isn't there if the '0 0 0' vis area is never visible).
i've learned a little more since the last time this happened to me and i know that using setorigin() on an entity 'links' it back into the world visibility or some-such.
so i open up the code and add a new line to the rotate_object function:
setorigin(self, self.origin);
this should link it in.
didn't work.
the other thing that plays a part in visibility is the bbox of an entity. so i put in:
setsize( self, '-512 -512 -512', '512 512 512' );
an arbitrary, very large, bbox.
ok, so it works now. yay!
but WHY?
rotate_object already sets it's size to self.mins and self.maxs. this works for 99% of rotate_objects that are made. why is it that occasionally i need to reset the bbox to some other value to get it to work?
is this a qbsp problem maybe? how does the engine first load up things like mins/maxs? it it precomputed or does the engine figure it out the first time?
Noob
#10563 posted by madfox on 2010/11/25 06:45:16
about coding, but could this bigger setsize not be the total of the start and end position?
#10564 posted by metlslime on 2010/11/25 09:35:29
Could be it has a huge bbox and touches too many vis leafs, this plagues large func_walls also. This problem has not been fixed in fitzquake yet as I don't know which numbers control that behavior.
#10565 posted by metlslime on 2010/11/25 09:35:30
Could be it has a huge bbox and touches too many vis leafs, this plagues large func_walls also. This problem has not been fixed in fitzquake yet as I don't know which numbers control that behavior.
Necros
#10566 posted by Preach on 2010/11/25 11:12:15
I would suppose that in order for the object to be visible one of the two must be true:
A) The bounding box must be large enough to fit the object at every point in its rotation.
B) The original bounding box is visible from every place that you can see the rotating object
B is what happens most of the time - although what might be termed a bug in the code is present, it doesn't manifest itself. In B I'm using visible in the sense of 'being in the engine's PVS', but 'see' in the sense of it being rendered for the observer.
For example, if you create an hour hand pointing to 1:30 in it's rest pose, the bounding box might be a square running from 12 o'clock to 3 o'clock. Then imagine you load it in game and move the hand to 7 o'clock. The bounding box does not rotate, so the hand is now completely outside the box, in the opposite quadrant. However it is still likely that in most places where you can see the 7 o'clock mark of the clock face, some part of the original bounding box is in the 'potentially visible set' that the engine gets from VIS.
I'm sure that in any case where the visible object can leave the original bounding box entirely, you can construct a point on the map where you can experience the bug. However, in most circumstances the rotating object is almost off-screen itself, and so it isn't apparent. Objects where their info_rotate lies some way outside their bounding box are much more susceptible to this. It's also worth noting that rotating your viewpoint can change what the engine deems visible.
So B is basically the usual situation, the bug is there all the time but by-and-large we get away with it. Setting the bounding box to some very large size moves us into category A - the rotating object never leaves its bounding box so no rendering bug can occur. We might ask how small can we make the bounding box and avoid the bug, both to keep overdraw down and to ensure that we do catch the entire size.
If we calculate the maximum of vlen(self.maxs) and vlen(self.mins) and call that x, then set the size of the bounding box to be '-x -x -x' to 'x x x'. This is sufficient and necessary, since we've found the furthest point from the rotation origin our object could be, and then created the smallest cube which contains a sphere of that radius.
Of course, this is only as optimal as a static bounding box can get. If the engine were to recalculate bounding boxes based on rotation then we would be home free. Since the engine doesn't bother, I wouldn't want to begin considering doing it in QC...
Splash Damage And Bboxes
#10567 posted by negke on 2010/11/25 15:36:04
Can someone please explain to me how that works - I'm getting a little frustrated here. I have a shootable button in a recess on the upper part of a wall small room. Shooting rockets at walls and floor doesn't affect it. However, there's a monster in front of it which somehow transfers the rocket's splash damage to the button. Or at least doesn't block it. What do I have to consider here?
#10568 posted by gb on 2010/11/25 18:18:21
> Could be it has a huge bbox and touches too many vis leafs, this plagues large func_walls also. This problem has not been fixed in fitzquake yet as I don't know which numbers control that behavior.
I think this is it. I'm pretty sure that was fixed in RMQ, probably DirectQ, Proquake etc. a while ago, I remember it being called the flicker fix or flickering bmodels fix.
#10569 posted by Preach on 2010/11/25 19:49:34
What do I have to consider here?
Splash damage against BSP objects is meted out based strictly on a traceline between {the midpoint of the entity's mins and maxs} and {the origin of the blast}. Monsters (strictly things with FL_MONSTER) are ignored by the traceline. If the trace_fraction equals 1 or the trace_ent is the BSP object in question then damage is inflicted.
I'm guessing that normally the centre of mass of the button can't be traced to, but that when hitting a monster the explosion gets a clean line of sight at it (ignoring the monster itself which doesn't count for these traces).
Ok
#10570 posted by negke on 2010/11/25 22:03:23
Makes sense. Moving the button further into the wall fixed it. Maybe I just expected too much of Quake's physics.
Oh How The Bsp Tree Taunts Me
#10571 posted by RickyT33 on 2010/11/26 00:08:03
Oh why, oh little cuboid light fitting, oh why do you taunt me so? How can there be 300 more vertexes when you are a func_illusionary, oh why?
#10572 posted by necros on 2010/11/26 05:40:12
Could be it has a huge bbox and touches too many vis leafs, this plagues large func_walls also. This problem has not been fixed in fitzquake yet as I don't know which numbers control that behavior.
i can confirm this has a high likely hood of being the problem as i just ran a quick test with the rmq engine that was release a few days ago and the problem isn't present.
thanks for helping clear this up for me. :)
the actual bbox dimensions that the engine was generating for the bmodel must have been even larger than 512^3.
#10573 posted by necros on 2010/11/26 05:42:01
ditto for DirectQ.
#10574 posted by metlslime on 2010/11/27 09:43:24
Check it with sv_showboxes 1 if you're curious.
Static Ents Modelindex
#10575 posted by negke on 2010/12/02 17:58:13
How does the static entity handling work? On mapstart things like illusionaries, ambient_ and flames are moved to the static roster and then removed from the entity list or something like that. Now how can I find out which modelindex they have, the flames for instance, without trying every single value?
Oh, Of Course
#10576 posted by negke on 2010/12/02 18:53:36
DP's "modellist" command!
(Thanks Preach 2005.)
Random Thought
#10577 posted by necros on 2010/12/02 21:18:32
if you were making a custom progs, you could create a new lightstyle, let's say #12 that was the same as #0 (always on).
then, every single pointlight in the map you would set to style #12 (instead of leaving it blank).
now, set up your sunlight which would be lightstyle #0.
you could make a map/mod where you started at dusk, with sunlight and an appropriate skybox, then mid-way through the map, have your qc change lightstyle 0 to off, making your sunlight disappear and swap to a nighttime skybox, leaving you with a full dark exterior wtih only pointlights still showing.
not ground breaking or anything, but it'd be cool to see...
Question
#10578 posted by Tronyn on 2010/12/03 05:06:48
is the maximum map size/grid in worldcraft/Hammer reflective of any limit in Quake itself and if not, is there any way to make the map size/grid bigger?
#10579 posted by necros on 2010/12/03 08:15:38
not quite sure what you are asking.
the maximum map size in glquake/fq is +-4096.
you can build beyond that range, but only the visual component will be correct. entities passing beyond those ranges 'loop around' to the other side of the map like pacman.
extended engines like DP allow you to build beyond the 4096 boundary.
Yeah...
#10580 posted by metlslime on 2010/12/03 08:37:24
the +=4096 boundary is purely a network protocol limit, not a limit in the quakec interpreter or map/bsp format.
#10581 posted by gb on 2010/12/03 21:46:25
If your editor has the 4096 limit hardwired into it, then that sucks. Both Quest and Radiant let you build wherever you want, so I'd be amazed if an editor actually limits you to that area o_O
hack the editor?
oh wait, would need source.
RMQEngine has that limit removed, too, and is Fitz-based.
One thing to remember with engines that use floats for coordinates is that when you have something very far away from (0 0 0) you can have floating point inaccuracies, or so ISTR. But ask a real engine coder ;-)
#10582 posted by metlslime on 2010/12/04 00:53:21
i don't think floating point inaccuracies will be a problem unless you are very far from the origin. Regular quake protocol precision is 1/8th of a unit. To reach precisions that low in floating point, you would need to be about 1 million units from the origin.
(reasoning: 23 bits devoted to the floating point value, 3 bits are fractional part if we want 1/8th unit precision, leaving 20 bits, 2^20 is about 1 million.)
GTKRadiant Ubuntu Crash Fixed
#10583 posted by gb on 2010/12/04 03:21:05
Would anyone know off hand why Gtkradiant wont work under Ubuntu 10.04? When I run it I get this error:
Gdk-CRITICAL **: gdk_window_get_window_type: assertion `GDK_IS_WINDOW (window)' failed
(process:1680): Gdk-CRITICAL (recursed) **: gdk_window_get_window_type: assertion `GDK_IS_WINDOW (window)' failed
aborting...
Aborted
Any ideas?
Also can anyone suggest any alternative map editors? (Ideally one that will run under Linux.)
Cheers!
This is the solution:
http://ubuntuforums.org/showpost.php?p=9919688&postcount=9
Compile Radiant manually after doing an SVN checkout.
Find the file in the sourcecode and switch these two lines around in a text editor. Then build.
There is a file COMPILING included with Radiant that lists the dependencies and tells you how to use scons to build it.
It works now (switched to ubuntu recently and had same problem).
My Radiant is hack'd anyway, so this wasn't a big problem.
#10584 posted by gb on 2010/12/04 03:35:04
and the explanation: It seems like a problem with Gnome, possibly a Gnome update b0rked this, not Linux as a whole.
Help With Camera Code !
#10585 posted by Mic Hey on 2010/12/05 15:00:45
I'm still in trouble with creation of a DAMN CAMERA for cutscenes !
A static camera would be enuff for me so I studied info_intermission code from client.qc
..this is my (wannabe)(not working)cam.qc:
// CAMERA BY MIK //
float cam_running;
float cam_exittime;
/*QUAKED info_cam (1 0.5 0.5) (-16 -16 -16) (16 16 16)
This is the camera point for the intermission.
Use mangle instead of angle, so you can set pitch or roll as well as yaw. 'pitch roll yaw'
*/
void() info_cam =
{
};
/*
============
FindIntermission
Returns the entity to view from
============
*/
entity() Findcam =
{
local entity spot;
// look for info_intermission first
spot = find (world, classname, "info_cam");
if (spot)
return spot;
}
void() Exitcam =
{
// skip any text in deathmatch
if (deathmatch)
{
GotoNextMap ();
return;
}
cam_exittime = time + 1;
cam_running = cam_running + 1;
self.view_ofs = '0 0 22';
}
/*
//
// run some text if at the end of an episode
//
if (cam_running == 2)
{
if (world.model == "maps/e1m7.bsp")
{
WriteByte (MSG_ALL, SVC_CDTRACK);
WriteByte (MSG_ALL, 2);
WriteByte (MSG_ALL, 3);
if (!cvar("registered"))
{
WriteByte (MSG_ALL, SVC_FINALE);
WriteString (MSG_ALL, "As the corpse of ");
}
else
{
WriteByte (MSG_ALL, SVC_FINALE);
WriteString (MSG_ALL, "As the corpse of t");
}
return;
*/
/*
============
IntermissionThink
When the player presses attack or jump, change to the next level
============
*/
void() camThink =
{
if (time < cam_exittime)
return;
if (!self.button0 && !self.button1 && !self.button2)
return;
Exitcam ();
};
void() execute_cam =
{
local entity pos;
cam_running = 1;
pos = Findcam ();
other = find (world, classname, "player");
while (other != world)
{
other.view_ofs = '0 0 0';
other.angles = other.v_angle = pos.mangle;
other.fixangle = TRUE; // turn this way immediately
other.nextthink = time + 0.5;
other.takedamage = DAMAGE_NO;
other.solid = SOLID_NOT;
other.movetype = MOVETYPE_NONE;
other.modelindex = 0;
setorigin (other, pos.origin);
other = find (other, classname, "player");
}
};
void() cam_touch =
{
local entity pos;
if (other.classname != "player")
return;
};
/*QUAKED trigger_cam (0.5 0.5 0.5) ? NO_INTERMISSION
When the player touches this, he gets sent to the map listed in the "map" variable. Unless the NO_INTERMISSION flag is set, the view will go to the info_intermission spot and display stats.
*/
void() trigger_cam =
{
if (!self.target)
objerror ("cam trigger doesn't have target");
InitTrigger ();
self.touch = cam_touch;
};
Well
#10586 posted by Preach on 2010/12/05 15:21:36
It's quite hard to diagnose your code if you don't describe the problem you're having with it, but I'll start with this:
void() cam_touch =
{
local entity pos;
if (other.classname != "player")
return;
};
This is the function that is run when an entity touches the trigger. It returns if that entity is not a player, which is sensible to prevent monsters or rockets setting off the camera. The problem is that this is the end of the function, so it doesn't do anything when a player does touch it.
Before you can start fixing the rest of the code, you need to call execute_cam after that if statement. I hesitated to recommend this though, because you've still got a lot of work to do for a feature that already exists in mods like custents...
|