home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Der Mediaplex Sampler - Die 6 von Plex
/
6_v_plex.zip
/
6_v_plex
/
DISK2
/
MULTI_04
/
3DSDKB.ZIP
/
3DS2DKB.C
next >
Wrap
C/C++ Source or Header
|
1991-09-04
|
19KB
|
665 lines
/* 3DS2DKB.C Sep 1991 (c) Jeff Bowermaster
Reads a 3DS ascii save file and writes a DKB DATa file
Version 1.1 Written 9/03/91
Compiled with Borland C++ ver. 2.0
*/
#define BUFSIZE 128
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <alloc.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
float x, y, z;
} Vector;
typedef struct
{
int A;
int B;
int C;
} Triangle;
Vector huge * coords, huge * face_normals, huge * vertex_normals;
Triangle huge * tiplist;
char * matlist;
FILE *in,*out,*ext,*txtdkb;
/* globals */
float max_x, max_y, max_z, min_x, min_y, min_z;
int faces,vertices,materials=0,listed=0,internal=0,debug=1,txt=1;
char mtl[17],catmtl[17],material[50][17],object[12];
/* protos */
void Abort(char*,int);
void Process();
void FaceNorm (int, Vector, Vector, Vector);
void Txt_Out();
void main(argc, argv)
int argc;
char *argv[];
{
int face_number,vertex_number,d,e,f,l,m,yesno;
char parse,string[81],mp;
char inname[80],outname[80],extname[80],txtname[80],*index;
float a,b,c,x,y,z,tx,ty,tz,red,green,blue,mag;
max_x = max_y = max_z = -10000000.0; /* init bounding limits */
min_x = min_y = min_z = 10000000.0;
clrscr();
printf("\n\nAutoDesk 3D Studio to DKB .Data file Translator\n");
printf("Version 1.1 (c) Jeff Bowermaster, 9/03/91\n\n");
if (argc < 2)
{
printf("Usage: %s infile[.ASC] [outfile[.DAT]]\n", argv[0]);
exit(1);
}
/* Handle the input file */
strcpy(inname, argv[1]); /* make copy we can mess with */
if (!strchr(inname, '.')) /* no dot present in filename? */
strcat(inname, ".asc");
if (!(in = fopen(inname, "rt"))) {
printf("Cannot open input file %s!\n", inname);
exit(1);
}
/* Handle the output file */
switch (argc){
case(2): /* no output file name supplied... */
if (!strchr(inname, '\\')) /* no subdirectory stuff? */
strcpy(outname,inname);
else {
index = strrchr(inname, '\\'); /* break out directory info */
strcpy(outname,index+1);
}
strcpy(extname, outname); /* make copy just in case */
strcpy(txtname, outname); /* make copy just in case */
if (!strchr(outname, '.')) /* no dot in filename? */
strcat(outname, ".dat"); /* make new ext. .DAT... */
else {
index = strchr(outname, '.'); /* find the dot */
strcpy(index, ".dat"); /* make the new ext. .DAT... */
}
if(!internal) {
if (!strchr(extname, '.')) /* no dot in filename? */
strcat(extname, ".inc"); /* make new ext. .INC... */
else {
index = strchr(extname, '.'); /* find the dot */
strcpy(index, ".inc"); /* make the new ext. .INC... */
}
}
if(txt) {
if (!strchr(txtname, '.')) /* no dot in filename? */
strcat(extname, ".txt"); /* make new ext. .TXT... */
else {
index = strchr(txtname, '.'); /* find the dot */
strcpy(index, ".txt"); /* make the new ext. .TXT... */
}
}
break;
case(3): /* output file name or options supplied */
switch(argv[2][0]){
case '/':
case '-':
switch(argv[2][1]){
case 'i':
case 'I':
internal=1;
if(internal)
printf("internal material definition selected\n");
break;
default: /* Add options here... */
break;
}
/* Now go make the input into the output */
if (!strchr(inname, '\\')) /* no subdirectory stuff? */
strcpy(outname,inname);
else {
index = strrchr(inname, '\\'); /* break out directory info */
strcpy(outname,index+1);
}
strcpy(extname, outname); /* make copy just in case */
strcpy(txtname, outname); /* make copy just in case */
if (!strchr(outname, '.')) /* no dot in filename? */
strcat(outname, ".dat"); /* make new ext. .DAT... */
else {
index = strchr(outname, '.'); /* find the dot */
strcpy(index, ".dat"); /* make the new ext. .DAT... */
}
if(!internal) {
if (!strchr(extname, '.')) /* no dot in filename? */
strcat(extname, ".inc"); /* make new ext. .INC... */
else {
index = strchr(extname, '.'); /* find the dot */
strcpy(index, ".inc"); /* make the new ext. .INC... */
}
}
if(txt) {
if (!strchr(txtname, '.')) /* no dot in filename? */
strcat(txtname, ".txt"); /* make new ext. .TXT... */
else {
index = strchr(txtname, '.'); /* find the dot */
strcpy(index, ".txt"); /* make the new ext. .TXT... */
}
}
break;
default: /* output name supplied */
strcpy(outname, argv[2]);
if (!strchr(outname, '.')) /* no dot in filename? */
strcat(outname, ".dat"); /* add .DAT extension */
break;
}
break;
case(4): /* output file name AND options supplied */
switch(argv[3][0]){
case '/':
case '-':
switch(argv[3][1]){
case 'i':
case 'I':
internal=1;
if(internal)
printf("internal material definition selected\n");
break;
default: /* Add more options here... */
break;
}
strcpy(outname, argv[2]);
strcpy(extname, outname); /* make copy just in case */
strcpy(txtname, outname); /* make copy just in case */
if (!strchr(outname, '.')) /* no dot in filename? */
strcat(outname, ".dat"); /* add .DAT extension */
if(!internal) {
if (!strchr(extname, '.')) /* no dot in filename? */
strcat(extname, ".inc"); /* make new ext. .INC... */
else {
index = strchr(extname, '.'); /* find the dot */
strcpy(index, ".inc"); /* make the new ext. .INC... */
}
}
if(txt) {
if (!strchr(txtname, '.')) /* no dot in filename? */
strcat(txtname, ".txt"); /* make new ext. .TXT... */
else {
index = strchr(txtname, '.'); /* find the dot */
strcpy(index, ".txt"); /* make the new ext. .TXT... */
}
}
default:
break;
}
default:
break;
}
if (!(out = fopen(outname, "wt"))) {
printf("Cannot create output file %s!\n", outname);
fclose(in);
exit(1);
}
if (!internal) {
if (!(ext = fopen(extname, "wt"))) {
printf("Cannot create include output file %s!\n", extname);
fclose(in);
exit(1);
}
}
if(txt) {
if (!(txtdkb = fopen(txtname,"wt"))){
printf("Can't open text output file\n");
exit(1);
}
}
printf("Input from: %s\n",inname);
printf("Output to: %s\n",outname);
if(!internal)
printf("External to: %s\n",extname);
if(txt)
printf("Text Output: %s\n",txtname);
printf("\nPlease wait; Processing...\n");
fprintf(out,"INCLUDE \"colors.dat\"\n");
fprintf(out,"INCLUDE \"shapes.dat\"\n");
fprintf(out,"INCLUDE \"textures.dat\"\n");
if(!internal)
fprintf(out,"INCLUDE \"%s\"\n",extname);
while(fgets(string,BUFSIZ,in)!=NULL) {
parse=string[0];
switch(parse){
case 'A': /* Ambient light color: Red=0.3 Green=0.3 Blue=0.3 */
sscanf(string,"%*s %*s %*s %*4s %f %*6s %f %*5s %f",
&red,&green,&blue);
/* Ignore for now */
break;
case 'B': /* Bank angle: 0.00 degrees */
/* Background solid color: Red=0 Green=0.105882 Blue=0.32549 */
/* Ignore for now */
break;
case 'C': /* Camera (50.000000mm) */
fprintf(out,"VIEW_POINT\n");
fprintf(out," LOCATION <0.0 0.0 0.0>\n");
break;
case 'D': /* Direct light */
fprintf(out,"OBJECT \n");
fprintf(out," SPHERE <0.0 0.0 0.0> 1.0 END_SPHERE\n");
break;
case 'F': /* Face list: */
if(strstr(string,"list:"))
break;
/* Falloff size: 18.25 degrees */
if(strstr(string,"Fall"))
break;
/* Face 0: A:0 B:1 C:109 Mtl:CHROME */
sscanf(string,"%*s %d %*s %2*s %d %2*s %d %2*s %d %4*s %17c",
&face_number,&d,&e,&f,&mtl);
tiplist[face_number].A=d;
tiplist[face_number].B=e;
tiplist[face_number].C=f;
/* get material names */
for(l=0;l<17;l++){
mp=mtl[l];
switch(mp) {
case ' ':
catmtl[l]='_'; /* glue separate words together */
break;
case '\n':
catmtl[l]='\0'; /* convert cr to end of string */
l=17; /* done (does this work?) */
break;
default :
catmtl[l]=mp; /* pass everything else */
}
}
/* is this different from any material we have so far? */
yesno=1; /*set to yes */
for(m=0;m<materials;m++){
yesno=strcmp(&material[m][0],catmtl);
if(!yesno) {
matlist[face_number]=(char)m;
break;
}
}
if(yesno) {
strcpy(&material[materials++][0],catmtl);
matlist[face_number]=(char)materials-1;
}
if(face_number==faces-1) { /* done with this object */
if(internal){
fprintf(out,"\n{New materials: }\n");
for(m=listed;m<materials;m++){
fprintf(out," DECLARE %s = TEXTURE\n",material[m]);
fprintf(out," COLOUR White\n");
fprintf(out," PHONG 1.0\n");
fprintf(out," END_TEXTURE\n\n");
}
listed=materials; /* only new materials */
}
Process();
}
break;
case 'L': /* Light color: Red=0.32 Green=0.9 Blue=0.72 */
sscanf(string,"%*s %*s %*4s %f %*6s %f %*5s %f",
&red,&green,&blue);
fprintf(out," COLOUR RED %4.2f GREEN %4.2f BLUE %4.2f\n",red,green,blue);
fprintf(out," TEXTURE\n");
fprintf(out," AMBIENT 1.0\n");
fprintf(out," DIFFUSE 0.0\n");
fprintf(out," COLOUR RED %4.2f GREEN %4.2f BLUE %4.2f\n",red,green,blue);
fprintf(out," END_TEXTURE\n");
fprintf(out," LIGHT_SOURCE\n");
fprintf(out,"END_OBJECT\n\n");
break;
case 'N': /* Named object: teacup */
sscanf(string,"%*s %*s %s",&object);
fprintf(out,"{ %s }\n",object);
printf("Working on: %s\n",object);
break;
case 'P': /* Position: X:298.177734 Y:-314.924225 Z:182.459198 */
sscanf(string,"%*s %2*s %f %2*s %f %2*s %f",
&x,&y,&z);
fprintf(out," TRANSLATE <%11.6f %11.6f %11.6f>\n",x,y,z);
break;
case 'S': /* Smoothing: 1, 10 */
/* Smoothing: 17 */
/* don't know what it means */
/* Spotlight to: X:-98.558777 Y:-176.971039 Z:-363.822357 */
break;
/* Could be synthesized, flaming terror */
case 'T': /* Target: X:79.31871 Y:-11.135715 Z:27.661964 */
if(strstr(string,"Target:")){
sscanf(string,"%*s %2*s %f %2*s %f %2*s %f",&tx,&ty,&tz);
x-=tx; y-=ty; z-=tz;
mag=(float)sqrt((double)(x*x+y*y+z*z));
x/=mag; y/=mag; z/=mag;
fprintf(out," DIRECTION <%4.2f %4.2f %4.2f>\n",x,y,z);
fprintf(out," SKY <0.0 0.0 1.0>\n");
fprintf(out," RIGHT <-1.33 0.0 0.0>\n");
fprintf(out," LOOK_AT <%11.6f %11.6f %11.6f>\n",tx,ty,tz);
fprintf(out,"END_VIEW_POINT\n\n");
break;
}
/* Tri-mesh, Vertices: 3240 Faces: 6480 */
sscanf(string,"%*s %*s %d %*s %d",&vertices,&faces);
if((coords = farmalloc ((long)vertices * sizeof(Vector)))==NULL)
Abort ("Insufficient memory for coordinates.", 1);
if((face_normals = farmalloc ((long)faces * sizeof(Vector)))==NULL)
Abort ("Insufficient memory for face normals.", 2);
if((vertex_normals = farmalloc ((long)vertices * sizeof(Vector)))==NULL)
Abort ("Insufficient memory for vertex normals.", 3);
if((tiplist = farmalloc ((long)faces * sizeof(Triangle)))==NULL)
Abort ("Insufficient memory for face list.", 4);
if((matlist = farmalloc ((long)faces * sizeof(char)))==NULL)
Abort ("Insufficient memory for materials list.", 5);
break;
case 'V': /* Vertex list: */
if(strstr(string,"list:"))
break;
/* Vertex 0: X: 82.320801 Y: -15.238132 Z: 28.071295 */
sscanf(string,"%*s %d %*s %2*s %f %2*s %f %2*s %f",
&vertex_number,&a,&b,&c);
coords[vertex_number].x=a;
coords[vertex_number].y=b;
coords[vertex_number].z=c;
max_x = (a > max_x) ? a : max_x;
min_x = (a < min_x) ? a : min_x;
max_y = (b > max_y) ? b : max_y;
min_y = (b < min_y) ? b : min_y;
max_z = (c > max_z) ? c : max_z;
min_z = (c < min_z) ? c : min_z;
break;
default: /* Blank lines, page numbers... */
break;
}
}
fprintf(out,"\n{Deal with the following materials: }\n");
for(m=0;m<materials;m++)
if(!internal) {
fprintf(ext," DECLARE %s = TEXTURE\n",material[m]);
fprintf(ext," COLOUR White\n");
fprintf(ext," PHONG 1.0\n");
fprintf(ext," END_TEXTURE\n\n");
}
else
fprintf(out," { %s }\n",material[m]);
fclose(in);
fclose(out);
if(!internal)
fclose(ext);
if(txt)
fclose(txtdkb);
}
void Process()
{
int face_number,vertex_number;
float m2,magnitude;
fprintf(out,"COMPOSITE\n");
/* Calculate the face normals */
if(debug) printf("face normals\n");
for(face_number=0;face_number<faces;face_number++) {
FaceNorm(face_number,
coords[tiplist[face_number].A],
coords[tiplist[face_number].B],
coords[tiplist[face_number].C]);
}
/* normalize to unit vectors */
if(debug) printf("unit vector1\n");
for(face_number=0;face_number<faces;face_number++) {
m2=face_normals[face_number].x*face_normals[face_number].x+
face_normals[face_number].y*face_normals[face_number].y+
face_normals[face_number].z*face_normals[face_number].z;
magnitude=(float)sqrt((double)m2);
if (magnitude==0.0) {
printf("Face expected; vector encountered\n");
magnitude=1;
}
face_normals[face_number].x/=magnitude;
face_normals[face_number].y/=magnitude;
face_normals[face_number].z/=magnitude;
}
/* Clear out the memory for the averages */
for(vertex_number=0;vertex_number<vertices;vertex_number++) {
vertex_normals[vertex_number].x=0.0;
vertex_normals[vertex_number].y=0.0;
vertex_normals[vertex_number].z=0.0;
}
/* add all the normals for faces touching each vertex */
if (debug) printf("average face normals\n");
for(face_number=0;face_number<faces;face_number++) {
vertex_normals[tiplist[face_number].A].x+=face_normals[face_number].x;
vertex_normals[tiplist[face_number].A].y+=face_normals[face_number].y;
vertex_normals[tiplist[face_number].A].z+=face_normals[face_number].z;
vertex_normals[tiplist[face_number].B].x+=face_normals[face_number].x;
vertex_normals[tiplist[face_number].B].y+=face_normals[face_number].y;
vertex_normals[tiplist[face_number].B].z+=face_normals[face_number].z;
vertex_normals[tiplist[face_number].C].x+=face_normals[face_number].x;
vertex_normals[tiplist[face_number].C].y+=face_normals[face_number].y;
vertex_normals[tiplist[face_number].C].z+=face_normals[face_number].z;
}
/* normalize to unit vectors */
if(debug) printf("normalize #2\n");
for(vertex_number=0;vertex_number<vertices;vertex_number++) {
m2=(vertex_normals[vertex_number].x*vertex_normals[vertex_number].x)+
(vertex_normals[vertex_number].y*vertex_normals[vertex_number].y)+
(vertex_normals[vertex_number].z*vertex_normals[vertex_number].z);
magnitude=(float)sqrt((double)m2);
if (magnitude==0.0) {
printf("Normals all cancel (?)\n");
magnitude=1;
}
vertex_normals[vertex_number].x/=magnitude;
vertex_normals[vertex_number].y/=magnitude;
vertex_normals[vertex_number].z/=magnitude;
}
/* print out the results */
for(face_number=0;face_number<faces;face_number++) {
fprintf(out,"OBJECT\n");
fprintf(out," SMOOTH_TRIANGLE \n");
fprintf(out," <%8.4f %8.4f %8.4f> <%8.4f %8.4f %8.4f>\n",
coords[tiplist[face_number].A].x,
coords[tiplist[face_number].A].y,
coords[tiplist[face_number].A].z,
vertex_normals[tiplist[face_number].A].x,
vertex_normals[tiplist[face_number].A].y,
vertex_normals[tiplist[face_number].A].z);
fprintf(out," <%8.4f %8.4f %8.4f> <%8.4f %8.4f %8.4f>\n",
coords[tiplist[face_number].B].x,
coords[tiplist[face_number].B].y,
coords[tiplist[face_number].B].z,
vertex_normals[tiplist[face_number].B].x,
vertex_normals[tiplist[face_number].B].y,
vertex_normals[tiplist[face_number].B].z);
fprintf(out," <%8.4f %8.4f %8.4f> <%8.4f %8.4f %8.4f>\n",
coords[tiplist[face_number].C].x,
coords[tiplist[face_number].C].y,
coords[tiplist[face_number].C].z,
vertex_normals[tiplist[face_number].C].x,
vertex_normals[tiplist[face_number].C].y,
vertex_normals[tiplist[face_number].C].z);
fprintf(out," END_SMOOTH_TRIANGLE\n");
fprintf(out," TEXTURE \n");
fprintf(out," %s\n",material[matlist[face_number]]);
fprintf(out," END_TEXTURE\n");
fprintf(out,"END_OBJECT\n\n");
}
fprintf(out,"BOUNDED_BY\n");
fprintf(out," INTERSECTION\n");
fprintf(out," PLANE < 1.0 0.0 0.0> %f END_PLANE\n",max_x);
fprintf(out," PLANE <-1.0 0.0 0.0> %f END_PLANE\n",-1*min_x);
fprintf(out," PLANE < 0.0 1.0 0.0> %f END_PLANE\n",max_y);
fprintf(out," PLANE < 0.0 -1.0 0.0> %f END_PLANE\n",-1*min_y);
fprintf(out," PLANE < 0.0 0.0 1.0> %f END_PLANE\n",max_z);
fprintf(out," PLANE < 0.0 0.0 -1.0> %f END_PLANE\n",-1*min_z);
fprintf(out," END_INTERSECTION\n");
fprintf(out,"END_BOUND\n\n");
fprintf(out,"END_COMPOSITE\n\n");
/* free up the memory for the next object */
/* if you want a text list of the points */
if(txt)
Txt_Out();
farfree((void far *)coords);
farfree((void far *)vertex_normals);
farfree((void far *)face_normals);
farfree((void far *)tiplist);
farfree((void far *)matlist);
max_x = max_y = max_z = -10000000.0; /* reset bounding limits */
min_x = min_y = min_z = 10000000.0;
}
void FaceNorm (int face_number,Vector V1, Vector V2, Vector V3)
{
Vector V4, V5;
V4.x = V1.x - V2.x;
V4.y = V1.y - V2.y;
V4.z = V1.z - V2.z;
V5.x = V1.x - V3.x;
V5.y = V1.y - V3.y;
V5.z = V1.z - V3.z;
face_normals[face_number].x = (V4.y * V5.z) - (V4.z * V5.y);
face_normals[face_number].y = (V4.z * V5.x) - (V4.x * V5.z);
face_normals[face_number].z = (V4.x * V5.y) - (V4.y * V5.x);
}
void Abort (char *Msg, int ExitCode)
{
puts (Msg);
exit (ExitCode);
}
void Txt_Out() {
/* Modify this routine to get lists of whatever you need */
int vertex_number,face_number;
fprintf(txtdkb,"%s\n",object); /* delimits objects */
for(face_number=0;face_number<faces;face_number++) {
fprintf(txtdkb,"%f %f %f ",
coords[tiplist[face_number].A].x,
coords[tiplist[face_number].A].y,
coords[tiplist[face_number].A].z);
fprintf(txtdkb,"%f %f %f ",
coords[tiplist[face_number].B].x,
coords[tiplist[face_number].B].y,
coords[tiplist[face_number].B].z);
fprintf(txtdkb,"%f %f %f\n",
coords[tiplist[face_number].C].x,
coords[tiplist[face_number].C].y,
coords[tiplist[face_number].C].z);
}
}