/* Copyright (C) 1996, 1997 Paul Sheer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* 3dtext */ #include #include #include #include #include #include #include #include #include #include "app_glob.c" #include "coolwidget.h" #include "widget3d.h" #include "quickmath.h" #include "dialog.h" /* this processes a text file into a 3d world the text file contains the following commands seperated by zero or more newlines. Charaacters after a # at the beginning of a line are ignored. # x, y, z, a, b, h, w, and c are floats. (x,y,z) is a vector. scale a # specifies the absolute value of the maximum extent of the scene in 3D space # (after offset has been subtracted (see next)). This must come first. offset x y z # specifies the a vector that is to be subtracted from the given position of # forthcoming object. Must also come before any drawing commands. cylinder x y z a b c r # draws a cylinder beginning at (a,b,c) ending at (a,b,c)+(x,y,z) of radius r cappedcylinder x y z a b c r # draws a cylinder beginning at (a,b,c) ending at (a,b,c)+(x,y,z) of radius r # with closed ends. surface a b x y z x y z x y z ... x y z # draws a surface of grid size a by b there must be a*b (x, y, z) points. trapezium x y z a b c u v w p q r # draws a trapezium with one corner at (x,y,z) and the other three at (x,y,z)+(a,b,c) etc. pipe r a x y z x y z x y z x y z ... x y z # draw a pipe with corners at (x,y,z) the pipe diameter is r and the corner radii are a * the first (x,y,z) is the start the last is the finish. Points mus be more than 2a appart cappedpipe r a x y z x y z x y z x y z ... x y z # same with closed ends rectangle a b c x y z # rectangle with (height,width,depth) = (x,y,z), corner at (a,b,c) ellipse a b c x y z # an ellipse with (height,width,depth) = (x,y,z), centre at (a,b,c) density a # will set the density of the grid making up any of the specific surfaces above. # can be called before each surface command. */ /* globals: */ int GridDensity = 6; double DimensionScale = 1; Vec DimensionOffset = {0, 0, 0}; static inline void assignTD (TD_Point *p, Vec v) { p->x = (double) (v.x + DimensionOffset.x) * DimensionScale; p->y = (double) (v.y + DimensionOffset.y) * DimensionScale; p->z = (double) (v.z + DimensionOffset.z) * DimensionScale; } static void third_cyl (double t, TD_Point * p, Vec A, Vec X, Vec r1, Vec r2, int g, double f) { int i = 0; double h; double alpha = t; Vec rv; while (alpha < (2 * PI / 3 + t + 0.001)) { for (h = 0; h <= 1; h += 0.5) { rv = plus (plus (plus (times (r1, cos (alpha) * (1 + h * (f - 1))), times (r2, sin (alpha) * (1 + h * (f - 1)))), A), times (X, h)); assignTD(&(p[i]), rv); i++; } alpha += (2 * PI / 3) / g; } } void Cdraw3d_cone (const char *ident, double x, double y, double z, double a, double b, double c, double ra, double rb) { int g = 4 * GridDensity / 3; TD_Point *p = Cmalloc ((g + 1) * 3 * sizeof (TD_Point)); Vec r1; Vec r2; Vec A, X; double f = rb / ra; A.x = a; A.y = b; A.z = c; X.x = x; X.y = y; X.z = z; orth_vectors (X, &r1, &r2, ra); third_cyl (0, p, A, X, r1, r2, g, f); Cinit_surf_points (ident, 3, g + 1, p); third_cyl (2 * PI / 3, p, A, X, r1, r2, g, f); Cinit_surf_points (ident, 3, g + 1, p); third_cyl (4 * PI / 3, p, A, X, r1, r2, g, f); Cinit_surf_points (ident, 3, g + 1, p); free (p); } void Cdraw3d_cylinder (const char *ident, double x, double y, double z, double a, double b, double c, double r) { Cdraw3d_cone (ident, x, y, z, a, b, c, r, r); } void Cdraw3d_roundplate (const char *ident, double x, double y, double z, double a, double b, double c, double r) { TD_Point *p = Cmalloc ((GridDensity * 4 + 1) * 2 * sizeof (TD_Point)); double alpha = 0; Vec r1; Vec r2; Vec rv; Vec A; Vec X; int i = 0; A.x = a; A.y = b; A.z = c; X.x = x; X.y = y; X.z = z; orth_vectors (X, &r1, &r2, r); while (alpha < (2 * PI + 0.001)) { rv = plus (plus (times (r1, cos (alpha)), times (r2, sin (alpha))), A); assignTD (&p[i], rv); i++; assignTD (&p[i], A); i++; alpha += (2 * PI) / (GridDensity * 4); } Cinit_surf_points (ident, 2, GridDensity * 4 + 1, p); free (p); } void Cdraw3d_cappedcylinder (const char *ident, double x, double y, double z, double a, double b, double c, double r) { Cdraw3d_cylinder (ident, x, y, z, a, b, c, r); Cdraw3d_roundplate (ident, -x, -y, -z, a, b, c, r); Cdraw3d_roundplate (ident, x, y, z, x + a, y + b, z + c, r); } void textformaterror (int line, const char *ident) { Cerrordialog (CMain, 20, 20, " Compile text to 3D ", " A text format error was encounted at line %d,\nwhile trying to draw 3d item to widget %s.\n ", line, ident); } void Cdraw3d_scale (const char *ident, double a) { DimensionScale = 32767 / a; } void Cdraw3d_offset (const char *ident, double x, double y, double z) { DimensionOffset.x = x; DimensionOffset.y = y; DimensionOffset.z = z; } void Cdraw3d_density (const char *ident, double a) { GridDensity = a; } void draw3d_surface(const char *ident, int w, int h, Vec *v) { int i; TD_Point *p = Cmalloc (w * h * sizeof (TD_Point)); for(i=0;i