Gamestudio Links
Zorro Links
Newest Posts
Zorro S for Oanda US
by SteveG. 06/06/20 15:24
The Black Book
by SteveG. 06/06/20 14:01
Indicator coding
by danatrader. 06/06/20 11:53
New AUM
by Aku_Aku. 06/06/20 10:10
Reading a TXT file on server
by Truth. 06/05/20 18:22
Oanda instruments
by Morris. 06/05/20 10:24
AUM Magazine
Latest Screens
The Space Between
Pogostuck: Rage With Your Friends
Worst Case Z
AckCon'18 - Lotter vs the World 2 - Preview Release
Who's Online Now
7 registered members (AndrewAMD, SteveG, kalmar, Grat, Mio, 3run, Iglarion), 478 guests, and 6 spiders.
Key: Admin, Global Mod, Mod
Newest Members
Frank_Shieh, PBSeven, Hardi01, Giuseppe, AdamWu
18461 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Pushing object with PhysX #480110
05/20/20 18:01
05/20/20 18:01
Joined: Oct 2010
Posts: 73
0110111
C
CodeMaster Offline OP
Junior Member
CodeMaster  Offline OP
Junior Member
C

Joined: Oct 2010
Posts: 73
0110111
I need help how to implement physics in my code, so the player can push objects, nothing more. I found 3run have a great example (59_rigid_template) but I want try implement this in my player code. When I register my player into physX, after that he can't move anymore, because now physics has primacy over my movement code. Is there a some easy way to make this? If I understand good, it has to do with pXent_getvelocity? Here is my code:

Code
#include <acknex.h>
#include <default.c>
#include <windows.h>
#include <strio.c>
#include <ackphysX.h>

var ph_gravity = 9.81;
VECTOR camera_move_to;
var camera_distance = 700;
var camera_tilt;

#define movement_speed skill2
#define rot_pan_to skill15 
#define rot_force_pan skill16 
#define rot_velocity_pan skill19 
#define move_x skill22 
#define move_y skill23 
#define move_z skill24 
#define force_x skill25 
#define force_y skill26 
#define force_z skill27 
#define velocity_x skill28 
#define velocity_y skill29 
#define velocity_z skill30 
#define foot_height skill38
#define soil_contact skill39
#define soil_height skill40
#define store_movement_speed skill56

var result_local;
var result2;
var pkey_up;var pkey_down;var pkey_left;var pkey_right;
var up_press;var down_press;var left_press;var right_press;

STRING* key__up = "cuu"; STRING* key__down = "cud"; STRING* key__left = "cul"; STRING* key__right = "cur";

VECTOR temp;
VECTOR temp_local;
ANGLE temp2;
ANGLE temp3;
VECTOR temp4;


function handle_input_startup (){
	while (1) {
		pkey_up = 0; pkey_down = 0; pkey_left = 0;pkey_right = 0;
		if (key_pressed(key_for_str(key__up)) == 1) { pkey_up = 1; }
		if (key_pressed(key_for_str(key__down)) == 1) { pkey_down = 1; }
		if (key_pressed(key_for_str(key__left)) == 1) { pkey_left = 1; }
		if (key_pressed(key_for_str(key__right)) == 1) { pkey_right = 1; }
		if (pkey_up == 0 && up_press == 1) { up_press = 0; }
		if (pkey_down == 0 && down_press == 1) { down_press = 0; }
		if (pkey_left == 0 && left_press == 1) { left_press = 0; }
		if (pkey_right == 0 && right_press == 1) { right_press = 0; }
		camera_distance -= mickey.z * time_step;
		camera_distance = clamp(camera_distance, 200, 1000);
		wait(1);
	}
}

function rotate_entity(ANGLE* rotate_angle,var rotate_speed) {
	if (my.pan == rotate_angle.pan) { return; }
	temp.x = ang(rotate_angle.pan - my.pan);
	if (temp.x > 0) { result_local = 1; }
	if (temp.x < 0) { result_local = -1; }
	my.rot_force_pan = rotate_speed * 0.3 * ang(rotate_angle.pan - my.pan);
	my.rot_velocity_pan += (time_step * my.rot_force_pan) - (minv(time_step*0.7,1) * my.rot_velocity_pan);
	temp.x = ang(rotate_angle.pan - (my.pan + my.rot_velocity_pan));
	if ((temp.x > 0 && result_local == -1) || (temp.x < 0 && result_local == 1)) { my.rot_velocity_pan = ang(rotate_angle.pan - my.pan); }
	c_rotate(my,vector(my.rot_velocity_pan * time_step,0,0),IGNORE_PASSABLE|IGNORE_YOU|USE_AXIS|USE_POLYGON|GLIDE);

}

function move_rotate_variable(variable_to_move,rotate_to_angle,rotate_speed) {
	if (variable_to_move == rotate_to_angle) { return(variable_to_move); }
	temp_local.x = ang(rotate_to_angle - variable_to_move);
	if (temp_local.x > 0) { result_local = 1; }
	if (temp_local.x < 0) { result_local = -1; }
	temp_local.y = 0.3 * rotate_speed * result_local;
	temp_local.x = ang(rotate_to_angle - (variable_to_move + temp_local.y));
	if ((temp_local.x > 0 && result_local == -1) || (temp_local.x < 0 && result_local == 1)) { temp_local.y = ang(rotate_to_angle - variable_to_move); }
	return(variable_to_move + temp_local.y);
}

function player_gravity(){
	if(my.force_z <= 0){
		vec_set(temp,vector(my.x,my.y,my.z-150));
		c_trace(my.x,temp,IGNORE_PASSABLE | IGNORE_ME | USE_BOX);
		if(!trace_hit) vec_set(target,temp);
		my.soil_height = target.z;
	}
	if(my.z > my.soil_height+(5+20*my.soil_contact)*time_step || my.force_z > 0) {
		my.soil_contact = 0;
		my.force_z = maxv(my.force_z-9*time_step,-90);
	}
	else{
		c_move(me,nullvector,vector(0,0,my.soil_height-my.z),IGNORE_PASSABLE);
		my.soil_contact = 1;
		my.force_z = 0;
		// jump code
	}
	if(my.force_z) c_move(me,nullvector,vector(0,0,maxv(my.force_z*time_step,my.soil_height-my.z)),IGNORE_PASSABLE); 
	if(HIT_TARGET && normal.z < -0.5) my.force_z = minv(my.force_z,0);
}

function handle_player_input() {
	my.velocity_x = 0;
	my.velocity_y = 0;
	my.move_x = 0;
	my.move_y = 0;
	temp2.pan = -1000;
	temp3.pan = 0;
	if (pkey_up == 1 && pkey_down == 0 && pkey_left == 0 && pkey_right == 0) { temp2.pan = camera.pan; }
	if (pkey_down == 1 && pkey_up == 0 && pkey_left == 0 && pkey_right == 0) { temp2.pan = camera.pan + 180; }
	if (pkey_left == 1 && pkey_down == 0 && pkey_up == 0 && pkey_right == 0) { temp2.pan = camera.pan + 90; temp3.pan += 5 * time_step; }
	if (pkey_right == 1 && pkey_down == 0 && pkey_left == 0 && pkey_up == 0) { temp2.pan = camera.pan - 90; temp3.pan -= 5 * time_step; }
	if (pkey_up == 1 && pkey_left == 1 && pkey_right == 0 && pkey_down == 0) { temp2.pan = camera.pan + 45; temp3.pan += 2.5 * time_step; }
	if (pkey_up == 1 && pkey_right == 1 && pkey_left == 0 && pkey_down == 0) { temp2.pan = camera.pan - 45; temp3.pan -= 2.5 * time_step; }
	if (pkey_down == 1 && pkey_left == 1 && pkey_right == 0 && pkey_up == 0) { temp2.pan = camera.pan + 135; temp3.pan += 6 * time_step; }
	if (pkey_down == 1 && pkey_right == 1 && pkey_left == 0 && pkey_up == 0) { temp2.pan = camera.pan - 135; temp3.pan -= 6 * time_step; }

	//move player
	my.store_movement_speed = my.movement_speed;
	if (temp2.pan != -1000) {
		my.rot_pan_to = temp2.pan;
		my.velocity_x = fcos(temp2.pan,my.store_movement_speed * time_step);
		my.velocity_y = fsin(temp2.pan,my.store_movement_speed * time_step);
	} else {
		my.rot_pan_to = my.pan;
	}
}

function process_movement() {
	result2 = my.movement_speed;
	accelerate(my.force_x,my.velocity_x*0.85,0.85);
	accelerate(my.force_y,my.velocity_y*0.85,0.85);
	rotate_entity(my.rot_pan_to,1);
	c_move(my,my.move_x,vector(my.force_x,my.force_y,0),IGNORE_PASSABLE | GLIDE);
}

function handle_camera() {
	camera_tilt = clamp(camera_tilt,-54,-54);//50
	temp.x = fcos(camera_tilt,-camera_distance);
	vec_set(camera_move_to.x,vector(my.x + fcos(camera.pan,temp.x),my.y + fsin(camera.pan,temp.x),my.z + 20 + fsin(camera_tilt,-camera_distance)));
	temp.x = minv(1,0.5 * time_step);
	temp4.x = minv(1,0.1 * time_step);
	camera.x += temp4.x*(camera_move_to.x - camera.x);
	camera.y += temp.x*(camera_move_to.y - camera.y);
	camera.z = player.z + 60;	
}

action ph_ball(){
	wait(1);
	c_setminmax(my);
	set(my, POLYGON);
	pXent_settype(my, PH_RIGID, PH_SPHERE);
}

action player_act() {
	player = my;
	my.emask |= (ENABLE_SCAN|ENABLE_DETECT|ENABLE_ENTITY);
	my.rot_pan_to = my.pan;
	while (1){ //the main loop
		player_gravity();
		handle_player_input();
		process_movement();
		handle_camera();
		wait(1);
	}
}

void level_init_physics(){
	physX_open();
	pX_setunit(0.02);
	ph_fps_max_lock = 120;
	ph_check_distance = 2;
	pX_setccd(1);
	pX_setgravity(vector(0, 0, -ph_gravity));
}

void main (){
	video_set(1920, 1045, 32, 2);
	collision_mode = 2;
	level_init_physics();
	wait(3);
	level_load("level.wmb");
}
 

Last edited by CodeMaster; 05/20/20 18:03.
Re: Pushing object with PhysX [Re: CodeMaster] #480111
05/20/20 21:51
05/20/20 21:51
Joined: May 2009
Posts: 5,265
Caucasus
3run Online
Senior Expert
3run  Online
Senior Expert

Joined: May 2009
Posts: 5,265
Caucasus
Hey, take a look at this example (it shouldn't be hard to integrate into your project)
Code
#include <acknex.h>
#include <default.c>
#include <ackphysX.h>

#define PRAGMA_POINTER

#define RIGID_GROUP 3
#define PLAYER_GROUP 4

// make sure that skill50 isn't already used in your project!
// if it is, then you need to change this skill50 to not used skill
#define OBJ_MOVING_SPEED skill50

void ph_body_event()
{
	if(event_type == EVENT_PUSH)
	{
		VECTOR speed_vec;
		vec_diff(&speed_vec, vector(my->x, my->y, 0), vector(you->x, you->y, 0));
		speed_vec.z = 0; // we ignore Z pushes, because they are not really needed in this demo
		// also as CharacterControl.cpp from the physX source code says:
		
		/*
		We only allow horizontal pushes. Vertical pushes when we stand on dynamic objects creates
		useless stress on the solver.
		*/
		
		// player's OBJ_MOVING_SPEED is affecting the pushing force
		// if you want to ignore player's moving speed and want to have constant pushing strength
		// then remove you->OBJ_MOVING_SPEED and play around with 10.0
		var coeff = you->OBJ_MOVING_SPEED * 10.0;
		vec_normalize(&speed_vec, coeff);
		pXent_addvelcentral(my, &speed_vec);
	}
}

function create_body(ENTITY *ent, var type)
{
	set(ent, LIGHT | UNLIT | CAST | SHADOW);
	
	ent->group = RIGID_GROUP;
	ent->push = RIGID_GROUP;
	
	ent->emask |= ENABLE_PUSH;
	ent->event = ph_body_event;
	
	vec_fill(&ent->scale_x, 0.6 + random(0.4));
	pXent_settype(ent, PH_RIGID, type);
	pXent_setelasticity(ent, 90);
	pXent_addvelcentral(ent, vector(2 - random(4), 2 - random(4), 0));
	
	var lifetime = 16; // after 16 seconds the body get's removed
	while(ent)
	{
		lifetime -= time_frame / 16;
		if(lifetime <= 0)
		{
			break;
		}
		wait(1);
	}
	
	ptr_remove(ent);
}

void ph_ball()
{
	vec_set(&my->blue, vector(0, random(100), 150 + random(100)));
	create_body(my, PH_SPHERE);
}

void ph_cube()
{
	vec_set(&my->blue, vector(150 + random(100), random(100), 0));
	create_body(my, PH_BOX);
}

void main()
{
	video_mode = 8;
	fps_max = 60;
	warn_level = 6;
	shadow_stencil = 2;
	sun_light = 5;
	
	physX_open();
	pX_setunit(0.05);
	pX_setgravity(vector(0, 0, -9.81));
	
	level_load("");
	
	ENTITY *ground_ent = ent_create(CUBE_MDL, nullvector, NULL);
	vec_set(&ground_ent->scale_x, vector(100, 100, 0.01));
	c_setminmax(ground_ent);
	set(ground_ent, LIGHT | UNLIT);
	vec_set(&ground_ent->blue, COLOR_GREEN);
	pXent_settype(ground_ent, PH_STATIC, PH_POLY);
	
	ENTITY *player_ent = ent_create(CUBE_MDL, vector(-128, -128, 16), NULL);
	vec_set(&player_ent->scale_x, vector(1, 1, 1.9)); // we set Z to 1.9 so player doesn't touch the ground ent
	c_setminmax(player_ent);
	set(player_ent, LIGHT | UNLIT | SHADOW | CAST);
	vec_set(&player_ent->blue, COLOR_WHITE);
	player_ent->group = PLAYER_GROUP;
	player_ent->push = PLAYER_GROUP;
	
	var movement_speed = 5, gnd_fric = 0.5;
	VECTOR input, speed;
	vec_fill(&input, 0);
	vec_fill(&speed, 0);
	
	var cam_dist = 256, cam_focus = 0, cam_mouse_sensitivity = 1.0;
	var spawn_counter = 0, spawn_time = 0.075;
	
	// rotate camera by default at center of the map
	vec_to_angle(&camera->pan, vec_diff(NULL, nullvector, &player_ent->x));
	camera->tilt = -25;
	camera->arc = 90;
	
	while(player_ent)
	{
		// spawn rigid bodies
		spawn_counter += time_frame / 16;
		if(spawn_counter > spawn_time)
		{
			ent_create(SPHERE_MDL, vector(random(20), random(20), 150), ph_ball);
			if(random(100) > 70)
			{
				ent_create(CUBE_MDL, vector(random(20), random(20), 170), ph_cube);
			}
			spawn_counter -= spawn_time;
		}
		
		fps_max = 60;
		if(key_space)
		{
			fps_max = 20;
		}
		
		// input and acceleration
		input.x = movement_speed * (key_w - key_s);
		input.y = movement_speed * (key_a - key_d);
		input.z = 0;
		
		// running
		if(key_shift)
		{
			input.x *= 2;
			input.y *= 2;
		}
		
		vec_rotate(&input, vector(camera->pan, 0, 0));
		accelerate(&speed.x, input.x * time_step, gnd_fric);
		accelerate(&speed.y, input.y * time_step, gnd_fric);
		
		// since player's group/push is set to 4 (PLAYER_GROUP) and c_move has IGNORE_PUSH set on
		// player will ignore all entities with the same or smaller group/push values (rigid bodies group/push set to RIGID_GROUP which is 3)
		// and will also trigger their ENABLE_PUSH/EVENT_PUSH events, where we will push them away
		// check out ph_body_event for more info
		var dist = c_move(player_ent, nullvector, &speed, IGNORE_PUSH | IGNORE_PASSABLE | GLIDE);
		player_ent->OBJ_MOVING_SPEED = dist / time_step;
		
		// fix player's Z position
		// so he doesn't move up or down on collisions
		player_ent->z = 16;
		
		// simple 3d camera with zoom in/out
		camera->pan = cycle(camera->pan - mickey.x / 6.5 * cam_mouse_sensitivity, 0, 360);
		camera->tilt = clamp(camera->tilt - mickey.y / 6.5 * cam_mouse_sensitivity, -90, 90);
		
		cam_dist -= 0.3 * mickey.z;
		cam_dist = clamp(cam_dist, 64, 512);
		cam_focus = fcos(camera->tilt, -cam_dist);
		
		camera->x = player_ent->x + fcos((camera->pan), cam_focus);
		camera->y = player_ent->y + fsin((camera->pan), cam_focus);
		camera->z = player_ent->z + 16 + fsin(camera->tilt, -cam_dist);			
		wait(1);
	}
}
However if you want more realistic collisions between player and physical objects, then I'd recommend to use rigid body for the player (instead of OBB collision detection).


Looking for free stuff?? Take a look here: http://badcom.at.ua
Re: Pushing object with PhysX [Re: 3run] #480120
05/21/20 14:54
05/21/20 14:54
Joined: Oct 2010
Posts: 73
0110111
C
CodeMaster Offline OP
Junior Member
CodeMaster  Offline OP
Junior Member
C

Joined: Oct 2010
Posts: 73
0110111
Hey 3run, thank you man, just what I needed. Works like a baby laugh

I only have problem when I use ignore_push in my movement code, the collision between the player and the static model stops working good as without ignore_push. I made a small test level where you can see when is ignore_push turned on in c_move, the player just doesn't stop when he hits the crate model, simply walk over it. On blocks still works good. For example I need that player only can walk on first small block and crate in level, but not on those biger.

https://easyupload.io/lbswpa

Re: Pushing object with PhysX [Re: CodeMaster] #480127
05/21/20 16:02
05/21/20 16:02
Joined: May 2009
Posts: 5,265
Caucasus
3run Online
Senior Expert
3run  Online
Senior Expert

Joined: May 2009
Posts: 5,265
Caucasus
Glad it helped!

By default push and group are set to 0 for all entities... So make sure to set them high for all obstacles.
Because c_move with IGNORE_PUSH will ignore everything with same or smaller push and group values...
Code
#define OBSTACLE_GROUP 10

void main()
{
	level_load("level.wmb");
	
	if(level_ent)
	{
		// we set group/push for level blocks
		level_ent->group = OBSTACLE_GROUP;
		level_ent->push = OBSTACLE_GROUP;
	}
}


Greets!


Looking for free stuff?? Take a look here: http://badcom.at.ua
Re: Pushing object with PhysX [Re: CodeMaster] #480139
05/21/20 21:15
05/21/20 21:15
Joined: Oct 2010
Posts: 73
0110111
C
CodeMaster Offline OP
Junior Member
CodeMaster  Offline OP
Junior Member
C

Joined: Oct 2010
Posts: 73
0110111
Works! Thank you 3run, you helped me a lot.

I have one more question, maybe you can help me because I download this gravity code from your page. How I can in this code reduce the height of the edge that the player can climb? For example, I do not use stairs in the game, but only flat surfaces. Now it happens to me that a player can climb on smaller crate model, at the place where he should stop, and there player must jump. This fast z moving looks really bad in game.
Should I need to use c_trace to detect if there is a block in front or there is some better solution? Example, now player can climb on crate where maximum z is 30, I want to reduce it on 5 or less.

Re: Pushing object with PhysX [Re: CodeMaster] #480140
05/21/20 21:31
05/21/20 21:31
Joined: May 2009
Posts: 5,265
Caucasus
3run Online
Senior Expert
3run  Online
Senior Expert

Joined: May 2009
Posts: 5,265
Caucasus
That is the main problem I've been fighting since I started creating movement codes with acknex... It's related to the ellipsoid hull that OBB uses. And unfortunately it can't be fixed with few lines of code. I'm planning to publish my current movement code (the one I came up with after years struggling with ellipsoid bbox hull) in the near future, I can only suggest waiting for it. Or use physX instead of OBB.


Looking for free stuff?? Take a look here: http://badcom.at.ua
Re: Pushing object with PhysX [Re: CodeMaster] #480141
05/21/20 22:01
05/21/20 22:01
Joined: Oct 2010
Posts: 73
0110111
C
CodeMaster Offline OP
Junior Member
CodeMaster  Offline OP
Junior Member
C

Joined: Oct 2010
Posts: 73
0110111
I'm sure take a look into this code when you publish it. I'll study your 59_rigid and 53_CCT code, maybe I'll try move my code to physX instead of OBB, but I afraid this will be pain work. I notice that cloth in CTT example not working, did cloth is generally problematic? I think I had problems in past with cloth in my game, so I gave up.

Re: Pushing object with PhysX [Re: CodeMaster] #480142
05/21/20 22:26
05/21/20 22:26
Joined: May 2009
Posts: 5,265
Caucasus
3run Online
Senior Expert
3run  Online
Senior Expert

Joined: May 2009
Posts: 5,265
Caucasus
The whole physX plugin is a mess (well, physX 2.x itself is pretty bad and limited too)... I'm currently trying to make PH_CHAR more or less useable to recreate my old CCT movement code. Also I remember I had problems with cloth not working too (it just didn't appear), but then with help of rojart we got it working. But then, I faced problems with removing the cloth (to load the level) and it's still unsolved. Give me a few days, I hope, I'll be able to get more or less working CCT (character controller with physX). But I'm currently working with the ackphysX community version, which doesn't have cloths at all. So, even if I'll get working CCT, note that there won't be any cloth in it.


Looking for free stuff?? Take a look here: http://badcom.at.ua
Re: Pushing object with PhysX [Re: 3run] #480143
05/21/20 22:49
05/21/20 22:49
Joined: Oct 2010
Posts: 73
0110111
C
CodeMaster Offline OP
Junior Member
CodeMaster  Offline OP
Junior Member
C

Joined: Oct 2010
Posts: 73
0110111
Yes now I remembered, the problem with the cloth occurred after the level change. Nevermind I just need this to put some flags in game, nothing special.

Ok, I'll be around and follow what's going on wink


Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1