PDA

View Full Version : Using calloc, is it needed?



MiniFireDragon
10-10-2007, 10:42 AM
I have been reading over the various different samples included with the SDK. Some have the calloc and some don't.

Is it needed for plug ins or does the done(); function clear everything away?

One of the reasons I am asking this is I put the free(); function before the done(); and Lightwave pretty much didn't like it.

Lightwolf
10-10-2007, 12:00 PM
I have been reading over the various different samples included with the SDK. Some have the calloc and some don't.

It depends on where it is used. Generally every plugin instance needs to have some memory to store its settings.
This is created by the plugin when it is first created by LW, and freed when LW deletes the plugin. (thus the calloc/free in thos callbacks).

Usually plugins allocate the size of a struct containing the variables needed for the instance.

Cheers,
Mike

MiniFireDragon
10-10-2007, 12:57 PM
Well, In my case, the calloc is located in the function that creates points and faces. At the end of building them and before returning to the Activate Function is when free() is used.

Lightwolf
10-10-2007, 01:39 PM
Well, In my case, the calloc is located in the function that creates points and faces. At the end of building them and before returning to the Activate Function is when free() is used.
In that case it ought to be fine. What kind of plugin?
You're not acessing the memory from any other part of your plugin, are you?

What exactly are you doing? Can you write some pseudo code to show the code flow?

Cheers,
Mike

MiniFireDragon
10-12-2007, 10:26 AM
What I am doing right now is learning to write programs in lightwave to build meshes in modeler then moving into Lightwave to do it. Here is my 1st plug in (still working on it).

What is does is create an object in the shape of a bullet. When I am done with this initial learning phase, it will create the casing with different pin style selections, and have handles to edit the shape of the projectile (the actual bullet).

My final end goal of this undertaking is to use it in layout to create bullet effects. Ya know, place some points, click the plug in, it animates, deforms and alters the mesh according to settings.

It's big I know, but I am taking my time and by the end, hope to have a good grip on plugin making.

Now if I could only get my head around nodes and shaders....



/*
================================================== ====================
firstplug.c

Learning to build geometry.

MiniFireDragon
================================================== ====================


Entry point for the plug-in.
================================================== ==================== */
#include "box.h"
#include <lwserver.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdio.h>


int get_user( LWXPanelFuncs *xpanf, double *diameter, double *length,
int *nsegments )
{
LWXPanelID panel;
int ok = 0;

enum { ID_DIAMETER = 0x8001, ID_LENGTH, ID_NSEGMENTS };
LWXPanelControl ctl[] = {
{ ID_DIAMETER, "Diameter", "distance" },
{ ID_LENGTH, "Length", "distance" },
{ ID_NSEGMENTS, "Segments", "integer" },
{ 0 }
};
LWXPanelDataDesc cdata[] = {
{ ID_DIAMETER, "Diameter", "distance" },
{ ID_LENGTH, "Length", "distance" },
{ ID_NSEGMENTS, "Segments", "integer" },
{ 0 }
};
LWXPanelHint hint[] = {
XpLABEL( 0, "Bullet Size" ),
XpMIN( ID_NSEGMENTS, 3 ),
XpMAX( ID_NSEGMENTS, 200 ),
XpDIVADD( ID_DIAMETER ),
XpDIVADD( ID_LENGTH ),
XpEND
};

panel = xpanf->create( LWXP_FORM, ctl );
if ( !panel ) return 0;

xpanf->describe( panel, cdata, NULL, NULL );
xpanf->hint( panel, 0, hint );
xpanf->formSet( panel, ID_DIAMETER, diameter );
xpanf->formSet( panel, ID_LENGTH, length );
xpanf->formSet( panel, ID_NSEGMENTS, nsegments );

ok = xpanf->post( panel );

if ( ok ) {
double *d;
int *i;

d = xpanf->formGet( panel, ID_DIAMETER );
*diameter = *d;

d = xpanf->formGet( panel, ID_LENGTH );
*length = *d;

i = xpanf->formGet( panel, ID_NSEGMENTS );
*nsegments = *i;
}

xpanf->destroy( panel );
return ok;
}

int Bullet ( MeshEditOp *edit, BulletData *dat )
{
LWPntID *id, vt[3];
LWPntID *sid, *tid, *lid;
LWPolID *pol;
double pt[3], cdegs, r, rads, pi, radeg, degs, n_len;
int i, j, k, m, n, o, p;

pt[0] = pt[1] = pt[2] = 0.0;
cdegs = 0;
r = dat->diameter/2;
pi = 3.1415926538;
rads = pi/180;
n_len = dat->length*2/3;

id = calloc( dat->nsegments + 1, sizeof(LWPntID));
sid = calloc( dat->nsegments, sizeof(LWPntID));
tid = calloc( dat->nsegments, sizeof(LWPntID));
lid = calloc( 1, sizeof(LWPntID));
pol = calloc( dat->nsegments, sizeof(LWPolID));

// computer angle increments
degs = ( 360.0 / dat->nsegments );

/* Build 1st ring (the base) of polygons */
for (i = 0, k = 0; i < dat->nsegments; i++) {
// put point at zero x,y,z
if ( i == 0 ) {
id[k++] = edit->addPoint( edit->state, pt );
//++i;
}

if (cdegs == 0)
{
//add first point of circle
pt[0] = r ;
pt[1] = 0;
pt[2] = 0;
id[k++] = edit->addPoint( edit->state, pt );
cdegs = cdegs + degs;
}
else
{
//need to convert degree to radians for trig functions
radeg = cdegs * rads;
pt[0] = r * cos(radeg);
pt[1] = r * sin(radeg);
pt[2] = 0;
id[k++] = edit->addPoint( edit->state, pt );
cdegs = cdegs + degs;
}
}

/* Create triangle polygons for the base */
for ( i = 0, j = 1, k = 2; i < dat->nsegments; i++)
{
//for faces
if ( k > dat->nsegments ) k = 1;
vt[0] = id[0];
vt[1] = id[k];
vt[2] = id[j];
pol[ i ] = edit->addFace( edit->state, NULL, 3, vt );
j = j++;
k = k++;
}

// create next ring 2/3rds the total length
for (i = 0, k = 0; i < dat->nsegments; i++) {

if (cdegs == 0)
{
//add first point of circle
pt[0] = r ;
pt[1] = 0;
pt[2] = n_len;
sid[k++] = edit->addPoint( edit->state, pt );
cdegs = cdegs + degs;
}
else
{
//need to convert degree to radians for trig functions
radeg = cdegs * rads;
pt[0] = r * cos(radeg);
pt[1] = r * sin(radeg);
pt[2] = n_len;
sid[k++] = edit->addPoint( edit->state, pt );
cdegs = cdegs + degs;
}
}


m = 1; n = 2; o = 1; p = 0;
// going to use this function to draw the next set of polys
for (i = 0; i < dat->nsegments; i++)
{
if ( i == dat->nsegments - 1)
{
n = 1;
o = 0;
}
edit->addQuad( edit->state, id[m++], id[n++], sid[o++], sid[p++] );
}

//draw the 3rd ring, smaller then the other 2 and 3/4 the length
n_len = dat->length*.75;
r = r/2;

for (i = 0, k = 0; i < dat->nsegments; i++) {

if (cdegs == 0)
{
//add first point of circle
pt[0] = r ;
pt[1] = 0;
pt[2] = n_len;
tid[k++] = edit->addPoint( edit->state, pt );
cdegs = cdegs + degs;
}
else
{
//need to convert degree to radians for trig functions
radeg = cdegs * rads;
pt[0] = r * cos(radeg);
pt[1] = r * sin(radeg);
pt[2] = n_len;
tid[k++] = edit->addPoint( edit->state, pt );
cdegs = cdegs + degs;
}
}

//Polygon the sides
m = 0; n = 1; o = 1; p = 0;
// going to use this function to draw the next set of polys
for (i = 0; i < dat->nsegments; i++)
{
if ( i == dat->nsegments - 1)
{
n = 0;
o = 0;
}
edit->addQuad( edit->state, sid[m++], sid[n++], tid[o++], tid[p++] );
}

//create last point at full length, 0,0
pt[0] = 0;
pt[1] = 0;
pt[2] = dat->length;
lid[0] = edit->addPoint( edit->state, pt );

/* Create triangle polygons for the base */
for ( i = 0, j = 0, k = 1; i < dat->nsegments; i++)
{
//for faces
if ( k > dat->nsegments - 1 ) k = 0;
vt[0] = lid[0];
vt[1] = tid[j];
vt[2] = tid[k];
pol[ i ] = edit->addFace( edit->state, NULL, 3, vt );
j = j + 1;
k = k + 1;
}




edit->done(edit->state, EDERR_NONE, EDSELM_FORCEVRTS | EDSELM_FORCEPOLS );
free(id);
free(sid);
free(tid);
free(lid);
free(pol);
return dat->nsegments;
}


XCALL_( int )
Activate( int version, GlobalFunc *global, MeshEditBegin *local, void *serverData )
{
MeshEditOp *edit;
LWXPanelFuncs *xpanf;
BulletData dat;

/* Numbers are in metric */
double diameter = 0.09;
double length = 0.039;
int nsegments = 3;

if ( version != LWMESHEDIT_VERSION )
return AFUNC_BADVERSION;

xpanf = global( LWXPANELFUNCS_GLOBAL, GFUSE_TRANSIENT );
if ( !xpanf ) return AFUNC_BADGLOBAL;

edit = (*local) (0, 0, OPSEL_USER);
if (!edit)
return AFUNC_OK;

if ( get_user( xpanf, &diameter, &length, &nsegments ))
/* do something here */
{
dat.diameter = diameter;
dat.length = length;
dat.nsegments = nsegments;

Bullet( edit, &dat);
}

return AFUNC_OK;

}


static ServerTagInfo srvtag[] = {
{ "Bullet", SRVTAG_USERNAME | LANGID_USENGLISH },
{ "create", SRVTAG_CMDGROUP },
{ "objects/primitives", SRVTAG_MENU },
{ "Bullet", SRVTAG_BUTTONNAME },
{ "", 0 }
};

ServerRecord ServerDesc[] = {
{ LWMESHEDIT_CLASS, "Bullet", Activate, srvtag },
{ NULL }
};


And here is the H File:



#ifndef BOX_H
#define BOX_H

#include <lwserver.h>
#include <lwmodtool.h>
#include <lwxpanel.h>
#include <lwmeshedt.h>
#include <lwpolygon.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>


typedef struct st_BulletData {
double length, diameter;
int nsegments;
} BulletData;

// extern int Bullet (MeshEditOp *, double, double, int);
/* Put here by ESM for reference purposes

typedef struct st_SpikeyData {
MeshEditOp *op;
LWMonitor *mon;
unsigned int count;
double spike;
} SpikeyData;
*/

#endif

MiniFireDragon
10-12-2007, 10:28 AM
Oh, one more thing, I will be condensing the point builder and the poly builder into their own functions, this was my 1st 5 days of figuring out what I am doing and how I need to do it via looking at the samples and reading the SDK and tinkering.

Lightwolf
10-12-2007, 11:07 AM
At a quick glance the use of calloc looks right to me.

I don't see anything else that is obviously wrong, but I'm not a hardcore modeler tools writer either.

Cheers,
Mike

MiniFireDragon
10-12-2007, 02:56 PM
It's surprisingly easy to build raw points and poly's in modeler. It's getting over the math and remembering that C arrays start at 0 and an Array[9] is really ten items!

Lightwolf
10-12-2007, 05:19 PM
It's surprisingly easy to build raw points and poly's in modeler. It's getting over the math and remembering that C arrays start at 0 and an Array[9] is really ten items!
In no time you'll be thinking how it could ever be different... and start cursing LScript for having 1 based arrays ;)

Cheers,
Mike