**vertAPI**

Thanks to Tepi and TheSnidr for the help

move/rotate/scale vertices using functions similar to GM's d3d_transform

Flawless camera rotation and position

Download vertAPI3.gmk V 3 beta2. Adds pitch yaw and roll (Airplane type or World relative) and a d3d_transform function to draw your models at the right orientation

** Note that your points added to the vert list do not yet rotate according to pitch yaw and roll, only the directional vectors are updated. Coming soon though

UPDATE:

Now you can match a 3d model transform to match vertapi with a single function

Download vertAPI.gmk GM7 merge file v1

Download vertAPI2.gmk V 2, Supports facing vector, right vector and up vector directly as per some of the documentaion in bottom of post. These vectors are useful for flawless camera movement and position as well as moving characters arround, See the vert_cam object

Users of API

3dStarMap

The idea is 3d transformation for points, or a series of points to match GM's d3d transform functions.

You see, the trouble with using gm's transformations to move/rotate/scale models (or any other stuff) is that you have no idea where, in x,y,z,rotx,roty,rotz the model finally ends up. Well you do (visually) but you have no data points to match and use in other function. For example, if I set the position to 10,0,0 then apply a scale on the x axis, say 15 then I rotate around the y axis, say 23 degrees, then rotate around the z axis, say 56 degrees, your basic model facing code or gun pointing. Where is that gun now in x,y,z,rotx,roty,rotz coords? Where is itÃ¢Â€Â™s tip?

example

d3d_transform_add_rotation_y( point_direction( 0, z, point_distance( x, y, other.x, other.y), other.z) + 90);

d3d_transform_add_rotation_z( point_direction( other.x, other.y, x, y));

d3d_transform_add_translation(( other.x + x) / 2 - off, (other.y + y) / 2, (other.z + z) / 2);

d3d_draw_cylinder( -2, -2, -dis, 2, 2, dis, global.jointtex, -2, -1, 0, 3);

Where are the edges of the cylinders now?

The solution is to mirror the calls d3d_transform calls with vert_transform calls

**example:**

Create:

model = d3d_model_create(); vert = vert_create(); COLOR = vert_create_extra_data(vert); d3d_model_primitive_begin(model,pr_pointlist); d3d_model_vertex_color(model,-5,-5,-5,c_blue,1); d3d_model_vertex_color(model,-5,-5, 5,c_blue,1); d3d_model_vertex_color(model,-5, 5,-5,c_yellow,1); d3d_model_vertex_color(model,-5, 5, 5,c_yellow,1); d3d_model_vertex_color(model, 5,-5,-5,c_lime,1); d3d_model_vertex_color(model, 5,-5, 5,c_lime,1); d3d_model_vertex_color(model, 5, 5,-5,c_orange,1); d3d_model_vertex_color(model, 5, 5, 5,c_orange,1); d3d_model_vertex_color(model, 0, 0, 0,c_red,1); d3d_model_primitive_end(model); vert_add(vert,-5,-5,-5); vert_add_extra_data(vert,COLOR,c_blue); vert_add(vert,-5,-5, 5); vert_add_extra_data(vert,COLOR,c_blue); vert_add(vert,-5, 5,-5); vert_add_extra_data(vert,COLOR,c_yellow); vert_add(vert,-5, 5, 5); vert_add_extra_data(vert,COLOR,c_yellow); vert_add(vert, 5,-5,-5); vert_add_extra_data(vert,COLOR,c_lime); vert_add(vert, 5,-5, 5); vert_add_extra_data(vert,COLOR,c_lime); vert_add(vert, 5, 5,-5); vert_add_extra_data(vert,COLOR,c_orange); vert_add(vert, 5, 5, 5); vert_add_extra_data(vert,COLOR,c_orange); vert_add(vert, 0, 0, 0); vert_add_extra_data(vert,COLOR,c_red);

Draw:

d3d_transform_set_identity(); //transforms d3d_transform_add_rotation_x(a) d3d_transform_add_rotation_y(a) d3d_transform_add_rotation_z(a) d3d_transform_add_translation(40,30,0); //draw d3d_model_draw(model,0,0,0,-1); d3d_transform_set_identity(); //mirror vert_transform_start(vert); //transforms vert_transform_add_rotation_x(vert, a) vert_transform_add_rotation_y(vert, a) vert_transform_add_rotation_z(vert, a) vert_transform_add_translation(vert,40,30,0); var s; s = vert_get_size(vert); //get the new position, draw in 2d (x/y axis only) for debugging. var i; i = 0; repeat(s) { draw_set_color(vert_get_extra_data(vert,COLOR,i)); draw_point(vert_get_transformed_x(vert,i),vert_get_transformed_y(vert,i)); i+=1; }

done:

d3d_model_destroy(model) vert_destroy(vert);

**Suggestions welcomed**

Maybe adding vn so to rotate them at the same time as the vertices, but I decided not to add those in for speed, the function is the same as for the standard vertices rotation, you can add the extra lists in the create and do the transform in the proper functions if you want to also do VNs

I also added extra information support so you can add other lists in the container, for color or alpha

Facet functions, like cross product could be added. Though the system is vertices, it could be a good helper function.

I also added extra information support so you can add other lists in the vert container, such as color and alpha, vn, uv

Added normalizing functions;

**Demo room:**

Drop the test object in the room, removing the one there to see it in action.

hold space to see the GM d3d transfrom result to compare with the API result.

on the left is the result of the get_tranform_rotation (Wich is wrong and will not be fixed as it's totaly useless), in the middle is the vertices result.

**Changes:**

Added normize calculation, it is done on the transformed points. So if you want the normalized point of the original vertex, call vert_transform_start then perform the call. As stated I do not do the normals for the entire set, this is faster if you ocasionally need the normal of the point. But slower if you need it all the time.

Added rotation_axes

Fixed the destroy

**Figuring Final Direction**(From the top of my head)

**This is included as a default feature of Version 2. Version 2 has vectors (facing, right and up vectors) to figure of the final direction the rotation transforms (only) brought you.

To figure the final direction of an object (the facing direction), simply add a point 1,0,0 to your vertices. As the first or last point in your set. 1,0,0 is a point (in this case a vector) facing directly right. Since everything starts off facing right in GM, that is your model should be facing right (+x) in the modeler, just like your sprites, in 2d, should be facing right when image_angle is 0. Rotating this point in your set will give you the direction vector.

which, in terms of deviation, you can use to shoot a bullet in that directions simply using

hspeed = finalx*maxspeed;

vspeed = finaly*maxspeed;

zspeed = finalz*maxspeed;

The angle difference between the original point and the new point will be

a = radtodeg(arccos(median(-1,1,dot_product(1,0,0,finalx,finaly,finalz))));

*Note the median is used to avoid floating point errors which WILL occure as the dot potduct will ocasionaly yield a value like +-1.000000000001 which will cause arccos to blow up

and to rotate an object to this angle, say a bullet model that is too facing right originally, you would use

nx,ny,nz = normalized_cross_product(1, 0, 0, finalx, finaly, finalz);

d3d_transform_add_rotation_axis(nx,ny,nz,a);

**Helper scripts**

//cross_product(x1,y1,z1,x2,y2,z2,x3,y3,z3) //also does the normalize __x = (argument7-argument1)*(argument5-argument2)-(argument4-argument1)*(argument8-argument2); __y = (argument8-argument2)*(argument3-argument0)-(argument5-argument2)*(argument6-argument0); __z = (argument6-argument0)*(argument4-argument1)-(argument3-argument0)*(argument7-argument1); //__x = (y3-y1)*(z2-z1)-(y2-y1)*(z3-z1); //__y = (z3-z1)*(x2-x1)-(z2-z1)*(x3-x1); //__z = (x3-x1)*(y2-y1)-(x2-x1)*(y3-y1); var mag; mag=sqrt((__x*__x)+(__y*__y)+(__z*__z)) if(mag = 0) { __nx = __x __ny = __y __nz = __z exit; } __nx = __x/mag __ny = __y / mag __nz = __z /mag

//dot_product(x1,y1,z1,x2,y2,z2,x3,y3,z3) var Ax,Ay,Az,Bx,By,Bz; Ax = argument0; Ay = argument1; Az = argument2; Bx = argument3; By = argument4; Bz = argument5; return Ax * Bx + Ay * By + Az * Bz

//normalize(x1,y1,z1) //1 vector var mag; mag=sqrt((argument0*argument0)+(argument1*argument1)+(argument2*argument2)) if(mag = 0) { __nx = argument0 __ny = argument1 __nz = argument2 exit; } __nx = argument0/mag __ny = argument1/mag __nz = argument2/mag

//normalize2(x1,y1,z1,x2,y2,z2) //2 3d coords/vectors var mag; mag=sqrt((argument0*argument0)+(argument1*argument1)+(argument2*argument2)) if(mag = 0) { __nx = argument0 __ny = argument1 __nz = argument2 exit; } __nx = argument0/mag __ny = argument1/mag __nz = argument2/mag

//vector(x1,y1,z1,x2,y2,z2) //gets the deviation between 2 3d points and normalizes the result into __nx,__ny,__nz __vx = argument3-argument0; __vy = argument4-argument1; __vz = argument5-argument2; normalize(__vx,__vy,__vz);

**Edited by icuurd12b42, 22 December 2011 - 11:19 PM.**