#336 posted by necros on 2010/04/21 02:54:22
a little bit more on SOLID_BSP and .velocity
a SOLID_BSP entity won't move unless it's .nextthink is non-zero. it doesn't matter what it's set to, although, obviously if it's less than ltime, it will be set to 0, just as long as it's set. if you set .velocity without setting .nextthink, no movement occurs (although the entity retains .velocity setting).
Preach, Re: 332
#337 posted by necros on 2010/04/21 06:09:30
preach, could you correct me if i'm wrong?
in post 332, i mention that time seems to more slower on ltime than real time.
say, on your bsp entity, you set:
self.nextthink = self.ltime + 0.01;
to loop a function over and over via .think.
if your framerate was really low, like 10fps. according to what you said above: The entity's .nextthink will occur before .ltime + host_frametime(within this frame) in which case ltime is increased only as far as .nextthink
if time = 0.
one frame goes by at 10fps:
if your nextthink is 0.01, but you are getting 10fps, then .ltime will be set to 0.01 even though real time = 0.1
we get ready for the next frame and set self.nextthink = self.ltime + 0.01; //next frame
.nextthink is 0.02 now.
now more frame at 10fps:
time is 0.2, but .ltime wil only be 0.02.
and so on and so forth.
ltime is only incrementing by 0.01, even though actual time is incrementing by 0.1.
am i getting this right?
Yup
#338 posted by Preach on 2010/04/21 10:05:33
Yeah, that's right. Remember it will also only move for 0.01 seconds per frame, so you need to set its velocity carefully if you are relying on velocity for motion.
#339 posted by necros on 2010/04/21 21:26:56
i made accelerating/decelerating movers but i couldn't find an acceptable way to make them accurate.
from what i have seen, it seems the only way to make it 100% accurate would be to externally set velocity via a helper entity. unfortunately, this would nullify the point of .blocked and ltime as a blocked mover wouldn't pause and would risk becoming out of sync.
as such, i've just left the acceleration with ltime and accepted the inaccuracy. it unfortunately means if you are getting really bad frame rate 10-20fps, you will see a marked increase in time for movers to complete their movements.
otoh, maybe if i accepted a lower precision by setting nextthink to ltime + 0.1 (use slower refreshes), it would decrease the disparity between time and ltime...
i'll have to see how that works out i guess. :S
Accellerated Progress
#340 posted by Preach on 2010/04/21 23:04:51
I think that there is a way to overcome these difficulties without a helper entity, so long as you're happy with a bit of not-really-calculus behind the scenes. You can get a version with one frame lag just by using a few entity fields to store some floats(and the one frame lag could be eliminated using the trick mentioned a few posts above of pushing updates to a mover's velocity during startframe, in order to occur before physics).
The key is to increment one of the variables by frametime in every frame which you are blocked. I'm writing out the details in my notebook currently, but it's the kind of thing that would really be best served with an external page full of diagrams and equation notation rather than a hurried post on this board. Perhaps even some genuine, complete QC code to prove I'm not chatting out my arse. Watch this space...
Lol
#341 posted by necros on 2010/04/21 23:46:49
well, i will definitely want to see what you are talking about, but bear in mind i'm not that much of a mathematician, so if it's as complicated as you are implying, i probably won't do it. ^_^;;
Running Dry
#342 posted by madfox on 2010/04/26 04:54:39
Hey Preach, did you receive my email?
I'm rather stuck in the monster toppic.
Hmm
#343 posted by Preach on 2010/04/26 10:34:59
Send it again, don't think I have it.
#344 posted by madfox on 2010/04/26 21:29:05
#345 posted by necros on 2010/05/11 04:37:26
.huntt_ime
Set to time + something when the player is in sight, but movement straight for
him is blocked. This causes the monster to use wall following code for
movement direction instead of sighting on the player. (sic)
in ai.qc
is this true? it sounds like a lie. :P
The Hunt Is Over
#346 posted by Preach on 2010/05/16 16:37:21
The only instance of "hunt_time" in the qc source is in the comment about ideal_yaw. I'm guessing it's something they used to do in ai_run. It may have been taken out because movetogoal tries the direct path to the enemy before using the wall following code. This would suppose that originally the function would call walkmove if hunt_time wasn't set, set hunt_time if walkmove returned false, and called movetogoal while hunt_time was active.
#347 posted by necros on 2010/05/16 21:05:02
ah that would make sense.
one thing i noticed about the movetogoal code...
it always seemed to me that doom had much better wall following code. quake monsters often get caught in areas when trying to path to the player, but doom monsters quite often turn up in surprising places especially if you watch them in the automap. quake AI seems to 'give up' wall following very early, usually before the wall following has a chance to get around a particular corner or whatever.
mm, that was random. :P
Well Then
#348 posted by meTch on 2010/05/17 01:44:31
we should just see how D00M does it,
and port it to,
(_)uake :D
.|
Monster Only Clip...
#349 posted by necros on 2010/05/31 21:35:41
i wonder if it would be feasible to take the func_togglewall and do this:
rename it to func_monsterclip
make it non-solid
movetogoal -> movetogoal_builtin
and then we make a new movetogoal that loops through all func_monsterclips, makes them solid, called the movetogoal_builtin and then afterwards, makes all the func_monsterclips nonsolid again.
#350 posted by necros on 2010/05/31 21:59:19
ran a little test.
instead of a generic monsterclip, i created a method to get larger bbox monsters to move correctly.
you essentially build your 'hull3' out of brushes and turn the entire thing into a single func_clipModel, and then you tie that clipModel to the monster you want to run collision with via clipModel->targetname editor key fields.
this could actually work because it won't impede smaller bbox monsters (that can use normal hull1/2 collision) since the clipModel is only every solid during that single monster's walk frame...
Necros:
#351 posted by metlslime on 2010/06/01 00:35:07
Nice, I'd really like to see some larger monsters or bosses/minibosses (that can actually move) in quake. This could be a piece of that puzzle.
#352 posted by necros on 2010/06/01 01:06:00
yeah, works pretty decent, but of course it imposes some limitations.
you need to 'clip' any area where the monster will be, of course, and that means you have to visualize the hull expansion yourself and implement it.
also, currently how i do it is to use the same method that hipnotic did for the func_togglewall and that is to just add '8000 8000 8000' to the origin when you want to turn it off, and then subtract the same vector when you want it on.
i don't know how big a deal it is if you had a generic monsterclip entity that EVERY monster in the map would have to toggle back and forth every animation frame. that could be pretty brutal.
it's probably better to somehow localize monster clips so only the monsters most likely to actually touch them will be toggling them (hence why i opted for a clipModel->targetname method instead of just putting it in walkmove and movetogoal). (large bbox monsters use a special wrapper for ai_walk and ai_run).
Some Problems
#353 posted by necros on 2010/06/01 01:33:09
quake seems to use start the hull2 bbox from the bottom left (mins) of the monster.
this means that if you use a bbox of size (for example) '-128 -128 -24' - '128 128 64' only the mins up to '-64 -64 64' is used when checking collision.
i thought that quake would start the hull2 size from the center of the monster, but this is not the case.
this creates a problem now because collision is still messed up.
if we resize the monster to hull2, call movetogoal and resize back to the new hull size, collision against the world (and func_clipModels) is fine, but the monster is now able to walk inside the player and other monsters.
i'll have to put more thought into this, i guess...
#354 posted by metlslime on 2010/06/01 02:59:10
Wait, how do shub and chthon work? They have large (stationery) bboxes and players seem to collide against them correctly.
#355 posted by necros on 2010/06/01 03:12:01
yeah, the collision of other bboxes is fine.
it's the collision against the world that is messed up.
and that's the big problem:
movetogoal will function correctly vs other bboxes if you set the bbox correctly. 256x256x128 or whatever.
movetogoal will function incorrectly vs world when bbox is set to 256x256x128.
if you set bbox to standard hull2 size before movetogoal and reset to 256x256x128 after, monster will move inside player.
what i've done so far is left the bbox at 256x256x128 and simply 'offset' the func_clipModel so that sides that the mins hits are smaller than sides that the maxs hits.
kind of hard to explain, when i figure everything out, i'll probably make a blog post about it with pictures to explain it properly.
also, another interesting (and annoying) side effect: because of the way the standard ai_run code is sandwiched between func_clipModel toggles such that the clipModel is active when ai_run is called, things like the visible() function fail if the player is inside the clipModel since visible uses a traceline to determine if the monster can see it (and since the clipModel is solid during that period, the trace hits the clipModel and determines the player is not visible).
Append
#356 posted by necros on 2010/06/01 03:16:11
another way to look at it is this:
for the purpose of bbox vs world, only the first hull2 coordinates starting at the mins are solid.
that is to say:
if the bbox was mins: -128 -128 -24, maxs: 128 128 64
world collision is done from -128 -128 -24 to -64 -64 64 (mins + VEC_HULL2_SIZE)
because VEC_HULL2_SIZE = 64 64 88
Oh I See...
#357 posted by metlslime on 2010/06/01 07:21:30
if you set the bbox down to standard hull2 size, it's collision against other entities is wrong. If you leave the bbox alone, its collision box is offset from the correct location.
Two ideas:
1. before moving the oversized entity, make ALL other solid entities (or at least all entities within a findradius) larger by XYZ amount, to compensate.
2. have two entities, one oversize and one normal size, and move them both. If either one is blocked, set both entities to the location of the blocked entity.
Not sure if either of these are completely workable.
#358 posted by necros on 2010/06/01 08:12:49
1. could work, except it's just (potentially) a lot of entities to enlarge.
2. this is better, but the problem is that if one is blocked, and we reset the position, nothing happens for that frame and likely movetogoal will try the same thing next frame.
currently what i've done is use bboxes on all the func_clipModels. this means each brush needs to be a seperate entity and we can't have sloped/angled faces anymore (since everything is just a box now).
it works and doesn't seem too slow, but we loose a bit of brush flexibility since we can't have any angles any more. of course, you're really just blocking out the area, so this could actually work. i'll leave it this way for now and test it out for now.
I'm Not Compensating. Really!
#359 posted by necros on 2010/06/10 22:31:26
http://necros.quaddicted.com/temp/dragon.jpg
the collision stuff has been working well without any further problems so far.
the really nice thing about it is that for monstrously large monsters like the dragon in that shot where you don't necessarily want the bbox to completely cover the entire model, all you have to do is expand the clipModel entities out further from the actual walls.
#360 posted by negke on 2010/06/10 22:36:16
Is that the DOE dragon?
|