Camera passing through wall

Posted By: Ruben

Camera passing through wall - 02/14/18 07:29

I am trying to make it so that if the player moves near a wall, and turns its back toward it while turning its body, the camera following the player will glide along the inside of the wall, pushing itself closer to the player's back, and then backs up to its normal following distance once the player's back is turned away from the wall.

I have a function that mostly does this. However, for some reason, while the player is turning its body while facing its front away from the wall (back toward wall), the camera will go behind the wall for the first 90 degrees on the left side of the turn instead of gliding on the inside of the wall, staying at the same distance behind the player as it would have with no collision detected, but then for the second 90 degrees of the turn on the right, the camera will start doing what I want it to do by gliding on the inside of the wall coming closer to the player's back for the remainder of the turn. It is always the first 90 degrees on the left side of the turn where the camera goes through the wall behind the player (what I do NOT want to happen), and always the second 90 degrees on the right of that same turn where the camera does not go through the wall and instead glides on the inside of the wall (what I would like to happen for the whole 180 degrees of this turn). This happens in the exact same manner from left to right, no matter what the wall, no matter where the wall is.

Here is my camera function:

Code:
void _handle_cam_3rdperson()
{
   c_rotate ( me, vector(-mickey.x * 0.3, 0, 0), IGNORE_ME |
              IGNORE_PASSABLE | IGNORE_SPRITES | USE_POLYGON |
              GLIDE );
		
   my.skNextPan = my.pan;
	
   my.skNextTilt = clamp ( my.skNextTilt - mickey.y * 0.3, 
                              -90, 90 );
   my.skNextRoll = 0; 
	
   VECTOR vecOrigin;	
			
   vec_set ( vecOrigin, vector(5,-25,40) ); 
   vec_rotate ( vecOrigin, vector(my.pan,0,0) ); 
   vec_add ( vecOrigin, my.x ); 	

   VECTOR vecTarget;
   vec_for_angle ( vecTarget, my.skNextPan );
	
   vec_scale ( vecTarget, -80 );
	
   vec_add ( vecTarget, vecOrigin );

   // THIS SEEMS TO BE WHERE THE ERROR LIES		
   var distance = c_trace ( vecOrigin, vecTarget, IGNORE_ME |
                            IGNORE_PASSABLE | IGNORE_SPRITES |
                            USE_POLYGON ); 
	
   if ( HIT_TARGET )
   {
      beep(); // THIS BEEPS DURING THE 2ND 90 DEGREES OF THE TURN IN
              //    QUESTION, NOT DURING THE 1ST 90 DEGREES.

      vec_set ( vecTarget, hit.x );
		
      if ( distance > 0 )
         reset ( me, TRANSLUCENT );
      else
         set ( me, TRANSLUCENT );
   
   }
   else
   {
      reset ( me, TRANSLUCENT );
   }
		
   vec_lerp ( camera.x, camera.x, vecTarget, time_step );
		
   vec_sub ( vecOrigin, camera.x );
   vec_to_angle ( camera.pan, vecOrigin );
}


It appears that this line of code is causing the error in question:

Code:
var distance = c_trace ( vecOrigin, vecTarget, IGNORE_ME |
                         IGNORE_PASSABLE | IGNORE_SPRITES |
                         USE_POLYGON );


The beep() right after the HIT_TARGET beeps like crazy during the 2nd 90 degrees of the turn sensing the collision, but does not beep at all during the 1st 90 degrees of the turn which shows that collision is not being detected. Why is the c_trace line from vecOrigin and vecTarget not being detected during the first 90 degrees of the turn, but is being detected during the second 90 degrees of the same turn?

Any help will be greatly appreciated. Thank you.
Posted By: Ruben

Re: Camera passing through wall - 02/16/18 05:21

Okay, made a little progress. I find that altering the xyz coordinates in:
Code:
vector(5,-25,40)


...for this code:
Code:
vec_set ( vecOrigin, vector(5,-25,40) );


...is changing the location of the c_trace line, and making the first part of the turn where the camera is behind the wall last shorter (like maybe first 30 degrees of turn), and more quickly start gliding inside the wall like I want it to (for about the last 110 degrees of the turn). Only thing is that I have to permanently change the camera position to accomplish this. It might work great for turning player with its back facing a wall, but when the player's back faces away from the wall, the camera is not in a position that I want it to be in.

Trying to make it so that the camera does not go through a wall when facing player's back against it during a turn, and also having the camera be where I want it to be when the player's back is facing away from a wall as well.
Posted By: DriftWood

Re: Camera passing through wall - 02/16/18 05:50

Very old engine means every simple thing is solved already on forum or...
http://opserver.de/twik11/index.php?title=Main_Page
Slin did this 8 years ago
http://opserver.de/twik11/index.php?title=Improved_3rd_Person_Camera
I think superku has done another one.
Then there is always
http://www.coniserver.net/coni_users/web_users/pirvu/aum/aumonline_e/
Posted By: Ruben

Re: Camera passing through wall - 02/17/18 04:05

Thank you Driftwood. I will check it out.
Posted By: Ruben

Re: Camera passing through wall - 02/20/18 01:02

So, it seems I made some progress. I changed this code:
Code:
var distance = c_trace ( vecOrigin, vecTarget, IGNORE_ME |
                            IGNORE_PASSABLE | IGNORE_SPRITES |
                            USE_POLYGON );


...to this:
Code:
var distance = c_trace ( player.x, vecTarget, IGNORE_ME |
                            IGNORE_PASSABLE | IGNORE_SPRITES |
                            USE_POLYGON );


The beep() just after the HIT_TARGET now beeps whenever the camera touches the wall (which is great), and the camera does not go behind the wall (which is also great), at least not entirely (which still gives me an issue).

The issue is, lets say you are the player, and your player's front side is facing a wall. You move your mouse left, making the player rotate left. The camera rotates with and behind the player, facing the player's back at all times, all while the right side of the camera moves closer toward the wall given that the player is rotating. The camera's right side makes contact with the wall, and glides along the wall, making it move closer to the player's back as the player keeps rotating, all the way till the player rotates so far to the point that its back is not facing the wall anymore, at which point the camera detaches from the wall and moves back to its original distance behind the player.

In the first half of this rotation where the camera makes contact with the wall, I can see a vertical sliver of blue on the right side of the screen past the wall (which is not great). The camera is not entirely moving through the wall like before, but it feels like a small section on the right side of the camera is peeking through the wall, as the camera glides along the wall. Once the camera reaches the middle of the rotation, making the camera face directly away from the wall and toward the player's back, the blue disappears (which is great). Once the camera reaches the opposite side of this same rotation, no blueness is present at all (which is great). This gives the feeling like the right side of the camera peeks through the wall, and the left side of the camera does not.

Does anyone have a clue on how to prevent the camera from peeking past the wall for the entire rotation, while the player's back is facing the wall?
Posted By: DriftWood

Re: Camera passing through wall - 02/20/18 03:03

The solution is to move the camera further away from the wall.

I don't read 3dgs code perfectly anymore.
Ok you seem to be placing the camera right at hit.x or in other words *on the surface of the wall.*

My solution would be to simply move vecTarget closer to the player after the set . Assume the camera has a size of 20.

Vec_set(vecTarget,hit.x)
**Now adjust the vec say 20 closer to the player.
Get the Vector from vecTarget to the player.
Normalize it to 20.
Then vec_add it to vecTarget ?? Or is vec_sub I forget.
Bam! Camera has extra room and is off the surface of the wall.
So I'll have to look at the manual and remember how to do that.
Posted By: DriftWood

Re: Camera passing through wall - 02/20/18 03:17

I'm guessing something like this.
Code:
Vec_set ( vecTarget, hit.x);
Vec_set (temp_vecA, player.x);
Vec_set (temp_vecB, vecTarget);
Vec_sub (temp_vecA, temp_vecB);
Vec_nomalize(temp_vecA, 20);
Vec_add (vecTarget, temp_vecA);
//Now vecTarget "should be" 20 units off the wall and closer to the player.


Other solutions could be putting the camera in abox. Using side traces from the camera. Using 3 traces to the wall and blending the vecTarget further to the open side. Or hiring a virtual monkey to fly the camera in the dangerous isolation of 3dgs space!!!
Posted By: DriftWood

Re: Camera passing through wall - 02/20/18 03:29

Wait!!! Cool idea! Why not just push off the wall using it's own normal?!
Yeah that could work!
Code:
Vec_set( vecTarget, hit.x);
Vec_set ( vec_temp, hit.nx);
Vec_normalize ( vec_temp, 20);
Vec_add ( vecTarget, vec_temp);
// Bam!!! Virtual Monkey!!!

Posted By: DriftWood

Re: Camera passing through wall - 02/20/18 03:34

Virtual Monkey freezes and dies in the cold frigid isolation of A8 3dgs space.
Alone and sad his body floats away.

But good news!
Aliens clone virtual monkey and resurrect him in another engines!!
He's saved and happy.
Posted By: Ruben

Re: Camera passing through wall - 02/20/18 08:42

Originally Posted By: DriftWood
Wait!!! Cool idea! Why not just push off the wall using it's own normal?!
Yeah that could work!
Code:
Vec_set( vecTarget, hit.x);
Vec_set ( vec_temp, hit.nx);
Vec_normalize ( vec_temp, 20);
Vec_add ( vecTarget, vec_temp);
// Bam!!! Virtual Monkey!!!


Interesting, I never heard of ".nx". I cannot seem to find it in the manual, or online. Where does it discuss the concept of ".nx"?*
Posted By: Kartoffel

Re: Camera passing through wall - 02/20/18 09:20

it's a 3-component-vector (should also be a unit vector) which is perpendicular to the surface (i.e. facing away from it)

http://www.conitec.net/beta/hit.htm
Posted By: DriftWood

Re: Camera passing through wall - 02/20/18 16:12

Kartoffel answers perfectly.

Haha - did the "hit" part escape you? Go to c_trace in the manual. There you'll find the link to the "hit" struc that holds even more cool data after a trace.
The concept of nx is the a Normal. A Normal unit vector is common in all 3D. It would truly be amazing if you have been working with 3D for so long and have no idea what a Normal are.

Here is your reading https://en.m.wikipedia.org/wiki/Normal_(geometry)
Posted By: Ruben

Re: Camera passing through wall - 02/21/18 03:01

Originally Posted By: DriftWood
Kartoffel answers perfectly.

Haha - did the "hit" part escape you? Go to c_trace in the manual. There you'll find the link to the "hit" struc that holds even more cool data after a trace.
The concept of nx is the a Normal. A Normal unit vector is common in all 3D. It would truly be amazing if you have been working with 3D for so long and have no idea what a Normal are.

Here is your reading https://en.m.wikipedia.org/wiki/Normal_(geometry)

Thanks for the sprinkling of condescension in your tone. I saw that one coming. I knew you couldn't reasonably be that chipper. ;-)

However, as long as I have been doing this, this is a part-time gig for me, as I have my full time bread and butter job. Got to keep a roof over my head. :-)

You are right, though. I should have linked it to the hit variable, and looked that one up. Learned a lesson. Thank you for the advice on what a Normal is.
Posted By: Ruben

Re: Camera passing through wall - 02/21/18 03:10

Originally Posted By: DriftWood
Wait!!! Cool idea! Why not just push off the wall using it's own normal?!
Yeah that could work!
Code:
Vec_set( vecTarget, hit.x);
Vec_set ( vec_temp, hit.nx);
Vec_normalize ( vec_temp, 20);
Vec_add ( vecTarget, vec_temp);
// Bam!!! Virtual Monkey!!!


I tried both your ideas inside the HIT_TARGET brackets, and both of them are not working. I am still seeing the vertical blue line on the right, in the first half of the rotation when turning right to left near a wall, with the player's back facing the wall.

In other words, I am getting the exact same result I already had. Nothing changed.
Posted By: DriftWood

Re: Camera passing through wall - 02/21/18 03:20

I see. Well great enjoy your hobby.
It's impossible for *"Nothing changed" to change. It is possible that the change was too small. After all we moved the vecTarget so something change. So let's assume the change is just too small. Than try this.
Code:
vec_set( vecTarget, hit.x);
vec_set ( vec_temp, hit.nx);
vec_normalize ( vec_temp, 555);// Huge change
vec_add ( vecTarget, vec_temp);



If you still see no change something else is happening.
If you see a big change, than adjust 555 down until close to correct.

I also don't understand this lerp
Code:
vec_lerp ( camera.x, camera.x, vecTarget, time_step );]


The value of Time_step is a small decimal. It's not collecting or adding to anything or itself. This could be a your big problem.

Try

Code:
..............
var range = 0;
.............

if(Taget_hit)
{
.........
if (range < 1)
range += time_step;
}
else
{
.....
range = 0;
}

vec_lerp ( camera.x, camera.x, vecTarget, range );]



I would like you to understand, I don't use this engine, I haven't in over a year. I don't have this engine installed and I work from memory, logic and looking in the manual to answer your questions. Finally I get nothing out of helping you, I answer for your benefit, my involvement is volunteer and I can stop if it's not to you're taste.

We all have jobs or other things to take our time. I currently am working on a project in another community and also learning a second engine, so my free time has other things to fill it than answering here.
Posted By: DriftWood

Re: Camera passing through wall - 02/21/18 04:10

Also check you clip_near and clip_far
Posted By: Ruben

Re: Camera passing through wall - 02/21/18 04:12

Originally Posted By: DriftWood
I see. Well great enjoy your hobby.
It's impossible for *"Nothing changed" to change. It is possible that the change was too small. After all we moved the vecTarget so something change. So let's assume the change is just too small. Than try this.
Code:
vec_set( vecTarget, hit.x);
vec_set ( vec_temp, hit.nx);
vec_normalize ( vec_temp, 555);// Huge change
vec_add ( vecTarget, vec_temp);



If you still see no change something else is happening.
If you see a big change, than adjust 555 down until close to correct.

I also don't understand this lerp
Code:
vec_lerp ( camera.x, camera.x, vecTarget, time_step );]


The value of Time_step is a small decimal. It's not collecting or adding to anything or itself. This could be a your big problem.

Try

Code:
..............
var range = 0;
.............

if(Taget_hit)
{
.........
if (range < 1)
range += time_step;
}
else
{
.....
range = 0;
}

vec_lerp ( camera.x, camera.x, vecTarget, range );]



I would like you to understand, I don't use this engine, I haven't in over a year. I don't have this engine installed and I work from memory, logic and looking in the manual to answer your questions. Finally I get nothing out of helping you, I answer for your benefit, my involvement is volunteer and I can stop if it's not to you're taste.

We all have jobs or other things to take our time. I currently am working on a project in another community and also learning a second engine, so my free time has other things to fill it than answering here.

I apologize. I really do sincerely appreciate your help.

I am realizing that your code actually does work. I am just seeing blue on the right half of the camera before the HIT_TARGET is activated in the exact middle of the camera, and once it is activated, the camera is pushed inside the wall using your code, as it needs to do. So, thank you. Thanks to you, the code is working as it should after the HIT_TARGET is activated.

Now I am trying to make it so that the:

Code:
var distance = c_trace ( player.x, vecTarget, IGNORE_ME |
   IGNORE_PASSABLE | IGNORE_SPRITES | USE_POLYGON );


...before the HIT_TARGET call makes collision on the right side of the camera, instead of its dead center. It seems to me that collision is happening only in the middle of the camera, instead of the actual side of the camera, making it so that the camera's right half peeks past the wall, until the wall hits center on the camera lens, then collision happens, and activates your code. I am trying to figure out how to make collision happen on the right side of the camera, so that I do not have to see the blue at all when turning the player's back toward the wall.

I will try to use your logic before the HIT_TARGET call to make the same thing happen before that call, as it does after.
Posted By: DriftWood

Re: Camera passing through wall - 02/21/18 05:54

Here is my best attempt from my mobile.
Two extra traces from camera left and right.


Code:
if ( HIT_TARGET )
   {

      vec_set ( vecTarget, hit.x );
      vec_set( vecTarget, hit.x);
      vec_set ( vec_temp, hit.nx);
      vec_normalize ( vec_temp, 20);
      vec_add ( vecTarget, vec_temp);

		
      if ( distance > 0 )
         reset ( me, TRANSLUCENT );
      else
         set ( me, TRANSLUCENT );
   
   }
   else
   {
      // CREATE A SIDE VECTOR FROM CAMERA
      vec_set(vec_temp,vector(0,20,0));
      // ROTATE TO BY CAM PAN AND ADD CAM VEC
      vec_rotate ( vec_temp, vector(camera.pan,0,0) ); 
      vec_add ( vec_temp camera.x ); 
      // YOUR CODE
      reset ( me, TRANSLUCENT );
      // TRACE SIDEWAYS FROM CAMERA
      distance = c_trace ( camera.x, vec_temp, IGNORE_ME |
                            IGNORE_PASSABLE | IGNORE_SPRITES |
                            USE_POLYGON | IGNORE_MODELS );
      //CHECK HIT
      if(HIT_TARGET)
        {
    /* ANOTHER WAY
     // SET DISTANCE INTO TEMP.Y ( POS trace = NEG Distance
         vec_set( vec_temp, vector(0,-distance,0));
         // ROTATE BY CAM PAN
         vec_rotate(vec_temp, vector (camera.pan,0,0);
         // ADD TO VecTarget ** because it's already available
         vec_add(vecTarget, vec_temp); */

      vec_set ( vec_temp, hit.nx);
      vec_normalize ( vec_temp, 20);
      vec_add ( vecTarget, vec_temp);

        }

        // REPEAT FOR LEFT TRACE !!!
        
      // CREATE A SIDE VECTOR FROM CAMERA ** CHANGE TO NEG VEC
      vec_set(vec_temp,vector(0,-20,0));
      // ROTATE TO BY CAM PAN AND ADD CAM VEC
      vec_rotate ( vec_temp, vector(camera.pan,0,0) ); 
      vec_add ( vec_temp camera.x ); 
     
      // TRACE SIDEWAYS FROM CAMERA
      distance = c_trace ( camera.x, vec_temp, IGNORE_ME |
                            IGNORE_PASSABLE | IGNORE_SPRITES |
                            USE_POLYGON | IGNORE_MODELS);
      //CHECK HIT
      if(HIT_TARGET)
        {
         /* // SET DISTANCE INTO TEMP.Y (*!  NEG trace = POS Distance
         vec_set( vec_temp, vector(0,distance,0));
         // ROTATE BY CAM PAN
         vec_rotate(vec_temp, vector (camera.pan,0,0);
         // ADD TO VecTarget ** because it's already available
         vec_add(vecTarget, vec_temp); */

      vec_set ( vec_temp, hit.nx);
      vec_normalize ( vec_temp, 20);
      vec_add ( vecTarget, vec_temp);
        }

   }	
	// REMOVED	
   //vec_lerp ( camera.x, camera.x, vecTarget, time_step );
    vec_set(camera.x, vecTarget);
		
   vec_sub ( vecOrigin, camera.x );
   vec_to_angle ( camera.pan, vecOrigin );
}



BTW vec_scale messes up the direction it should also be vec_nornalize
Code:
VECTOR vecTarget;
   vec_for_angle ( vecTarget, my.skNextPan );
	
  // vec_scale ( vecTarget, -80 );
     vec_normalize( vecTarget, -80);



Bonus homework - vec_scale and vec_normalize both multiply the elements of a vector. So find out what is the difference and why it is important.
Posted By: txesmi

Re: Camera passing through wall - 02/21/18 12:30

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.

Code:
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!
Posted By: DriftWood

Re: Camera passing through wall - 02/21/18 16:06

@Ruban txesmi presents the best solution and far better code( always) than I do. Take his advice.
I do reference you to my prior post which I suggest camera in a box. Txesmi presents the end evolution of using an invisible box entity for camera collision.

@txesmi you're still the best under the sun!
Posted By: Ruben

Re: Camera passing through wall - 02/23/18 09:01

Originally Posted By: txesmi
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.

Code:
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?

Code:
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();

   ...
}

Posted By: txesmi

Re: Camera passing through wall - 02/23/18 14:30

here goes the whole thing

Code:
#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);
}

Posted By: Ruben

Re: Camera passing through wall - 02/24/18 02:37

Thank you Txesmi. I will study your code, and let you know how it goes. Thanks again.
Posted By: Ruben

Re: Camera passing through wall - 02/24/18 03:18

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.
Posted By: Ruben

Re: Camera passing through wall - 02/24/18 03:47

Probably just a matter of changing the vec_set dimensions.
Posted By: Ruben

Re: Camera passing through wall - 02/24/18 09:25

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:

Code:
vec_set(&my->skOffsetX, vector(0, -7, 35)); // CENTER BEHIND PLAYER


to
Code:
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.
Posted By: txesmi

Re: Camera passing through wall - 02/24/18 11:14

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 grin

edited____________________________

Code:
#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);
}

Posted By: Ruben

Re: Camera passing through wall - 02/25/18 01:28

Thank you Txesmi, again! Your code makes the camera work perfectly! Thank you! You are a true genius! :-D
Posted By: txesmi

Re: Camera passing through wall - 02/25/18 09:02

glad to help laugh
© 2024 lite-C Forums