0 registered members (),
1,094
guests, and 1
spider. |
Key:
Admin,
Global Mod,
Mod
|
|
|
Re: Camera passing through wall
[Re: txesmi]
#471202
02/23/18 09:01
02/23/18 09:01
|
Joined: Jun 2010
Posts: 590 California
Ruben
OP
User
|
OP
User
Joined: Jun 2010
Posts: 590
California
|
That workaround fails when the view ray is nearly parallel to a surface the camera ends close to and the c_trace did not collide to. The only solution I know is the use of a dummy entity and USE_BOX in the trace.
action actCameraCollider () {
proc_mode = PROC_LATE; // execute after player action
my->flags |= INVISIBLE | PASSABLE | FAT | NARROW;
vec_set(&my->max_x, vector(16, 16, 16)); // collision hull
vec_set(&my->min_x, vector(-16, -16, -16));
VECTOR vOffset;
vec_set(&vOffset, vector(0, -7, 35)); // camera rotation center in player space
var nCamDist = 200; // distance to the center
...
vec_set(&my->x, &vOffset); // set the collider position in reference to the player position and orientation
vec_rotate(&my->x, &player->pan);
vec_add(&my->x, &player->x);
VECTOR vDir;
vec_for_angle(&vDir, &camera->pan); // compute the inverse of the view ray; the trace is backwards
vec_scale(&vDir, -nCamDist);
VECTOR vTarget; // compute the target position for c_trace
vec_set(&vTarget, &my->x); // it is also the final camera position when the trace collides nothing
vec_add(&vTarget, &vDir);
you = player;
var nDist = c_trace(&my->x, &vTarget, IGNORE_YOU | IGNORE_PASSABLE | USE_BOX);
if (nDist > 0) { // when it collides
vec_normalize(&vDir, nDist); // enshort the view ray
vec_set(&camera->x, &my->x); // and recompute the position of the camera
vec_add(&camera->x, &vDir);
} else { // when it does not collide
vec_set(&camera->x, &vTarget); // set the already computed position of the camera
}
...
Salud! Hello Txesmi. Thank you for your help again. Believe it or not, I am kind of new to the idea of using a dummy entity. Does it go something like this?
action actCameraCollider()
{
proc_mode = PROC_LATE; // execute after player action
my->flags |= INVISIBLE | PASSABLE | FAT | NARROW;
vec_set(&my->max_x, vector(16, 16, 16)); // collision hull
vec_set(&my->min_x, vector(-16, -16, -16));
VECTOR vOffset;
vec_set(&vOffset, vector(0, -7, 35)); // camera rotation center
// in player space
var nCamDist = 200; // distance to the center
vec_set(&my->x, &vOffset); // set the collider position in
// reference to the player position
// and orientation
vec_rotate(&my->x, &player->pan);
vec_add(&my->x, &player->x);
VECTOR vDir;
vec_for_angle(&vDir, &camera->pan); // compute the inverse of the
// view ray; the trace is
// backwards
vec_scale(&vDir, -nCamDist);
VECTOR vTarget; // compute the target position for c_trace
vec_set(&vTarget, &my->x); // it is also the final camera position
// when the trace collides nothing
vec_add(&vTarget, &vDir);
you = player;
var nDist = c_trace(&my->x, &vTarget, IGNORE_YOU | IGNORE_PASSABLE
| USE_BOX);
if (nDist > 0)
{ // when it collides
vec_normalize(&vDir, nDist); // enshort the view ray
vec_set(&camera->x, &my->x); // and recompute the position of
// the camera
vec_add(&camera->x, &vDir);
}
else
{ // when it does not collide
vec_set(&camera->x, &vTarget); // set the already computed
// position of the camera
}
}
action cameraDummy()
{
actCameraCollider();
}
void _handle_cam_3rdperson()
{
camDummy = ent_create(NULL,nullvector,cameraDummy);
}
action playerAction()
{
...
_handle_cam_3rdperson();
...
}
Last edited by Ruben; 02/23/18 09:02.
|
|
|
Re: Camera passing through wall
[Re: Ruben]
#471209
02/23/18 14:30
02/23/18 14:30
|
Joined: Jun 2007
Posts: 1,337 Hiporope and its pain
txesmi
Serious User
|
Serious User
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
|
here goes the whole thing
#include <acknex.h>
#define PRAGMA_PATH "%EXE_DIR%\templates\models"
#define skOffsetX skill1
#define skOffsetY skill2
#define skOffsetZ skill3
#define skDistance skill4
#define skDistSoft skill5
action actCameraCollider () {
proc_mode = PROC_LATE;
wait(1);
my->flags |= INVISIBLE | PASSABLE;
my->eflags = FAT | NARROW;
vec_set(&my->max_x, vector(8, 8, 8));
vec_set(&my->min_x, vector(-8, -8, -8));
vec_set(&my->skOffsetX, vector(0, -7, 35));
my->skDistance = 200;
my->skDistSoft = my->skDistance;
my->parent = player;
while (my->parent == player) {
my->skDistance = clamp(my->skDistance + mickey.z * 0.3, 20, 400);
camera->pan = player->pan;
camera->tilt = clamp(camera->tilt - mickey.y * 0.2, -80, 45);
vec_set(&my->pan, &camera->pan);
vec_set(&my->x, &my->skOffsetX);
vec_rotate(&my->x, &player->pan);
vec_add(&my->x, &player->x);
VECTOR vDir;
vec_for_angle(&vDir, &camera->pan);
vec_scale(&vDir, -my->skDistance);
VECTOR vTarget;
vec_set(&vTarget, &my->x);
vec_add(&vTarget, &vDir);
you = player;
var nDist = c_trace(&my->x, &vTarget, IGNORE_YOU | IGNORE_PASSABLE | USE_BOX);
if (nDist > 0)
my->skDistSoft += (nDist - my->skDistSoft) * time_step;
else
my->skDistSoft += (my->skDistance - my->skDistSoft) * time_step;
vec_normalize(&vDir, my->skDistSoft);
vec_set(&camera->x, &my->x);
vec_add(&camera->x, &vDir);
wait(1);
}
ent_remove(me);
}
#define skPan skill1
#define skAngle skill2
#define skMoveX skill3
#define skMoveY skill4
#define skMoveZ skill5
action actPlayer () {
player = me;
ent_create(NULL, &my->x, actCameraCollider);
wait(1);
my->eflags |= FAT | NARROW;
vec_set(&my->max_x, vector(16, 16, 32));
vec_set(&my->min_x, vector(-16, -16, -32));
my->skPan = 0;
my->skMoveZ = 0;
while (me == player) {
my->skPan = ang(my->skPan - mickey.x * 0.2);
my->skAngle = ang(my->skPan - my->pan) * time_step;
c_rotate(me, vector(my->skAngle, 0, 0), IGNORE_PASSABLE | GLIDE);
my->skMoveX = key_w - key_s;
my->skMoveY = key_a - key_d;
vec_normalize(&my->skMoveX, time_step * 10);
c_move(me, &my->skMoveX, NULL, IGNORE_PASSABLE | GLIDE);
wait(1);
}
ent_remove(me);
}
void main () {
video_mode = 10;
fps_max = 60;
wait(1);
level_load("level.wmb");
camera->clip_near = 1;
ent_create("player.mdl", vector(100, 100, 32), actPlayer);
while(!key_esc)
wait(1);
player = NULL;
wait(1);
sys_exit(NULL);
}
|
|
|
Re: Camera passing through wall
[Re: Ruben]
#471227
02/24/18 03:18
02/24/18 03:18
|
Joined: Jun 2010
Posts: 590 California
Ruben
OP
User
|
OP
User
Joined: Jun 2010
Posts: 590
California
|
Hello Txesmi. I tried using just your code, without using my code at all. It seems to work great, except if I turn quickly with my mouse. If I turn somewhat slow to medium speed, the camera stays within the wall while turning. If I turn quickly, I can see the blue past the wall for a split moment, before the camera moves back within the wall.
I am sure if I edit and tweek it as needed, that blue will disappear. This is just the first try with the code as it is, with no changes. Thank you.
Last edited by Ruben; 02/24/18 03:20.
|
|
|
Re: Camera passing through wall
[Re: Ruben]
#471229
02/24/18 09:25
02/24/18 09:25
|
Joined: Jun 2010
Posts: 590 California
Ruben
OP
User
|
OP
User
Joined: Jun 2010
Posts: 590
California
|
Okay. I changed some of the bounding box and camera location vec_set numbers in Txesmi's code to try and fit what I hope to have for my game. I probably should have mentioned this before, but I prefer the player model to be in between the left side of the screen and screen center, kind of like the video game "Dead Space". To do this, I changed:
vec_set(&my->skOffsetX, vector(0, -7, 35)); // CENTER BEHIND PLAYER
to
vec_set(&my->skOffsetX, vector(0, -27, 65)); // PLAYER IS BETWEEN
// LEFT SIDE OF
// SCREEN AND SCREEN
// CENTER.
Because I changed the location of the player to this location, I am now getting the same bug in Txesmi's code as I got in my original code shown in the beginning of this thread. The camera is again passing through the wall when the player pan rotates left close to a wall and its back starts facing the wall while turning, until it gets to about center, and then moves back inside the wall like it should for the remainder of the turn.
Last edited by Ruben; 02/24/18 09:30.
|
|
|
Re: Camera passing through wall
[Re: Ruben]
#471230
02/24/18 11:14
02/24/18 11:14
|
Joined: Jun 2007
Posts: 1,337 Hiporope and its pain
txesmi
Serious User
|
Serious User
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
|
Ok, I understand. That happens because the camera rotation center is orbiting out of player collision bounds and the trace starts cutting or in the other side of the wall so it does not collide. You might trace from a 'safe' point inside the player bounds to the hypothetical final position of the camera. But it will shake the whole projection for sure. Hard to be softened. I have not the clue.(not really) You might prevent the player get close to walls edited____________________________
#include <acknex.h>
#define PRAGMA_PATH "%EXE_DIR%\templates\models"
#define skOffsetX skill1
#define skOffsetY skill2
#define skOffsetZ skill3
#define skDistance skill4
#define skDistSoft skill5
#define skDirX skill6
#define skDirY skill7
#define skDirZ skill8
#define skTargetX skill9
#define skTargetY skill10
#define skTargetZ skill11
#define skOriginX skill12
#define skOriginY skill13
#define skOriginZ skill14
#define skCenterX skill15
#define skCenterY skill16
#define skCenterZ skill17
action actCameraCollider () {
proc_mode = PROC_LATE;
wait(1);
my->flags |= INVISIBLE | PASSABLE;
my->eflags = FAT | NARROW;
vec_set(&my->max_x, vector(8, 8, 8));
vec_set(&my->min_x, vector(-8, -8, -8));
vec_set(&my->skOriginX, vector(0, -5, 32));
vec_set(&my->skOffsetX, vector(0, -60, 40));
my->skDistance = 200;
my->skDistSoft = my->skDistance;
my->parent = player;
while (my->parent == player) {
my->skDistance = clamp(my->skDistance + mickey.z * 0.3, 20, 400);
camera->pan = player->pan;
camera->tilt = clamp(camera->tilt - mickey.y * 0.2, -80, 45);
vec_set(&my->pan, &player->pan);
vec_set(&my->x, &my->skOriginX);
vec_rotate(&my->x, &player->pan);
vec_add(&my->x, &player->x);
vec_set(&my->skCenterX, &my->skOffsetX);
vec_rotate(&my->skCenterX, &player->pan);
vec_add(&my->skCenterX, &player->x);
vec_for_angle(&my->skDirX, &camera->pan);
vec_scale(&my->skDirX, -my->skDistance);
vec_set(&my->skTargetX, &my->skCenterX);
vec_add(&my->skTargetX, &my->skDirX);
you = player;
var nDist = c_trace(&my->x, &my->skTargetX, IGNORE_YOU | IGNORE_PASSABLE | USE_BOX);
if (nDist > 0)
my->skDistSoft += (nDist - my->skDistSoft) * time_step * 2;
else
my->skDistSoft += (my->skDistance - my->skDistSoft) * time_step * 2;
vec_diff(&my->skDirX, &my->skTargetX, &my->x);
vec_normalize(&my->skDirX, my->skDistSoft);
vec_set(&camera->x, &my->x);
vec_add(&camera->x, &my->skDirX);
wait(1);
}
ent_remove(me);
}
#define skPan skill1
#define skAngle skill2
#define skMoveX skill3
#define skMoveY skill4
#define skMoveZ skill5
action actPlayer () {
player = me;
ent_create(NULL, &my->x, actCameraCollider);
wait(1);
my->eflags |= FAT | NARROW;
vec_set(&my->max_x, vector(16, 16, 32));
vec_set(&my->min_x, vector(-16, -16, -32));
my->skPan = 0;
my->skMoveZ = 0;
while (me == player) {
my->skPan = ang(my->skPan - mickey.x * 0.2);
my->skAngle = ang(my->skPan - my->pan) * time_step * 2;
c_rotate(me, vector(my->skAngle, 0, 0), IGNORE_PASSABLE | GLIDE);
my->skMoveX = key_w - key_s;
my->skMoveY = key_a - key_d;
vec_normalize(&my->skMoveX, time_step * 10);
c_move(me, &my->skMoveX, NULL, IGNORE_PASSABLE | GLIDE);
wait(1);
}
ent_remove(me);
}
void main () {
video_mode = 10;
fps_max = 60;
wait(1);
level_load("level.wmb");
camera->clip_near = 1;
ent_create("player.mdl", vector(100, 100, 32), actPlayer);
while(!key_esc)
wait(1);
player = NULL;
wait(1);
sys_exit(NULL);
}
Last edited by txesmi; 02/24/18 11:45.
|
|
|
Moderated by mk_1, Perro, rayp, Realspawn, Rei_Ayanami, rvL_eXile, Spirit, Superku, Tobias, TSG_Torsten, VeT
|