2 registered members (AndrewAMD, juanex),
1,247
guests, and 6
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
Pushing object with PhysX
#480110
05/20/20 18:01
05/20/20 18:01
|
Joined: Oct 2010
Posts: 73 0110111
CodeMaster
OP
Junior Member
|
OP
Junior Member
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:
#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,370 Caucasus
3run
Senior Expert
|
Senior Expert
Joined: May 2009
Posts: 5,370
Caucasus
|
Hey, take a look at this example (it shouldn't be hard to integrate into your project)
#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).
|
|
|
Re: Pushing object with PhysX
[Re: CodeMaster]
#480127
05/21/20 16:02
05/21/20 16:02
|
Joined: May 2009
Posts: 5,370 Caucasus
3run
Senior Expert
|
Senior Expert
Joined: May 2009
Posts: 5,370
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...
#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!
|
|
|
Re: Pushing object with PhysX
[Re: CodeMaster]
#480142
05/21/20 22:26
05/21/20 22:26
|
Joined: May 2009
Posts: 5,370 Caucasus
3run
Senior Expert
|
Senior Expert
Joined: May 2009
Posts: 5,370
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.
|
|
|
Re: Pushing object with PhysX
[Re: 3run]
#480143
05/21/20 22:49
05/21/20 22:49
|
Joined: Oct 2010
Posts: 73 0110111
CodeMaster
OP
Junior Member
|
OP
Junior Member
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
|
|
|
Moderated by mk_1, Perro, rayp, Realspawn, Rei_Ayanami, rvL_eXile, Spirit, Superku, Tobias, TSG_Torsten, VeT
|