Move Vertex in Direction of its Normal

Posted By: Pappenheimer

Move Vertex in Direction of its Normal - 08/21/11 14:09

As always, I probably missed something obvious.

As the title says, the vertices should move in direction of their normals.
As you might see in the code, I tried several approaches.
Each try results in the same - only a few vertices seemed at least to move in direction of the normals, all others move ..errm ...different...


There is something wrong with the hit point as well, but at least from the given camera position and angle this seems to be fine.

Any hints are welcome.
Thank you for your patience.


You can copy the code into an empty script and save and start it.
Right mouse button dragging turns the object, left click on the object influences the vertices.
Code:
#include <acknex.h>
#include <default.c>

ENTITY* object;

function deform_model()
{
	var vertices_max =0;
	var vertex_counter =0;
	VECTOR temp;
	VECTOR vertex_pos;
	VECTOR temp_normal;
	mouse_mode = 1;
	mouse_pointer = 1;
	mouse_range = 4000;
	while(1)
	{
		mouse_pos.x = mouse_cursor.x;
		mouse_pos.y = mouse_cursor.y;
		if(mouse_ent)
		{
			if(mouse_left)
			{
				me = mouse_ent;
				//send a trace at the object's surface
				vec_set(temp.x, camera.pan);
				vec_for_angle(temp.x, temp.x);
				vec_normalize(temp.x,1000);
				vec_add(temp.x, mouse_pos3d);
				c_trace(mouse_pos3d,temp.x, IGNORE_PASSABLE | USE_POLYGON| SCAN_TEXTURE);
				//get the hit point
				vec_set(temp.x,hit.x);
				//get the account of vertices of that model
				vertices_max = ent_status(my, 1);
				//count through the vertices
				while(vertex_counter <= vertices_max)
				{
					vec_set(vertex_pos.x, nullvector);
					vec_for_vertex(vertex_pos.x, me, vertex_counter);
					//look for the vertices within a certain distance of the hit point
					if(vec_dist(vertex_pos.x, temp.x)< 4)
					{
						vec_set(temp_normal.x, hit.nx);//move in direction of the hit normal
						vec_set(vertex_pos.x, nullvector);
						vec_for_vertex(vertex_pos.x, me, vertex_counter);
//						vec_diff(temp_normal.x,vertex_pos.x, my.x);//move away from the model's origin
//						vec_for_normal(temp_normal.x, my, vertex_counter);//move in direction of the vertex' normal
//						vec_scale(temp_normal.x, 1);
						vec_add(vertex_pos.x, temp_normal.x);
						vec_to_mesh(vertex_pos.x, my, vertex_counter);
					}
					vertex_counter += 1;
				}
				ent_fixnormals(my,0);//recalculate the normal after moving the vertices
				c_setminmax(me);//recalculate the collision
				while(mouse_left)wait(1);
			}
		}
		vertex_counter = 0;
		if(mouse_right)
		{
			object.pan += mouse_force.x;
			object.tilt += mouse_force.y;
		}
		camera.x += mickey.z * 0.1;
		wait(1);
	}
}

function main()
{
	level_load(NULL);
	you = ent_create(SPHERE_MDL, nullvector, NULL);
	object = you;
	deform_model();
	camera.x = -100;	
//	camera.z = 20;	
//	camera.tilt = -10;	
}


Posted By: Pappenheimer

Re: Move Vertex in Direction of its Normal - 08/21/11 20:24

I think I've got it - halfway.

I must not turn my model!!!111

A matter to discuss:
Aren't vec_for_normal and vec_for_vertex supposed to give the world vector?
Means, the result should be independent of the model's angle, shouldn't it?
Posted By: Pappenheimer

Re: Move Vertex in Direction of its Normal - 08/22/11 11:22

Another light in the dark of my ignorance.
I didn't recognize the difference between mouse_pos3d and mouse_dir3d - now, i sending t a trace from the mouse position into the 3d space is as simple as possible:
Quote:
//send a trace at the object's surface
vec_set(temp.x, mouse_dir3d);
vec_normalize(temp.x,1000);
vec_add(temp.x, mouse_pos3d);
c_trace(mouse_pos3d,temp.x, IGNORE_PASSABLE | USE_POLYGON | SCAN_TEXTURE);

This is more or less identical to the example under mouse_pos3d in the manual!
Posted By: MrGuest

Re: Move Vertex in Direction of its Normal - 08/22/11 13:39

done a bit of testing hopefully will help you out though didn't fix the problem
Code:
#include <acknex.h>
#include <default.c>

ENTITY* object;

function deform_model()
{
	int i;
	var vertices_max =0;
	var vertex_counter =0;
	VECTOR temp, pos;
	VECTOR vertex_pos;
	VECTOR temp_normal;
	mouse_mode = 1;
	mouse_pointer = 1;
	mouse_range = 4000;
	while(1)
	{
		mouse_pos.x = mouse_cursor.x;
		mouse_pos.y = mouse_cursor.y;
		if(mouse_ent)
		{
			
			for(i = 1; i <= ent_vertices(mouse_ent); i++){
				draw_point3d(vec_for_vertex(pos, mouse_ent, i), vector(0, 255, 255), 100, 0.5);
			}
			
			//send a trace at the object's surface
			vec_set(temp, mouse_dir3d);
			vec_normalize(temp.x, 1000);
			vec_add(temp, mouse_pos3d);
			c_trace(mouse_pos3d, temp, IGNORE_PASSABLE | USE_POLYGON | SCAN_TEXTURE);				
			
			vec_set(temp, hit.x); //hit point
			draw_point3d(temp, vector(0, 0, 255), 100, 0.6);
			
			DEBUG_VAR(temp.x, 20);
			DEBUG_VAR(temp.y, 40);
			DEBUG_VAR(temp.z, 60);
			
			if(mouse_left)
			{
				me = mouse_ent;
				//send a trace at the object's surface
				vec_set(temp, mouse_dir3d);
				vec_normalize(temp.x, 1000);
				vec_add(temp, mouse_pos3d);
				c_trace(mouse_pos3d, temp, IGNORE_PASSABLE | USE_POLYGON | SCAN_TEXTURE);				
				
				vec_set(temp, hit.x); //hit point
				for(i = 1; i <= ent_vertices(mouse_ent); i++){
					vec_for_vertex(vertex_pos, me, i);
//					if(1){
					if(vec_dist(vertex_pos, temp) < 4){
						vec_lerp(temp_normal, mouse_ent.x, vertex_pos, 1.5);
						vec_to_mesh(temp_normal, mouse_ent, i);
					}
				}
				
				ent_fixnormals(mouse_ent, 0);
				
/*				//get the hit point
				vec_set(temp.x,hit.x);
				//get the account of vertices of that model
				vertices_max = ent_status(my, 1);
				//count through the vertices
				while(vertex_counter <= vertices_max)
				{
					vec_set(vertex_pos.x, nullvector);
					vec_for_vertex(vertex_pos.x, me, vertex_counter);
					//look for the vertices within a certain distance of the hit point
					if(vec_dist(vertex_pos.x, temp.x)< 4)
					{
						vec_set(temp_normal.x, hit.nx);//move in direction of the hit normal
						vec_set(vertex_pos.x, nullvector);
						vec_for_vertex(vertex_pos.x, me, vertex_counter);
//						vec_diff(temp_normal.x,vertex_pos.x, my.x);//move away from the model's origin
//						vec_for_normal(temp_normal.x, my, vertex_counter);//move in direction of the vertex' normal
//						vec_scale(temp_normal.x, 1);
						vec_add(vertex_pos.x, temp_normal.x);
						vec_to_mesh(vertex_pos.x, my, vertex_counter);
					}
					vertex_counter += 1;
				}
				ent_fixnormals(my,0);//recalculate the normal after moving the vertices
*/				c_setminmax(me);//recalculate the collision
				while(mouse_left)wait(1);
			}
		}
		vertex_counter = 0;
		if(mouse_right)
		{
			object.pan += mouse_force.x;
			object.tilt += mouse_force.y;
		}
		camera.x += mickey.z * 0.1;
		wait(1);
	}
}

function main()
{
	level_load(NULL);
	you = ent_create(SPHERE_MDL, nullvector, NULL);
	object = you;
	deform_model();
	camera.x = -100;	
//	camera.z = 20;	
//	camera.tilt = -10;	
}


after rescaling the object the newly moved vertex(s) although update their position don't seem to recreate the normals correctly. the red square will show the hit position but will only determine this from the previous normals of the model

also changing vec_dist to always true will accurately redraw the model showing again the problem is the normals not being corrected

hope this helps somehow
Posted By: Pappenheimer

Re: Move Vertex in Direction of its Normal - 08/22/11 14:42

Thanks for your re-work, it is more slim than mine.

My solution for now is that I don't turn the model, but move the camera around it.
Posted By: Pappenheimer

Re: Move Vertex in Direction of its Normal - 09/11/11 18:20

Just for those who'd like to learn from this:

c_setminmax(me);

has to be replaced by

c_updatehull(me,1);

Only this anews the collision of the polygons.
© 2024 lite-C Forums