Compare commits

...
Author SHA1 Message Date
Christopher Sean Morrison 35399328c4 more removal of cvs branching artifacts where it was necessary to tag before and after merging, pushed into the depths of svn history (svn branch delete)
svn:revision:46328
svn:tag:autoconf-20031202
svn:account:brlcad
2011-08-23 13:42:42 +00:00
cvs-fast-export 6a06b7652e Synthetic commit for incomplete tag autoconf-20031202
svn:revision:22236
cvs:account:cvs-fast-export
2003-12-02 19:33:55 +00:00
Erik Greenwald 48fca06345 muchos autoconf fixes, libtcl and libtk are now built with the rest of the
system, instead of trying to use the pre-installed versions

svn:revision:22235
cvs:branch:autoconf-branch
cvs:account:erikg
2003-12-02 19:33:55 +00:00
Erik Greenwald c4df2bdf23 automake file
svn:revision:22233
cvs:account:erikg
cvs:branch:autoconf-branch
2003-12-02 15:01:40 +00:00
Erik Greenwald 717eac05c1 starting merged autoconf of libtcl84
svn:revision:22217
cvs:branch:autoconf-branch
cvs:account:erikg
2003-11-14 19:30:20 +00:00
Erik Greenwald 5c9635ac4f fix for fbsd5
svn:revision:22214
cvs:account:erikg
cvs:branch:autoconf-branch
2003-11-13 12:53:37 +00:00
Erik Greenwald 38f6879448 generated now
svn:revision:22213
cvs:branch:autoconf-branch
cvs:account:erikg
2003-11-07 16:41:46 +00:00
Erik Greenwald fbeee555d6 eliminated cyclic dependancy
svn:revision:22196
cvs:account:erikg
cvs:branch:autoconf-branch
2003-11-06 13:21:40 +00:00
Erik Greenwald 9ab28cfbdb expansion seems to cause confusion with dependancies, so it's been unrolled
svn:revision:22195
cvs:account:erikg
cvs:branch:autoconf-branch
2003-11-06 13:20:32 +00:00
Erik Greenwald 853153e61b automake files
svn:revision:22168
cvs:account:erikg
cvs:branch:autoconf-branch
2003-10-08 16:57:54 +00:00
Erik Greenwald 4ae2549b68 autoconf files
svn:revision:22166
cvs:account:erikg
cvs:branch:autoconf-branch
2003-10-08 16:54:51 +00:00
Christopher Sean Morrison e6f630c2e9 Import of initial port to Windows
svn:revision:21564
svn:revision:21565
cvs:account:morrison
cvs:branch:photonmap-branch
2002-09-26 04:01:00 +00:00
Robert Parker 096c109ece Import itcl3.2
svn:revision:19762
svn:revision:19763
cvs:account:bparker
cvs:branch:itcl3-2
2000-12-06 21:48:10 +00:00
Robert Parker e078a68d77 Import itcl3.2
svn:revision:19760
svn:revision:19761
cvs:account:bparker
cvs:branch:itcl3-2
2000-12-06 21:35:20 +00:00
Robert Parker 0287a35ffb Import tk8.3
svn:revision:19758
svn:revision:19759
cvs:account:bparker
cvs:branch:tk8-3
2000-12-06 21:34:21 +00:00
Robert Parker e77989c21b Import tcl8.3
svn:revision:19756
svn:revision:19757
cvs:account:bparker
cvs:branch:tcl8-3
2000-12-06 21:33:21 +00:00
Lee Butler 9c696591dd The html manuals for BRLCAD
svn:revision:15427
cvs:account:butler
cvs:branch:VendorARL
1998-06-30 17:38:07 +00:00
John Anderson bf843475ea libpng 1.0.2
svn:revision:15365
cvs:account:jra
cvs:branch:libpng
1998-06-24 20:00:14 +00:00
John Anderson e63f8fccee Initial inclusion of zlib (version 1.0.4).
svn:revision:15338
cvs:account:jra
cvs:branch:zlib
1998-06-24 13:19:59 +00:00
John Anderson 13e0bb1a11 Checkpoint
svn:revision:8061
cvs:account:jra
cvs:branch:unlabeled-1.1.1
1993-12-09 09:52:56 +00:00
John Anderson e83e56b866 Checkpoint
svn:revision:7885
cvs:account:jra
cvs:branch:unlabeled-1.1.1
1993-10-21 15:33:46 +00:00
John Anderson fab2420d37 Checkpoint (working version for just 3DFACE entities).
svn:revision:7884
cvs:account:jra
cvs:branch:unlabeled-1.1.1
1993-10-21 14:14:44 +00:00
Paul Tanenbaum 6b8c080c36 Attempt to add $Header$ to file.
svn:revision:5208
cvs:branch:unlabeled-1.1.1
cvs:account:pjt
1991-02-14 09:24:53 +00:00
4641 changed files with 1901081 additions and 72663 deletions
+5
View File
@@ -26,3 +26,8 @@ _$*
*.ln
core
# CVS default ignores end
.lib*.* .proc-db.* .cvsignore .util.* .patch.* .burst.* .iges.* .mged.*
.fbserv.* .canon.* .anim.* .bench.* .conv.* .remrt.* .tools.* .comgeom-g.*
.tab.* .sig.* .irprep.* .vdeck.* .fbed.* .jack.* .vas4.* .off.* .jove.*
.lgt.* .nirt.* .mk.* .db.* .fb.* .rt.* .halftone.* .gtools.*
.cake*.* .bwish.* .cwish.* .tk.* .btclsh.*
View File
+65
View File
@@ -0,0 +1,65 @@
The US Army BRL-CAD Develoment Team would like to take this opportunity
to thank the many people and organizations who have contributed code or
suggestions for improving the BRL-CAD Package:
Sun Microsystems (William C. Lindemann)
mged/dm-sun.c
Sun Microsystems (Timothy G. Smith, Christopher J. Jackson, and James D. Fiori)
Substantial fixes to ease Solaris 2.X porting
24-bit LIBFB support
New improved XGL support for Solaris
University of Alabama in Huntsville
Research Institute, RI E-47
Sparkman DR NW
Huntsville, AL 35899
POC: Mark Huston Bowden or M. Shane Strickland
mged/hideline.c Hidden line removal
mged/dm-hp.c HP2397A terminal
mged/m-ps390.c color version for serial line connection
mged/dm-pss.c gsr routines
util/pl-hpgl.c convert UNIX-plot file to HP plotter language
Geometric Solutions, Inc (Christopher T. Johnson) <cjohnson@camelot.com>
Paladin Software
Cray Research, Inc.
halftone/*
remrt/rtsrv control support, movie speed ups, extra commands
A/UX support
mged push support, articulation support, animation support
located awf for brlman support.
some plotting tools
bug fixes
too many dinner time bug reports
format converter support (librt/cv_* routines), CV program
scriptsort
Geometric Solutions: reed@camelot.com (Harry J. Reed)
havoc.g
tank-car.g
t62a.g
Manchester-Computing-Centre, UK (Terry Hewitt)
Computer Graphics Unit, MCC" <HEWITT@vmsfe.mcc.ac.uk>
and
Mario Brand <mgbk1@tnofel.fel.tno.nl>
Support for BRL-CAD on HP-9000/730:
machinetype.sh, Cakefile.defs, libplot3/htond.c
Bill Laut (Gull Island Consultants, Inc.)
P.O. Box 627, Muskegon, MI 49440
rt/sh_marble.c -- substantial enhancements
rt/sh_wood.c -- a completely new shader
h/light.h enhancements
rt/sh_light.c enhancements for more easily aimable lights.
Henry Spencer
Regular expression library
John Ousterhout <john.ousterhout@eng.sun.com>
Tcl/Tk
File diff suppressed because it is too large Load Diff
+28
View File
@@ -0,0 +1,28 @@
Re-distribution of this software is restricted, as described in your
"Statement of Terms and Conditions for the Release of The BRL-CAD
Package" agreement.
Portions of this software and the associated databases and images are
Copyright (C) 1985, 1986, 1987, 1988, 1989, 1991, 1994, 1995, 2000, 2001,
2002, 2003 by the United States Army in all countries except the USA.
Unauthorized redistribution in any form is prohibited. Recipients of this
distribution are authorized unlimited use within their corporation,
organization, or agency.
The mark "BRL-CAD" is a Registered Trademark of the United States Army.
All rights reserved.
There is no warranty or other guarantee of fitness for this software,
it is provided solely "as is". Bug reports or fixes must be sent
to ARL, which may or may not act on them.
This software was developed by and is proprietary to the United States
Government, and any use of the software without the written permission
of the US Army Research Laboratory is strictly prohibited. Any
unauthorized use of the software will be construed as an infringement of
the Government's rights and will subject the unauthorized user to
action(s) for infringement damages. (BRL MFR 380-15, Feb-88)
The software in the "contributed" directory is Public Domain, Distribution
Unlimited. In addition, certain other modules in the BRL-CAD package
bear this designation. Files so marked are available for unlimited use.
+2196 -451
View File
File diff suppressed because it is too large Load Diff
+42 -7
View File
@@ -27,6 +27,12 @@
#ifndef OBJ
# include "Symbol OBJ required"
#endif
#ifndef VERSION_VARIABLE
# include "Symbol VERSION_VARIABLE required"
#endif
#ifndef LIBRARY_TITLE
# include "Symbol LIBRARY_TITLE required"
#endif
#ifndef EXTRA_OBJ
# define EXTRA_OBJ /**/
@@ -36,22 +42,51 @@
# define EXTRA_SETUP /**/
#endif
#ifndef EXTRA_OBJ_NO_DEPENDENCY
# define EXTRA_OBJ_NO_DEPENDENCY /**/
#endif
#ifndef LIB_FLAGS
# define LIB_FLAGS /**/
#endif
#if !defined(BUILD_LIBRARY)
PRODUCTS:: EXTRA_OBJ OBJ
newvers.sh VERSION_VARIABLE LIBRARY_TITLE
CC CFLAGS -c vers.c
rm -f PRODUCTS; EXTRA_SETUP
AR r PRODUCTS OBJ EXTRA_OBJ
AR r PRODUCTS OBJ EXTRA_OBJ EXTRA_OBJ_NO_DEPENDENCY vers.o
RANLIB PRODUCTS
/* If RANLIB is specified, be sure it is run when installing libraries */
# define AFTERINSTALL RANLIB
#else
/* Shared library support.
* Can't list SHARED_PRODUCT in 'rm' command, or will get wrong version number.
* (Cake won't re-run the LIBVERS shell script)
* If non-null, LIBVERS will start with a leading dot.
* Note that the RM command zaps anything starting with PRODUCTS.
* Note that if you have shared libraries, you better have symlinks.
*/
# define SHARED_PRODUCT PRODUCTS''[[LIBVERS]]
PRODUCTS&:: EXTRA_OBJ OBJ
newvers.sh VERSION_VARIABLE LIBRARY_TITLE
CC CFLAGS -c vers.c
rm -f PRODUCTS*; EXTRA_SETUP
BUILD_LIBRARY SHARED_PRODUCT OBJ EXTRA_OBJ EXTRA_OBJ_NO_DEPENDENCY vers.o
sharedliblink.sh SHARED_PRODUCT
/* Use this opportunity to build the symlink on install */
# define AFTERINSTALL sharedliblink.sh
#endif
%.o&: SRCDIR,,%,o if exist ../SRCDIR/%.c
%9,,%,o&: ../%9/%.c [[cakeinclude -i INCDIR -s ../%9 ../%9/%.c]] \
if exist ../%9/%.c
CC CFLAGS -c ../%9/%.c
%9,,%,o&: ../%9/%.c HDR_DEP9 if exist ../%9/%.c
CC CFLAGS LIB_FLAGS -c ../%9/%.c
/* Override the modes for the library */
#undef BINDIR
#undef BINPERM
#define BINDIR LIBDIR
#define BINPERM LIBPERM
/* If RANLIB is specified, be sure it is run when installing libraries */
#define AFTERINSTALL RANLIB
+26 -5
View File
@@ -1,15 +1,15 @@
/*
* C A K E F I L E . P R O G
*
* Like Cakefile.lib, this is the common part for making programs.
* Like Cakefile.lib, this is the common part for compiling programs.
*
* Author -
* Authors -
* Michael John Muuss
* Bob Parker
*
* Source -
* SECAD/VLD Computing Consortium, Bldg 394
* The U. S. Army Ballistic Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5066
* The U. S. Army Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5068 USA
*
* Distribution Status -
* Public Domain, Distribution Unlimitied.
@@ -21,7 +21,28 @@
everything&:: PRODUCTS
%.o: ../SRCDIR/%.c HDR_DEP if exist ../SRCDIR/%.c
@rm -f ./%.o
CC CFLAGS -c ../SRCDIR/%.c
%.o: ../SRCDIR/%.f if exist ../SRCDIR/%.f
@rm -f ./%.o
FC FFLAGS -c ../SRCDIR/%.f
/* There is a conflict here: When debugging, it's nice to
* be able to examine the intermediate .c file that LEX and YACC produce.
* When trying to port to a new platform, those leftovers can "trick"
* the unwary.
*/
/* Non-ANSI compilers can't take tab-# */
%.o: ../SRCDIR/%.l if exist ../SRCDIR/%.l
-rm -f ./%.c ./%.o
LEX -t LEX_OPTS ../SRCDIR/%.l | sed -e 's/^[ ]#/#/' > ./%.c
if test `wc -l < ./%.c` -lt 2 ; then rm -f ./%.c ; exit 1 ; fi
CC CFLAGS -I. -c ./%.c
%.o: ../SRCDIR/%.y if exist ../SRCDIR/%.y
-rm -f ./%.c ./%.h ./%.o
YACC YACC_OPTS ../SRCDIR/%.y
mv ./y.tab.c ./%.c
CC CFLAGS -I. -c ./%.c
+55 -25
View File
@@ -12,12 +12,14 @@
#define STUB_EXISTS {{ls ../SRCDIR|grep -s .MANSECTION.stub'$'}}
#define ARG_EXISTS {{ARGS="%"; test '%' != "$ARGS" -o -f %}}
/* Format sources for printing on stdout */
print&: Cakefile.print \
/* Format sources for printing on stdout. Use macro to bypass ANSI cpp "bug" */
#define PRINT_STUFF [[SUB X X.print ../SRCDIR/Cakefile ]] \
[[SUB X X.print ../SRCDIR/''*.[h''MANSECTION] ]] \
[[SUB X X.nroff ../SRCDIR/''*.MANSECTION ]] \
[[SUB X ../SRCDIR/X''SRCSUFF.print FILES]]
print&: PRINT_SUFF
%.print&: do-%.print if ARG_EXISTS
%.print&: if not ARG_EXISTS
@@ -64,6 +66,9 @@ lint&:
tags: [[echo SRC_LIST]]
ctags SRC_LIST
TAGS: [[echo SRC_LIST]]
etags SRC_LIST
flow&: [[echo SRC_LIST]]
cflow -I''INCDIR SRC_LIST > SRCDIR.flow
@@ -75,7 +80,11 @@ compare&: [[SUB X X.compare PRODUCTS]]
%.compare&: %
cmp BINDIR/% %
#if !defined(DONT_INSTALL)
uninstall&: uninstall-prod uninstall-man uninstall-stub
#else
uninstall&:
#endif
#ifdef PRODUCTS
uninstall-prod&: [[SUB X X.uninstall-prod PRODUCTS]]
@@ -89,9 +98,9 @@ uninstall-prod&:
uninstall-man&: do-uninstall-man if MAN_EXISTS
uninstall-man&: if not MAN_EXISTS
do-uninstall-man&: [[SUB ../SRCDIR/X X.uninstall-man ../SRCDIR/''*.MANSECTION]]
do-uninstall-man&: [[SUB ../SRCDIR/X X.ui-man ../SRCDIR/''*.MANSECTION]]
%.uninstall-man&:
%.ui-man&:
rm -f MANDIR''MANSECTION/% MANDIR''MANSECTION/%.bak
uninstall-stub&: do-uninstall-stub if STUB_EXISTS
@@ -102,24 +111,35 @@ do-uninstall-stub&: [[SUB ../SRCDIR/X.stub X.uninstall-stub ../SRCDIR/''*.stub]
%.uninstall-stub&:
rm -f MANDIR''MANSECTION/% MANDIR''MANSECTION/%.bak
#if !defined(DONT_INSTALL)
install&: install-prod install-man install-stub inst-dist
install-nobak&: install-prod-nobak install-man install-stub inst-dist
#else
install&: inst-dist
install-nobak&: inst-dist
#if !defined(EXTRA_INSTALL_TARGETS)
# define EXTRA_INSTALL_TARGETS /**/
#endif
#if defined(PRODUCTS)
install-prod&: [[SUB X X.iprod PRODUCTS]]
#if !defined(DONT_INSTALL)
install&: install-prod install-man install-stub
install-prod-nobak&: [[SUB X X.iprod-nobak PRODUCTS]]
install-nobak&: install-prod-nobak install-man install-stub
#else
install&:
install-nobak&:
#endif
#if defined(SHARED_PRODUCT)
install-prod&: [[SUB X X.iprod SHARED_PRODUCT]] EXTRA_INSTALL_TARGETS
install-prod-nobak&: [[SUB X X.iprod-nobak SHARED_PRODUCT]] EXTRA_INSTALL_TARGETS
#else
# if defined(PRODUCTS)
install-prod&: [[SUB X X.iprod PRODUCTS]] EXTRA_INSTALL_TARGETS
install-prod-nobak&: [[SUB X X.iprod-nobak PRODUCTS]] EXTRA_INSTALL_TARGETS
# else
install-prod&:
install-prod-nobak&:
# endif
#endif
/* Here is where we depend on having /bin/sh as the shell */
@@ -150,9 +170,9 @@ install-prod-nobak&:
install-man&: do-install-man if MAN_EXISTS
install-man&: if not MAN_EXISTS
do-install-man&: [[SUB ../SRCDIR/X X.install-man ../SRCDIR/''*.MANSECTION ]]
do-install-man&: [[SUB ../SRCDIR/X X.i-man ../SRCDIR/''*.MANSECTION ]]
%.install-man&: ../SRCDIR/%
%.i-man&: ../SRCDIR/%
@if cmp -s MANDIR''MANSECTION/% ../SRCDIR/%; \
then exit 0; fi; \
mv -f MANDIR''MANSECTION/% MANDIR''MANSECTION/%.bak 2>/dev/null; \
@@ -193,14 +213,10 @@ do-install-stub&: [[SUB ../SRCDIR/X.stub X.install-stub ../SRCDIR/''*.stub]]
./Cakefile \\\\*.[hcsfyl] \\\\*.sh \
\\\\*.MANSECTION \\\\*.MANSECTION.stub \\\\*.doc
#endif
#define IS_MASTER {{test x''MASTERHOST = x`GETHOST`}}
inst-dist&: inst-dist-main if IS_MASTER
/* inst-dist is also called from "install", so say nothing if not master */
inst-dist&: if not IS_MASTER
inst-dist-main&: dist-clobber [[SUB X X.do-inst-dist INSTALL_PATTERNS]]
/* inst-dist is never run automatically, it has to be run by hand. */
/* inst-dist is run from gen.sh as part of the final packaging of a distribution */
inst-dist&: dist-clobber [[SUB X X.do-inst-dist INSTALL_PATTERNS]]
dist-clobber&:
-rm -fr DISTRIBUTION/SRCDIR
@@ -224,10 +240,24 @@ dist-clobber&:
clobber&: clean noprod
clean&:
-rm -f core *~ *.o EXTRA_CLEAN SRCDIR.out SRCDIR.err SRCDIR.xref SRCDIR.flow SRCDIR.lint
-rm -f core *.core *~ *.o EXTRA_CLEAN SRCDIR.out SRCDIR.err SRCDIR.xref SRCDIR.flow SRCDIR.lint
#if defined(LIBRARY_TITLE)
/*
* The asterisk is to glob all the variations of (shared) library names.
* This depends on the fact that for libraries, PRODUCTS is a single name,
* not a list of file names, and that there will be no source file called
* PRODUCTS.c, e.g., no librt.c file for making librt.so.10.
*
* The "SRCDIR.*" version is to catch the case where we're changing
* from shared libraries to non-shared libraries.
*/
noprod&:
-rm -f PRODUCTS* SRCDIR.*
#else
noprod&:
-rm -f PRODUCTS
#endif
#ifdef never
/*
+22
View File
@@ -0,0 +1,22 @@
This software was developed by and is proprietary to the United States
Government, and any use of the software without the written permission
of the Ballistic Research Laboratory is strictly prohibited. Any
unauthorized use of the software will be construed as an infringement of
the Government's rights and will subject the unauthorized user to
action(s) for infringement damages. (BRL MFR 380-15, Feb-88)
The terms and conditions for the use of this software are detailed
in your distribution agreement.
Please note that portions of this software and the associated databases
and images are Copyright (C) 1985, 1986, 1987, 1988, 1989, 1991 by the United
States Army. Unauthorized redistribution in any form is prohibited.
Recipients of this distribution are authorized unlimited use within
their corporation, organization, or agency.
There is no warranty or other guarantee of fitness for this software,
it is provided solely "as is". Bug reports or fixes must be sent
to BRL, which may or may not act on them.
The software in the "contributed" directory is Public Domain, Distribution
Unlimited. In addition, certain other modules in the BRL-CAD package
bear this designation. Files so marked are available for unlimited use.
+28
View File
@@ -0,0 +1,28 @@
Re-distribution of this software is restricted, as described in your
"Statement of Terms and Conditions for the Release of The BRL-CAD
Package" agreement.
Portions of this software and the associated databases and images are
Copyright (C) 1985, 1986, 1987, 1988, 1989, 1991, 1994 by the United
States Army in all countries except the USA. Unauthorized redistribution
in any form is prohibited. Recipients of this distribution are
authorized unlimited use within their corporation, organization, or
agency.
The mark "BRL-CAD" is a Registered Trademark of the United States Army.
All rights reserved.
There is no warranty or other guarantee of fitness for this software,
it is provided solely "as is". Bug reports or fixes must be sent
to ARL, which may or may not act on them.
This software was developed by and is proprietary to the United States
Government, and any use of the software without the written permission
of the US Army Research Laboratory is strictly prohibited. Any
unauthorized use of the software will be construed as an infringement of
the Government's rights and will subject the unauthorized user to
action(s) for infringement damages. (BRL MFR 380-15, Feb-88)
The software in the "contributed" directory is Public Domain, Distribution
Unlimited. In addition, certain other modules in the BRL-CAD package
bear this designation. Files so marked are available for unlimited use.
+28
View File
@@ -0,0 +1,28 @@
Re-distribution of this software is restricted, as described in your
"Statement of Terms and Conditions for the Release of The BRL-CAD
Package" agreement.
Portions of this software and the associated databases and images are
Copyright (C) 1985, 1986, 1987, 1988, 1989, 1991, 1994, 1995 by the United
States Army in all countries except the USA. Unauthorized redistribution
in any form is prohibited. Recipients of this distribution are
authorized unlimited use within their corporation, organization, or
agency.
The mark "BRL-CAD" is a Registered Trademark of the United States Army.
All rights reserved.
There is no warranty or other guarantee of fitness for this software,
it is provided solely "as is". Bug reports or fixes must be sent
to ARL, which may or may not act on them.
This software was developed by and is proprietary to the United States
Government, and any use of the software without the written permission
of the US Army Research Laboratory is strictly prohibited. Any
unauthorized use of the software will be construed as an infringement of
the Government's rights and will subject the unauthorized user to
action(s) for infringement damages. (BRL MFR 380-15, Feb-88)
The software in the "contributed" directory is Public Domain, Distribution
Unlimited. In addition, certain other modules in the BRL-CAD package
bear this designation. Files so marked are available for unlimited use.
+28
View File
@@ -0,0 +1,28 @@
Re-distribution of this software is restricted, as described in your
"Statement of Terms and Conditions for the Release of The BRL-CAD
Package" agreement.
Portions of this software and the associated databases and images are
Copyright (C) 1985, 1986, 1987, 1988, 1989, 1991, 1994, 1995, 2000 by
the United States Army in all countries except the USA. Unauthorized
redistribution in any form is prohibited. Recipients of this
distribution are authorized unlimited use within their corporation,
organization, or agency.
The mark "BRL-CAD" is a Registered Trademark of the United States Army.
All rights reserved.
There is no warranty or other guarantee of fitness for this software,
it is provided solely "as is". Bug reports or fixes must be sent
to ARL, which may or may not act on them.
This software was developed by and is proprietary to the United States
Government, and any use of the software without the written permission
of the US Army Research Laboratory is strictly prohibited. Any
unauthorized use of the software will be construed as an infringement of
the Government's rights and will subject the unauthorized user to
action(s) for infringement damages. (BRL MFR 380-15, Feb-88)
The software in the "contributed" directory is Public Domain, Distribution
Unlimited. In addition, certain other modules in the BRL-CAD package
bear this designation. Files so marked are available for unlimited use.
+28
View File
@@ -0,0 +1,28 @@
Re-distribution of this software is restricted, as described in your
"Statement of Terms and Conditions for the Release of The BRL-CAD
Package" agreement.
Portions of this software and the associated databases and images are
Copyright (C) 1985, 1986, 1987, 1988, 1989, 1991, 1994, 1995, 2000, 2001
by the United States Army in all countries except the USA. Unauthorized
redistribution in any form is prohibited. Recipients of this
distribution are authorized unlimited use within their corporation,
organization, or agency.
The mark "BRL-CAD" is a Registered Trademark of the United States Army.
All rights reserved.
There is no warranty or other guarantee of fitness for this software,
it is provided solely "as is". Bug reports or fixes must be sent
to ARL, which may or may not act on them.
This software was developed by and is proprietary to the United States
Government, and any use of the software without the written permission
of the US Army Research Laboratory is strictly prohibited. Any
unauthorized use of the software will be construed as an infringement of
the Government's rights and will subject the unauthorized user to
action(s) for infringement damages. (BRL MFR 380-15, Feb-88)
The software in the "contributed" directory is Public Domain, Distribution
Unlimited. In addition, certain other modules in the BRL-CAD package
bear this designation. Files so marked are available for unlimited use.
+28
View File
@@ -0,0 +1,28 @@
Re-distribution of this software is restricted, as described in your
"Statement of Terms and Conditions for the Release of The BRL-CAD
Package" agreement.
Portions of this software and the associated databases and images are
Copyright (C) 1985, 1986, 1987, 1988, 1989, 1991, 1994, 1995, 2000, 2001,
2002 by the United States Army in all countries except the USA.
Unauthorized redistribution in any form is prohibited. Recipients of this
distribution are authorized unlimited use within their corporation,
organization, or agency.
The mark "BRL-CAD" is a Registered Trademark of the United States Army.
All rights reserved.
There is no warranty or other guarantee of fitness for this software,
it is provided solely "as is". Bug reports or fixes must be sent
to ARL, which may or may not act on them.
This software was developed by and is proprietary to the United States
Government, and any use of the software without the written permission
of the US Army Research Laboratory is strictly prohibited. Any
unauthorized use of the software will be construed as an infringement of
the Government's rights and will subject the unauthorized user to
action(s) for infringement damages. (BRL MFR 380-15, Feb-88)
The software in the "contributed" directory is Public Domain, Distribution
Unlimited. In addition, certain other modules in the BRL-CAD package
bear this designation. Files so marked are available for unlimited use.
+28
View File
@@ -0,0 +1,28 @@
Re-distribution of this software is restricted, as described in your
"Statement of Terms and Conditions for the Release of The BRL-CAD
Package" agreement.
Portions of this software and the associated databases and images are
Copyright (C) 1985, 1986, 1987, 1988, 1989, 1991, 1994, 1995, 2000, 2001,
2002, 2003 by the United States Army in all countries except the USA.
Unauthorized redistribution in any form is prohibited. Recipients of this
distribution are authorized unlimited use within their corporation,
organization, or agency.
The mark "BRL-CAD" is a Registered Trademark of the United States Army.
All rights reserved.
There is no warranty or other guarantee of fitness for this software,
it is provided solely "as is". Bug reports or fixes must be sent
to ARL, which may or may not act on them.
This software was developed by and is proprietary to the United States
Government, and any use of the software without the written permission
of the US Army Research Laboratory is strictly prohibited. Any
unauthorized use of the software will be construed as an infringement of
the Government's rights and will subject the unauthorized user to
action(s) for infringement damages. (BRL MFR 380-15, Feb-88)
The software in the "contributed" directory is Public Domain, Distribution
Unlimited. In addition, certain other modules in the BRL-CAD package
bear this designation. Files so marked are available for unlimited use.
+47
View File
@@ -0,0 +1,47 @@
To compile and install the BRLCAD source, perform the following steps:
% mkdir /usr/brlcad
If you choose a directory other than /usr/brlcad, you will need to set the
environment variable BRLCAD_ROOT to be the name of this directory. Because a
number of paths are compiled into the package, it is not possible to compile
the package for one location, then move it to another. Be sure that
/usr/brlcad/bin or $BRLCAD_ROOT/bin is in your shell path. For example:
sh:
BRLCAD_ROOT=/foobar/brlcad
PATH=$PATH:/foobar/brlcad/bin
export PATH
csh:
setenv BRLCAD_ROOT /foobar/brlcad
set path=($path /foobar/brlcad/bin)
Compile:
% cd /foobar/brlcad
% sh setup.sh
The next step can take a considerable amount of time on some systems:
sh:
make > make.log 2>&1
csh:
make >& make.log
Install:
Review the log of compilation, then run:
make install
This process should proceed without problems on the following systems:
RedHat Linux 7.2
FreeBSD 4.5
SunOS 5.8 (Solaris)
Irix 6.5
Mac OS X (With X11 installed -- INSTALL.pmac for details)
For binary and source download instructions see:
http://ftp.arl.army.mil/brlcad
+58
View File
@@ -0,0 +1,58 @@
Max OS X Installation Notes:
Being that this is the newest architecture to be added, there are some issues
to keep in mind with the installation when building from source. First, XFree86
will need to be installed if you want a gui. Mac OS X does not ship with an
X11 server installed by default. The XDarwin project, however, will include
the X11 libraries and headers necessary to properly build Tk (the only
component that presently "requires" X) and may be found at:
http://www.xdarwin.org
To build and install, you'll need to modify the Cakefile.defs file in the
source root. Modify the compilation options (near the top of the file)
as follows:
#define BUILD_OPTIMIZED 1
#define BUILD_SHARED 0
#define BUILD_XWINDOWS 1
#define BUILD_OPENGL 0
#define BUILD_PRODUCTION 1
There are details in the Cakefile.defs file for what each of these options
means, but the important one is that it is presently not possible to build
with shared libaries (patches welcome). Other than that the instructions
in INSTALL will all work with the exception of the "make install" step.
Run this instead:
cake install
If the build and install fails for whatever reason, then the system default Tcl
library is most likely getting in the way. You can temporarily move it out of
the way by doing:
sudo mv /usr/lib/libtcl.dylib /usr/lib/libtcl.dylib.backup
sudo mv /usr/lib/libtcl8.3.dylib /usr/lib/libtcl8.3.dylib.backup
sudo mv /usr/lib/libtclstub8.3.a /usr/lib/libtclstub8.3.a.backup
sudo mv /System/Library/Tcl /System/Library/Tcl.backup
Then you should be able to do:
sh setup.sh
cake clobber
cake
cake install
You can tell if a build succeeded properly by running "mged" from a terminal.
Also, you should be able to go into the "bench" directory and run the benchmark
(see doc/benchmark.doc) test script:
bench/try.sh
A window should pop up with a raytrace being displayed. If not, something is
not right. If you build without X support (setting in Cakefile.defs), then
you may verify your build by running "mged -c" or "bench/run.sh".
E-mail the cad list [cad@arl.army.mil] if any issues or questions arise.
Happy installation!
-69
View File
@@ -1,69 +0,0 @@
#################################################################
# #
# Makefile #
# #
# The top-level Makefile for the BRL CAD Software Distribution #
# #
# This exists mostly as a convienience, so folks can #
# type "make install" and such like, and get the expected #
# results, even in the face of the rather complex mechanism. #
# Thus, we make Make into a simple front-end for gen.sh #
# #
# Author - #
# Michael John Muuss #
# #
# Source - #
# SECAD/VLD Computing Consortium, Bldg 394 #
# The U. S. Army Ballistic Research Laboratory #
# Aberdeen Proving Ground, Maryland 21005-5066 #
# #
# $Header$ #
# #
#################################################################
SHELL = /bin/sh
# Main rule (default):
all:
-@sh gen.sh all
help:
-@sh gen.sh help
benchmark:
-@sh gen.sh $@
depend:
-@sh gen.sh $@
install:
-@sh gen.sh $@
inst-man:
-@sh gen.sh $@
uninstall:
-@sh gen.sh $@
inst-dist:
-@sh gen.sh $@
clean:
-@sh gen.sh $@
noprod:
-@sh gen.sh $@
clobber:
-@sh gen.sh $@
lint:
-@sh gen.sh $@
ls:
-@sh gen.sh $@
print:
-@sh gen.sh $@
typeset:
-@sh gen.sh $@
checkin:
-@sh gen.sh $@
dist:
-@sh gen.sh $@
arch:
-@sh gen.sh $@
mkdir:
-@sh gen.sh $@
relink:
-@sh gen.sh $@
rmdir:
-@sh gen.sh $@
+29
View File
@@ -0,0 +1,29 @@
# $Id$
SUBDIRS=@TCL@ @TK@ @ITCL@\
h\
libtcl8.4\
libtk8.4\
libbn\
libbu\
libdm\
libfb\
libfft\
liboptical\
liborle\
libpkg\
librt\
libsysv\
libtermio\
libutahrle\
libwdb\
anim\
bwish\
fb\
mged\
rt\
sh\
sig\
tclscripts\
util\
html\
doc
+1 -1
View File
@@ -319,7 +319,7 @@ ARCH_SUF = a
LIBFB = ../libfb.'`sh ../mtype.sh`'/libfb.${ARCH_SUF}
LIBRT = ../librt.'`sh ../mtype.sh`'/librt.${ARCH_SUF}
LIBPLOT = ../libplot3.'`sh ../mtype.sh`'/libplot3.${ARCH_SUF}
LIBRLE = ../librle.'`sh ../mtype.sh`'/librle.${ARCH_SUF}
LIBRLE = ../libutahrle.'`sh ../mtype.sh`'/libutahrle.${ARCH_SUF}
LIBPKG = ../libpkg.'`sh ../mtype.sh`'/libpkg.${ARCH_SUF}
LIBWDB = ../libwdb.'`sh ../mtype.sh`'/libwdb.${ARCH_SUF}
LIBSPL = ../libspl.'`sh ../mtype.sh`'/libspl.${ARCH_SUF}
View File
+56 -103
View File
@@ -1,12 +1,13 @@
.\" $Header$
.\" groff -ms README | print-postscript
.TL
README
.sp
The Ballistic Research Laboratory CAD Package
The BRL-CAD Package
.br
Release 3.5
Release 6.0
.br
(29-May-1989)
(October-2002)
.RT
.IP "VERSION"
.sp
@@ -20,27 +21,25 @@ versions actually contained on the distribution tape.
.IP CONTENTS
.sp
This README file exists only to provide you a brief roadmap to
the contents of the BRL-CAD distribution tape.
The information on how to read the tape,
install and operate the software,
the contents of the BRL-CAD distribution.
The information on how to install and operate the software,
and perform the benchmark tests have become sufficiently large
that they are now each a standalone document.
.sp
Please note that
this distribution package does \fInot\fR include
the various military-specific model
analysis tools such as GIFT, SAR, SLAVE, VAST, etc., nor does it
analysis tools such as MUVES, GIFT, SAR, SLAVE, VAST, etc., nor does it
include any military databases.
If you desire to have access to this material,
please contact Keith Applin at (301)-278-6647.
please contact Sean Morrison at (410)-278-6678.
.sp
.IP "INSTALLATION"
.sp
To install the BRL-CAD Package see the instructions in doc/install.doc.
This file includes directions on the best way to read the distribution
tape,
as well as details on how to configure and install the software.
This file also includes directions on how to compile and run
This file includes directions on the best way to get started with the
distribution, as well as details on how to configure and install the
software. This file also includes directions on how to compile and run
the benchmark tests.
.sp
.IP "BENCHMARK"
@@ -60,95 +59,51 @@ Models", included in the file papers/solid-models.
.sp
.IP "DISTRIBUTION DETAILS"
.sp
This section is included in the README file for two purposes.
First, we wish to remind you of the terms of this limited distribution.
Second, if you have obtained a copy of the printed documentation, and now
wish to obtain a copy of the software, the procedures are listed here.
This software is governed by a limited distribution agreement.
To obtain a copy of the BRL-CAD Package distribution materials, there
are two options:
.sp
To obtain a copy of the distribution, you should send the authors:
1. Free distribution with no support privileges: Those users with
online access to the InterNet may obtain the BRL-CAD Package via
FTP file transfer, at no cost, after completing and returning a signed
copy of the printed distribution agreement. A blank agreement form is
available only via anonymous FTP from host ftp.arl.army.mil (address
192.12.65.24) from file "brl-cad/agreement". No installation
assistance or telephone support will be available.
.sp
1) Enough magnetic tape for 20 Mbytes of data. Standard nine-track
half-inch magtape is the strongly preferred format, and can be written
at either 1600 or 6250 bpi, in TAR format with 10k byte records. For
sites with no half-inch tape drives, Silicon Graphics and SUN tape
cartridges can also be accommodated, using QIC-24 format.
.sp
2) A letter indicating:
2. Full service distribution: The Survivability/Vulnerability
Information Analysis Center (SURVIAC) administers the supported BRL-CAD
distributions and information exchange programs for ARL. Full service
distributions a copy of the full distribution materials on your choice
of magnetic tape media, or you may elect to obtain your copy via FTP.
One printed set of BRL-CAD documentation will be mailed to you.
Software upgrades will be provided at no additional charge,
and you will have access to full technical assistance by phone, FAX,
letter, or E-mail. Agencies of the Federal Government may acquire the
full service distribution with a simple MIPR or OGA funds transfer.
.sp
.nf
-- Who you are
-- What the BRL-CAD package is to be used for
-- The equipment and operating system(s) you plan on using
-- That you agree to the conditions listed below.
For further details, contact:
.sp .5
BRL-CAD Distribution
SURVIAC Aberdeen Satellite Office
4695 Millennium Drive
Belcamp, MD 210017-1505 USA
.fi
.sp
It is vital that your letter include a sentence acknowledging your
agreement to the conditions, such as "We agree to the
conditions of the distribution listed in your letter".
This software is an unpublished work that is not generally available to the
public, except through the terms of this limited distribution.
The United States Department of the Army grants a royalty-free,
nonexclusive, nontransferable license and right to use,
free of charge, with the following terms and conditions:
.sp
1. The BRL-CAD package source files will not be disclosed to third
parties. BRL needs to know who has what, and what it is being used for.
.sp
2. BRL will be credited should the software be used in a product or written
about in any publication. BRL will be referenced as the original
source in any advertisements.
.sp
3. The software is provided "as is", without warranty by BRL.
In no event shall BRL be liable for any loss or for any indirect,
special, punitive, exemplary, incidental, or consequential damages
arising from use, possession, or performance of the software.
.sp
4. When bugs or problems are found, you will make a reasonable effort
to report them back to BRL.
.sp
5. Before using the software at additional sites, or for permission to
use this work as part of a commercial package, you agree to first obtain
authorization from BRL.
.sp
6. You will own full rights to any databases or images you create with this
package.
.sp
All requests from US citizens, or from US government agencies should be
sent to:
.sp
.nf
.ne 1i
Ballistic Research Lab
Attn: Mike Muuss
APG, MD 21005-5066
.sp .5
or call USA telephone (410)-273-7794, send
E-mail to <cad-dist@arl.army.mil>, FAX your letter to USA (410)-272-6763,
or write to the above address.
.fi
.sp
If you are not a US citizen (regardless of any affiliation with a
US industry), or if you represent a foreign-owned or foreign-controlled
industry, you must send your letter and tape through your Ambassador to
the United States in Washington DC. Have your Ambassador submit the
request to:
.sp
.nf
.ne 1i
Army Headquarters
Attn: DAMI-FL
Washington, DC 20310
.fi
.sp
Because distribution tapes are written by various members of the
development team in their spare time, and because of vagaries in
the supply of printed manuals, the turnaround time for responding
to distribution requests varies from 1 to 12 weeks.
.sp
.ne 1i
.IP "COMMUNICATION"
.sp
You are invited to participate in the DARPA InterNet (aka "ARPANET")
You are invited to participate in the InterNet (aka "ARPANET")
electronic mailing list on the BRL-CAD software, which is called
.sp .5
.ti +1i
<CAD @ BRL.MIL>.
<CAD @ ARL.ARMY.MIL>.
.sp .5
Bug reports and discussions of new features
are the main topics; volume of messages has been light (so far).
@@ -156,12 +111,15 @@ Direct your bug reports to this address. Request a subscription by
sending to
.sp .5
.ti +1i
<CAD-REQUEST @ BRL.MIL>.
<CAD-REQUEST @ ARL.ARMY.MIL>.
.sp .5
If you find bugs, please report your experiences via E-mail.
While BRL makes no
offer of support, we are most interested in hearing about your
experiences.
.sp
A variety of information on BRL-CAD is available via the World-Wide-Web.
Papers, documentation, and the software repository may be found at
.sp .5
.ti +1i
http://ftp.arl.army.mil/brlcad/
.sp
.IP "FUTURE EVENTS"
.sp
@@ -173,21 +131,16 @@ to recipients of this software.
If your address changes, please let us
know, so we can update our records.
.sp
The BRL-CAD Symposium '88 was a big success.
If you would be interested in attending the Symposium in '89,
and especially if you would like to make a presentation, please
contact Keith Applin <Keith@BRL.MIL>, or call 301-278-6647.
.sp
.KS
.nf
Best Wishes,
-Mike Muuss
-Lee Butler
.sp
Leader, Advanced Computer Systems Team
U.S. Army Ballistic Research Laboratory
APG, MD. 21005-5066
USA
Leader, Advanced Computer Systems Team
AMSRL-SL-BE
U.S. Army Research Laboratory
APG, MD 21005-5068 USA
.sp
ArpaNet: <Mike @ BRL.MIL>
E-mail: <BUTLER @ ARL.ARMY.MIL>
.KE
.fi
+69
View File
@@ -0,0 +1,69 @@
/*
* tab/Cakefile
*/
#define SRCDIR anim
#define PRODUCTS anim_cascade anim_fly anim_hardtrack anim_keyread \
anim_lookat anim_offset anim_orient anim_script \
anim_sort anim_time anim_track anim_turn chan_add \
chan_mult chan_permute \
#define SRCSUFF .c
#define MANSECTION 1
#include "../Cakefile.defs"
#include "../Cakefile.prog"
#define FILES anim_cascade anim_fly anim_hardtrack anim_keyread \
anim_lookat anim_offset anim_orient anim_script anim_sort \
anim-time anim_track anim_turn cattrack chan_add chan_mult \
chan_permute
/* Explicit composition of each product */
anim_cascade: anim_cascade.o LIBBN_DEP LIBBU_DEP
CC LDFLAGS anim_cascade.o LIBRT LIBBN LIBBU LIBBU_LIBES LIBES -o anim_cascade
anim_fly: anim_fly.o LIBBU_DEP
CC LDFLAGS anim_fly.o LIBBU LIBBU_LIBES LIBES -o anim_fly
anim_hardtrack: anim_hardtrack.o LIBBN_DEP LIBBU_DEP
CC LDFLAGS anim_hardtrack.o LIBRT LIBBN LIBBU LIBBU_LIBES LIBES -o anim_hardtrack
anim_keyread: anim_keyread.o LIBBN_DEP LIBBU_DEP
CC LDFLAGS anim_keyread.o LIBBN LIBBU LIBBU_LIBES LIBES -o anim_keyread
anim_lookat: anim_lookat.o LIBBN_DEP LIBBU_DEP
CC LDFLAGS anim_lookat.o LIBBN LIBBU LIBBU_LIBES LIBES -o anim_lookat
anim_offset: anim_offset.o LIBBN_DEP LIBBU_DEP
CC LDFLAGS anim_offset.o LIBBN LIBBU LIBBU_LIBES LIBES -o anim_offset
anim_orient: anim_orient.o LIBBN_DEP LIBBU_DEP
CC LDFLAGS anim_orient.o LIBRT LIBBN LIBBU LIBBU_LIBES LIBES -o anim_orient
anim_script: anim_script.o LIBBN_DEP LIBBU_DEP
CC LDFLAGS anim_script.o LIBRT LIBBN LIBBU LIBBU_LIBES LIBES -o anim_script
anim_sort: anim_sort.o LIBBU_DEP
CC LDFLAGS anim_sort.o LIBBU LIBBU_LIBES LIBES -o anim_sort
anim_time: anim_time.o
CC LDFLAGS anim_time.o LIBRT LIBBN LIBBU LIBBU_LIBES LIBES -o anim_time
anim_track: anim_track.o cattrack.o LIBBN_DEP LIBBU_DEP
CC LDFLAGS anim_track.o cattrack.o LIBRT LIBBN LIBBU LIBBU_LIBES LIBES -o anim_track
anim_turn: anim_turn.o LIBBN_DEP LIBBU_DEP
CC LDFLAGS anim_turn.o LIBRT LIBBN LIBBU LIBBU_LIBES LIBES -o anim_turn
chan_add: chan_add.o
CC LDFLAGS chan_add.o LIBES -o chan_add
chan_mult: chan_mult.o
CC LDFLAGS chan_mult.o LIBES -o chan_mult
chan_permute: chan_permute.o
CC LDFLAGS chan_permute.o LIBES -o chan_permute
#include "../Cakefile.rules"
+51
View File
@@ -0,0 +1,51 @@
bin_PROGRAMS = anim_cascade anim_fly anim_hardtrack anim_keyread anim_lookat anim_offset anim_orient anim_script anim_sort anim_time anim_track anim_turn chan_add chan_mult chan_permute
BN=$(top_builddir)/libbn/libbn.la $(BU)
BU=$(top_builddir)/libbu/libbu.la @TCL_LIBS@ @PTHREAD_LIBS@ -lm
anim_cascade_SOURCES = anim_cascade.c
anim_cascade_LDADD = $(BN) $(BU)
anim_fly_SOURCES = anim_fly.c
anim_fly_LDADD = $(BU)
anim_hardtrack_SOURCES = anim_hardtrack.c
anim_hardtrack_LDADD = $(BN) $(BU)
anim_keyread_SOURCES = anim_keyread.c
anim_keyread_LDADD = $(BN) $(BU)
anim_lookat_SOURCES = anim_lookat.c
anim_lookat_LDADD = $(BN) $(BU)
anim_offset_SOURCES = anim_offset.c
anim_offset_LDADD = $(BN) $(BU)
anim_orient_SOURCES = anim_orient.c
anim_orient_LDADD = $(BN) $(BU)
anim_script_SOURCES = anim_script.c
anim_script_LDADD = $(BN) $(BU)
anim_sort_SOURCES = anim_sort.c
anim_sort_LDADD = $(BU)
anim_time_SOURCES = anim_time.c
anim_time_LDADD = $(BU)
anim_track_SOURCES = anim_track.c cattrack.c
anim_track_LDADD = $(BN) $(BU)
anim_turn_SOURCES = anim_turn.c
anim_turn_LDADD = $(BN) $(BU)
chan_add_SOURCES = chan_add.c
chan_mult_SOURCES = chan_mult.c
chan_permute_SOURCES = chan_permute.c
CFLAGS = -I$(top_srcdir)/h
man_MANS = anim_cascade.1 anim_fly.1 anim_hardtrack.1 anim_keyread.1 anim_lookat.1 anim_offset.1 anim_orient.1 anim_script.1 anim_sort.1 anim_time.1 anim_track.1 anim_turn.1 chan_mult.1 chan_permute.1
EXTRA_DIST = $(man_MANS)
+187
View File
@@ -0,0 +1,187 @@
.TH ANIM_CASCADE 1 BRL/CAD
.SH NAME
anim_cascade - evaluate movement of an object relative to a moving frame of
reference
.SH SYNOPSIS
.B anim_cascade [-s][-o(f|r|a)] [-(f|r|a)(c|y) # # #] <
.B input.table >
.B output.table
.SH DESCRIPTION
.I Anim_cascade
is designed to enable the user to control the movement of objects relative to
other objects. In the normal mode of operation, the user supplies
the position and orientation of a (possibly moving) frame of reference and
the position
and orientation of an object relative to the frame of reference,
and
.I anim_cascade
produces the absolute position and orientation of the object at each
point in time.
All orientations are specified as yaw, pitch, and roll.
The columns of the input table are:
.sp
time fx fy fz fyaw fpitch froll rx ry rz ryaw rpitch rroll
.sp
and the columns of the output table are:
.sp
time ax ay az ayaw apitch aroll
.sp
Here "f" refers to the frame of reference, "r" refers to the position
and orientation of the object relative to the frame, and "a"
refers to the absolute position and orientation of the object.
.SH OPTIONS
.TP
.B \-or
Output the relative position and orientation.
If this option is specified,
.I anim_cascade
will expect the absolute position and orientation of the frame of
reference and the object as input,
and will produce the position and orientation or the object relative to
the frame as output. The
input columns should be:
.sp
time fx fy fz fyaw fpitch froll ax ay az ayaw apitch aroll
.sp
and the output columns will be:
.sp
time rx ry rz ryaw rpitch rroll
.sp
.TP
.B \-of
Output the frame of reference.
If this option is specified,
.I anim_cascade
will expect the absolute and relative positions and orientations of the
object as input,
and will produce the corresponding frame of reference as output.
The input columns should be:
.sp
time ax ay az ayaw apitch aroll rx ry rz ryaw rpitch rroll
.sp
and the output columns will be:
.sp
time fx fy fz fyaw fpitch froll
.sp
.TP
.B \-fc # # #
Specify a constant position for the frame of reference. The
columns fx, fy, and fz should be omitted from the input table, and the
command-line arguments will be used instead.
This has no effect if used
in conjunction with
.B -of
.TP
.B \-fy # # #
Specify a constant orientation for the frame of reference. The
columns fyaw, fpitch, and froll should be omitted from the input table,
and the command-line arguments will be used instead.
This has no effect if used
in conjunction with
.BR -of .
.TP
.B \-rc # # #
Specify a constant position of the object relative to the frame
of reference. The
columns rx, ry, and rz should be omitted from the input table, and the
command-line arguments will be used instead.
This has no effect if used
in conjunction with
.BR -or .
.TP
.B \-ry # # #
Specify a constant orientation of the object relative to the
frame of reference. The
columns ryaw, rpitch, and rroll should be omitted from the input table,
and the command-line arguments will be used instead.
This has no effect if used
in conjunction with
.BR -or .
.TP
.B \-ac # # #
Specify a constant absolute position for the object. The
columns ax, ay, and az should be omitted from the input table, and the
command-line arguments will be used instead.
This has no effect unless used
in conjunction with
.B -or
or
.BR -of .
.TP
.B \-ay # # #
Specify a constant absolute orientation for the object. The
columns ayaw, apitch, and aroll should be omitted from the input table,
and the
command-line arguments will be used instead.
This has no effect unless used
in conjunction with
.B -or
or
.BR -of .
.TP
.B \-s
Suppress time column. No time column is read or written.
.sp
Note: When all of the input columns are specified with command-line arguments,
then standard input is not read and
only one line of output is produced. The time value will be set to zero,
unless it is suppressed.
.SH EXAMPLES
1. Suppose that you want the virtual camera to pan in a circle around a
moving vehicle, always staying a fixed distance from the vehicle.
There should already exist an animation table with the time, position,
and orientation of the vehicle in each frame. This will be the moving
frame of reference. Next, you should create an animation table which
describes how the camera would need to move if the vehicle stood still
at the origin. The columns of the second animation table should be
appended to the columns of the first table
(using
.IR paste ,
for example), to create the
input table.
.I Anim_cascade
will produce an absolute animation table for
the camera, suitable to use as input to
.IR anim_script :
.sp
anim_cascade < input.table | anim_script -v500 > view.script
.sp
2. Suppose that you have an animation path for an object and you want to
know when it crosses a given oblique plane. You can use the
.B -or
option to
find out what the position of the object is relative to the frame of
reference of the plane. Suppose that the plane is defined by the
equation:
.sp
x + z = 0
.sp
In a frame of reference located at the origin with a pitch of 45
degrees, the x-axis is perpendicular to the given plane.
To convert the absolute animation path into this frame of reference, the command
would be:
.sp
anim_cascade -or -fc 0 0 0 -fy 0 45 0 < absolute.table > relative.table
.sp
Wherever the x coordinate in the output table is positive, the object
lies above the plane.
.sp
3. Suppose that one object is situated at the point (1,2,3) with a yaw,
pitch, and roll of (45, 25, 10). Suppose further that you want to
position a camera so that to the camera, the first object seems to be 10
units straight ahead, facing to the right. You could find the required
position and orientation of the camera with the following command:
.sp
anim_cascade -s -of -ac 1 2 3 -ay 45 25 10 -rc 10 0 0 -ry -90 0 0
.sp
.SH AUTHOR
Carl J. Nuzman
.SH COPYRIGHT
This software is Copyright (C) 1993 by the United States Army
in all countries except the USA. All rights reserved.
.SH "BUG REPORTS"
Reports of bugs or problems should be submitted via electronic
mail to <CAD@ARL.ARMY.MIL>.
+301
View File
@@ -0,0 +1,301 @@
/* A N I M _ C A S C A D E . C
*
* Purpose: Given position and orientation of main frame of reference,
* along with the position and orientation of another frame with respect
* to the main frame, give the absolute orientation and position of the
* second frame.
* For example, given the position and orientation of a tank, and of the
* turret relative to the tank, you can get the absolute position and
* orientation of the turret at each time.
* Or, optionally, given position and orientation of main frame of
* reference, and the absolute position and orientation of another frame,
* find the position and orientation of the second frame in terms of the main
* frame of reference. (-i option).
*
* Usage:
* anim_cascade main.table < relative.table > absolute.table
*
* The format of the tables is:
* time x y z yaw pitch roll
* unless specified otherwise by options.
*
* Author -
* Carl J. Nuzman
*
* Source -
* The U. S. Army Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5068 USA
*
* Distribution Notice -
* Re-distribution of this software is restricted, as described in
* your "Statement of Terms and Conditions for the Release of
* The BRL-CAD Pacakge" agreement.
*
* Copyright Notice -
* This software is Copyright (C) 1993 by the United States Army
* in all countries except the USA. All rights reserved.
*/
#include "conf.h"
#include <math.h>
#include <stdio.h>
#include "machine.h"
#include "vmath.h"
#include "bu.h"
#include "bn.h"
#include "anim.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifndef M_PI
#define RTOD 180.000/M_PI
#endif
#define CASCADE_A 0
#define CASCADE_R 1
#define CASCADE_F 2
int get_args();
extern void anim_dy_p_r2mat();
extern void anim_tran();
extern int anim_mat2ypr();
extern int bu_optind;
extern char *bu_optarg;
vect_t fcenter, fypr, rcenter, rypr, acenter, aypr;
int cmd_fcen, cmd_fypr, cmd_rcen, cmd_rypr, cmd_acen, cmd_aypr;
int output_mode, read_time, print_time;
int
main (argc,argv)
int argc;
char **argv;
{
int val;
fastf_t time, yaw1, pitch1, roll1, yaw2, pitch2, roll2;
vect_t cen1, cen2, cen_ans, ang_ans, rad_ang_ans, rotated;
mat_t m_rot1, m_rot2, m_ans;
int one_time, read_cen1, read_cen2, read_rot1, read_rot2;
read_cen1 = read_cen2 = read_rot1 = read_rot2 = 1;
if (!get_args(argc,argv))
fprintf(stderr,"anim_cascade: Argument error.");
switch (output_mode) {
case CASCADE_A:
if (cmd_fcen) {
VMOVE(cen1, fcenter);
read_cen1 = 0;
}
if (cmd_rcen) {
VMOVE(cen2, rcenter);
read_cen2 = 0;
}
if (cmd_fypr){
anim_dy_p_r2mat(m_rot1, fypr[0], fypr[1], fypr[2]);
read_rot1 = 0;
}
if (cmd_rypr){
anim_dy_p_r2mat(m_rot2, rypr[0], rypr[1], rypr[2]);
read_rot2 = 0;
}
break;
case CASCADE_R:
if (cmd_fcen) {
VMOVE(cen1, fcenter);
read_cen1 = 0;
}
if (cmd_acen) {
VMOVE(cen2, acenter);
read_cen2 = 0;
}
if (cmd_fypr){
anim_dy_p_r2mat(m_rot1, fypr[0], fypr[1], fypr[2]);
read_rot1 = 0;
}
if (cmd_aypr){
anim_dy_p_r2mat(m_rot2, aypr[0], aypr[1], aypr[2]);
read_rot2 = 0;
}
break;
case CASCADE_F:
if (cmd_acen) {
VMOVE(cen1, acenter);
read_cen1 = 0;
}
if (cmd_rcen) {
VMOVE(cen2, rcenter);
read_cen2 = 0;
}
if (cmd_aypr){
anim_dy_p_r2mat(m_rot1, aypr[0], aypr[1], aypr[2]);
read_rot1 = 0;
}
if (cmd_rypr){
anim_dy_p_r2mat(m_rot2, rypr[0], rypr[1], rypr[2]);
read_rot2 = 0;
}
break;
default:
break;
}
one_time = (!(read_cen1||read_cen2||read_rot1||read_rot2));
read_time = one_time ? 0 : print_time;
time = 0.0;
val = 3;
while(1){
if (read_time) {
val=scanf("%lf",&time);
if (val < 1) break;
}
if (read_cen1)
val =scanf("%lf %lf %lf",cen1, cen1+1, cen1+2);
if (read_rot1) {
val=scanf("%lf %lf %lf", &yaw1, &pitch1, &roll1);
anim_dy_p_r2mat(m_rot1, yaw1, pitch1, roll1);
}
if (read_cen2) {
val=scanf("%lf %lf %lf", cen2, cen2+1,cen2+2);
}
if (read_rot2) {
val=scanf("%lf %lf %lf", &yaw2, &pitch2, &roll2);
anim_dy_p_r2mat(m_rot2, yaw2, pitch2, roll2);
}
if (val<3) break;
if (output_mode==CASCADE_R) {
anim_tran(m_rot1);
VSUB2(rotated,cen2,cen1);
MAT4X3PNT(cen_ans, m_rot1, rotated);
bn_mat_mul(m_ans, m_rot1, m_rot2);
} else if (output_mode==CASCADE_F) {
anim_tran(m_rot2);
bn_mat_mul(m_ans, m_rot1, m_rot2);
MAT4X3PNT(rotated, m_ans, cen2);
VSUB2(cen_ans, cen1, rotated);
} else {
MAT4X3PNT(rotated, m_rot1, cen2);
VADD2(cen_ans, rotated, cen1);
bn_mat_mul(m_ans, m_rot1, m_rot2);
}
anim_mat2ypr(rad_ang_ans, m_ans);
VSCALE(ang_ans, rad_ang_ans, RTOD);
if (print_time){
printf("%g",time);
}
printf("\t%.12g\t%.12g\t%.12g", cen_ans[0], cen_ans[1], cen_ans[2]);
printf("\t%.12g\t%.12g\t%.12g", ang_ans[0], ang_ans[1], ang_ans[2]);
printf("\n");
if (one_time) break;
}
return( 0 );
}
#define OPT_STR "so:f:r:a:"
int get_args(argc,argv)
int argc;
char **argv;
{
int c,d;
output_mode = CASCADE_A;
cmd_fcen = cmd_fypr = cmd_rcen = cmd_rypr = cmd_acen = cmd_aypr = 0;
print_time = 1;
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
switch(c){
case 'f':
d = *(bu_optarg);
if (d == 'c'){
sscanf(argv[bu_optind],"%lf",fcenter+0);
sscanf(argv[bu_optind+1],"%lf",fcenter+1);
sscanf(argv[bu_optind+2],"%lf",fcenter+2);
bu_optind += 3;
cmd_fcen = 1;
break;
} else if ( d =='y'){
sscanf(argv[bu_optind],"%lf",fypr+0);
sscanf(argv[bu_optind+1],"%lf",fypr+1);
sscanf(argv[bu_optind+2],"%lf",fypr+2);
bu_optind += 3;
cmd_fypr = 1;
break;
} else {
fprintf(stderr,"anim_cascade: unknown option -f%c\n", d);
}
break;
case 'r':
d = *(bu_optarg);
if (d == 'c'){
sscanf(argv[bu_optind],"%lf",rcenter+0);
sscanf(argv[bu_optind+1],"%lf",rcenter+1);
sscanf(argv[bu_optind+2],"%lf",rcenter+2);
bu_optind += 3;
cmd_rcen = 1;
break;
} else if ( d =='y'){
sscanf(argv[bu_optind],"%lf",rypr+0);
sscanf(argv[bu_optind+1],"%lf",rypr+1);
sscanf(argv[bu_optind+2],"%lf",rypr+2);
bu_optind += 3;
cmd_rypr = 1;
break;
} else {
fprintf(stderr,"anim_cascade: unknown option -r%c\n", d);
}
break;
case 'a':
d = *(bu_optarg);
if (d == 'c'){
sscanf(argv[bu_optind],"%lf",acenter+0);
sscanf(argv[bu_optind+1],"%lf",acenter+1);
sscanf(argv[bu_optind+2],"%lf",acenter+2);
bu_optind += 3;
cmd_acen = 1;
break;
} else if ( d =='y'){
sscanf(argv[bu_optind],"%lf",aypr+0);
sscanf(argv[bu_optind+1],"%lf",aypr+1);
sscanf(argv[bu_optind+2],"%lf",aypr+2);
bu_optind += 3;
cmd_aypr = 1;
break;
} else {
fprintf(stderr,"anim_cascade: unknown option -a%c\n", d);
}
break;
case 'o':
d = *(bu_optarg);
if (d == 'r'){
output_mode = CASCADE_R;
} else if (d == 'f') {
output_mode = CASCADE_F;
} else if (d == 'a') { /* default */
output_mode = CASCADE_A;
} else {
fprintf(stderr,"anim_cascade: unknown option -i%c\n",d);
}
break;
case 's':
print_time = 0;
break;
default:
fprintf(stderr,"anim_cascade: unknown option: -%c\n",c);
return(0);
}
}
return(1);
}
+94
View File
@@ -0,0 +1,94 @@
.TH ANIM_FLY 1 BRL/CAD
.SH NAME
anim_fly - make animation table to simulate flying motion
.SH SYNOPSIS
.B anim_fly
.B [-f factor]
.B [-r]
.B [-p integer]
.B [-b max_bank_angle]
.B [-s step]
.B < in.table
.B > out.table
.SH DESCRIPTION
This filter is designed to simulate the motion of an airplane.
Given a four-column table specifying the desired 3D position of the
airplane at each relevant time step,
.I anim_fly
produces a seven-column file
which also includes the orientation of the plane in terms of yaw,
pitch, and roll. The yaw and pitch are manipulated so that
the plane faces the direction of motion, while the roll is used to do
banking.
.SH OPTIONS
.TP
.B -f#
This option specifies a factor to control the severity of the banking.
The best factor is a subjective decision; a good starting point can best
be obtained by using the -b option. Animations representing aircraft
of different scales will need different factors.
If the
slightest curve throws the plane into a 90 degree bank, the factor is
too large; if it doesn't bank enough, the factor is too small. The size
of the best factor varies inversely with the size of the imagined
aircraft plane.
If a factor of 0 is used, there will
be no banking. This would be appropriate for animating a ground
vehicle.
.TP
.B -b#
This option is used to estimate a good value for the -f option. The
parameter is the maximum desired banking angle. Anim_fly then computes
the factor necessary to keep the banking below the specified angle. This
value is returned instead of anim_fly's usual output.
.TP
.B -r
Suppress vertical loop smoothing.
A special case occurs if the aircraft is to perform a vertical
loop. Normally, the algorithm likes to keep the aircraft right-side up.
This would cause the airplane to do an instantaneous 180 roll as it hits
the vertical portion of the loop. To counter this, a capability was
built in which prevents this sudden roll, allowing the aircraft to go
upside-down in a loop situation. This feature can be suppressed with the
.B -r
flag.
.TP
.B -p
Specify the ratio of input rows to output rows, which must be
an integer. The default, of course, is one. The accuracy of the output
depends on having a large number of input lines, which is not usually a
problem in animations, which require a large number of frames per
second, anyway. If a test animation with a small number of frames per
second is being created, the user should still use an input table
with a high number of input rows, reducing the frequency of the output
with the
.B -p
option. For example, if
.B in.table
contains 30 rows for each
second of the animation, then the command:
.sp
anim_fly -f0.001 -p10 < in.table > out.table
.sp
would produce an animation table containing 3 rows for each
second of the animation.
.TP
.B -s
Specify the minimum step size for the discrete-time differentiation. At any
given point on the flight path, the yaw, pitch, and roll are calculated based
on a past point, the current point, and a future point. Normally,
these are consecutive points from the input table. If the time
difference between the points falls below a certain threshold,
then non-consecutive points are used to avoid
numerical instability. The default time threshhold is 0.1 seconds - this
can be raised or lowered using the -s option.
Try raising the threshold if the output orientations experience random
jiter.
.SH AUTHOR
Carl J. Nuzman
.SH COPYRIGHT
This software is Copyright (C) 1993 by the United States Army
in all countries except the USA. All rights reserved.
.SH "BUG REPORTS"
Reports of bugs or problems should be submitted via electronic
mail to <CAD@ARL.ARMY.MIL>.
+320
View File
@@ -0,0 +1,320 @@
/* A N I M _ F L Y . C
*
* Simulate flying motion, for an airplane or virtual camera.
*
* This filter operates on animation tables. Given the desired position
* of the airplane in each frame, anim_fly produces a table including the
* plane's position and orientation. A "magic factor" should be supplied
* to control the severity of banking. Looping behavior can be toggled
* with another option.
*
*
* Author -
* Carl J. Nuzman
*
* Source -
* The U. S. Army Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5068 USA
*
* Distribution Notice -
* Re-distribution of this software is restricted, as described in
* your "Statement of Terms and Conditions for the Release of
* The BRL-CAD Pacakge" agreement.
*
* Copyright Notice -
* This software is Copyright (C) 1993 by the United States Army
* in all countries except the USA. All rights reserved.
*/
#include "conf.h"
#include <math.h>
#include <stdio.h>
#include "machine.h"
#include "externs.h"
#include "bu.h"
#include "vmath.h"
#include "anim.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#define MAXN 100
int estimate_f = 0;
fastf_t max_bank = 0;
fastf_t max_cross = 0;
int loop = 1;
int print_int = 1;
fastf_t magic_factor = 1.0;
fastf_t desired_step = 0.1;
int get_args();
#define PREP -1
#define START 0
#define MIDDLE 1
#define WANE 2
#define END 3
#define STOP 4
int
main(argc,argv)
int argc;
char **argv;
{
int count, status, num_read, enn, i, pp;
fastf_t *points, *cur;
fastf_t yaw, pch, rll, stepsize, first[4], second[4];
fastf_t f_prm_0(), f_prm_1(), f_prm_2();
void get_orientation();
yaw = pch = rll = 0.0;
if (!get_args(argc,argv))
fprintf(stderr,"Anim_fly: Get_args error");
/* read first two lines of table to determine the time step used */
/* (a constant time step is assumed throughout the rest of the file)*/
scanf("%lf %lf %lf %lf", first, first+1, first+2, first+3);
scanf("%lf %lf %lf %lf", second, second+1, second+2, second+3);
stepsize = second[0]-first[0];
/* determine n, the number of points to store ahead and behind
* the current point. 2n points are stored, minimum enn=2 */
enn = (int) (desired_step/stepsize);
if (enn>MAXN) enn=MAXN;
if (enn<1) enn=1;
/* allocate storage */
points = (fastf_t *) calloc((3*enn+1)*4, sizeof(fastf_t));
/* read the first 3n points into the storage array*/
VMOVEN(points+4, first, 4);
VMOVEN(points+8, second, 4);
num_read=4; /* in order to pass test if n=1 */
for (cur=points+12; cur<points+(4*(3*enn+1)); cur+=4){
num_read=scanf("%lf %lf %lf %lf", cur,cur+1,cur+2,cur+3);
}
if (num_read<4){
fprintf(stderr,"Anim_fly: Not enough lines in input table.\n");
fprintf(stderr,"Increase number of lines or reduce the minimum stepsize with -s.\n");
fprintf(stderr,"Currently the minumum step size is %g seconds.\n",desired_step);
exit(0);
}
max_cross = 0;
count = 0;
pp = 0;
status = START;
while (status != STOP) {
switch (status) {
case START: /* first n points */
pp += 4;
get_orientation(points+pp,points+pp+4*enn,points+pp+4*2*enn, f_prm_0, &yaw, &pch, &rll);
if (!(count%print_int)&&!estimate_f) {
printf("%.10g\t%.10g\t%.10g\t%.10g\t%.10g\t%.10g\t%.10g\n",points[pp+0],points[pp+1],points[pp+2],points[pp+3],yaw,pch,rll);
}
if (pp >= 4*enn)
status=MIDDLE;
break;
case MIDDLE: /* middle points (at least one)*/
for (i=0; i<3*enn*4; i++){
VMOVEN(points+(4*i), points+(4*(i+1)), 4);
}
num_read=scanf("%lf %lf %lf %lf", points+(4*(3*enn)),points+(4*(3*enn)+1),points+(4*(3*enn)+2),points+(4*(3*enn)+3));
if (num_read < 4) {
pp = 0;
status = WANE;
}
get_orientation(points,points+(4*enn),points+4*(2*enn), f_prm_1, &yaw, &pch, &rll);
if (!(count%print_int)&&!estimate_f) {
printf("%.10g\t%.10g\t%.10g\t%.10g\t%.10g\t%.10g\t%.10g\n",points[4*(enn)+0],points[4*(enn)+1],points[4*(enn)+2],points[4*(enn)+3],yaw,pch,rll);
}
break;
case WANE: /* last n - 1 middle points */
pp += 4;
if (pp >= 4*enn){
status = END;
count--;
pp = 0;
break;
}
get_orientation(points+pp,points+pp+4*enn,points+pp+4*2*enn, f_prm_1, &yaw, &pch, &rll);
if (!(count%print_int)&&!estimate_f) {
printf("%.10g\t%.10g\t%.10g\t%.10g\t%.10g\t%.10g\t%.10g\n",points[4*(enn)+0+pp],points[4*(enn)+1+pp],points[4*(enn)+2+pp],points[4*(enn)+3+pp],yaw,pch,rll);
}
break;
case END: /* last n points */
get_orientation(points+pp,points+pp+4*enn,points+pp+4*2*enn, f_prm_2, &yaw, &pch, &rll);
if (!(count%print_int)&&!estimate_f) {
printf("%.10g\t%.10g\t%.10g\t%.10g\t%.10g\t%.10g\t%.10g\n",points[8*enn+pp+0],points[8*enn+pp+1],points[8*enn+pp+2],points[8*enn+pp+3],yaw,pch,rll);
}
pp += 4;
if (pp >= 4*enn)
status = STOP;
break;
}
count++;
}
/* Return the factor needed to achieve the requested max_bank */
if (estimate_f){
if (max_cross < VDIVIDE_TOL) {
printf("%.10g\n",0.0);
} else {
printf("%.10g\n", 1000.0 * max_bank/max_cross);
}
}
return( 0 );
}
void
get_orientation(p0,p1,p2,function, p_yaw, p_pch, p_rll)
fastf_t p0[4],p1[4],p2[4], *p_yaw, *p_pch, *p_rll;
fastf_t (*function)();
{
int i;
fastf_t step,vel[3],accel[3];
fastf_t f_double_prm(),xyz2yaw(),xyz2pch(),bank();
static fastf_t last_yaw;
static int not_first_time, upside_down;
step = p2[0] - p1[0];
for (i=1;i<4;i++) {
vel[i-1] = (*function)(p0[i],p1[i],p2[i],step);
accel[i-1] = f_double_prm(p0[i],p1[i],p2[i],step);
}
*p_yaw = xyz2yaw(vel);
*p_pch = xyz2pch(vel);
*p_rll = bank(accel,vel);
if (fabs(*p_pch)==90.0) /* don't change yaw if velocity vertical */
*p_yaw = last_yaw;
/* avoid sudden yaw changes in vertical loops */
if (not_first_time&&loop){
if ((fabs(last_yaw - *p_yaw)<181.0)&&(fabs(last_yaw - *p_yaw)>179.0))
upside_down = (upside_down) ? 0 : 1;
if (upside_down)
(*p_rll) += 180;
}
last_yaw = *p_yaw;
not_first_time = 1;
}
/* determine the yaw of the given direction vector */
fastf_t xyz2yaw(d)
fastf_t d[3];
{
fastf_t yaw;
yaw = RTOD*atan2(d[1],d[0]);
if (yaw < 0.0) yaw += 360.0;
return yaw;
}
/* determine the pitch of the given direction vector */
fastf_t xyz2pch(d)
fastf_t d[3];
{
fastf_t x;
x = sqrt(d[0]*d[0] + d[1]*d[1]);
return (RTOD*atan2(d[2],x));
}
/* given the 3-d velocity and acceleration of an imaginary aircraft,
find the amount of bank the aircraft would need to undergo.
Algorithm: the bank angle is proportional to the cross product
of the horizontal velocity and horizontal acceleration, up to a
maximum bank of 90 degrees in either direction. */
fastf_t bank(acc,vel)
fastf_t acc[3],vel[3];
{
fastf_t cross;
cross = vel[1]*acc[0] - vel[0]*acc[1];
if (estimate_f) {
max_cross = ( fabs(cross) > max_cross) ? fabs(cross) : max_cross;
}
cross *= magic_factor;
if (cross > 90) cross = 90;
if (cross < -90) cross = -90;
return cross;
}
/* given f(t), f(t+h), f(t+2h), and h, calculate f'(t) */
fastf_t f_prm_0(x0,x1,x2,h)
fastf_t x0,x1,x2,h;
{
return -(3.0*x0 - 4.0*x1 + x2)/(2*h);
}
/* given f(t), f(t+h), f(t+2h), and h, calculate f'(t+h) */
fastf_t f_prm_1(x0,x1,x2,h)
fastf_t x0,x1,x2,h;
{
return (x2 - x0)/(2*h);
}
/* given f(t), f(t+h), f(t+2h), and h, calculate f'(t+2h) */
fastf_t f_prm_2(x0,x1,x2,h)
fastf_t x0,x1,x2,h;
{
return (x0 - 4.0*x1 + 3.0*x2)/(2*h);
}
/* given f(t), f(t+h), f(t+2*h), and h, calculate f'' */
fastf_t f_double_prm(x0,x1,x2,h)
fastf_t x0,x1,x2,h;
{
return (x0 - 2.0*x1 + x2)/(h*h);
}
/* code to read command line arguments*/
#define OPT_STR "b:f:p:s:r"
int get_args(argc,argv)
int argc;
char **argv;
{
int c;
estimate_f = 0;
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
switch(c){
case 'b':
sscanf(bu_optarg,"%lf",&max_bank);
estimate_f = 1;
break;
case 'f':
sscanf(bu_optarg,"%lf",&magic_factor);
magic_factor *= 0.001; /* to put factors in a more reasonable range */
break;
case 'p':
sscanf(bu_optarg,"%d",&print_int);
break;
case 'r':
loop = 0;
break;
case 's':
sscanf(bu_optarg, "%lf", &desired_step);
break;
default:
fprintf(stderr,"Unknown option: -%c\n",c);
return(0);
}
}
return(1);
}
+241
View File
@@ -0,0 +1,241 @@
/* A N I M _ F L Y . C
*
* Simulate flying motion, for an airplane or virtual camera.
*
* This filter operates on animation tables. Given the desired position
* of the airplane in each frame, anim_fly produces a table including the
* plane's position and orientation. A "magic factor" should be supplied
* to control the severity of banking. Looping behavior can be toggled
* with another option.
*
* Author -
* Carl J. Nuzman
*
* Source -
* The U. S. Army Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5068 USA
*
* Distribution Notice -
* Re-distribution of this software is restricted, as described in
* your "Statement of Terms and Conditions for the Release of
* The BRL-CAD Pacakge" agreement.
*
* Copyright Notice -
* This software is Copyright (C) 1993 by the United States Army
* in all countries except the USA. All rights reserved.
*/
#include <math.h>
#include <stdio.h>
#include "machine.h"
#include "vmath.h"
#include "anim.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
extern int bu_optind;
extern char *bu_optarg;
int loop = 1;
int print_int = 1;
fastf_t magic_factor = 1.0;
#define PREP -1
#define START 0
#define MIDDLE 1
#define END 2
#define STOP 3
main(argc,argv)
int argc;
char **argv;
{
int count, status, num_read;
fastf_t point0[4],point1[4],point2[4],point3[4], yaw, pch, rll;
fastf_t f_prm_0(), f_prm_1(), f_prm_2();
VSETALL(point0,0.0);
VSETALL(point1,0.0);
VSETALL(point2,0.0);
VSETALL(point3,0.0);
yaw = pch = rll = 0.0;
if (!get_args(argc,argv))
fprintf(stderr,"Anim_fly: Get_args error");
count = -2;
status = PREP;
num_read = 4;
while (status != STOP) {
/* check for end of file status */
if (num_read < 4) status = END;
/*wait twice to prime the pump before starting calculations*/
if (!(count++)) status = START;
/* read one line of the table into point3, storing
previous values in point0, point1, and point2. */
if (status != END) {
VMOVEN(point0,point1,4);
VMOVEN(point1,point2,4);
VMOVEN(point2,point3,4);
num_read = scanf("%lf %lf %lf %lf", point3, point3+1, point3+2, point3+3);
}
if (status==START) { /* do calculations for the first point*/
get_orientation(point1,point2,point3, f_prm_0, &yaw, &pch, &rll);
if (!(count%print_int)) {
printf("%f %f %f %f %f %f %f\n",point1[0],point1[1],point1[2],point1[3],yaw,pch,rll);
}
status = MIDDLE;
}
else if (status==MIDDLE) {/*do calculations for all middle points*/
get_orientation(point0,point1,point2, f_prm_1, &yaw, &pch, &rll);
if (!(count%print_int)) {
printf("%f %f %f %f %f %f %f\n",point1[0],point1[1],point1[2],point1[3],yaw,pch,rll);
}
}
else if (status==END) { /*do calculations for the last point*/
get_orientation(point0,point1,point2, f_prm_2, &yaw, &pch, &rll);
if (!(count%print_int)) {
printf("%f %f %f %f %f %f %f\n",point2[0],point2[1],point2[2],point2[3],yaw,pch,rll);
}
status = STOP;
}
}
}
get_orientation(p0,p1,p2,function, p_yaw, p_pch, p_rll)
fastf_t p0[4],p1[4],p2[4], *p_yaw, *p_pch, *p_rll;
fastf_t (*function)();
{
int i;
fastf_t step,vel[3],accel[3];
fastf_t f_double_prm(),xyz2yaw(),xyz2pch(),bank();
static fastf_t last_yaw, last_pch, last_rll;
static int not_first_time, upside_down;
step = p2[0] - p1[0];
for (i=1;i<4;i++) {
vel[i-1] = (*function)(p0[i],p1[i],p2[i],step);
accel[i-1] = f_double_prm(p0[i],p1[i],p2[i],step);
}
*p_yaw = xyz2yaw(vel);
*p_pch = xyz2pch(vel);
*p_rll = bank(accel,vel);
if (fabs(*p_pch)==90.0) /* don't change yaw if velocity vertical */
*p_yaw = last_yaw;
/* avoid sudden yaw changes in vertical loops */
if (not_first_time&&loop){
if ((fabs(last_yaw - *p_yaw)<181.0)&&(fabs(last_yaw - *p_yaw)>179.0))
upside_down = (upside_down) ? 0 : 1;
if (upside_down)
(*p_rll) += 180;
}
last_yaw = *p_yaw;
last_pch = *p_pch;
last_rll = *p_rll;
not_first_time = 1;
}
/* determine the yaw of the given direction vector */
fastf_t xyz2yaw(d)
fastf_t d[3];
{
fastf_t yaw;
yaw = RTOD*atan2(d[1],d[0]);
if (yaw < 0.0) yaw += 360.0;
return yaw;
}
/* determine the pitch of the given direction vector */
fastf_t xyz2pch(d)
fastf_t d[3];
{
fastf_t x;
x = sqrt(d[0]*d[0] + d[1]*d[1]);
return (RTOD*atan2(d[2],x));
}
/* given the 3-d velocity and acceleration of an imaginary aircraft,
find the amount of bank the aircraft would need to undergo.
Algorithm: the bank angle is proportional to the cross product
of the horizontal velocity and horizontal acceleration, up to a
maximum bank of 90 degrees in either direction. */
fastf_t bank(acc,vel)
fastf_t acc[3],vel[3];
{
fastf_t cross;
cross = vel[1]*acc[0] - vel[0]*acc[1];
cross *= magic_factor;
if (cross > 90) cross = 90;
if (cross < -90) cross = -90;
return cross;
}
/* given f(t), f(t+h), f(t+2h), and h, calculate f'(t) */
fastf_t f_prm_0(x0,x1,x2,h)
fastf_t x0,x1,x2,h;
{
return -(3.0*x0 - 4.0*x1 + x2)/(2*h);
}
/* given f(t), f(t+h), f(t+2h), and h, calculate f'(t+h) */
fastf_t f_prm_1(x0,x1,x2,h)
fastf_t x0,x1,x2,h;
{
return (x2 - x0)/(2*h);
}
/* given f(t), f(t+h), f(t+2h), and h, calculate f'(t+2h) */
fastf_t f_prm_2(x0,x1,x2,h)
fastf_t x0,x1,x2,h;
{
return (x0 - 4.0*x1 + 3.0*x2)/(2*h);
}
/* given f(t), f(t+h), f(t+2*h), and h, calculate f'' */
fastf_t f_double_prm(x0,x1,x2,h)
fastf_t x0,x1,x2,h;
{
return (x0 - 2.0*x1 + x2)/(h*h);
}
/* code to read command line arguments*/
#define OPT_STR "f:p:r"
int get_args(argc,argv)
int argc;
char **argv;
{
int c;
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
switch(c){
case 'f':
sscanf(bu_optarg,"%lf",&magic_factor);
magic_factor *= 0.001; /* to put factors in a more reasonable range */
break;
case 'p':
sscanf(bu_optarg,"%d",&print_int);
break;
case 'r':
loop = 0;
break;
default:
fprintf(stderr,"Unknown option: -%c\n",c);
return(0);
}
}
return(1);
}
+293
View File
@@ -0,0 +1,293 @@
.TH ANIM_HARDTRACK 1 BRL/CAD
.SH NAME
anim_hardtrack - make an animation script for the links and/or wheels of a
tracked vehicle with rigid axles.
.SH SYNOPSIS
.B
anim_hardtrack [-l num_links linkname] [-w wheelname] [options] wheelfile < in.table > out.script
.SH DESCRIPTION
.I Anim_hardtrack
is designed to produce an animation script for the
animation of a track and/or the wheels defining a track, where the wheels
are rigidly fixed in place with respect to the vehicle. The main
difference between
.I anim_hardtrack
and
.I anim_track
is that
.I anim_track
handles vehicles with dynamic axles. Both are designed to be use in
conjunction with
.I anim_script,
to achieve the final result.
.PP
.B in.table
is the file that will be used to animate the
vehicle itself. By default, it is assumed that it contains a time column,
three columns of translation information, and three columns specifying the
vehicle's yaw, pitch, and roll. If it is desired that the vehicle be steered
automatically, then the table should contain only time and position, and the
.B -s
option should be used.
.PP
The track's
geometry is defined by
.BR wheelfile ,
a table which contains one row for each wheel defining the track. The
first three columns of the table specify the x, y, and z coordinates of
the wheel centers. The fourth column specifies the radius of each wheel.
.PP
The order in which the wheels are listed should be the order in which a
link of the track would move around the wheels when the vehicle is moving
forward. (clockwise, when looking from the right of the vehicle).
The wheel centers should all lie in a plane perpendicular to the vehicle's
left-right axis. If this is not the case,
.I anim_hardtrack
uses the first wheel as the standard and projects all the other wheels into
the same plane as the first wheel. By default, it is assumed that the
vehicle's left-right axis is the y-axis. If the modeled vehicle has some
other orientation, this must be specified with the
.B -b
option.
.PP
By default, it is
assumed that
all of the link objects are modeled at the model origin,
with the wheel-contacting surface centered on the origin and the
ground-contacting surface facing up. The sides of each link which
connect to other links should face the positive and negative x-axes.
.I Anim_hardtrack
prints the appropriate
commands to move the links from
the origin to the correct place around the wheels.
.PP
If the links are modeled in place around the wheels to begin with, the
the
.B -p
and
.B -i
options are needed.
.SH OPTIONS:
.PP
One or both of the first two options should always be specified.
.TP
.B \-l num linkname
Print animation scripts to animate the links of the track. Animation
commands will be printed for
.I num
different links
named
.IR linkname .0, linkname .1,
up through
.IR linkname .( num -1).
A typical example of a linkname might
be "tank/righttrack/links/link". The full pathname must be specified,
because anim_hardtrack's method is to roll the links around within
the vehicle's tree structure so that when the whole vehicle "tank" is
animated, the complete combination of rolling around and translating is
achieved.
.TP
.B \-w wheelname
Print animation
scripts to rotate each wheel. The wheels are named wheelname.0, wheelname.1,
and so on, where wheelname.0 is the first wheel listed in
.BR wheelfile .
As with the links, the full pathname for the wheels should be specified.
.TP
.B \-b # # #
Specify the yaw, pitch, and roll of the vehicle's axes
with respect to the world axes. By default, the vehicle is assumed to
have a yaw, pitch, and roll of 0.
.TP
.B \-d # # #
Specify (in world coordinates) the centroid of the vehicle
of which the track is a part. By default, the vehicle is assumed
centered at the origin.
.PP
When calling
.I anim_script
to handle the animation of the vehicle
itself, the parameters following the
.B -b
and
.B -d
options should be identical
to those used for
.IR anim_hardtrack .
.TP
.B \-r #
Specify the common radius of all wheels. In this case the fourth column
should be omitted from the
.BR wheelfile .
.TP
.B \-s
Automatic steering. In this case,
.B in.table
specifies only the time and position
of the vehicle. The orientation is calculated to always face the vehicle
in the direction of motion.
This should be used when the
.B \-s
option is used by
.I anim_script
to animate the vehicle.
.PP
.TP
.B \-f#
Specify the integer with which to begin numbering frames.
Default is zero.
.TP
.B \-p
Animate placed links, rather than links stored at the origin.
In order for placed links to be animated, they must be equally spaced
around the wheels defining the track. The track must be formed of arcs
around the wheels and straight lines between the wheels, and the links
must be numbered clockwise as seen from the right.
By default, it is assumed that the
center of the first link, linkname.0, is at the beginning of the
straight track segment between wheel.(n-1) and wheel.0 . If this is
not the case, the position of the first link must be identified with the
.B \-i#
option.
.TP
.B \-i#
Specify the initial offset of the first link. If this option is
not used, the initial position of linkname.0 is assumed to be the
beginning of the straight track segment between wheel.(n-1) and wheel.0.
If it is used, the argument specifies the distance clockwise around the
track from the default position to the actual desired offset. If the
links are modeled at the origin, the user can choose any offset. This
can be useful for lining up the links with gears of a drive wheel, for
example.
If the
.B -p
option is being used to animated pre-placed links, then it is essential
that the actual offset of the first pre-placed link be specified.
.SS Output:
.PP
The output is a script containing as many frames as there
are positions in
.BR in.table .
If there are
.I n
links and
.I k
wheels, each
frame contains up to
.IR n + k
anim commands, either:
.nf
anim linkname.i matrix lmul
[... matrix ...] ;
or
anim wheelname.j matrix lmul
[... matrix ...] ;
for 0<=i<n and 0<=j<k.
.fi
.SH EXAMPLES
Suppose you want to make an animation of a tank rolling across
flat ground. A list of desired positions is created, perhaps by
interpolating between a few key positions; this information is placed
in a four column animation table, in.table. The model of the tank is stored in
model.g as a combination named "tank". Its centroid is at the
point (0,0,1000) and it faces the y-axis. An animation script for the
tank itself is created as follows:
.PP
anim_script -s -d 0 0 1000 -b 90 0 0 /tank < in.table > tank.script
.PP
Suppose that there are two
roadwheels and a drivewheel (tank/rwheel/wheel.i, 0<=i<3) which define
the shape of the right track.
A file called
.B rwheelfile
is created:
.nf
1500 -2000 30 30
1500 0 1000 35
1500 2000 30 30
.fi
This
.B rwheelfile
lists the position and
radius of each of the three wheels.
.PP
There are eighty links which make up the right track
(tank/rtrack/link.i, 0<=i<80).
The links of the right track are all modeled
at the origin with the outer, ground-contacting surface
facing up and the inner, wheel-contacting surface centered at the
origin.
.PP
The appropriate call to
.I anim_hardtrack
is now:
.sp
anim_hardtrack -d 0 0 1000 -b 90 0 0 -w tank/rwheel -l 80 tank/rtrack/link
rwheelfile < in.table > rtrack.script
.sp
Suppose that the left track is similar to the right track,
except that all the wheels are of radius 30 units, and the links, rather
than being stored at the origin, are actually placed in position around
the left wheels to begin with. The
.B lwheelfile
would be:
.nf
-1500 -2000 30
-1500 0 1000
-1500 2000 30
.fi
and the call would be:
.sp
anim_hardtrack -p -r 30 -d 0 0 1000 -b 90 0 0 -w tank/lwheel
-l 80 tank/ltrack/link lwheelfile <in.table > ltrack.script
.sp
Here, it is assumed that tank/ltrack/link.0 is initially at the
beginning of the straight track segment between lwheel.2 and lwheel.0,
that is, at the point (2000,1500,-1000) in the vehicle's coordinates.
If, instead, the first link is initially centered halfway between the
two roadwheels, this must be specified with the
.B -i#
option. If the link's
actual position is 2000 units farther around the track than expected:
.sp
anim_hardtrack -i 2000 -p -r 30 -d 0 0 1000 -b 90 0 0 -w tank/lwheel
-l 80 tank/ltrack/link lwheelfile <in.table > ltrack.script
.sp
One final step may remain. The above procedure produces a script with rigid
naming conventions, in order to make input simple. This may mean that
the names in the script do not match the names in model.g. An editor
should then be used at the end to replace all instances of the
conventional name with the real name; for example, in this case it may
be necessary to replace "rwheel.1" with "r_drivewheel".
.PP
.BR Tank.script ,
.BR rtrack.script ,
and
.B ltrack.script
can be combined
with
.I anim_sort
to make the complete script.
.PP
.SH BUGS
Tracks must have at least two wheels, and they must be listed in clockwise
order, or the results are unpredictable.
.SH SEE ALSO
anim_script(1), anim_track(1)
.SH AUTHOR
Carl J. Nuzman
.SH COPYRIGHT
This software is Copyright (C) 1993 by the United States Army
in all countries except the USA. All rights reserved.
.SH "BUG REPORTS"
Reports of bugs or problems should be submitted via electronic
mail to <CAD@ARL.ARMY.MIL>.
+517
View File
@@ -0,0 +1,517 @@
/* A N I M _ H A R D T R A C K . C
*
* Animate the links and wheels of a tracked vehicle. It is assumed
* that the wheels do not translate with respect to the vehicle.
*
* Author -
* Carl J. Nuzman
*
* Source -
* The U. S. Army Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5068 USA
*
* Distribution Notice -
* Re-distribution of this software is restricted, as described in
* your "Statement of Terms and Conditions for the Release of
* The BRL-CAD Pacakge" agreement.
*
* Copyright Notice -
* This software is Copyright (C) 1993 by the United States Army
* in all countries except the USA. All rights reserved.
*/
#include "conf.h"
#ifdef USE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "machine.h"
#include "vmath.h"
#include "bu.h"
#include "bn.h"
#include "anim.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifndef M_PI_2
#define M_PI_2 (M_PI*0.5)
#endif
#define NW num_wheels
#define NEXT(i) (i+1)%NW
#define PREV(i) (i+NW-1)%NW
#define TRACK_ANIM 0
#define TRACK_ARCED 1
typedef double *pdouble;
struct wheel {
vect_t pos; /* displacement of wheel from vehicle origin */
fastf_t rad; /* radius of wheel */
fastf_t ang0; /* angle where track meets wheel; 0 < a < 2pi */
fastf_t ang1; /* angle where track leaves wheel; 0 < a < 2pi */
fastf_t arc; /* arclength of contact between wheel and track */
};
struct track {
vect_t pos0; /* beginning point of track section */
vect_t pos1; /* end point of track section */
vect_t dir; /* unit vector: direction of track section */
fastf_t len; /* length of track section */
};
struct slope {
vect_t dir; /* vector from previous to current axle */
fastf_t len; /* length of vector described above */
};
struct all {
struct wheel w; /* parameters describing the track around a wheel */
struct track t; /* track between this wheel and the previous wheel */
struct slope s; /* vector between this axle and the previous axle */
};
struct rlink {
vect_t pos; /* reverse of initial position */
fastf_t ang; /* initial angle */
};
/* external variables */
extern int bu_optind;
extern char *bu_optarg;
/* variables describing track geometry - used by main, trackprep, get_link */
struct all *x;
struct rlink *r; /* reverse of initial locations of links */
int num_links, num_wheels;
fastf_t track_y, tracklen;
/* variables set by get_args */
int wheel_nindex; /* argv[wheel_nindex] = wheelname*/
int link_nindex; /* argv[link_nindex] = linkname*/
int print_wheel; /* flag: do wheel animation */
int print_link; /* flag: do link animation */
int print_mode; /* anim for rt or arced for mged */
int arced_frame; /* which frame to arced */
int links_placed; /* flag: links are initially on the track */
int axes, cent; /* flags: alternate axes, centroid specified */
int steer; /* flag: vehicle automatically steered */
int first_frame; /* integer with which to begin numbering frames */
fastf_t radius; /* common radius of all wheels */
fastf_t init_dist; /* initial distance of first link along track */
vect_t centroid, rcentroid; /* alternate centroid and its reverse */
mat_t m_axes, m_rev_axes; /* matrices to and from alternate axes */
char link_cmd[10]; /* default is "rarc" */
char wheel_cmd[10]; /* default is "lmul" */
int get_circumf; /* flag: just return circumference of track */
int get_link();
int
main(argc,argv)
int argc;
char **argv;
{
void anim_dir2mat(), anim_y_p_r2mat(), anim_add_trans(),anim_mat_print();
int get_args(), track_prep(), val, frame, go, i, count;
fastf_t y_rot, distance, yaw, pitch, roll;
vect_t p1, p2, p3, dir, dir2, wheel_now, wheel_prev;
vect_t zero, position, vdelta, temp, to_track, to_front;
mat_t mat_v, wmat, mat_x;
FILE *stream;
int last_frame;
VSETALL(zero,0.0);
VSETALL(to_track,0.0);
VSETALL(centroid,0.0);
VSETALL(rcentroid,0.0);
init_dist = y_rot = radius= 0.0;
first_frame = num_wheels = steer = axes = cent = links_placed=0;
num_wheels = num_links = last_frame = 0;
MAT_IDN(mat_v);
MAT_IDN(mat_x);
MAT_IDN(wmat);
MAT_IDN(m_axes);
MAT_IDN(m_rev_axes);
if (!get_args(argc,argv)){
fprintf(stderr,"anim_hardtrack: argument error.");
return(-1);
}
if (axes || cent ){ /* vehicle has own reference frame */
anim_add_trans(m_axes,centroid,zero);
anim_add_trans(m_rev_axes,zero,rcentroid);
}
/* get track information from specified file */
if (!(stream = fopen(*(argv+bu_optind),"r"))){
fprintf(stderr,"Anim_hardtrack: Could not open file %s.\n",*(argv+bu_optind));
return(0);
}
num_wheels = -1;
if (radius) {
while (!feof(stream)) {
fscanf(stream,"%*f %*f %*f");
num_wheels++;
}
} else {
while (!feof(stream)) {
fscanf(stream,"%*f %*f %*f %*f");
num_wheels++;
}
}
rewind(stream);
/*allocate memory for track information*/
x = (struct all *) calloc(num_wheels,sizeof(struct all));
/*read rest of track info */
for (i=0;i<NW;i++){
fscanf(stream,"%lf %lf %lf", temp, temp+1, temp+2);
if (radius)
x[i].w.rad = radius;
else
fscanf(stream,"%lf",& x[i].w.rad);
MAT4X3PNT(x[i].w.pos,m_rev_axes,temp);
if (i==0)
track_y = x[0].w.pos[1];
else
x[i].w.pos[1] = track_y;
}
(void) fclose(stream);
(void) track_prep();
if (get_circumf) {
printf("%.10g\n",tracklen);
return(0);
}
/* initialize to_track */
VSET(to_track, 0.0, track_y, 0.0);
VSET(to_front,1.0,0.0,0.0);
if ((!print_link)&&(!print_wheel)) {
fprintf(stderr,"anim_hardtrack: no ouput requested. Use -l or -w.\n");
exit(0);
}
/* main loop */
distance = 0.0;
if(!steer)
frame = first_frame;
else
frame = first_frame-1;
for (val = 3; val > 2; frame++) {
go = 1;
/*p2 is current position. p3 is next;p1 is previous*/
VMOVE(p1,p2);
VMOVE(p2,p3);
scanf("%*f");/*time stamp*/
val = scanf("%lf %lf %lf", p3, p3+1, p3 + 2);
if(!steer){
scanf("%lf %lf %lf",&yaw,&pitch,&roll);
anim_dy_p_r2mat(mat_v,yaw,pitch,roll);
anim_add_trans(mat_v,p3,rcentroid);
}
else { /* analyze positions for steering */
/*get useful direction unit vectors*/
if (frame == first_frame){ /* first frame*/
VSUBUNIT(dir,p3,p2);
VMOVE(dir2,dir);
}
else if (val < 3){ /*last frame*/
VSUBUNIT(dir,p2,p1);
VMOVE(dir2,dir);
}
else if (frame > first_frame){ /*normal*/
VSUBUNIT(dir,p3,p1);
VSUBUNIT(dir2,p2,p1);/*needed for vertical case*/
}
else go = 0;/*first time through loop;no p2*/
/*create matrix which would move vehicle*/
anim_dir2mat(mat_v,dir,dir2);
anim_add_trans(mat_v,p2,rcentroid);
}
/*determine distance traveled*/
VMOVE(wheel_prev,wheel_now);
MAT4X3PNT(wheel_now,mat_v,to_track);
if (frame > first_frame){ /* increment distance by distance moved */
VSUB2(vdelta,wheel_now,wheel_prev);
MAT3X3VEC(temp,mat_v,to_front);/*new front of vehicle*/
distance += VDOT(temp,vdelta);/*portion of vdelta in line with track*/
}
if (go){
if (print_mode==TRACK_ANIM) {
printf("start %d;\nclean;\n", frame);
} else if (print_mode==TRACK_ARCED) {
if (frame != arced_frame) continue;
last_frame = 1;
}
if (print_link) {
for (count=0;count<num_links;count++){
(void) get_link(position,&y_rot,distance+tracklen*count/num_links+init_dist);
anim_y_p_r2mat(wmat,0.0,y_rot+r[count].ang,0.0);
anim_add_trans(wmat,position,r[count].pos);
if ((axes || cent) && links_placed){ /* link moved from vehicle coords */
bn_mat_mul(mat_x,wmat,m_rev_axes);
bn_mat_mul(wmat,m_axes,mat_x);
}
else if (axes || cent){ /* link moved to vehicle coords */
MAT_MOVE(mat_x,wmat);
bn_mat_mul(wmat,m_axes,mat_x);
}
if (print_mode==TRACK_ANIM) {
printf("anim %s.%d matrix %s\n", *(argv+link_nindex),count,link_cmd);
anim_mat_printf(stdout,wmat,"%.10g ","\n",";\n");
} else if (print_mode==TRACK_ARCED) {
printf("arced %s.%d matrix %s ", *(argv+link_nindex),count,link_cmd);
anim_mat_printf(stdout,wmat,"%.10g ","","\n");
}
}
}
if (print_wheel){
for (count = 0;count<num_wheels;count++){
anim_y_p_r2mat(wmat,0.0,-distance/x[count].w.rad,0.0);
VREVERSE(temp,x[count].w.pos);
anim_add_trans(wmat,x[count].w.pos,temp);
if (axes || cent){
bn_mat_mul(mat_x,wmat,m_rev_axes);
bn_mat_mul(wmat,m_axes,mat_x);
}
if (print_mode==TRACK_ANIM) {
printf("anim %s.%d matrix %s\n",*(argv+wheel_nindex),count,wheel_cmd);
anim_mat_printf(stdout,wmat,"%.10g ","\n",";\n");
} else if (print_mode==TRACK_ARCED) {
printf("arced %s.%d matrix %s ",*(argv+wheel_nindex),count,wheel_cmd);
anim_mat_printf(stdout,wmat,"%.10g ","","\n");
}
}
}
if (print_mode==TRACK_ANIM)
printf("end;\n");
}
if (last_frame) break;
}
return( 0 );
}
int track_prep()/*run once at the beginning to establish important track info*/
{
int i;
fastf_t phi, costheta, link_angle, arc_angle;
vect_t difference, link_cent;
/* first loop - get inter axle slopes and start/end angles */
for (i=0;i<NW;i++){
/*calculate current slope vector*/
VSUB2(x[i].s.dir,x[i].w.pos,x[PREV(i)].w.pos);
x[i].s.len = MAGNITUDE(x[i].s.dir);
/*calculate end angle of previous wheel - atan2(y,x)*/
phi = atan2(x[i].s.dir[2],x[i].s.dir[0]);/*absolute angle of slope*/
costheta = (x[PREV(i)].w.rad - x[i].w.rad)/x[i].s.len;/*cosine of special angle*/
x[PREV(i)].w.ang1 = phi + acos(costheta);
while (x[PREV(i)].w.ang1 < 0.0)
x[PREV(i)].w.ang1 += 2.0*M_PI;
x[i].w.ang0 = x[PREV(i)].w.ang1;
}
/* second loop - handle concavities */
for (i=0;i<NW;i++){
arc_angle = x[i].w.ang0 - x[i].w.ang1;
while (arc_angle < 0.0)
arc_angle += 2.0*M_PI;
if (arc_angle > M_PI) { /* concave */
x[i].w.ang0 = 0.5*(x[i].w.ang0 + x[i].w.ang1);
x[i].w.ang1 = x[i].w.ang0;
x[i].w.arc = 0.0;
}
else { /* convex - angles are already correct */
x[i].w.arc = arc_angle;
}
}
/* third loop - calculate geometry of track segments */
tracklen = 0.0;
for (i=0;i<NW;i++){
/*calculate endpoints of track segment*/
x[i].t.pos1[0] = x[i].w.pos[0] + x[i].w.rad*cos(x[i].w.ang0);
x[i].t.pos1[1] = x[i].w.pos[1];
x[i].t.pos1[2] = x[i].w.pos[2] + x[i].w.rad*sin(x[i].w.ang0);
x[i].t.pos0[0] = x[PREV(i)].w.pos[0] + x[PREV(i)].w.rad*cos(x[PREV(i)].w.ang1);
x[i].t.pos0[1] = x[PREV(i)].w.pos[1];
x[i].t.pos0[2] = x[PREV(i)].w.pos[2] + x[PREV(i)].w.rad*sin(x[PREV(i)].w.ang1);
/*calculate length and direction*/
VSUB2(difference,x[i].t.pos1,x[i].t.pos0);
x[i].t.len = MAGNITUDE(difference);
VSCALE((x[i].t.dir),difference,(1.0/x[i].t.len));
/*calculate arclength and total track length*/
tracklen += x[i].t.len;
tracklen += x[i].w.arc*x[i].w.rad;
}
/* for a track with links already placed, get initial positions*/
r = (struct rlink *) calloc(num_links, sizeof(struct rlink));
if (links_placed)
for (i=0;i<num_links;i++){
get_link(link_cent,&link_angle,init_dist + tracklen*i/num_links);
VREVERSE(r[i].pos,link_cent);
r[i].ang = -link_angle;
}
return(0);
}
int get_link(pos,angle_p,dist)
fastf_t *angle_p, dist;
vect_t pos;
{
int i;
vect_t temp;
while (dist >= tracklen) /*periodicize*/
dist -= tracklen;
while (dist < 0.0)
dist += tracklen;
for (i=0;i<NW;i++){
if ( (dist -= x[i].t.len) < 0 ){
VSCALE(temp,(x[i].t.dir),dist);
VADD2(pos,x[i].t.pos1,temp);
*angle_p = atan2(x[i].t.dir[2],x[i].t.dir[0]);
return(2*i);
}
if ((dist -= x[i].w.rad*x[i].w.arc) < 0){
*angle_p = dist/x[i].w.rad;
*angle_p = x[i].w.ang1 - *angle_p;/*from x-axis to link*/
pos[0] = x[i].w.pos[0] + x[i].w.rad*cos(*angle_p);
pos[1] = x[i].w.pos[1];
pos[2] = x[i].w.pos[2] + x[i].w.rad*sin(*angle_p);
*angle_p -= M_PI_2; /*angle of clockwise tangent to circle*/
return(2*i+1);
}
}
return -1;
}
#define OPT_STR "b:d:f:i:l:pr:w:sg:m:c"
int get_args(argc,argv)
int argc;
char **argv;
{
fastf_t yaw, pch, rll;
void anim_dx_y_z2mat(), anim_dz_y_x2mat();
int c, i;
axes = cent = links_placed = print_wheel = print_link = 0;
get_circumf = 0;
print_mode = TRACK_ANIM;
strcpy(link_cmd, "rarc");
strcpy(wheel_cmd, "lmul");
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
i=0;
switch(c){
case 'b':
bu_optind -= 1;
sscanf(argv[bu_optind+(i++)],"%lf", &yaw );
sscanf(argv[bu_optind+(i++)],"%lf", &pch );
sscanf(argv[bu_optind+(i++)],"%lf", &rll );
bu_optind += 3;
anim_dx_y_z2mat(m_axes, rll, -pch, yaw);
anim_dz_y_x2mat(m_rev_axes, -rll, pch, -yaw);
axes = 1;
break;
case 'd':
bu_optind -= 1;
sscanf(argv[bu_optind+(i++)],"%lf",centroid);
sscanf(argv[bu_optind+(i++)],"%lf",centroid+1);
sscanf(argv[bu_optind+(i++)],"%lf",centroid+2);
bu_optind += 3;
VREVERSE(rcentroid,centroid);
cent = 1;
break;
case 'f':
sscanf(bu_optarg,"%d",&first_frame);
break;
case 'i':
sscanf(bu_optarg,"%lf",&init_dist);
break;
case 'p':
links_placed = 1;
break;
case 'r':
sscanf(bu_optarg,"%lf",&radius);
break;
case 'w':
wheel_nindex = bu_optind - 1;
/*sscanf(bu_optarg,"%s",wheel_name);*/
print_wheel = 1;
break;
case 'l':
sscanf(bu_optarg,"%d", &num_links);
link_nindex = bu_optind;
bu_optind += 1;
print_link = 1;
break;
case 's':
steer = 1;
break;
case 'g':
sscanf(bu_optarg,"%d",&arced_frame);
print_mode = TRACK_ARCED;
break;
case 'm':
switch (*bu_optarg) {
case 'l':
strncpy(link_cmd,argv[bu_optind], 10);
break;
case 'w':
strncpy(wheel_cmd,argv[bu_optind], 10);
break;
default:
fprintf(stderr,"Unknown option: -m%c\n",*bu_optarg);
return(0);
}
bu_optind += 1;
break;
case 'c':
get_circumf = 1;
break;
default:
fprintf(stderr,"Unknown option: -%c\n",c);
return(0);
}
}
return(1);
}
void show_info(which)/* for debugging - -1:track 0:both 1:link*/
int which;
{
int i;
if (which <=0){
fprintf(stderr,"track length: %f\n",tracklen);
fprintf(stderr,"link length: %f\n",tracklen/num_links);
for (i=0;i<NW;i++){
fprintf(stderr,"wheel %d: %f %f %f %f %f %f\n",i,x[i].w.pos[0],x[i].w.pos[1],x[i].w.pos[2],x[i].w.rad,x[i].w.ang1,x[i].w.arc);
fprintf(stderr,"track %d: %f %f %f %f %f %f %f\n",i,x[i].t.pos1[0],x[i].t.pos1[1],x[i].t.pos1[2],x[i].t.dir[0],x[i].t.dir[1],x[i].t.dir[2],x[i].t.len);
fprintf(stderr,"slope %d: %f %f %f %f\n",i,x[i].s.dir[0],x[i].s.dir[1],x[i].s.dir[2],x[i].s.len);
}
}
/* if (which >= 0){
fprintf(stderr,"%d %f %f %f %f\n",count,position[0],position[1],position[2],y_rot);
}*/
}
+114
View File
@@ -0,0 +1,114 @@
.TH ANIM_KEYREAD 1 BRL/CAD
.SH NAME
anim_keyread - prepares key frames from the mged savekey command for interpolation
.SH SYNOPSIS
.B anim_keyread
.B [-y|z]
.B < key.file
.B > key.table
.SH DESCRIPTION
.I Anim_keyread
takes as input a file containing a series of keyframes
generated by the
.I mged
command `savekey', and produces a table containing
the same information, except that the view orientation matrix is
changed to a form that can be interpolated. The default form for the
orientation information is the quaternion.
For each such keyframe in the input file,
.I anim_keyread
will produce a
row in the output file containing the time, the viewsize, the position
of the camera, and the orientation of the camera, specified as a unit
quaternion in the order x, y, z, and w.
.SH OPTIONS
.TP
.B -y
Specify the orientation in terms of yaw, pitch, and roll.
.TP
.B -z
Specify the orientation as a rotation about the z-axis, y-axis,
and then x-axis, where the columns are in the order: x,y,z.
.SH EXAMPLES
The following is an example of a typical keyframe generated by the
`savekey' command. The time is 0, the viewsize is ten, the camera is at the
point (2.5,2.5,3.53) and the camera orientation is specified by a
matrix.
.nf
0.000000
1.000000000e+01
2.500000000e+00 2.500000000e+00 3.535533906e+00
-7.071067812e-01 7.071067812e-01 0.000000000e+00 0.000000000e+00
-5.000000000e-01 -5.000000000e-01 7.071067812e-01 0.000000000e+00
5.000000000e-01 5.000000000e-01 7.071067812e-01 0.000000000e+00
0.000000000e+00 0.000000000e+00 0.000000000e+00 1.000000000e+00
.fi
For the key frame shown above, the output would
be:
.sp
0.000000 10.000000 2.500000 2.500000 3.535534 0.146447 0.353553 0.853553 0.353553
.sp
The last four numbers define the desired orientation as a
quaternion.
.PP
With the
.B -y
option, the output would be:
.sp
0.000000 10.000000 2.500000 2.500000 3.535534 -135.000000 -45.000000 0.000000
.sp
Here, the last three numbers are the yaw, pitch, and roll,
which can be interpreted as follows: Imagine a camera at the origin
originally facing the positive x-direction, with the z-axis going up
and the y-axis positive to the left. The camera should be rotated
+roll degrees about the x-axis, -pitch degrees about the y-axis,
and +yaw degrees about the z-axis. In this case, the camera ends up
pointing down and to the right of its original position.
.PP
With the -z option, the output would be:
.sp
0.000000 10.000000 2.500000 2.500000 3.535534 -35.264390 30.000000 144.735610
.sp
The last three numbers are x, y, and z rotation angles.
The camera is considered to be originally on the z-axis, looking toward
the origin with the x-axis to the right and the y-axis going up. The
camera is rotated 144.7 degrees about the model's z-axis, then 30
degrees about the model's y-axis, and finally -35.2 degrees about the
model x-axis.
.SH DIAGNOSTICS
Problems arise when using Eulers angles, because
certain orientations do not have a uniqe representation, and the program
must arbitrarily select among an infinite number of possibilities. For
example, when using yaw, pitch and roll, the yaw and roll
become indistinguishable when the pitch is 90 degrees.
.PP
When this happens, the roll is set to 0, and the following
messages appear on standard error:
.nf
Warning: roll arbitrarily set to 0.0; yaw set to -0.585334 radians.
Warning: yaw and roll arbitrarily defined at time = 1.000000.
.fi
A similar effect occurs in xyz format when the rotation about
the y-axis is 90 degrees.
.nf
Warning: x arbitrarily set to 0.0; z set to 0.000000.
Warning: x and z rotations arbitrarily defined at time = 9.000000.
.fi
One nice thing about quaternions is that you don't run into such
problems.
.SH SEE ALSO
mged(1), tabsub(1), anim_script(1), tabinterp(1)
.SH AUTHOR
Carl J. Nuzman
.SH COPYRIGHT
This software is Copyright (C) 1993 by the United States Army
in all countries except the USA. All rights reserved.
.SH "BUG REPORTS"
Reports of bugs or problems should be submitted via electronic
mail to <CAD@ARL.ARMY.MIL>.
+162
View File
@@ -0,0 +1,162 @@
/* A N I M _ K E Y R E A D . C
*
* Convert an list of mged-style 'savekey' keyframes into an
* animation table
*
* The output table specifies the orientation in one of three ways:
*
* default - quaternions in the order x, y, z, w.
*
* -z option - Eulers angles, in the order xyz. The model axes are
* considered to be rotated about the camera's z, y, and
* x axes (in that order).
*
* -y option - Eulers angles in the form yaw, pitch, roll.
*
* This is more or less a special case of anim_orient.c
*
* Author -
* Carl J. Nuzman
*
* Source -
* The U. S. Army Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5068 USA
*
* Distribution Notice -
* Re-distribution of this software is restricted, as described in
* your "Statement of Terms and Conditions for the Release of
* The BRL-CAD Pacakge" agreement.
*
* Copyright Notice -
* This software is Copyright (C) 1993 by the United States Army
* in all countries except the USA. All rights reserved.
*/
#include "conf.h"
#include <stdio.h>
#include <math.h>
#include "machine.h"
#include "vmath.h"
#include "bu.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#define YPR 0
#define XYZ 1
#define QUATERNION 2
#define DEGREES 0
#define RADIANS 1
#define NORMAL 0
#define ERROR1 1
#define ERROR2 2
#define DTOR M_PI/180.0
#define RTOD 180.0/M_PI
int mode;
int units;
extern int bu_optind;
extern char *bu_optarg;
int get_args();
extern void anim_v_unpermute();
int
main(argc,argv)
int argc;
char **argv;
{
int c;
fastf_t time, viewsize;
fastf_t eyept[3], viewrot[16], angle[3], quat[4];
int anim_mat2ypr(), anim_mat2zyx(), anim_mat2quat();
if (!get_args(argc,argv))
fprintf(stderr,"anim_keyread: get_args error");
while (!feof(stdin)){ /* read one keyframe */
scanf("%lf", &time);
scanf("%lf", &viewsize);
scanf("%lf %lf %lf", eyept, eyept+1, eyept+2);
/* read in transposed matrix */
scanf("%lf %lf %lf %lf", viewrot+0, viewrot+4, viewrot+8, viewrot+12);
scanf("%lf %lf %lf %lf", viewrot+1, viewrot+5, viewrot+9, viewrot+13);
scanf("%lf %lf %lf %lf", viewrot+2, viewrot+6, viewrot+10, viewrot+14);
scanf("%lf %lf %lf %lf", viewrot+3, viewrot+7, viewrot+11, viewrot+15);
if (feof(stdin)) break;
printf("%.10g\t%.10g\t%.10g\t%.10g\t%.10g\t", time, viewsize,
eyept[0], eyept[1], eyept[2]);
if (mode==YPR) {
anim_v_unpermute(viewrot);
c = anim_mat2ypr(angle,viewrot);
if (c==ERROR1)
fprintf(stderr,"Warning: yaw and roll arbitrarily defined at time = %f.\n",time);
else if (c==ERROR2)
fprintf(stderr,"Keyread: can't interpret matrix at time = %f.\n",time);
if (units == DEGREES)
VSCALE(angle,angle,RTOD);
printf("%.10g\t%.10g\t%.10g\n",angle[0],angle[1],angle[2]);
}
else if (mode==XYZ) {
c = anim_mat2zyx(angle,viewrot);
if (c==ERROR1)
fprintf(stderr,"Warning: x and z rotations arbitrarily defined at time = %f.\n",time);
else if (c==ERROR2)
fprintf(stderr,"Keyread: can't interpret matrix at time = %f\n.",time);
if (units == DEGREES)
VSCALE(angle,angle,RTOD);
printf("%.10g\t%.10g\t%.10g\n",angle[X],angle[Y],angle[Z]);
}
else if (mode==QUATERNION){
anim_mat2quat(quat,viewrot);
printf("%.10g\t%.10g\t%.10g\t%.10g\n",quat[X],quat[Y],quat[Z],quat[W]);
}
}
return( 0 );
}
#define OPT_STR "yzqr"
int get_args(argc,argv)
int argc;
char **argv;
{
int c;
mode = QUATERNION; /* default */
units = DEGREES;
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
switch(c){
case 'y':
mode = YPR;
break;
case 'z':
mode = XYZ;
break;
case 'q':
mode = QUATERNION;
break;
case 'r':
units = RADIANS;
break;
default:
fprintf(stderr,"Unknown option: -%c\n",c);
return(0);
}
}
return(1);
}
+58
View File
@@ -0,0 +1,58 @@
.TH ANIM_LOOKAT 1 BRL/CAD
.SH NAME
anim_lookat - create a view animation script or table which looks from an eye point to
a specified point.
.SH SYNOPSIS
.B anim_lookat
.B [\-f #]
.B \[-v]
.B < in.table
.B > out.script
.PP
.B anim_lookat
.B \-[y|q]
.B \[-v]
.B < in.table
.B > out.table
.SH DESCRIPTION
This program takes as input a seven-column animation table
consisting of time, an eye point, and a "look-at point", and prints a
view animation script to control the virtual camera.
The camera always remains "right-side up"; that is, it yaws and pitches but
doesn't roll. In cases where the camera looks vertically up or down, the
yaw from the previous frame is retained. This avoids sudden jumps as much
as possible.
.PP
.SH OPTIONS
.TP
.B \-f#
Specify an integer with which to begin
numbering frames. The default is 0.
.TP
.B \-y
The output will be an animation table rather
than a view animation script. The output table has 7 columns:
a time column, three
columns representing position, and three columns representing yaw,
pitch, and roll.
.TP
.B \-q
The output will be an animation table rather than a view animation script.
The output table has eight columns:
a time column, three position columns, and four columns
representing the x,y,z, and w coordinates of an orientation quaternion.
.TP
.B \-v
Include the viewsize in the output script or table. The viewsize is
calculated in every frame as twice the distance from the eye point to
the lookat point. If the output is a table, then the viewsize is printed
in the second column.
.SH AUTHOR
Carl J. Nuzman
.SH COPYRIGHT
This software is Copyright (C) 1993 by the United States Army
in all countries except the USA. All rights reserved.
.SH "BUG REPORTS"
Reports of bugs or problems should be submitted via electronic
mail to <CAD@ARL.ARMY.MIL>.
+159
View File
@@ -0,0 +1,159 @@
/* A N I M _ L O O K A T . C
*
* Given animation tables for the position of the virtual camera
* and a point to look at at each time, this program produces an animation
* script to control the camera. The view is kept rightside up, whenever
* possible. When looking vertically up or down, the exact orientation
* depends on the previous orientation.
*
* Author -
* Carl J. Nuzman
*
* Source -
* The U. S. Army Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5068 USA
*
* Distribution Notice -
* Re-distribution of this software is restricted, as described in
* your "Statement of Terms and Conditions for the Release of
* The BRL-CAD Pacakge" agreement.
*
* Copyright Notice -
* This software is Copyright (C) 1993 by the United States Army
* in all countries except the USA. All rights reserved.
*/
#include "conf.h"
#include <stdio.h>
#include <math.h>
#include "machine.h"
#include "vmath.h"
#include "anim.h"
#include "bu.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifndef RTOD
#define RTOD (180/M_PI)
#endif
#define LOOKAT_SCRIPT 0
#define LOOKAT_YPR 1
#define LOOKAT_QUAT 2
extern int bu_optind;
extern char *bu_optarg;
int frame = 0;
int print_mode = LOOKAT_SCRIPT;
int print_viewsize = 0;
int get_args();
extern void anim_dirn2mat();
extern int anim_mat2ypr();
extern int anim_mat2quat();
int
main(argc,argv)
int argc;
char **argv;
{
fastf_t time, vsize=0.0;
vect_t eye,look,dir, angles, norm, temp;
quat_t quat;
mat_t mat;
int val = 0;
VSETALL(look,0.0);
VSETALL(eye,0.0);
if (argc > 1)
get_args(argc,argv);
VSET(norm, 0.0, 1.0, 0.0);
while (!feof(stdin)){
val=scanf("%lf %lf %lf %lf %lf %lf %lf",&time,eye,eye+1,eye+2,look,look+1,look+2);
if (val < 7){
break;
}
if (print_viewsize) {
VSUB2(temp, eye, look);
vsize = MAGNITUDE(temp);
vsize *= 2.0;
}
VSUBUNIT(dir,look,eye);
anim_dirn2mat(mat,dir,norm);
VSET(norm, mat[1],mat[5], 0.0);
switch (print_mode) {
case LOOKAT_SCRIPT:
printf("start %d;\n",frame++);
printf("clean;\n");
if (print_viewsize)
printf("viewsize %.10g;\n",vsize);
printf("eye_pt %.10g %.10g %.10g;\n",eye[0],eye[1],eye[2]);
printf("viewrot %.10g\t%.10g\t%.10g\t0\n", -mat[1], -mat[5], -mat[9]);
printf("%.10g\t%.10f\t%.10g\t0\n", mat[2], mat[6], mat[10]);
printf("%.10g\t%.10g\t%.10g\t0\n", -mat[0], -mat[4], -mat[8]);
printf("0\t0\t0\t1;\n");
printf("end;\n");
break;
case LOOKAT_YPR:
anim_mat2ypr(angles,mat);
angles[0] *= RTOD;
angles[1] *= RTOD;
angles[2] *= RTOD;
printf("%.10g",time);
if (print_viewsize)
printf("\t%.10g",vsize);
printf("\t%.10g\t%.10g\t%.10g",eye[0],eye[1],eye[2]);
printf("\t%.10g\t%.10g\t%.10g\n",angles[0],angles[1],angles[2]);
break;
case LOOKAT_QUAT:
anim_mat2quat(quat,mat);
printf("%.10g",time);
if (print_viewsize)
printf("\t%.10g",vsize);
printf("\t%.10g\t%.10g\t%.10g",eye[0],eye[1],eye[2]);
printf("\t%.10g\t%.10g\t%.10g\t%.10g\n",quat[0],quat[1],quat[2],quat[3]);
break;
}
}
return( 0 );
}
#define OPT_STR "f:yqv"
int get_args(argc,argv)
int argc;
char **argv;
{
int c;
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
switch(c){
case 'f':
sscanf(bu_optarg,"%d",&frame);
break;
case 'y':
print_mode = LOOKAT_YPR;
break;
case 'q':
print_mode = LOOKAT_QUAT;
break;
case 'v':
print_viewsize = 1;
break;
default:
fprintf(stderr,"Unknown option: -%c\n",c);
return(0);
}
}
return(1);
}
+97
View File
@@ -0,0 +1,97 @@
.TH ANIM_OFFSET 1 BRL/CAD
.SH NAME
anim_offset - create an animation table for an object rigidly attached to
another object.
.SH SYNOPSIS
.B anim_offset
.B -o # # #
.B [-r]
.B < in.table
.B > out.table
.SH DESCRIPTION
This filter operates on animation tables of the type used by
.I tabsub
and
.I anim_script.
Given a table specifying the position and
orientation of one object at every applicable time,
.I anim_offset
calculates
the position of another object which is rigidly attached to it.
.PP
The columns of the input table should be time, three columns of
position, followed by yaw, pitch, and roll. The output will be
normally be a four-column file specifying time and position. If the
.B -r
option is used, the output is a seven-column file in which the last
three columns are copies of the orientation information from the input
file.
.PP
The position of the object relative to the rigid body should be
given on the command line in the order x, y, z, with the
.B -o # # #
option. These offset values
should be as measured from the centroid of the rigid body.
.SH EXAMPLES
This filter could be used, for example, to do an animation where
the camera is placed inside a moving vehicle.
.PP
Suppose that truck.table contains the desired position of the
center of the front axle of the truck as well as its orientation at each
time. One row of the table might look like this:
.nf
35.2 12450 -140 600 90.0 0.0 0.0
.fi
Thus 35.2 seconds into the animation, the center of the front axle will
be at (12450, -140, 600), and the truck will be pointed in the positive
y direction. (yaw = 90).
.PP
Now, suppose we want the camera to ride along in the cab, above
and behind the front axle and somewhat to the left. To specify this
offset, we use the coordinate frame of the truck, with the origin at the
center of the front axle, the x-axis to the front, y to the left, and z
pointing up. Let the exact offset from the axle to the desired camera
position in this case be (-600, 900, 1200), in units of mm. Now we use
the routine:
.nf
anim_offset -o -600 900 1200 < truck.table > camera.table
.fi
The result is a four-column table giving the desired position of the
virtual camera at each time. The row corresponding to the sample row
above would be:
.nf
35.2 11550 -740 1800
.fi
With the
.B -r
option, the output would have been:
.nf
35.2 11550 -740 1800 90.0 0.0 0.0
.fi
Now
.I tabsub
and/or
.I anim_script
can be used to process these two animation
tables into an animation script.
.SH BUGS
The program will only use orientations specified as yaw,
pitch, and roll. You can get around this using
.IR anim_orient ,
which converts between different orientation representations.
.SH AUTHOR
Carl J. Nuzman
.SH COPYRIGHT
This software is Copyright (C) 1993 by the United States Army
in all countries except the USA. All rights reserved.
.SH "BUG REPORTS"
Reports of bugs or problems should be submitted via electronic
mail to <CAD@ARL.ARMY.MIL>.
+110
View File
@@ -0,0 +1,110 @@
/* A N I M _ O F F S E T . C
*
* Animate an object which is rigidly attached to another.
*
* Given an animation table specifying the position and orientation of
* one object, anim_offset produces a similar table specifying the
* position of an object rigidly attached to it.
*
*
* Author -
* Carl J. Nuzman
*
* Source -
* The U. S. Army Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5068 USA
*
* Distribution Notice -
* Re-distribution of this software is restricted, as described in
* your "Statement of Terms and Conditions for the Release of
* The BRL-CAD Pacakge" agreement.
*
* Copyright Notice -
* This software is Copyright (C) 1993 by the United States Army
* in all countries except the USA. All rights reserved.
*/
#include "conf.h"
#include <math.h>
#include <stdio.h>
#include "machine.h"
#include "vmath.h"
#include "bu.h"
#include "anim.h"
extern int bu_optind;
extern char *bu_optarg;
int full_print = 0;
vect_t offset;
int get_args();
extern void anim_dy_p_r2mat();
extern void anim_add_trans();
int
main(argc,argv)
int argc;
char **argv;
{
int val;
fastf_t yaw, pitch, roll, time;
vect_t temp,point,zero;
mat_t mat;
VSETALL( temp , 0.0 );
VSETALL( point , 0.0 );
VSETALL( zero , 0.0 );
(void) get_args(argc,argv);
while (1) {
/*read line from table */
val = scanf("%lf%*[^-0123456789]",&time); /*read time,ignore garbage*/
val = scanf("%lf %lf %lf", point, point+1, point +2);
val = scanf("%lf %lf %lf", &yaw, &pitch, &roll);
if (val < 3) {
break;
}
anim_dy_p_r2mat(mat,yaw, pitch,roll);
anim_add_trans(mat,point,zero);
MAT4X3PNT(temp,mat,offset);
printf("%.10g\t%.10g\t%.10g\t%.10g",time, temp[0], temp[1], temp[2]);
if (full_print)
printf("\t%.10g\t%.10g\t%.10g", yaw, pitch, roll);
printf("\n");
}
return( 0 );
}
#define OPT_STR "ro:"
int get_args(argc,argv)
int argc;
char **argv;
{
int c;
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
switch(c){
case 'r':
full_print = 1;
break;
case 'o':
sscanf(argv[bu_optind-1],"%lf",offset+0);
sscanf(argv[bu_optind],"%lf",offset+1);
sscanf(argv[bu_optind+1],"%lf",offset+2);
bu_optind += 2;
break;
default:
fprintf(stderr,"Unknown option: -%c\n",c);
return(0);
}
}
return(1);
}
+217
View File
@@ -0,0 +1,217 @@
.TH ANIM_ORIENT 1 BRL/CAD
.SH NAME
anim_orient - convert between orientation formats
.SH SYNOPSIS
.B anim_orient
.B [q|y|a|z|m][vri]
.B [q|y|a|z|m][vriu]
.B < in.table
.B > out.table
.SH DESCRIPTION
.I Anim_orient
is a filter which translates a table of orientation
information from one format to another. The method used is to convert
the input format to a matrix, then convert the matrix to the desired
output format. The input format is specified in the first argument, and
the output format is specified in the second.
The orientation formats
must be one of the following:
.B q
(quaternion),
.B y
(yaw,pitch, and roll),
.B a
(azimuth, elevation, and twist),
.B z
(x-y-z angles), or
.B m
(rotation matrix).
In addition, the output format may be modified by the
.B u
option, and the input and output formats may be modified by the
.BR r ,
.BR i ,
and
.B v
options. The
.B r
option specifies that angles are read or written in radians, rather
than degrees. The
.BR i , v ,
and
.B u
options are explained below.
.PP
To clearly understand the operation of anim_orient, it is important to
examine the difference between orientation and rotation.
The matrices, quaternions, and angles
used by anim_orient specify rotations. These are transformations
which, when applied to an object, preserve its shape but change its
orientation with respect to a fixed set of axes. Given the initial
orientation of an object, a rotation defines the final orientation, but
different initial orientations will yield different final orientations.
In order
to represent orientations with rotations, we
must define a default initial orientation for the object.
Then a given matrix, quaternion, or set of angles represents the orientation
resulting from applying the rotation to the initial object orientation.
.PP
If no modifying codes are specified, anim_orient assumes that the
default orientation of the object in question faces the positive
x-direction, with the world y-axis pointing to the object's left and the
z-axis pointing up. This is the orientation in which many
.I brlcad
objects
are modeled, and the default assumed by other animation routines such as
anim_script. If the
.B v
code is specified, then the default orientation
is taken to be facing the negative z-direction, with the world x-axis
pointing to the object's right and the y-axis pointing up. This is the
default orientation of the eye in
.I mged
and
.IR rt .
Some common uses of the v
option are demonstrated in the examples section.
.PP
The input and output format codes are:
.TP
.BR q :
Quaternions, in the order x,y,z,w. This is the default input and
output format. The output will
always be unit quaternions. For a unit quaternion, the
xyz-vector represents an axis of rotation and and w represents
cos(omega/2), where
omega is the angle to be rotated about the given axis.
.TP
.BR z :
x-y-z angles, in the order x, y, z. They represent a rotation
of z degrees around the z-axis, followed by y degrees around the y-axis,
followed by x degrees around the x-axis. If the code
.B zr
is used
then the angles will be read or written in radians
rather than degrees.
.TP
.BR y :
yaw-pitch-roll format, in that order. They represent
a rotation of +roll degrees about the x-axis, -pitch degrees about
the y-axis, followed by +yaw degrees about the z-axis. If the code
.B yr
is used, angles are in radians rather than degrees.
.TP
.BR a :
azimuth, elevation, twist, in that order. They represent a rotation of
-twist degrees about the x-axis, +elevation degrees about the y-axis,
and +azimuth + 180 degrees about the z-axis. Alternatively, they can
be thought of as a 180 degree rotation about the z-axis followed by a
rotation of +twist degrees about the x-axis, -elevation degrees about
the y-axis, and +azimuth degrees about the z-axis.
.TP
.BR m :
pre-multiplication rotation matrix. Sixteen
numbers form a 4x4 matrix, although only the nine elements in the upper
left corner are actually used. This is the format used at the interior of
the conversion routine. It is a transformation from initial orientation to
a new orientation.
.PP
The input and ouput modification codes are:
.TP
.B i
This code is used in conjunction with any of the format codes to represent
the inverse transformation. Under the
.B i
code, a matrix, quaternion, or
set of angles represents the inverse of the rotation that it normally
represents.
For example, normally, the orientation
corresponding to a given matrix is the orientation that the default
object ends up in after the matrix is applied to it. With the
.B i
code,
a given matrix represents the orientation an object should be placed
in so that the applying the matrix puts it back in the default
orientation.
One common use of the
.B i
option is for handling "Viewrot" matrices used
by
.I mged
and
.IR rt .
The viewrot matrix is a model-to-view matrix, which is
the transpose (inverse) of the matrix which would conceptually be
applied to an eye object to put it in the desired place in the model.
.TP
.B v
When this option is specified, the corresponding rotation is considered
applied to the default view orientation, rather than the default object
orientation, as explained above.
.TP
.B u
This option forces the output orientation to be upright, or "right-side
up", where the z-axis is the up direction. In terms of yaw, pitch, and
roll, this means that the roll is forced to zero. Because this is a
one-way operation, it can only be applied to the output orientation, not
the input.
.SH EXAMPLES
.sp
Normalize a table of quaternions to unit magnitude. (quaternions are the
default format).
.sp
anim_orient < in.table > out.table
.sp
change xyz angles to a rotation matrix
.sp
anim_orient z m < in.table > out.table
.sp
change azimuth,elevation, and twist to a matrix suitable for the
.I rt
viewrot command
.sp
anim_orient a miv < in.table > out.table
.sp
transpose matrices
.sp
anim_orient m mi < in.table > out.table
.sp
change radian xyz angles to yaw-pitch-roll in degrees
.sp
anim_orient zr y < in.table > out.table
.sp
given a quaternion being applied to an object facing the x-axis,
find the quaternion needed
to turn the virtual camera in the same direction using
.IR rt 's
orientation command
.sp
anim_orient q qv < in.table > out.table
.sp
Given the yaw, pitch, and roll of an object, find the yaw, pitch, and
roll which would bring it back to the default position.
.sp
anim_orient y yi < in.table > out.table
.sp
Force a table of view quaternions to represent "right-side up"
orientations.
.sp
anim_orient qv qvu < in.table > out.table
.SH BUGS
There are built-in trouble spots which occur, in ypr, xyz, or aet
formats, when the pitch, y-rotation, or elevation is an odd multiple of 90
degrees, because at this point the other two angles become
indistinguishable. The program makes the arbitrary assumption that the
roll is zero or that the x-rotation is zero, depending on the format,
and gives a warning to that effect on standard error.
.SH AUTHOR
Carl J. Nuzman
.SH COPYRIGHT
This software is Copyright (C) 1993 by the United States Army
in all countries except the USA. All rights reserved.
.SH "BUG REPORTS"
Reports of bugs or problems should be submitted via electronic
mail to <CAD@ARL.ARMY.MIL>.
+290
View File
@@ -0,0 +1,290 @@
/* A N I M _ O R I E N T . C
*
* Convert between different orientation formats. The formats are:
* quaternion, yaw-pitch-roll, azimuth-elevation-twist, xyz angles,
* pre-multiplication rotation matrices, and transposed matrices (inverses).
* By default, the information is assumed to represent a transformation
* which should be an object which initially faces the x-axis, with the
* z-axis going up. Alternatively, the information can be interpreted as
* transformations which should be applied to an object initially facing the
* negative z-axis, with the y-axis going up.
* The conversion is done by converting each input form to a matrix,
* and then converting that matrix to the desired output form.
* Angles may be specified in radians or degrees.
*
* Author -
* Carl J. Nuzman
*
* Source -
* The U. S. Army Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5068 USA
*
* Distribution Notice -
* Re-distribution of this software is restricted, as described in
* your "Statement of Terms and Conditions for the Release of
* The BRL-CAD Pacakge" agreement.
*
* Copyright Notice -
* This software is Copyright (C) 1993 by the United States Army
* in all countries except the USA. All rights reserved.
*/
#include "conf.h"
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <math.h>
#include "machine.h"
#include "vmath.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#define YPR 0
#define XYZ 1
#define AET 2
#define QUAT 3
#define MAT 4
#define DEGREES 0
#define RADIANS 1
#define ANIM_NORMAL 0
#define ANIM_ERROR1 1
#define ANIM_ERROR2 2
#define DTOR M_PI/180.0
#define RTOD 180.0/M_PI
int parse_args();
extern void anim_y_p_r2mat();
extern void anim_tran();
extern void anim_v_unpermute();
extern void anim_dirn2mat();
extern void anim_v_permute();
extern int optind;
extern char *optarg;
int upright;
int input_mode, output_mode, length, input_units, output_units;
int input_perm, output_perm, input_inv, output_inv;
int
main(argc,argv)
int argc;
char **argv;
{
int num_read;
fastf_t temp[3], temp2[3],angle[3],quat[4],matrix[16];
void anim_zyx2mat(),anim_ypr2mat(),anim_quat2mat(), anim_mat_print();
int anim_mat2ypr(),anim_mat2zyx(),anim_mat2quat();
if(!parse_args(argc,argv)) {
fprintf(stderr,"Get_args error.\n");
exit(0);
}
/* read data */
num_read = length;
while (1){
switch (input_mode) {
case YPR:
case XYZ:
case AET:
num_read = scanf("%lf %lf %lf",angle,angle+1,angle+2);
/* convert to radians if in degrees */
if (input_units==DEGREES) {
VSCALE(angle,angle,DTOR);
}
break;
case QUAT:
num_read = scanf("%lf %lf %lf %lf", quat,quat+1,quat+2,quat+3);
break;
case MAT:
num_read = 0;
num_read += scanf("%lf %lf %lf %lf",matrix,matrix+1,matrix+2,matrix+3);
num_read += scanf("%lf %lf %lf %lf",matrix+4,matrix+5,matrix+6,matrix+7);
num_read += scanf("%lf %lf %lf %lf",matrix+8,matrix+9,matrix+10,matrix+11);
num_read += scanf("%lf %lf %lf %lf",matrix+12,matrix+13,matrix+14,matrix+15);
break;
}
if (num_read < length)
break;
/* convert to (object) matrix form */
switch (input_mode) {
case YPR:
anim_ypr2mat(matrix,angle);
break;
case AET:
anim_y_p_r2mat(matrix, angle[0]+M_PI, -angle[1],-angle[2]);
break;
case XYZ:
anim_zyx2mat(matrix,angle);
break;
case QUAT:
anim_quat2mat(matrix,quat);
break;
}
if (input_inv){
anim_tran(matrix);
}
if (input_perm){
anim_v_unpermute(matrix);
}
/* end of input conversion, begin output conversion*/
if (upright) { /* force right-side up */
VSET(temp, matrix[0], matrix[4], matrix[8]);
VSET(temp2, matrix[1], matrix[5], matrix[9]);
anim_dirn2mat(matrix,temp,temp2);
}
if (output_perm){
anim_v_permute(matrix);
}
if (output_inv){
anim_tran(matrix);
}
/* convert from matrix form and print result*/
switch (output_mode) {
case YPR:
anim_mat2ypr(angle,matrix);
if (output_units==DEGREES)
VSCALE(angle,angle,RTOD);
printf("%.12g\t%.12g\t%.12g\n",angle[0],angle[1],angle[2]);
break;
case AET:
anim_mat2ypr(angle,matrix);
if (angle[0] > 0.0) {
angle[0] -= M_PI;
} else {
angle[0] += M_PI;
}
angle[1] = -angle[1];
angle[2] = -angle[2];
if (output_units==DEGREES)
VSCALE(angle,angle,RTOD);
printf("%.12g\t%.12g\t%.12g\n",angle[0],angle[1],angle[2]);
break;
case XYZ:
anim_mat2zyx(angle,matrix);
if (output_units==DEGREES)
VSCALE(angle,angle,RTOD);
printf("%.12g\t%.12g\t%.12g\n",angle[0],angle[1],angle[2]);
break;
case QUAT:
anim_mat2quat(quat,matrix);
printf("%.12g\t%.12g\t%.12g\t%.12g\n",quat[0],quat[1],quat[2],quat[3]);
break;
case MAT:
anim_mat_print(stdout,matrix,0);
printf("\n");
}
}
return( 0 );
}
int parse_args(argc,argv)
int argc;
char **argv;
{
int c;
char *cp;
/* defaults */
upright = 0;
input_mode = QUAT;
output_mode = QUAT;
input_units = DEGREES;
output_units = DEGREES;
input_perm = 0;
output_perm = 0;
input_inv = 0;
output_inv = 0;
length = 4;
if (argc > 2) { /*read output mode */
cp = argv[2];
while ( (c=*cp++) ) {
switch (c) {
case 'q':
output_mode = QUAT;
break;
case 'y':
output_mode = YPR;
break;
case 'a':
output_mode = AET;
break;
case 'z':
output_mode = XYZ;
break;
case 'm':
output_mode = MAT;
break;
case 'i':
output_inv = 1;
break;
case 'r':
output_units = RADIANS;
break;
case 'v':
output_perm = 1;
break;
case 'u':
upright = 1;
break;
default:
fprintf(stderr,"anim_orient: unknown output option: %c\n",c);
return(0);
}
}
}
if (argc > 1) { /*read input mode */
cp = argv[1];
while ( (c=*cp++) ) {
switch (c) {
case 'q':
input_mode = QUAT;
length = 4;
break;
case 'y':
input_mode = YPR;
length = 3;
break;
case 'a':
input_mode = AET;
length = 3;
break;
case 'z':
input_mode = XYZ;
length = 3;
break;
case 'm':
input_mode = MAT;
length = 16;
break;
case 'i':
input_inv = 1;
break;
case 'r':
input_units = RADIANS;
break;
case 'v':
input_perm = 1;
break;
default:
fprintf(stderr,"anim_orient: unknown input option: %c\n",c);
return(0);
}
}
}
return(1);
}
+339
View File
@@ -0,0 +1,339 @@
.TH ANIM_SCRIPT 1 BRL/CAD
.SH NAME
anim_script - make an animation script for one object
.SH SYNOPSIS
.B anim_script
.B [-v #]
.B [-r|t|s]
.B [-q][-p]
.B [-a|b # # #]
.B [-c|d # # #]
.B [-f #]
.B [-m cmd]
.B [objectname]
.B < in.table
.B > out.script
.SH DESCRIPTION
.I Anim_script
is designed to produce an animation script for the
animation of the virtual camera or one
.I brlcad
object at a time. It is
complementary to
.I tabsub
in that it performs a similar
function, but with a different philosophy.
.PP
Both
.I anim_script
and
.I tabsub
use one row of an animation table to
produce one frame of an animation script. With
.I tabsub,
the user supplies
a template file which controls the form of the animation frames. This
allows the maximum user control, but also requires a good understanding
of the script format. With
.I anim_script,
the user supplies all the necessary
information on the command line. The range of possible output scripts is
limited, but the user does not have to deal directly with the details.
Both routines have special features which make certain common situations
easy to do. One of the most important special features of
.I anim_script
is the
ability to specify a reference position and orientation, as explained
below.
.PP
The objectname is the name of the object which is to be
animated, as it will appear in the ouput script. For example, if
"hatch1"
is a member of "turret" which is a member of "tank" which is one of the
objects specified on the command line of the call to
.I rt,
then the objectname "tank/turret/hatch1" or simply "turret/hatch1" would be used to
animate the hatch. The tank itself would be referred to by the name,
"/tank". Note that toplevel objects should be preceeded by a slash.
If view animation is being performed, no objectname
should be included.
.PP
.B in.table
should be a seven-column animation table,
specifying the time, 3d position, yaw, pitch and roll of the
object (or camera), although this changes if the
.BR -r ,
.BR -t ,
.BR -s ,
or
.B -v#
options are used.
.SH OPTIONS
.TP
.B \-r
.B in.table
is a four-column file including time and rotation
information only. No translation will occur.
.TP
.B \-t
.B in.table
is a four-column file including time and translation
information only. No rotation will occur.
.TP
.B \-s
.B in.table
is a four-column file including time and translation
information only. The vehicle will be rotated (steered) to face the
direction of motion.
.TP
.B \-q
Quaternion orientation. Any orientation information in
.B in.table
will be in quaternion form, in the order x,y,z,w. The identity quaternion
representing no orientation change is (0,0,0,1).
.TP
.B \-p
Permuted orientation. This option indicates that transformations defined by
the quaternions should be applied to an object which has first been placed
in
.IR rt 's
default eye orientation. Thus, the identity quaternion represents yawing the
object 90 degrees to the left and then pitching it 90 degrees downward.
The quaternions produced by
.IR mged 's
saveview command and used by
.IR rt 's
orientation command
are quaternions of this type. See
.I anim_orient
for more information.
.TP
.B \-v#
The desired output is a view animation script, rather
than an object animation script. No object should be specified. The
argument can be any floating point number. If
the argument
is positive, the command:
.sp
viewsize #;
.sp
will be placed at the beginning of the ouput file. If it is
zero, the `viewsize' command is omitted from the output script. If it is
negative, then the
viewsize for each frame is expected to be in the first column after the
time in
.BR in.table .
A `viewsize' command would then be
included immediately after the `start' command of each frame.
.TP
.B \-f#
Specify the integer with which to begin
numbering the frames of the output script. The default is 0.
.PP
The remaining options give information about the object which is
to be animated.
.TP
.B \-a # # #
or
.TP
.B \-b # # #
These options take three arguments, which are the
yaw, pitch, and roll of the object's axes with respect to the
world axes. With
.B \-a,
rotations specified in the infile will be applied
with respect to the object's axes. With the
.B \-b
option, the object is
rotated so that its axes coincide with the world axes, and then all
rotations and translations are carried out with respect to the world
axes. The
.B \-b
option is particularly useful in conjunction with the
.B \-s
option, because it tells
.I anim_script
which way the front of the vehicle faces. See
the examples below.
.TP
.B \-c # # #
or
.TP
.B \-d # # #
These options take three arguments, which are the x, y,
and z coordinates of the point which is to be considered the "centroid"
of the object. All rotations will occur about this point. If
.B \-c
is used,
translations from the input table will be considered to be relative
displacements from this point. If
.B \-d
is used, the translations in the
input table will be interpreted as absolute displacement from the world
origin. The direction of translation in both cases is along the world
axes, unless the
.B \-a
option has been used, in which case the
translations are with respect to the object's axes. See the examples below.
.PP
When the
.B \-v
option is used, the virtual camera is the object
being animated, and so the meaning of the preceeding four options
changes somewhat. The
.B \-c
and
.B \-a
options are not useful in this context.
The
.B \-d
option can be thought of as specifying the position and
orientation of a virtual
tripod with respect to the camera lens. The translations and rotations
specified in
the input table will be applied to the tripod, to which the camera is
rigidly attached. For example, the option
.B \-d 10 0 \-2
in conjunction with
the
.B \-v#
option means that the virtual tripod is 10 units in front of the
camera and 2
units below the camera's line of sight. The option
.B \-b -90 0 0
in this
context would mean that the front of the virtual tripod faces 90 degrees
to the right of the virtual camera. As translation and rotation
information are read in from in.table, they are applied to the virtual
tripod, with the virtual camera rigidly attached. See below for examples
of how this might be used.
.TP
.B -m cmd
Specify a matrix command to use in, object animation. The default value
is "lmul", which means that matrices in the output script are
multiplied onto the
left of the matrix between the object being animated and its parent.
The matrix residing between the object and its parent is referred to as
the current arc. The possible matrix commands are the following:
.nf
lmul - left-multiply the matrix onto the current arc
rmul - right-multiply the matrix onto the current arc
rarc - replace the current arc with the matrix
rstack - replace the stack of ancestor matrices with the matrix
rboth - replace the current arc with the matrix and replace the
stack of ancestor matrices with the identity matrix.
.fi
This option is intended primarily to give expert users additional
flexibility, and shouldn't be needed by most animators.
.SH EXAMPLES
To animate a truck which is modeled with the front facing the positive
x-direction, the position of the center of the truck and its orientation at
each time should be in
.BR truck.table .
If the center of the modeled truck is at
the point (234,0,1200) then the following command could be used:
.sp
anim_script -d 234 0 1200 /truck < truck.table > truck.script.
.sp
If the front of the model truck faces (for some reason)
halfway
between the x and y axes, a
.B \-b
option is added, to show the relationship
between world and truck axes:
.sp
anim_script -b 45 0 0 -d 234 0 1200 /truck < truck.table > truck.script.
.sp
To steer the truck automatically to face the direction of motion,
the
.B \-s
option is added, and the orientation columns should be removed from
.BR truck.table .
.sp
anim_script -s -b 45 0 0 -d 234 0 1200 /truck < truck.table > truck.script.
.sp
.sp
Animating a steering wheel: Suppose the steering wheel is stored
in the database so that the axis it turns on is at an yaw of -135
degrees and an pitch of 30 degrees. It passes through the point
(700,800,2400). Then we select "rotation only" with
.B \-r
and specify the
relationship between the steering wheels axes and the world with the
.B \-a
and
.B \-c
options. In
.B roll.table
we put the time, two zero columns, and a
column specifying the roll of the wheel (How much it is to be twisted).
.sp
anim_script -r -a -135 30 0 -c 700 800 2400 truck/steering_column/wheel <
roll.table > steer.table
.sp
Alternativly, if the turning of the wheel was stored in the yaw
(second) column of a file,
.BR turn.table ,
a different set of axes would be
used to achieve the same effect:
.sp
anim_script -r -a 45 60 0 -c 700 800 2400 truck/steering_column/wheel <
turn.table > steer.table
.sp
.PP
To animate seven little men doing simultaneous backflips in different
places, you would want to use relative motion. That is, a translation
vector of (0,0,1) means move one unit upward, instead of move to the
point (0,0,1). For each little man, we specify his position in the
model using the
.B \-c
option. Then we can use the same backflip instuctions
for each of the little men.
.sp
anim_script -c 12 34 5 /little.man.one < generic.backflip.table >
little.man.one.script
.sp
anim_script -c -3 13 5 /little.man.two < generic.backflip.table >
little.man.two.script
.sp
and so on.
.sp
.sp
.SS Camera examples
If we know the desired postion of the camera and its orientation
at each time, it's very simple. The
.B -v#
option indicates that the view is
being animated; no object is specified.
.sp
anim_script -v0 < view.table > view.script
.sp
To follow a truck, so that the camera is always ten units behind and 4
units above it, we specify a virtual tripod in front of and below the
camera:
.sp
anim_script -v0 -d 10 0 -4 < truck.table > view.script
.sp
To do the same thing but with the camera turned to look at the right
side of the truck, we specify that the virtual tripod originally faces
to the right, so that the camera faces its right side. Thus when the
virtual tripod is placed in the same position and orientation as the
truck, the camera will be looking at the right side of the
truck.
.sp
anim_script -v0 -d 10 0 -4 -b -90 0 0 < truck.table > view.script
.SH BUGS
The reading of command line options which take more than one
argument are somewhat finicky. For example, it understands the
option "-d 1 1 1" but not "-d1 1 1".
.SH AUTHOR
Carl J. Nuzman
.SH COPYRIGHT
This software is Copyright (C) 1993 by the United States Army
in all countries except the USA. All rights reserved.
.SH "BUG REPORTS"
Reports of bugs or problems should be submitted via electronic
mail to <CAD@ARL.ARMY.MIL>.
+272
View File
@@ -0,0 +1,272 @@
/* A N I M _ S C R I P T . C
*
* Turn an animation table into an animation script suitable for
* use by rt. Anim_script.c makes a script for one object at a time (or the
* virtual camera). Some of the available options include rotation
* only, translation only, automatic steering, and specifying reference
* coordinates.
*
* Author -
* Carl J. Nuzman
*
* Source -
* The U. S. Army Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5068 USA
*
* Distribution Notice -
* Re-distribution of this software is restricted, as described in
* your "Statement of Terms and Conditions for the Release of
* The BRL-CAD Pacakge" agreement.
*
* Copyright Notice -
* This software is Copyright (C) 1993 by the United States Army
* in all countries except the USA. All rights reserved.
*/
#include "conf.h"
#ifdef USE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#include <math.h>
#include <stdio.h>
#include "machine.h"
#include "vmath.h"
#include "bu.h"
#include "bn.h"
#include "anim.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
int get_args();
extern int anim_steer_mat();
extern void anim_quat2mat();
extern void anim_v_unpermute();
extern void anim_mat_print();
extern int bu_optind;
extern char *bu_optarg;
/* info from command line args */
int relative_a, relative_c, axes, translate, quaternion, rotate;/*flags*/
int steer, view, readview, permute; /* flags*/
int first_frame;
fastf_t viewsize;
vect_t centroid, rcentroid, front;
mat_t m_axes, m_rev_axes; /* rotational analogue of centroid */
char mat_cmd[10]; /* default is lmul */
int
main(argc,argv)
int argc;
char **argv;
{
void anim_dx_y_z2mat(), anim_add_trans();
fastf_t yaw, pitch, roll;
vect_t point, zero;
quat_t quat;
mat_t a, m_x;
int val, go, frame, last_steer;
frame=last_steer=go=view=relative_a=relative_c=axes=0;
VSETALL(centroid,0);
VSETALL(rcentroid,0);
VSETALL(front,0);
VSETALL(point,0);
VSETALL(zero,0);
yaw = pitch = roll = 0.0;
MAT_IDN(m_axes);
MAT_IDN(m_rev_axes);
MAT_IDN(a);
if (!get_args(argc,argv))
fprintf(stderr,"anim_script: Get_args error\n");
frame = (steer) ? first_frame -1 : first_frame;
if (view && (viewsize > 0.0))
printf("viewsize %.10g;\n", viewsize);
while (1) {
/* read one line of table */
val = scanf("%*f"); /*ignore time */
if (readview)
scanf("%lf",&viewsize);
if(translate)
val=scanf("%lf %lf %lf", point, point+1, point+2);
if(rotate&&quaternion){
val = scanf("%lf %lf %lf %lf", quat,quat+1,quat+2,quat+3);
val -= 1;
} else if (rotate) {
val=scanf("%lf %lf %lf",&yaw,&pitch,&roll);
}
if (val < 3){ /* ie. scanf not completely successful */
/* with steering option, must go extra loop after end of file */
if (steer && !last_steer)
last_steer = 1;
else break;
}
/* calculate basic rotation matrix a */
if (steer)
go = anim_steer_mat(a,point,last_steer); /* warning: point changed by anim_steer_mat */
else if (quaternion) {
anim_quat2mat(a,quat);
go = 1;
} else {
anim_dx_y_z2mat(a,roll,-pitch,yaw);/* make ypr matrix */
go = 1;
}
/* if input orientation (presumably from quaternion) was
* designed to manipulate the view, first move the object
* to the default object position */
if (permute)
anim_v_unpermute(a);
/* make final matrix, including translation etc */
if (axes){ /* add pre-rotation from original axes */
bn_mat_mul(m_x,a,m_rev_axes);
MAT_MOVE(a,m_x);
}
anim_add_trans(a,point,rcentroid); /* add translation */
if (axes && relative_a){ /* add post-rotation back to original axes */
bn_mat_mul(m_x,m_axes,a);
MAT_MOVE(a,m_x);
}
if (relative_c)
anim_add_trans(a,centroid,zero); /* final translation */
/* print one frame of script */
if (go && view){
printf("start %d;\n", frame);
printf("clean;\n");
if (readview)
printf("viewsize %.10g;\n", viewsize);
printf("eye_pt %.10g %.10g %.10g;\n",a[3],a[7],a[11]);
/* implicit anim_v_permute */
printf("viewrot %.10g %.10g %.10g 0\n",-a[1],-a[5],-a[9]);
printf("%.10g %.10g %.10g 0\n", a[2], a[6], a[10]);
printf("%.10g %.10g %.10g 0\n", -a[0], -a[4],-a[8]);
printf("0 0 0 1;\n");
printf("end;\n");
}
else if (go){
printf("start %d;\n", frame);
printf("clean;\n");
printf("anim %s matrix %s\n", *(argv+bu_optind), mat_cmd);
anim_mat_print(stdout,a,1);
printf("end;\n");
}
frame++;
}
return( 0 );
}
#define OPT_STR "a:b:c:d:f:m:pqrstv:"
int get_args(argc,argv)
int argc;
char **argv;
{
int c, i, yes;
double yaw,pch,rll;
void anim_dx_y_z2mat(), anim_dz_y_x2mat();
rotate = translate = 1; /* defaults */
quaternion = permute = 0;
strcpy(mat_cmd, "lmul");
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
i=0;
switch(c){
case 'a':
bu_optind -= 1;
sscanf(argv[bu_optind+(i++)],"%lf", &yaw );
sscanf(argv[bu_optind+(i++)],"%lf", &pch );
sscanf(argv[bu_optind+(i++)],"%lf", &rll );
bu_optind += 3;
anim_dx_y_z2mat(m_axes, rll, -pch, yaw);
anim_dz_y_x2mat(m_rev_axes, -rll, pch, -yaw);
axes = 1;
relative_a = 1;
break;
case 'b':
bu_optind -= 1;
sscanf(argv[bu_optind+(i++)],"%lf", &yaw );
sscanf(argv[bu_optind+(i++)],"%lf", &pch );
sscanf(argv[bu_optind+(i++)],"%lf", &rll );
bu_optind += 3;
anim_dx_y_z2mat(m_axes, rll, -pch, yaw);
anim_dz_y_x2mat(m_rev_axes, -rll, pch, -yaw);
axes = 1;
relative_a = 0;
break;
case 'c':
bu_optind -= 1;
sscanf(argv[bu_optind+(i++)],"%lf",centroid);
sscanf(argv[bu_optind+(i++)],"%lf",centroid+1);
sscanf(argv[bu_optind+(i++)],"%lf",centroid+2);
bu_optind += 3;
VREVERSE(rcentroid,centroid);
relative_c = 1;
break;
case 'd':
bu_optind -= 1;
sscanf(argv[bu_optind+(i++)],"%lf",centroid);
sscanf(argv[bu_optind+(i++)],"%lf",centroid+1);
sscanf(argv[bu_optind+(i++)],"%lf",centroid+2);
bu_optind += 3;
VREVERSE(rcentroid,centroid);
relative_c = 0;
break;
case 'f':
sscanf(bu_optarg,"%d",&first_frame);
break;
case 'm':
strncpy(mat_cmd,bu_optarg, 10);
break;
case 'p':
permute = 1;
break;
case 'q':
quaternion = 1;
break;
case 'r':
rotate = 1;
translate = 0;
break;
case 's':
steer = 1;
relative_a = 0;
rotate = 0;
translate = 1;
break;
case 't':
translate = 1;
rotate = 0;
break;
case 'v':
yes = sscanf(bu_optarg,"%lf",&viewsize);
if (!yes) viewsize = 0.0;
if (viewsize < 0.0)
readview = 1;
view = 1;
break;
default:
fprintf(stderr,"Unknown option: -%c\n",c);
return(0);
}
}
return(1);
}
+143
View File
@@ -0,0 +1,143 @@
.TH ANIM_SORT 1 BRL/CAD
.SH NAME
anim_sort - combine concatenated animation scripts into one script
.SH SYNOPSIS
.B anim_sort
.B [-ic]
.B < mixed.script
.B > ordered.script
.SH DESCRIPTION
Note:
.I anim_sort
has been preempted in release 5.0 by
.IR scriptsort ,
which sorts scripts much faster.
.PP
.I Anim_sort
allows the user to combine several animation scripts
into a single script suitable for input to
.IR rt .
A convenient way to
prepare a complicated animation script is to develop each part
separately and then use
.I anim_sort
to combine the various parts. For
example, suppose that
.B view.script
is an animation script controlling the
movement of the virtual camera and the lighting,
.B mill.script
rotates
the blades of a windmill, and
.B quixote.script
controlls the movement of a
knight. These scripts should first be concatenated together:
.sp
cat view.script mill.script quixote.script > mixed.script
.sp
Calling
.I anim_sort
with
.B mixed.script
on standard input would
reorder the commands in
.B mixed.script
to make a viable script on standard
output.
.sp
Each of the input files to be concatenated is expected to be a
viable
.I rt
animation script, containing a series of frames of the
following form:
.sp
.nf
start framenumber;
any number of semi-colon terminated commands for rt;
end;
any number of post-raytracing commands
.fi
.sp
.I Anim_sort
reads the framenumber of the first start command, and uses
this to as the first frame number of the output file. The commands of
all frames in
.B mixed.script
with that framenumber are combined in the
ouput frame. The post-raytracing commands following all frames with that
framenumber are placed after the
.B end;
command of the output frame. This process is continued for each
successive integer,
until anim_sort reaches a framenumber which is not included in any of
the original scripts.
.sp
For example, if
.B view.script
contained frames numbered from 5 to
20,
.B mill.script
contained frames from 0 to 10, and
.B quixote.script
contained frames numbered from 15 to 25, the output script would start
at frame 5 (since
.B view.script
comes first in
.B mixed.script
) and end with
frame 25 (since frames 5 through 25 can be found somewhere in
.B mixed.script
). If the user wanted to include frames 0 through 4, which
are found only in
.B mill.script
, then
.B mill.script
should be concatenated
onto the beginning of
.B mixed.script
instead of the middle. In the
majority of animation situations, all of the input scripts would have
identical frame numbers anyway.
.sp
The first input script may also contain some lines preceeding
the first start command, which are copied to the beginning of the output
script. This is useful for commands such as 'viewsize', which are often
specified before the sequence of animations begins.
.sp
.SH OPTIONS
.TP
.B \-i
Incremental mode. The frames of the output script are printed in a scrambled
order which incrementally increases the time resolution of the animation.
For example, the frames of an eight-frame script would be printed in the
order: 0 4 2 6 1 3 5 7.
.TP
.B \-c
For most animation purposes, it is desirable to have a
.B clean
command immediately following the
.B start
command of each frame. The
default behavior of
.I anim_sort
is to include one
.B clean
command following the
.B start
command of each frame.
.B clean
commands from the input files are ignored. If the
.B -c
flag is activated, then no clean
commands are printed.
.SH SEE ALSO
rt(1), tabsub(1), anim_script(1)
.SH AUTHOR
Carl J. Nuzman
.SH COPYRIGHT
This software is Copyright (C) 1993 by the United States Army
in all countries except the USA. All rights reserved.
.SH "BUG REPORTS"
Reports of bugs or problems should be submitted via electronic
mail to <CAD@ARL.ARMY.MIL>.
+188
View File
@@ -0,0 +1,188 @@
/* A N I M _ S O R T . C
*
* Combine multiple animation scripts on standard input into a
* single script on standard output. The output can be in natural order
* or in a scrambled order for incrementally increasing time
* resolution (-i option).
*
*
* Author -
* Carl J. Nuzman
*
* Source -
* The U. S. Army Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5068 USA
*
* Distribution Notice -
* Re-distribution of this software is restricted, as described in
* your "Statement of Terms and Conditions for the Release of
* The BRL-CAD Pacakge" agreement.
*
* Copyright Notice -
* This software is Copyright (C) 1993 by the United States Army
* in all countries except the USA. All rights reserved.
*/
#include "conf.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "machine.h"
#include "externs.h"
#include "bu.h"
#define MAXLEN 50 /*maximum length of lines to be read */
#define MAXLINES 30 /* maximum length of lines to be stored*/
int suppressed; /* flag: suppress printing of 'clean;' commands */
int incremental; /* flag: order for incremental time resolution */
int get_args();
int
main(argc, argv)
int argc;
char **argv;
{
int length,frame_number, number, success, maxnum;
int first_frame,spread,reserve;
long last_pos;
char line[MAXLEN];
char pbuffer[MAXLEN*MAXLINES];
if (!get_args(argc,argv))
fprintf(stderr,"Get_args error\n");
/* copy any lines preceeding the first "start" command */
last_pos = ftell(stdin);
while (fgets(line,MAXLEN,stdin)!=NULL){
if (strncmp(line,"start",5)){
printf("%s",line);
last_pos = ftell(stdin);
}
else
break;
}
/* read the frame number of the first "start" command */
sscanf( strpbrk(line,"0123456789"),"%d", &frame_number);
/* find the highest frame number in the file */
maxnum = 0;
while(fgets(line,MAXLEN,stdin)!=NULL){
if(!strncmp(line,"start",5)){
sscanf(strpbrk(line,"0123456789"),"%d",&number);
maxnum = (maxnum>number)?maxnum:number;
}
}
length = maxnum - frame_number + 1;
/* spread should initially be the smallest power of two larger than
* or equal to length */
spread = 2;
while (spread < length)
spread = spread<<1;
first_frame = frame_number;
success = 1;
while (length--){
number = -1;
success = 0; /* tells whether or not any frames have been found which have the current frame number*/
if (incremental){
fseek(stdin, 0L, 0);
} else {
fseek(stdin, last_pos, 0);
}
reserve = MAXLEN*MAXLINES;
pbuffer[0] = '\0'; /* delete old pbuffer */
/* inner loop: search through the entire file for frames */
/* which have the current frame number */
while (!feof(stdin)){
/*read to next "start" command*/
while (fgets(line,MAXLEN,stdin)!=NULL){
if (!strncmp(line,"start",5)){
sscanf( strpbrk(line,"0123456789"),"%d", &number);
break;
}
}
if (number==frame_number){
if (!success){ /*first successful match*/
printf("%s",line);
if (!suppressed) printf("clean;\n");
success = 1;
last_pos = ftell(stdin);
}
/* print contents until next "end" */
while (fgets(line,MAXLEN,stdin)!=NULL){
if (!strncmp(line,"end;",4))
break;
else if (strncmp(line,"clean",5))
printf("%s",line);
}
/* save contents until next "start" */
while (fgets(line,MAXLEN,stdin)!=NULL){
if(!strncmp(line,"start",5))
break;
else {
reserve -= strlen(line);
reserve -= 1;
if (reserve > 0){
strncat(pbuffer,line,MAXLEN);
strcat(pbuffer,"\n");
}
}
}
}
}
if (success)
printf("end;\n");
/* print saved-up post-raytracing commands, if any */
printf("%s",pbuffer);
/* get next frame number */
if (incremental){
frame_number = frame_number + 2*spread;
while (frame_number > maxnum){
spread = spread>>1;
frame_number = first_frame + spread;
}
} else {
frame_number += 1;
}
}
return( 0 );
}
#define OPT_STR "ci"
int get_args(argc,argv)
int argc;
char **argv;
{
int c;
suppressed = 0;
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
switch(c){
case 'c':
suppressed = 1;
break;
case 'i':
incremental = 1;
break;
default:
fprintf(stderr,"Unknown option: -%c\n",c);
return(0);
}
}
return(1);
}
+89
View File
@@ -0,0 +1,89 @@
.TH ANIM_TIME 1 BRL/CAD
.SH NAME
anim_time - estimate appropriate time parameters for path
.SH SYNOPSIS
.B anim_time
.B [-s start_speed (absolute)]
.B [-e end_speed (absolute)]
.B [-i initial_speed (relative)]
.B [-f final_speed (relative)]
.B [-m max_len]
.B [-v|q]
.B < in.table
.B > out.table
.SH DESCRIPTION
This filter is designed to estimate appropriate time parameters for
an animation curve in 3D space. Given a four-column table specifying
time and 3D position for an object,
.I anim_time
ignores all but the first and last time specifications and
calculates reasonable time values for each intermediate point in the table.
The
output time values are based on the distances between points and the
calculated speed of the object. Various options allow the user to
control the assumptions on the object's initial and final speeds, and the
form of the output.
.I Anim_time
is intended to be used in situations where the user knows what key points
an object should pass through and how long the entire motion should take,
but doesn't care exactly when the object
reaches each point. It is also useful for getting objects to accelerate
smoothly to and from rest.
.SH OPTIONS
.TP
.BR -m #
Specify the maximum number of points to be read. This default to 64, so
you must use this option if you want to use tables with more than 64
points.
.TP
.BR -s #
Specify the starting speed of the object. If this option is not
specified, then the object is assumed to be initially travelling on a
pace to negotiate the entire path in the given time at a constant rate.
The argument must be positive and no greater than three times the speed
needed to traverse the path at a constant rate.
.TP
.BR -e #
Specify the final speed of the object. If this option is not specified,
then the object is assumed to end up travelling on a pace to negotiate
the entire path in the given time at a constant rate. The argument must
be positive and no greater than three times the speed needed to traverse
the path at a constant rate.
.TP
.BR -i #
Specify the initial speed of the object, relative to the speed that
would negotiate the given path at a constant rate. For example, an
argument of 2.0 means twice the speed needed to traverse the path at a
constant rate. Must lie between 0.0 and 3.0.
.TP
.BR -f #
Specify the final speed of the object, relative to the speed that would
negotiate the given path at a constant rate. Must lie between 0.0 and
3.0.
.TP
.B -v
Verbose option. The output table will contain a time column and three
position columns. If this option is not specified, only the new time
column will be printed.
.TP
.B -q
Query the total distance. If this option is specified, the only output
will be a number representing the total length of the input path.
.SH BUGS
The algorithm fits a cubic polynomial to the distance vs time graph, and then
uses Newton's method to find the times corresponding to each given distance.
If for some reason convergence is not reached,
.I anim_time
will print a warning on standard error. If the
.B -d
option is specified, the results of each iteration will be printed.
.SH AUTHOR
Carl J. Nuzman
.SH COPYRIGHT
This software is Copyright (C) 1996 by the United States Army
in all countries except the USA. All rights reserved.
.SH "BUG REPORTS"
Reports of bugs or problems should be submitted via electronic
mail to <CAD@ARL.ARMY.MIL>.
+287
View File
@@ -0,0 +1,287 @@
/* A N I M _ T I M E . C
*
* Given an animation path consiting of time stamps and 3-d points,
* estimate new time stamps based on the distances between points, the
* given starting and ending times, and optionally specified starting
* and ending velocities.
*
* Author -
* Carl J. Nuzman
*
* Source -
* The U. S. Army Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5068 USA
*
* Distribution Notice -
* Re-distribution of this software is restricted, as described in
* your "Statement of Terms and Conditions for the Release of
* The BRL-CAD Pacakge" agreement.
*
* Copyright Notice -
* This software is Copyright (C) 1993 by the United States Army
* in all countries except the USA. All rights reserved.
*/
#include "conf.h"
#include <math.h>
#include <stdio.h>
#include "machine.h"
#include "externs.h"
#include "vmath.h"
#include "bu.h"
#include "raytrace.h"
extern int bu_optind;
extern char *bu_optarg;
#define MAXLEN 64
#define DIVIDE_TOL (1.0e-10)
#define MAXITS 100
#define DELTA (1.0e-6)
#define TIME_NONE 0
#define TIME_ABSOLUTE 1
#define TIME_RELATIVE 2
/* command line variables */
fastf_t inv0,inv1;
int v0_set = TIME_NONE;
int v1_set = TIME_NONE;
int query = 0;
int verbose = 0;
int maxlines = 0;
int domem = 0;
int debug = 0;
int get_args();
fastf_t
gettime(dist, a, b, c, init)
fastf_t dist;
fastf_t a;
fastf_t b;
fastf_t c;
fastf_t init;
{
fastf_t old,new,temp;
int countdown,success;
countdown = MAXITS;
old = init;
success = 0;
while(countdown-->0){
temp = (3.0*a*old+2.0*b)*old+c;
if (temp<DIVIDE_TOL){
new = 0.75*old;
} else {
new = old - (((a*old+b)*old+c)*old-dist)/temp;
}
if (((new-old)<DELTA)&&((old-new)<DELTA)){
success = 1;
break;
}
if (debug)
printf("c: %d %f\t%f\n",countdown,new,new-old);
old = new;
}
if (!success) fprintf(stderr,"warning - max iterations reached\n");
return (new);
}
int
main(argc,argv)
int argc;
char **argv;
{
fastf_t *l, *x, *y, *z;
fastf_t temp0,temp1,temp2,start=0.0,end,v0,v1;
int i,j , num,plen;
fastf_t time,dist,slope,a,b,c;
plen = 0;
if (!get_args(argc,argv))
fprintf(stderr,"Usage: anim_time [-s#] [-e#] [-d] < in.table\n");
if (!domem) {
maxlines = MAXLEN;
}
l = (fastf_t *) bu_malloc(maxlines*sizeof(fastf_t),"l[]");
if (verbose) {
x = (fastf_t *) bu_malloc(maxlines*sizeof(fastf_t),"x[]");
y = (fastf_t *) bu_malloc(maxlines*sizeof(fastf_t),"y[]");
z = (fastf_t *) bu_malloc(maxlines*sizeof(fastf_t),"z[]");
} else {
x = (fastf_t *) bu_malloc(2*sizeof(fastf_t),"x[]");
y = (fastf_t *) bu_malloc(2*sizeof(fastf_t),"y[]");
z = (fastf_t *) bu_malloc(2*sizeof(fastf_t),"z[]");
}
l[0] = 0.0;
while(plen<maxlines){
i = (verbose) ? plen : plen%2;
j = (verbose) ? (plen-1) : (plen+1)%2;
num = scanf("%lf %lf %lf %lf",&end,x+i,y+i,z+i);
if (num<4)
break;
if(plen){
temp0 = x[i]-x[j];
temp1 = y[i]-y[j];
temp2 = z[i]-z[j];
l[plen] = sqrt(temp0*temp0+temp1*temp1+temp2*temp2);
l[plen] += l[plen-1];
} else {
start = end;
}
plen++;
}
time = end - start;
dist = l[plen-1];
if (query){
printf("%f\n",dist);
return(0);
}
if (time < DIVIDE_TOL){
fprintf(stderr,"anim_time: time too small. Only %f s.\n",time);
exit(-1);
}
if (dist < DIVIDE_TOL){
fprintf(stderr,"anim_time: pathlength too small. Only %f\n",dist);
exit(-1);
}
slope = dist/time;
switch (v0_set) {
case TIME_ABSOLUTE:
v0 = inv0;
break;
case TIME_RELATIVE:
v0 = slope*inv0;
break;
default:
case TIME_NONE:
v0 = slope;
break;
}
switch (v1_set) {
case TIME_ABSOLUTE:
v1 = inv1;
break;
case TIME_RELATIVE:
v1 = slope*inv1;
break;
default:
case TIME_NONE:
v1 = slope;
break;
}
if (v0<0.0) {
fprintf(stderr,"anim_time: Start velocity must be non-negative.\n");
exit(-1);
}
if (v1<0.0) {
fprintf(stderr,"anim_time: End velocity must be non-negative.\n");
exit(-1);
}
if (v0>3*slope) {
fprintf(stderr,"anim_time: Start velocity must be not be greater than %f units/s for this path.\n", 3.0*slope);
exit (-1);
}
if (v1>3*slope) {
fprintf(stderr,"anim_time: End velocity must not be greater than %f for this path.\n", 3.0*slope);
exit(-1);
}
a = ((v1+v0) - 2.0*slope)/(time*time);
b = (3*slope - (v1+2.0*v0))/time;
c = v0;
temp2 = 1.0/slope;
if (verbose) {
printf("%.12e\t%.12e\t%.12e\t%.12e\n",start,x[0],y[0],z[0]);
for (i=1; i<plen-1; i++){
temp0 = gettime(l[i],a,b,c,l[i]*temp2);
printf("%.12e\t%.12e\t%.12e\t%.12e\n",temp0+start,x[i],y[i],z[i]);
}
printf("%.12e\t%.12e\t%.12e\t%.12e\n",end,x[plen-1],y[plen-1],z[plen-1]);
} else {
printf("%.12e\n",start);
for (i=1; i<plen-1; i++){
temp0 = gettime(l[i],a,b,c,l[i]*temp2);
printf("%.12e\n",temp0+start);
}
printf("%.12e\n",end);
}
bu_free((char *) l, "l[]");
bu_free((char *) x, "x[]");
bu_free((char *) y, "y[]");
bu_free((char *) z, "z[]");
return( 0 );
}
/* code to read command line arguments*/
#define OPT_STR "ds:e:i:f:qm:v"
int get_args(argc,argv)
int argc;
char **argv;
{
int c;
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
switch(c){
case 's':
sscanf(bu_optarg,"%lf",&inv0);
v0_set = TIME_ABSOLUTE;
break;
case 'e':
sscanf(bu_optarg,"%lf",&inv1);
v1_set = TIME_ABSOLUTE;
break;
case 'i':
sscanf(bu_optarg,"%lf",&inv0);
v0_set = TIME_RELATIVE;
if ((inv0>3.0)||(inv0<0.0)) {
fprintf(stderr,"anim_time: -i argument must lie between 0.0 and 3.0\n");
exit(-1);
}
break;
case 'f':
sscanf(bu_optarg,"%lf",&inv1);
v1_set = TIME_RELATIVE;
if ((inv1>3.0)||(inv1<0.0)) {
fprintf(stderr,"anim_time: -f argument must lie between 0.0 and 3.0\n");
exit(-1);
}
break;
case 'q':
query = 1;
break;
case 'm':
sscanf(bu_optarg,"%d",&maxlines);
domem = 1;
break;
case 'v':
verbose = 1;
break;
case 'd':
debug = 1;
break;
default:
fprintf(stderr,"Unknown option: -%c\n",c);
return(0);
}
}
return(1);
}
+435
View File
@@ -0,0 +1,435 @@
.TH ANIM_TRACK 1 BRL/CAD
.SH NAME
anim_track - make an script to model or animate the pads and wheels of a
tracked vehicle.
.SH SYNOPSIS
.B
anim_track [options] wheelfile < in.table > out.script
.SH DESCRIPTION
.I anim_track
is designed to produce an animation script for the
animation of the track pads and/or the wheels which define the track.
Alternatively, track can output a file which produces a track model
when sourced by mged.
.PP
A track consists of a number of identical pads which
are wrapped in a chain around two or more ordered wheels. Normally, the
track is linear between the wheels. The exeption is that between the
first and last wheels, any extra track length is taken up in a hanging
caternary arc.
.PP
Anim_track requires two input files. The first, referred to above as
.BR wheelfile ,
is a table which
defines the initial track geometry by describing the wheels around which
the track is to be wrapped. The first three columns of the table give
the center point of the wheels, and the fourth column gives the radius
of each wheel. The table contains one line for each wheel; the
wheels should be listed in clockwise order as viewed from the right of
the vehicle. This is the direction that the track pads move around the
wheels when the vehicle is moving forward.
.PP
The track is part of a vehicle which has a front, back, left, right, up,
and down. By default these directions are +x, -x, +y, -y, +z, and -z,
respectively, but any orientation can be specified by the user with the
.B -b
option.
The track is always confined to a plane which has no left to right
variation; that is, the wheels can be in front of, behind, above, and
below each other, but may not be to the left or right of each other. If
the wheel positions specified in
.B wheelfile
do not lie in such a plane, then the first wheel defines the plane into
which all of the other wheels are projected.
.PP
The track pads are spread evenly along the entire length of the track.
The track segments between wheels are always linear, except for the
segment between the first and last wheels. If there is any extra track
length, it is taken up in a caternary arc which hangs down between the
first and last wheels. Thus if the the first wheel in
.B wheelfile
should be the top front wheel of the vehicle, and the last wheel in
.B wheelfile
should be the top back wheel of the vehicle. Depending on the track
length mode specified with the
.B -l
option, the caternary segment may or may not appear.
.PP
The second input file required by
.IR anim_track ,
referred to above as
.BR in.table ,
describes the state of the track in every frame of the animation. The
format of this second file can vary greatly according to the command-line
options. The first column of the file is ignored, but is expected to
contain the time values corresponding to each frame. Next come one or
more columns which specify directly or indirectly the distance that the
track has rolled around the wheels in each frame (see the
.BR -u ,
.BR -y ,
and
.B -s
options). Finally, the file may specify new wheel position for every
frame (see the
.B -v
option).
.PP
.SH MODEL REQUIREMENTS
Certain model conventions are needed in order for the animation to work
properly. First of all, if the wheels are to be animated, they must
all be named
.IR wheelname . i ,
where
.I i
ranges from 0 to one less than the number of wheels.
.I wheelname
is an arbitrary string.
.IR wheelname 0
must be
the top front wheel in a given track and
.IR wheelname (n-1)
must be the top
back wheel. The central axes of all the wheels should be parallel to
each other and perpendicular to a plane containing all of the wheel
centers.
.PP
The pads of the track should be identical instances or copies of a
prototype pad object, and they all should be named
.IR padname i,
where
.I i
ranges from 0 to one less than the number of pads.
The prototype pad should be centered on the origin in the x and y
directions. In the z direction, the inner, wheel-contacting surface of
the pad should lie on the z=0 plane. The outer, ground-contacting
surface should face the positive z-direction. The side of the pad which
would connect with the pad in front of it should face the positive x
direction, and the side which would connect with the pad behind it
should face the negative x direction. If the pads are a part of a higher
level combination, as they typically are, then the matrix between each
pad and the higher combination may be modified at will as long as the
prototype pad is not disturbed.
.SH OPTIONS
.TP
.B -p num_pads parent/basename
Animate the track pads. This option takes two arguments; the number of
pads in the track and a slash-separated path to the pad basename.
For
example, if there is a combination named "lpads" containing 80 track
pads with names ranging from "pad.0" to "pad.79", then the correct
arguments would be:
.sp
.B -p 79 lpads/pad.
.sp
Each frame of the output animation script will contain an animation
command for each of the track pads.
.TP
.B -w parent/basename
Animate the track wheels. This option takes one argument: a
slash-separated path to the wheel basename. The number of wheels is
obtained from the number of lines in the
.BR wheelfile .
If there is, for example, a combination named "rwheels" containing 4
wheels named wheel_0, wheel_1, wheel_2, and wheel_3, then the correct
argument is:
.sp
.B -w rwheels/wheel_
.sp
Each frame of the output animation script will contain an animation
command for each of the wheels.
.TP
.B \-b # # #
Specify the yaw, pitch, and roll of the vehicle's axes
with respect to the world axes. By default, the vehicle is assumed to
have a yaw, pitch, and roll of 0, and the track is therefore put into a
xz plane.
.TP
.B \-d # # #
Specify (in world coordinates) the centroid of the vehicle
of which the track is a part. By default, the vehicle is assumed
centered at the origin.
.TP
.B -u
User-specified track distance. The user
should provide, in the second column of
.IR in.table ,
the distance that the track should be rolled around the wheels in each
frame. This is the default.
.TP
.B -y
Derive the track distance from a table of position, yaw, pitch, and
roll. The second column through the seventh columns of the
.I in.table
should contain the position and orientation of the vehicle in every
frame. The distance that the track should be rolled around the wheels is
automatically calculated in every frame. If
.I anim_script
is being used with the same table to create the animaion script for the
vehicle itself, the
.B -b
and
.B -d
options to
.I anim_script
and
.I anim_track
should be the same.
.TP
.B -s
Derive the track distance from a table of positions, using automatic
steering. The second column through the fourth column of the
.I in.table
should contain the position of the vehicle in every frame. The distance
that the track should be rolled around the wheels is automatically
calculated in every frame, based on the assumption that the vehicle is
always steered to face the direction of motion.
If
.I anim_script
is being used with the same table to create the animaion script for the
vehicle itself, the
.B -b
and
.B -d
options to
.I anim_script
and
.I anim_track
should be the same.
.TP
.B -a
Enable anti-strobing measures. When the track is rolling fast enough, track
animations exhibit a strobing effect which may make the track appear to
slow down or rotate backwards. This is an artifact of the discrete time
nature of the animations, and occurs when the distance traveled by the
track in one frame is close to the pad length. If the
.B -a
option is selected,
.I anim_track
adds random jitter to the track's motion when the track speed is high
enough to cause strobing. This causes a motion blur effect rather than
strobing.
.TP
.B -v
Specify new wheel positions in every frame. This option allows dynamic
suspensions to be animated. If there are n wheels, then the last 2n
columns of
.I in.table
should contain the front-back and up-down coordinates of each wheel,
relative to the vehicle center and orientation specified with
.B -d
and
.BR -b .
The columns should be in pairs: The front-back coordinate of the first
wheel, followed by its up-down coordinate, followed by the front-back
coordinate of the second wheel, and so on.
.sp
If this option is not specified, then the wheel positions are fixed
throughout the animation.
.TP
.B -c
Calculate the track circumference, that is, the length of the shortest
track that can wrap around a given set of wheels. If the -v option is
specified, then
the output is a table containing the frame number and the track
circumference in each frame. Otherwise, a single value representing the
constant track circumference is returned.
.TP
.B -lm
Minimize the track length. With this option the length of the track is
set to the track circumference in every frame, ie the track shrinks to
fit the wheels.
.TP
.B -lf #
Specify a fixed track length. The argument specifies the track length, which
remains constant throughout the animation. If at any time the track
circumference exceeds the track length, the program is aborted and a
message is printed on standard error.
.TP
.B -ls #
Specify a stretchable track. The argument specifies the initial track
length. If at any time the track circumference exceeds the track length,
the track length is increased to meet the need. The track length never
decreases once it has been increased.
.TP
.B -le #
Specify an elastic track. The argument specifies the initial track
length. If at any time the track circumference exceeds the track length,
the track length is increased to meet the need. When the track
circumference decreases again, the track length also decreases, but it
never gets shorter than its original length.
.TP
.B -i #
Specify the initial offset of the track. By default, the first track pad
is initially placed at the point where the caternary arc meets the first
wheel. If an offset is specified, it represents the distance clockwise
around the track to from this point to the desired initiall point of
the first pad. This option is typically used to align the track pads
with drive wheel teeth.
.TP
.B -f #
Specify the integer with which to begin numbering the frames of the
animation script. The default is zero.
.TP
.B -r #
Specify the common radius of all the wheels. In this case, the fourth column
should be omitted from the
.BR wheelfile .
.TP
.B -g #
Instead of an animation script, create a file which can be sourced by
.I mged
to edit the track geometry. This will actually wrap the modeled pad
instances around the wheels.
The argument is the number of the frame which is to be emulated. For
example, to model the pads in the positions they will have in the first
frame of an animation, the specified frame number would be zero.
.TP
.B -mp command
Specify the animation matrix command to apply to the pads. The default
value is "rarc", meaning that the matrix between the pad and its parent
is replaced by a new matrix. See the
.I anim_script
man page for more information.
.TP
.B -mw command
Specify the animation matrix command to apply to the wheels. The default
value is "lmul", meaning that the new matrix is multiplied onto the left
of the old matrix between the pad and its parent combination. See the
.I anim_script
man page for more information.
.SH EXAMPLES
A typical use of
.I anim_track
would be to make an animation of a tank rolling across
bumpy ground. By some method (such as physical simulation)
you obtain the position of the center of
the tank and its orientation at each time. You also nead to obtain the
position of the each wheel relative to the vehicle center at each time.
All of this information is placed in
.BR in.table .
The model of the tank is stored in
model.g as a combination named "tank". Its centroid is at the
point (0,0,1005) and it faces the y-axis. An animation script for the
tank itself is created as follows:
.PP
anim_script -d 0 0 1005 -b 90 0 0 /tank < tank.table > tank.script
.PP
Here
.B tank.table
specifies the position and orientation of the tank in each frame; the
.B \-d
and
.B \-b
options specify the original position and orientation of the tank in the
database.
.PP
To create the model of the track, a prototype track pad is created,
centered on the origin in the x and y directions, with the
wheel-contacting surface face-down on the origin. The pad is 100mm
long and 5mm thick. Ninety-six instances of the pad are created, with names "rpad.0"
through "rpad.95", and grouped together in a combination called "rtrack".
.PP
Now, a file called
.B rwheelfile
is created, describing the positions and radii of the four wheels in the
right track:
.nf
1300 2000 1005 60
1300 1500 55 50
1300 -1500 55 50
1300 -2000 1005 60
.fi
Two roadwheels both have radius 50mm, while the idler and drivewheels
have a 60mm radius, and the wheels are named wh.0, wh.1, wh.2, and wh.3.
.PP
The following call checks the circumference of the track:
.nf
%> anim_track -c rwheelfile
9502.448956
.fi
The 96 100mm-long pads should be sufficient to wrap around the wheels,
leaving a shallow caternary arc between the idler and driver wheels.
.PP
The following call creates a file which can be used by
.I mged
to wrap the pads around the wheels in the model.
.nf
%> anim_track -g 0 -b 90 0 0 -d 0 0 100 -lf 9600 -p 96 rtrack/rpad.
rwheelfile <<EOF > rtrack.src
? 0 0
? EOF
.fi
In this case,
.I in.table
consisted of only one row and two columns. The two columns represented
time and the distance the track should be rolled from it's initial
position. The
.B -g
option was set to 0 since frame zero was the only frame in the
input table.
The changes are applied to the geometry in
.I mged
with the following command:
.nf
mged> source rtrack.src
.fi
The pads are now permanently modeled in their new positions.
.PP
In order to animate the pads and wheels, the following command would be
appropriate:
.PP
anim_track -p 96 rtrack/rpad. -w rwheel/wh. -d 0 0 1005 -b 90 0 0 -y -v -lf
9600 rwheelfile < in.table > rtrack.script
.PP
The in.table contains 15 columns specifying the time, the 3D position and
yaw, pitch, and roll of the vehicle, and the front-back and up-down
coordinates of each of the four wheels relative to the vehicle center.
For example, one row of
.B in.table
could be:
.PP
0.5 234.0 1415.6 1005 45 0 0 2000 0 1500 -950 -1500 -950 -2000 -10
.PP
This would specify the new position of the vehicle half of a second into
the animation, and indicate that
the first three wheels remained in their original positions
while the fourth wheel had dropped 10mm.
Note that the previous step (modeling) wasn't necessary in order for the
animation to work.
.PP
.B rtrack.script
by itself causes the wheels to move and rotate and the
pads to roll around them. When the entire tank, including to track,
is moved along across the ground by
.BR track.script ,
the full effect is acheived. The two scripts
could be combined
with a script for the left track, using
.IR script_sort ,
to make the complete script.
.PP
.SH BUGS
Tracks must have at least two wheels. The front edge of wheel.(n-1) must
stay behind the back edge of wheel.0, or the results are unpredictable.
(Usually a lot of NaN's on the output).
.SH SEE ALSO
anim_script(1)
.SH AUTHOR
Carl J. Nuzman
.SH COPYRIGHT
This software is Copyright (C) 1996 by the United States Army
in all countries except the USA. All rights reserved.
.SH "BUG REPORTS"
Reports of bugs or problems should be submitted via electronic
mail to <CAD@ARL.ARMY.MIL>.
+694
View File
@@ -0,0 +1,694 @@
/* A N I M _ T R A C K . C
*
* Animate the links and wheels of a tracked vehicle. Handles tracks that
* change in shape during the animation.
*
* Author -
* Carl J. Nuzman
*
* Source -
* The U. S. Army Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5068 USA
*
* Distribution Notice -
* Re-distribution of this software is restricted, as described in
* your "Statement of Terms and Conditions for the Release of
* The BRL-CAD Pacakge" agreement.
*
* Copyright Notice -
* This software is Copyright (C) 1993 by the United States Army
* in all countries except the USA. All rights reserved.
*/
#include "conf.h"
#ifdef USE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#include <math.h>
#include <stdio.h>
#include "machine.h"
#include "externs.h"
#include "vmath.h"
#include "raytrace.h"
#include "anim.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923
#endif
#define GIVEN 0
#define CALCULATED 1
#define STEERED 2
#define PRINT_ANIM 0
#define PRINT_ARCED 1
#define TRACK_MIN 0
#define TRACK_FIXED 1
#define TRACK_STRETCH 2
#define TRACK_ELASTIC 3
#define NW num_wheels
#define NEXT(i) (i+1)%NW
#define PREV(i) (i+NW-1)%NW
typedef double *pdouble;
struct wheel {
vect_t pos; /* displacement of wheel from vehicle origin */
fastf_t rad; /* radius of wheel */
fastf_t ang0; /* angle where track meets wheel 0<a<2pi*/
fastf_t ang1; /* angle where track leaves wheel 0<a<p2i */
fastf_t arc; /* radian length of contact between wheel and track 0<a<pi*/
};
struct track {
vect_t pos0; /* beginning point of track section */
vect_t pos1; /* end of track section */
vect_t dir; /* unit vector:direction of track section ending here*/
fastf_t len; /* length of track section ending here*/
};
struct slope {
vect_t dir; /* vector from previous to current axle*/
fastf_t len; /* length of vector above*/
};
struct all {
struct wheel w; /* parameters describing the track around a wheel */
struct track t; /* track between this wheel and the previous wheel */
struct slope s; /* vector between this axle and the previous axle */
};
/* external variables */
extern int bu_optind;
extern char *bu_optarg;
/* variables describing track geometry - used by main, trackprep, get_link*/
struct all *x;
fastf_t curve_a, curve_b, curve_c, s_start;
int num_links, num_wheels;
fastf_t track_y, tracklen, first_tracklen;
/* variables set by get_args */
int wheel_nindex; /* argv[wheel_nindex] = wheelname*/
int link_nindex; /* argv[link_nindex] = linkname*/
int print_wheel; /* flag: do wheel animation */
int print_link; /* flag: do link animation */
int print_mode; /* anim for rt or arced for mged */
int arced_frame; /* which frame to arced */
int axes, cent; /* flags: alternate axes, centroid specified */
int dist_mode; /* given, steered, or calculated */
int first_frame; /* integer to begin numbering frames */
fastf_t init_dist; /* initial distance of first link along track */
int one_radius; /* flag: common radius specified */
fastf_t radius; /* common radius of all wheels */
vect_t centroid, rcentroid; /* alternate centroid and its reverse */
mat_t m_axes, m_rev_axes; /* matrices to and from alternate axes */
char link_cmd[10]; /* default is "rarc" */
char wheel_cmd[10]; /* default is "lmul" */
int get_circumf; /* flag: just return circumference of track */
int read_wheels; /* flag: read new wheel positions each frame */
int len_mode; /* mode for track_len */
int anti_strobe; /* flag: take measures against strobing effect */
int
main(argc,argv)
int argc;
char **argv;
{
void anim_y_p_r2mat(), anim_add_trans(), anim_mat_print();
int get_args(), get_link(), track_prep(), val, frame, i, count;
int go;
fastf_t y_rot, distance, yaw, pch, roll;
vect_t cent_pos, wheel_now, wheel_prev;
vect_t zero, position, vdelta, temp, to_track, to_front;
mat_t wmat, mat_x;
FILE *stream;
struct wheel *wh;
int last_steer, last_frame;
int rndtabi=0;
fastf_t halfpadlen, delta, prev_dist;
VSETALL(zero,0.0);
VSETALL(to_track,0.0);
VSETALL(centroid,0.0);
VSETALL(rcentroid,0.0);
y_rot = 0.0;
num_wheels = 0;
last_steer = last_frame = 0;
MAT_IDN(mat_x);
MAT_IDN(wmat);
MAT_IDN(m_axes);
MAT_IDN(m_rev_axes);
if (!get_args(argc,argv))
fprintf(stderr,"Anim_track: Argument error.\n");
if (axes || cent ){ /* vehicle has own reference frame */
anim_add_trans(m_axes,centroid,zero);
anim_add_trans(m_rev_axes,zero,rcentroid);
}
/* get track information from specified file */
if (!(stream = fopen(*(argv+bu_optind),"r"))){
fprintf(stderr,"Track: Could not open file %s.\n",*(argv+bu_optind));
return(0);
}
num_wheels = -1;
if (one_radius) {
while (!feof(stream)) {
fscanf(stream,"%*f %*f %*f");
num_wheels++;
}
} else {
while (!feof(stream)) {
fscanf(stream,"%*f %*f %*f %*f");
num_wheels++;
}
}
rewind(stream);
/*allocate memory for track information*/
/* x: contains track geometry for the current frame */
x = (struct all *) calloc(num_wheels,sizeof(struct all));
/* wh: contains geometry of wheels in mged database */
wh = (struct wheel *) calloc(num_wheels,sizeof(struct wheel));
/*read original wheel positions*/
for (i=0;i<NW;i++){
fscanf(stream,"%lf %lf %lf", temp, temp+1, temp+2);
if (one_radius)
x[i].w.rad = radius;
else
fscanf(stream,"%lf",& x[i].w.rad);
MAT4X3PNT(x[i].w.pos,m_rev_axes,temp);
if (i==0)
track_y = x[0].w.pos[1];
else
x[i].w.pos[1] = track_y;
wh[i].pos[0] = x[i].w.pos[0];
wh[i].pos[1] = x[i].w.pos[1];
wh[i].pos[2] = x[i].w.pos[2];
wh[i].rad = x[i].w.rad;
}
(void) fclose(stream);
/* initialize to_track */
VSET(to_track, 0.0, track_y, 0.0);
VSET(to_front,1.0,0.0,0.0);
if (get_circumf&& (!read_wheels)) {
track_prep();
printf("%.10g\n",tracklen);
return(0);
}
if (dist_mode==STEERED) {
/* prime the pumps */
scanf("%*f");/*time*/
val = scanf("%lf %lf %lf", cent_pos, cent_pos+1, cent_pos + 2);
if (val < 3)
return(0);
go = anim_steer_mat(mat_x, cent_pos, 0);
last_steer = 0;
} else {
go = 1;
}
if (anti_strobe) {
BN_RANDSEED(rndtabi, 0);
}
/* main loop */
prev_dist = distance = 0.0;
frame = first_frame;
for ( ; ; frame++) {
if (dist_mode==GIVEN){
scanf("%*f");/*time*/
val = scanf("%lf",&distance);
if (val < 1) {
break;
}
}
else if (dist_mode==CALCULATED){
scanf("%*f");/*time*/
scanf("%lf %lf %lf", cent_pos, cent_pos+1, cent_pos+2);
val = scanf("%lf %lf %lf",&yaw,&pch,&roll);
if (val < 3)
break;
anim_dy_p_r2mat(mat_x,yaw,pch,roll);
anim_dy_p_r2mat(mat_x,yaw,pch,roll);
anim_add_trans(mat_x,cent_pos,rcentroid);
}
if (read_wheels) {
/* read in all wheel positions */
for(i=0;i<NW;i++){
val=scanf("%lf %lf",x[i].w.pos, x[i].w.pos + 2);
if (val < 2) {
break;
}
}
}
if (dist_mode==STEERED) {
scanf("%*f");/*time*/
val = scanf("%lf %lf %lf", cent_pos, cent_pos+1, cent_pos + 2);
if (val < 3){
if (last_steer)
break;
else
last_steer = 1;
}
go = anim_steer_mat(mat_x, cent_pos, last_steer);
anim_add_trans(mat_x,cent_pos,rcentroid);
}
/* call track_prep to calculate geometry of track */
if ((frame==first_frame)||read_wheels) {
if ((track_prep())==-1){
fprintf(stderr,"Track: error in frame %d: track too short.\n",frame);
break;
}
if (get_circumf) {
printf("%d\t%.10g\n",frame,tracklen);
}
}
if ((dist_mode==CALCULATED)||(dist_mode==STEERED)){
/*determine distance traveled*/
VMOVE(wheel_prev,wheel_now);
MAT4X3PNT(wheel_now,mat_x,to_track);
if (frame > first_frame){ /* increment distance by distance moved*/
VSUB2(vdelta,wheel_now,wheel_prev);
MAT3X3VEC(temp,mat_x,to_front);/*new front of vehicle*/
distance += VDOT(temp,vdelta);/*portion of vdelta in line with track*/
}
}
if (anti_strobe) {
halfpadlen = 0.5 * tracklen/(fastf_t) num_links;
delta = distance - prev_dist;
prev_dist = distance;
if ((delta >= halfpadlen)||(delta <= -halfpadlen)) {
distance += BN_RANDOM(rndtabi) * 2.0* halfpadlen;
}
}
if (go && (!get_circumf)) {
if (print_mode==PRINT_ANIM) {
printf("start %d;\nclean;\n", frame);
} else if (print_mode==PRINT_ARCED) {
if (frame != arced_frame) continue;
last_frame = 1;
}
if (print_link) {
for (count=0;count<num_links;count++){
(void) get_link(position,&y_rot,distance+tracklen*count/num_links+init_dist);
anim_y_p_r2mat(wmat,0.0,y_rot,0.0);
anim_add_trans(wmat,position,zero);
if (axes || cent){ /* link moved to vehicle coords */
MAT_MOVE(mat_x,wmat);
bn_mat_mul(wmat,m_axes,mat_x);
}
if (print_mode==PRINT_ANIM) {
printf("anim %s%d matrix %s\n", *(argv+link_nindex),count,link_cmd);
anim_mat_printf(stdout,wmat,"%.10g ","\n",";\n");
} else if (print_mode==PRINT_ARCED) {
printf("arced %s%d matrix %s ", *(argv+link_nindex),count,link_cmd);
anim_mat_printf(stdout,wmat,"%.10g ","","\n");
}
}
}
if (print_wheel){
for (count = 0;count<num_wheels;count++){
anim_y_p_r2mat(wmat,0.0,-distance/wh[count].rad,0.0);
VREVERSE(temp,wh[count].pos);
anim_add_trans(wmat,x[count].w.pos,temp);
if (axes || cent){
bn_mat_mul(mat_x,wmat,m_rev_axes);
bn_mat_mul(wmat,m_axes,mat_x);
}
if (print_mode==PRINT_ANIM) {
printf("anim %s%d matrix %s\n",*(argv+wheel_nindex),count,wheel_cmd);
anim_mat_printf(stdout,wmat,"%.10g ","\n",";\n");
} else if (print_mode==PRINT_ARCED) {
printf("arced %s%d matrix %s ",*(argv+wheel_nindex),count,wheel_cmd);
anim_mat_printf(stdout,wmat,"%.10g ","","\n");
}
}
}
if (print_mode==PRINT_ANIM)
printf("end;\n");
}
if (last_frame) break;
}
free(x);
free(wh);
return( 0 );
}
#define OPT_STR "sycuvb:d:f:i:r:p:w:g:m:l:a"
int get_args(argc,argv)
int argc;
char **argv;
{
int c, i;
fastf_t yaw, pch, rll;
void anim_dx_y_z2mat(), anim_dz_y_x2mat();
/* defaults*/
wheel_nindex = link_nindex = 0;
axes = cent = print_wheel = print_link = 0;
arced_frame = first_frame = 0;
init_dist = radius = 0.0;
one_radius = get_circumf = read_wheels = 0;
strcpy(link_cmd, "rarc");
strcpy(wheel_cmd, "lmul");
print_mode = PRINT_ANIM;
dist_mode = GIVEN;
len_mode = TRACK_MIN;
anti_strobe = 0;
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
i=0;
switch(c){
case 's':
dist_mode = STEERED;
break;
case 'y':
dist_mode = CALCULATED;
break;
case 'c':
get_circumf = 1;
break;
case 'u':
dist_mode = GIVEN;
break;
case 'v':
read_wheels = 1;
break;
case 'b':
bu_optind -= 1;
sscanf(argv[bu_optind+(i++)],"%lf", &yaw );
sscanf(argv[bu_optind+(i++)],"%lf", &pch );
sscanf(argv[bu_optind+(i++)],"%lf", &rll );
bu_optind += 3;
anim_dx_y_z2mat(m_axes, rll, -pch, yaw);
anim_dz_y_x2mat(m_rev_axes, -rll, pch, -yaw);
axes = 1;
break;
case 'd':
bu_optind -= 1;
sscanf(argv[bu_optind+(i++)],"%lf",centroid);
sscanf(argv[bu_optind+(i++)],"%lf",centroid+1);
sscanf(argv[bu_optind+(i++)],"%lf",centroid+2);
bu_optind += 3;
VREVERSE(rcentroid,centroid);
cent = 1;
break;
case 'f':
sscanf(bu_optarg,"%d",&first_frame);
break;
case 'i':
sscanf(bu_optarg,"%lf",&init_dist);
break;
case 'r':
sscanf(bu_optarg,"%lf",&radius);
one_radius = 1;
break;
case 'p':
sscanf(bu_optarg,"%d", &num_links);
link_nindex = bu_optind;
bu_optind += 1;
print_link = 1;
break;
case 'w':
wheel_nindex = bu_optind - 1;
/*sscanf(bu_optarg,"%s",wheel_name);*/
print_wheel = 1;
break;
case 'g':
sscanf(bu_optarg,"%d",&arced_frame);
print_mode = PRINT_ARCED;
break;
case 'm':
switch (*bu_optarg) {
case 'p':
strncpy(link_cmd,argv[bu_optind], 10);
break;
case 'w':
strncpy(wheel_cmd,argv[bu_optind], 10);
break;
default:
fprintf(stderr,"Unknown option: -m%c\n",*bu_optarg);
return(0);
}
bu_optind += 1;
break;
case 'l':
switch (*bu_optarg) {
case 'm':
len_mode = TRACK_MIN;
break;
case 'f':
len_mode = TRACK_FIXED;
sscanf(argv[bu_optind],"%lf",&first_tracklen);
tracklen = first_tracklen;
bu_optind++;
break;
case 's':
len_mode = TRACK_STRETCH;
sscanf(argv[bu_optind],"%lf",&first_tracklen);
tracklen = first_tracklen;
bu_optind++;
break;
case 'e':
len_mode = TRACK_ELASTIC;
sscanf(argv[bu_optind],"%lf",&first_tracklen);
tracklen = first_tracklen;
bu_optind++;
break;
default:
fprintf(stderr,"Unknown option: -l%c\n",*bu_optarg);
return(0);
}
break;
case 'a':
anti_strobe = 1;
break;
default:
fprintf(stderr,"Unknown option: -%c\n",c);
return(0);
}
}
return(1);
}
/* TRACK_PREP - Calculate the geometry of the track. Wheel positions and
* radii should already exist in the x[i] structs. Track_prep fills in the
* rest of the x[i] structs and also calculates values for curve_a, curve_b,
* curve_c, and s_start, which describe the caternary segment
* return values: 0 = GOOD
* -1 = BAD. Track too short to fit around wheels
*/
int track_prep()
{
int i;
fastf_t phi, costheta, arc_angle;
fastf_t linearlen, hyperlen;
vect_t difference;
int getcurve();
fastf_t hyper_get_s();
/* first loop - get inter axle slopes and start/end angles */
for (i=0;i<NW;i++){
/*calculate current slope vector*/
VSUB2(x[i].s.dir,x[i].w.pos,x[PREV(i)].w.pos);
x[i].s.len = MAGNITUDE(x[i].s.dir);
/*calculate end angle of previous wheel assuming all convex*/
phi = atan2(x[i].s.dir[2],x[i].s.dir[0]);/*absolute angle of slope*/
costheta = (x[PREV(i)].w.rad - x[i].w.rad)/x[i].s.len;/*cosine of special angle*/
x[PREV(i)].w.ang1 = phi + acos(costheta);
while (x[PREV(i)].w.ang1 < 0.0)
x[PREV(i)].w.ang1 += 2.0*M_PI;
x[i].w.ang0 = x[PREV(i)].w.ang1;
}
/* second loop - handle concavities */
for (i=0;i<NW;i++){
arc_angle = x[i].w.ang0 - x[i].w.ang1;
while (arc_angle < 0.0)
arc_angle += 2.0*M_PI;
if (arc_angle > M_PI) { /* concave */
x[i].w.ang0 = 0.5*(x[i].w.ang0 + x[i].w.ang1);
x[i].w.ang1 = x[i].w.ang0;
x[i].w.arc = 0.0;
}
else { /* convex - angles are already correct */
x[i].w.arc = arc_angle;
}
}
/* third loop - calculate geometry of straight track segments */
for (i=0;i<NW;i++){
/*calculate endpoints of track segment*/
x[i].t.pos1[0] = x[i].w.pos[0] + x[i].w.rad*cos(x[i].w.ang0);
x[i].t.pos1[1] = x[i].w.pos[1];
x[i].t.pos1[2] = x[i].w.pos[2] + x[i].w.rad*sin(x[i].w.ang0);
x[i].t.pos0[0] = x[PREV(i)].w.pos[0] + x[PREV(i)].w.rad*cos(x[PREV(i)].w.ang1);
x[i].t.pos0[1] = x[PREV(i)].w.pos[1];
x[i].t.pos0[2] = x[PREV(i)].w.pos[2] + x[PREV(i)].w.rad*sin(x[PREV(i)].w.ang1);
/*calculate length and direction of track segment*/
VSUB2(difference,x[i].t.pos1,x[i].t.pos0);
x[i].t.len = MAGNITUDE(difference);
VSCALE((x[i].t.dir),difference,(1.0/x[i].t.len));
}
/* calculate total track length used so far*/
linearlen = x[0].w.arc*x[0].w.rad;
for (i=1;i<NW;i++){
linearlen += x[i].t.len;
linearlen += x[i].w.arc*x[i].w.rad;
}
if (len_mode==TRACK_MIN) {
tracklen = linearlen + x[0].t.len;
curve_a = 0.0;
return(0); /* early return */
}
if (len_mode==TRACK_ELASTIC) {
tracklen = first_tracklen;
}
/* calculate geometry of hyperbolic segment */
hyperlen = tracklen - linearlen;
if(hyperlen < x[0].t.len){ /* desired length of hyperbola less than straight line*/
if((len_mode==TRACK_ELASTIC)||(len_mode==TRACK_STRETCH)){
tracklen += (x[0].t.len-hyperlen);
hyperlen = tracklen - linearlen;
}
else{
return(-1);/*bad, track is too short*/
}
}
getcurve(&curve_a,&curve_b,&curve_c,&(x[NW-1].w.ang1),&(x[0].w.ang0),hyperlen,x[NW-1].w.pos,x[0].w.pos,x[NW-1].w.rad,x[0].w.rad);
/* re-evaluate zeroth track section in light of curve information */
x[0].t.pos0[X] = x[NW-1].w.pos[X] + x[NW-1].w.rad * cos(x[NW-1].w.ang1);
x[0].t.pos0[Z] = x[NW-1].w.pos[Z] + x[NW-1].w.rad * sin(x[NW-1].w.ang1);
x[0].t.pos1[X] = x[0].w.pos[X] + x[0].w.rad * cos(x[0].w.ang0);
x[0].t.pos1[Z] = x[0].w.pos[Z] + x[0].w.rad * sin(x[0].w.ang0);
VSUB2(difference,x[0].t.pos1,x[0].t.pos0);
x[0].t.len = MAGNITUDE(difference);
VSCALE(x[0].t.dir,difference,(1.0/x[0].t.len));
if (curve_a > VDIVIDE_TOL)
s_start = hyper_get_s(curve_a, 0.0, x[0].t.pos0[X] - curve_c);
x[0].w.arc = x[0].w.ang0 - x[0].w.ang1;
if (x[0].w.arc<0.0)
x[0].w.arc += 2.0*M_PI;
x[NW-1].w.arc = x[NW-1].w.ang0 - x[NW-1].w.ang1;
if (x[NW-1].w.arc<0.0)
x[NW-1].w.arc += 2.0*M_PI;
return(0); /*good*/
}
/* GET_LINK - Find the position and angle of a link which is a given
* distance around the track, measured from the point where the caternary
* section meets wheel.0.
*/
int get_link(pos,angle_p,dist)
fastf_t *angle_p, dist;
vect_t pos;
{
int i;
vect_t temp;
fastf_t hyper_get_x(), hyper_get_z(), hyper_get_ang();
while (dist >= tracklen) /*periodicize*/
dist -= tracklen;
while (dist < 0.0)
dist += tracklen;
/* we want it to ignore the distance between wheel(n-1) and wheel(0)*/
dist += x[0].t.len;
for (i=0;i<NW;i++){
if ( (dist -= x[i].t.len) < 0 ){
VSCALE(temp,(x[i].t.dir),dist);
VADD2(pos,x[i].t.pos1,temp);
*angle_p = atan2(x[i].t.dir[2],x[i].t.dir[0]);
return(2*i);
}
if ((dist -= x[i].w.rad*x[i].w.arc) < 0){
*angle_p = dist/x[i].w.rad;
*angle_p = x[i].w.ang1 - *angle_p;/*from x-axis to link*/
pos[X] = x[i].w.pos[X] + x[i].w.rad*cos(*angle_p);
pos[Y] = x[i].w.pos[Y];
pos[Z] = x[i].w.pos[Z] + x[i].w.rad*sin(*angle_p);
*angle_p -= M_PI_2; /*angle of clockwise tangent to circle*/
return(2*i+1);
}
}
/* caternary section */
if ( curve_a > VDIVIDE_TOL){
pos[X] = hyper_get_x(curve_a, 0.0, s_start+dist);
pos[Y] = x[0].w.pos[Y];
pos[Z] = hyper_get_z(curve_a,curve_b,0.0, pos[X]);
pos[X] += curve_c;
*angle_p = hyper_get_ang(curve_a,curve_c, pos[X]);
}
else { /* practically linear */
VSCALE(temp,(x[0].t.dir),dist);
VADD2(pos,x[0].t.pos0,temp);
*angle_p = atan2(x[0].t.dir[Z],x[0].t.dir[X]);
}
return -1;
}
void show_info(which)/* for debugging - -1:track 0:both 1:link*/
int which;
{
int i;
if (which <=0){
fprintf(stderr,"track length: %f\n",tracklen);
fprintf(stderr,"link length: %f\n",tracklen/num_links);
for (i=0;i<NW;i++){
fprintf(stderr,"wheel %d: \n",i);
fprintf(stderr," pos\t%f\t%f\t%f\t\n",x[i].w.pos[X],x[i].w.pos[Y],x[i].w.pos[Z]);
fprintf(stderr," rad\t%f\tang0\t%f\tang1\t%f\tarc\t%f\n",x[i].w.rad,x[i].w.ang0,x[i].w.ang1,x[i].w.arc);
fprintf(stderr,"track %d: \n",i);
fprintf(stderr," pos0\t%f\t%f\tpos1\t%f\t%f\n",x[i].t.pos0[X],x[i].t.pos0[Z],x[i].t.pos1[X],x[i].t.pos1[Z]);
fprintf(stderr," dir\t%f\t%f\t%f\tlen\t%f\n",x[i].t.dir[X],x[i].t.dir[Y],x[i].t.dir[Z],x[i].t.len);
fprintf(stderr,"slope %d: %f %f %f %f\n",i,x[i].s.dir[0],x[i].s.dir[1],x[i].s.dir[2],x[i].s.len);
}
}
/* if (which >= 0){
fprintf(stderr,"%d %f %f %f %f\n",count,position[0],position[1],position[2],y_rot);
}*/
}
+95
View File
@@ -0,0 +1,95 @@
.TH ANIM_TURN 1 BRL/CAD
.SH NAME
anim_turn - make animation table for vehicle with front-wheel steering.
.SH SYNOPSIS
.B anim_turn -l length
.B [-a angle]
.B [-r radius]
.B [-f factor]
.B [-p integer]
.B < in.table
.B > out.table
.SH DESCRIPTION
The motion of a front wheel steered vehicle is not simple - the
instaneous velocity of the front wheels is in the direction they are
pointed, while the instantaneous velocity of the back wheels is the
direction the vehicle is pointed. The purpose of
.I anim_turn
is to
produce a complete animation table for such a vehicle, given a table
specifying the desired position of the front axle at each relevant
time step. The input table should contain four columns, specifying the
time and 3D position of the center of the front axle. Actually, the path
is assumed to be confined to an x-y plane, but the three columns are
included for consistency with other animation routines.
.PP
The output is normally a seven-column table which is a copy of
the input table with three extra columns specifying the yaw,
pitch, and roll of the truck at each time. The pitch and roll
are always zero, since the motion is assumed be in an x-y plane.
.PP
The
.B \-l#
option is not optional, and is used to specify the length
of the wheelbase (from the front axle to the rear axle).
.PP
.SH OPTIONS
.TP
.B \-a#
.I Track
assumes that the truck should initially be oriented
along the line defined by the first two positions in the input table.
Otherwise, the desired initial yaw of the truck can be specified with the
.B \-a#
option.
.TP
.B \-r#
Specify the radii of the front wheels. If this option is selected,
.I track
will create an animation script to animate the front wheels. The output
table would contain four columns: time, swivel-angle, roll, and a zero
channel. These represent the orientation of the front wheels, in terms
of yaw, pitch, and roll, and the table can be piped directly to
.IR anim_script .
.TP
.B \-f#
Specify a factor to be used to animate a steering wheel. If this option
is selected, the output table will contain four columns: time, swivel,
and two zero columns. This table can be used directly by
.I anim_script
to make an animation script for a steering wheel. The argument to the
option should be the factor by which to exagerate the swiveling of
the wheels. For
example, on a typical truck, you may need to turn the steering wheel 360
degrees in order for the wheels to swivel 20 degrees. To model this
effect, a factor of 18 would be used.
.TP
.B \-p#
Specify the ratio of input rows to output rows,
which must be an integer. The default, of course, is one. The accuracy
of the output depends on having a large number of input lines, which is
not usually a problem in animations, which require a large number of
frames per second. However, if a test animation with a small number of
frames per second is being created, the user should give an input table
with a high number of input rows and reduce the output with the
.B \-p#
option. For example, if
.B in.table
contains 30 rows for each second of the
animation, then the command
.sp
.B
anim_turn -l 3000 -p10 < in.table > out.table
.sp
would produce an animation table containing 3 rows for each second of
the animation.
.SH BUGS
The algorithm used only works for motion in an x-y plane.
.SH AUTHOR
Carl J. Nuzman
.SH COPYRIGHT
This software is Copyright (C) 1993 by the United States Army
in all countries except the USA. All rights reserved.
.SH "BUG REPORTS"
Reports of bugs or problems should be submitted via electronic
mail to <CAD@ARL.ARMY.MIL>.
+185
View File
@@ -0,0 +1,185 @@
/* A N I M _ T U R N . C
*
* Animate front-wheel steered vehicles.
*
* This is a filter which operates on animation tables. Given an
* animation table for the position of the front axle, anim_turn produces
* an animation table for position and orientation. Options provide for
* animating the wheels and/or steering wheel.
*
* Author -
* Carl J. Nuzman
*
* Source -
* The U. S. Army Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5068 USA
*
* Distribution Notice -
* Re-distribution of this software is restricted, as described in
* your "Statement of Terms and Conditions for the Release of
* The BRL-CAD Pacakge" agreement.
*
* Copyright Notice -
* This software is Copyright (C) 1993 by the United States Army
* in all countries except the USA. All rights reserved.
*/
#include "conf.h"
#include <math.h>
#include <stdio.h>
#include "machine.h"
#include "vmath.h"
#include "bu.h"
#include "anim.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
int get_args();
extern void anim_y_p_r2mat();
extern void anim_add_trans();
extern int bu_optind;
extern char *bu_optarg;
int print_int = 1;
int angle_set = 0;
int turn_wheels = 0;
fastf_t length, angle, radius;
fastf_t factor = 1.0;
int
main(argc,argv)
int argc;
char **argv;
{
int count;
fastf_t val, time, roll_ang, yaw,sign;
vect_t v, point, front, back, zero, temp1, temp2;
mat_t m_from_world, m_to_world;
double bn_atan2();
/* initialize variables */
VSETALL(zero, 0.0);
VSETALL( v , 0.0 );
VSETALL( point, 0.0 );
VSETALL( front, 0.0 );
VSETALL( back, 0.0 );
VSETALL( temp1, 0.0 );
VSETALL( temp2, 0.0 );
for( count=0 ; count<ELEMENTS_PER_MAT ; count++ )
m_from_world[count]=m_to_world[count]=0.0;
length = angle = radius = roll_ang = 0.0;
if (!get_args(argc,argv))
fprintf(stderr,"ascript: Get_args error");
if (!angle_set) { /* set angle if not yet done */
scanf("%*f%*[^-0123456789]");
VSCAN(temp1);
scanf("%*f%*[^-0123456789]");
VSCAN(temp2);
angle = bn_atan2( (temp2[1]-temp1[1]),(temp2[0]-temp1[0]) );
rewind(stdin);
}
count = 0;
while (1) {
/* read one line of table */
val = scanf("%lf%*[^-0123456789]",&time); /*read time,ignore garbage*/
val = scanf("%lf %lf %lf", point, point+1, point +2);
if (val < 3) {
break;
}
/*update to and from matrices */
if (count) { /* not first time through */
/* calculate matrices corrsponding to last position*/
anim_y_p_r2mat(m_to_world,angle,0.0,0.0);
anim_add_trans(m_to_world,front,zero);
anim_y_p_r2mat(m_from_world,-angle,0.0,0.0);
VREVERSE(temp1,front);
anim_add_trans(m_from_world,zero,temp1);
/* calculate new position for front and back axles */
/* front goes to the point, back slides along objects*/
/* current front to back axis */
MAT4X3PNT(v,m_from_world,point);/* put point in vehicle coordinates*/
if (v[1] > length) {
fprintf(stderr,"anim_turn: Distance between positions greater than length of vehicle - ABORTING\n");
break;
}
temp2[0] = v[0] - sqrt(length*length - v[1]*v[1]); /*calculate back*/
temp2[1] = temp2[2] = 0.0;
MAT4X3PNT(back,m_to_world,temp2);/*put "back" in world coordinates*/
VMOVE(front,point);
/*calculate new angle of vehicle*/
VSUB2(temp1,front,back);
angle = bn_atan2(temp1[1],temp1[0]);
}
else { /*first time through */
/*angle is already determined*/
VMOVE(front, point);
}
/*calculate turn angles and print table*/
if (turn_wheels){
if (v[0] >= 0)
sign = 1.0;
else
sign = -1.0;
yaw = bn_atan2(sign*v[1],sign*v[0]);
if (radius > VDIVIDE_TOL)
roll_ang -= sign * MAGNITUDE(v) / radius;
if (!(count%print_int))
printf("%.10g %.10g %.10g 0.0\n",time,factor*RTOD*yaw,RTOD*roll_ang);
}
else { /* print position and orientation of vehicle */
if (!(count%print_int))
printf("%.10g %.10g %.10g %.10g %.10g 0.0 0.0\n",time,front[0],front[1],front[2], RTOD * angle);
}
count++;
}
return( 0 );
}
#define OPT_STR "r:l:a:f:p:"
int get_args(argc,argv)
int argc;
char **argv;
{
int c;
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
switch(c){
case 'l':
sscanf(bu_optarg,"%lf",&length);
break;
case 'a':
sscanf(bu_optarg,"%lf",&angle);
angle *= DTOR; /* degrees to radians */
angle_set = 1;
break;
case 'r':
sscanf(bu_optarg,"%lf",&radius);
turn_wheels = 1;
break;
case 'f':
turn_wheels = 1;
sscanf(bu_optarg,"%lf",&factor);
break;
case 'p':
sscanf(bu_optarg,"%d",&print_int);
break;
default:
fprintf(stderr,"Unknown option: -%c\n",c);
return(0);
}
}
return(1);
}
+277
View File
@@ -0,0 +1,277 @@
/* C A T T R A C K . C
*
* Caternary curve routines used by anim_track.c
*
*/
#include "conf.h"
#include <math.h>
#include <stdio.h>
#include "machine.h"
#include "vmath.h"
#include "anim.h"
#define MAX_REACHED 0
#define SOLVED 1
/* the total maximum number of lowest level iterations possible is
* T_MAX_ITS*MAX_OUT_ITS*2*MAX_ITS
*/
#define MAX_ITS 25
#define MAX_OUT_ITS 25
#define T_MAX_ITS 50
/* these tolerances are guessed at, except that it seems to be important
* in elastic situations that T_TOL be significantly smaller than the others
*/
#define T_TOL 1.0e-14
#define G_TOL 1.0e-12
#define F_TOL 1.0e-12
/* HYPER_GET_X - get x value of a point which is a given distance along
* caternary curve.
* x(s) = arcsinh(a*s-sinh(a*c))/a + c
* Left to calling routine to avoid dividing by zero.
*/
fastf_t hyper_get_x(a,c, s, d, x, cos_ang)
fastf_t a, c; /* curve parameters */
fastf_t s; /* arclength value */
{
fastf_t arg, asinh_arg;
arg = a*s - sinh(a*c);
asinh_arg = log(arg + sqrt(arg*arg + 1.0));
return(asinh_arg/a + c);
}
/* HYPER_GET_S - calculate the arclength parameter of a caternary
* curve corresponding to the given value of x.
* s(x) = (sinh(a(x-c))+sinh(ac))/a
* Left to calling routime to avoid dividing by zero.
*/
fastf_t hyper_get_s(a, c, x)
fastf_t a, c, x;
{
return((sinh(a*(x-c))+sinh(a*c))/a);
}
/* HYPER_GET_Z - calculate point on the caternary curve:
* z(x) = cosh(a*(x-c))/a + b
* Left to calling routine to avoid dividing by zero.
*/
fastf_t hyper_get_z(a,b,c,x)
fastf_t a,b,c,x;
{
fastf_t z;
if (fabs(a)>VDIVIDE_TOL){
z = cosh(a*(x-c))/a + b;
} else {
z = b;
}
return(z);
}
/* HYPER_GET_ANG - calculate angle corresponding to the slope of
* caternary curve.
* z'(x) = sinh(a*(x-c))
*/
fastf_t hyper_get_ang(a,c,x)
fastf_t a,c,x;
{
fastf_t slope;
slope = sinh(a*(x-c));
return( atan2(slope, 1.0));
}
/* GET_CURVE - Find the constants a, b, and c such that the curve
* z = cosh(a*(x-c))/a + b
* is tangent to circles of radii r0 and r1 located at
* (x0,z0) and (x1,z1) and such that the curve has
* arclength delta_s between circles. Also find the angle where
* the curve touches each circle. When called successively,
* It uses the values of a,b, and c from the last call as a start.
*/
int getcurve(pa,pb,pc,pth0,pth1,delta_s, p_zero, p_one, r_zero, r_one)
fastf_t *pa, *pb, *pc; /* curve parameters */
fastf_t *pth0, *pth1; /* angle where curve contacts circle0,circle1 */
fastf_t delta_s; /* desired arclength */
fastf_t r_zero, r_one; /* radii of circle0 and circle1 */
vect_t p_zero, p_one; /* center of circle0 and circle1 */
{
int status, i, solved;
int ingetcurve();
fastf_t theta_one, theta_zero, new_theta_zero, new_theta_one;
fastf_t avg_theta_zero, avg_theta_one, arc_dist;
fastf_t tang_ang, costheta;
double stmp;
vect_t q_zero, q_one, diff;
static fastf_t last_a, last_c, last_theta_one, last_theta_zero;
static int called_before = 0;
/*first calculate angle at which tangent line would contact circles*/
VSUB2(diff,p_one,p_zero);
tang_ang = atan2(diff[Z],diff[X]);
costheta = (r_zero-r_one)/MAGNITUDE(diff);
tang_ang += acos(costheta);
if (!called_before){
theta_one = tang_ang;
theta_zero = tang_ang;
(*pa) = 1.0;
*pc = 0.5*(p_one[X]+p_zero[X]);
called_before = 1;
}
else {
theta_zero = last_theta_zero;
theta_one = last_theta_one;
*pa = last_a;
*pc = last_c;
}
status = MAX_REACHED;
for (i=0;i<T_MAX_ITS;i++){
q_zero[X] = p_zero[X] + r_zero * cos(theta_zero);
q_zero[Z] = p_zero[Z] + r_zero * sin(theta_zero);
q_one[X] = p_one[X] + r_one * cos(theta_one);
q_one[Z] = p_one[Z] + r_one * sin(theta_one);
/* determine distance taken by arc*/
arc_dist = r_zero * (tang_ang - theta_zero);
arc_dist += r_one * (theta_one - tang_ang);
ingetcurve(pa,pb,pc, delta_s-arc_dist, q_zero, q_one);
solved = 0;
/* refine theta_one */
stmp = sinh( (*pa)*(q_zero[X]-(*pc)) );
new_theta_zero = atan2(1.0,-stmp);
avg_theta_zero = 0.5 * (theta_zero + new_theta_zero);
if (fabs(theta_zero-avg_theta_zero)<T_TOL){
solved++;
}
theta_zero = avg_theta_zero;
/* refine theta_two */
stmp = sinh( (*pa)*(q_one[X]-(*pc)) );
new_theta_one = atan2(1.0,-stmp);
avg_theta_one = 0.5 * (theta_one + new_theta_one);
if (fabs(theta_one-avg_theta_one)<T_TOL){
solved++;
}
theta_one = avg_theta_one;
if (solved == 2){
status = SOLVED;
break;
}
}
last_theta_zero = theta_zero;
last_theta_one = theta_one;
last_a = *pa;
last_c = *pc;
*pth0 = theta_zero;
*pth1 = theta_one;
return(status);
}
/* INGETCURVE - find constants a, b, and c, such that the curve
* z = cosh(a*(x-c))/a + b
* passes through (x0,z0) and (x1,z1) and has arclength delta_s
* Appropriate first guesses for a,b, and c should be given.
*/
int ingetcurve(pa,pb,pc, delta_s, p_zero, p_one)
fastf_t *pa, *pb, *pc;
fastf_t delta_s;
vect_t p_zero, p_one;
{
int status, i, j, k;
fastf_t adjust;
fastf_t eff(),gee();
status = MAX_REACHED;
i=0;
while (i++<MAX_OUT_ITS){
for (j=0;j<MAX_ITS;j++){
adjust = eff(*pa,*pc,p_zero[X],p_one[X],delta_s);
if ((*pa-adjust)<=0.0){
*pa *= 0.5;
}
else {
*pa -= adjust;
}
if (adjust<F_TOL){
break;
}
}
for (k=0;k<MAX_ITS;k++){
adjust = gee(*pa,*pc,p_zero[X],p_one[X],(p_one[Z]-p_zero[Z]));
*pc -= adjust;
if (adjust<G_TOL){
break;
}
}
if ((j==0)&&(k==0)){
status = SOLVED;
break;
}
}
*pb = p_zero[Z] - cosh( (*pa)*(p_zero[X]-(*pc)) )/(*pa);
return(status);
}
/* find Newtonian adjustment for 'a', assuming 'c' fixed*/
fastf_t eff(a,c,x0,x1,delta_s)
fastf_t a,c,x0,x1,delta_s;
{
double f,fprime;
double arg0, arg1, sarg0, sarg1;
arg0 = a*(x0-c);
arg1 = a*(x1-c);
sarg0 = sinh(arg0);
sarg1 = sinh(arg1);
f = a*(sarg1-sarg0 - a*delta_s);
fprime = sarg0 - sarg1 - arg0*cosh(arg0) + arg1*cosh(arg1);
if (fabs(fprime) > VDIVIDE_TOL)
return(f/fprime);
else if ((a*a) > VDIVIDE_TOL)
return(f/(a*a));
else if (fabs(a) > VDIVIDE_TOL)
return(f/a);
else
return(f);
}
/* find Newtonian adjustment for c, assuming 'a' fixed*/
fastf_t gee(a,c,x0,x1,delta_z)
fastf_t a,c,x0,x1,delta_z;
{
double g, gprime, arg0, arg1;
arg0 = a*(x0-c);
arg1 = a*(x1-c);
g = cosh(arg1)-cosh(arg0) - a*delta_z;
gprime = a*(sinh(arg0) - sinh(arg1));
if (fabs(gprime) > VDIVIDE_TOL)
return(g/gprime);
else if (fabs(a) > VDIVIDE_TOL)
return(g/a);
else
return(g);
}
+68
View File
@@ -0,0 +1,68 @@
/* C H A N _ A D D . C
*
* Add a given value to specified columns of data.
*
* Author -
* Carl J. Nuzman
*
* Source -
* The U. S. Army Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5068 USA
*
* Distribution Notice -
* Re-distribution of this software is restricted, as described in
* your "Statement of Terms and Conditions for the Release of
* The BRL-CAD Pacakge" agreement.
*
* Copyright Notice -
* This software is Copyright (C) 1993 by the United States Army
* in all countries except the USA. All rights reserved.
*/
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
int
main(argc,argv)
int argc;
char **argv;
{
double addend, temp;
int i,j,doit, of, count, val, *col_list;
if (argc < 3) {
fprintf(stderr,"Usage: chan_add value num_columns column [column ...] < in.file > out.file\n");
return(-1);
}
sscanf(*(argv+1),"%lf",&addend);
sscanf(*(argv+2),"%d",&of);
col_list = (int *) calloc(argc-2,sizeof(int));
for (i=3;i<argc;i++){
sscanf(*(argv+i),"%d",col_list+(i-3));
}
count = 0;
while (!feof(stdin)){
val = scanf("%lf",&temp);
if (val<1)
;
else {
doit = 0;
for (j=0;j<argc-3;j++){
if (col_list[j]==count)
doit = 1;
}
if (doit)
printf("%.10g\t",temp + addend);
else
printf("%.10g\t",temp);
}
if ( count == (of-1))
printf("\n");
count = (count+1)%of;
}
return( 0 );
}
+49
View File
@@ -0,0 +1,49 @@
.TH CHAN_MULT 1 BRL/CAD
.SH NAME
chan_mult - multiply columns of data by a given factor
.PP
chan_add - add a given value to columns of data
.SH SYNOPSIS
chan_mult factor num_columns column [column column ...] < infile > outfile
.PP
chan_add value num_columns column [column column ...] < infile > outfile
.SH DESCRIPTION
.I Mult_chan
will multiply all numbers in the specified columns by the given
factor. The infile is
an ASCII file, with columns separeted by white space. The columns are
numbered from 0 to (n-1).
.I Add_chan
behaves analogously, but with
addition rather than multiplication.
.SH EXAMPLES
These routines are useful for converting between units in animation
tables.
.PP
To multiply all but the first column of a four column file by 2.54:
.PP
.B
chan_mult 2.54 4 1 2 3
.PP
To add ten to the first six columns of an eight-column file:
.PP
.B
chan_add 10.0 8 0 1 2 3 4 5
.PP
To convert the second of three columns from Fahrenheit to Celcius:
.PP
.B
chan_add -32 3 1
.br
.B
chan_mult 0.56 3 1
.SH BUGS
The files must contain numbers and whitespaces only.
.SH AUTHOR
Carl J. Nuzman
.SH COPYRIGHT
This software is Copyright (C) 1993 by the United States Army
in all countries except the USA. All rights reserved.
.SH "BUG REPORTS"
Reports of bugs or problems should be submitted via electronic
mail to <CAD@ARL.ARMY.MIL>.
+67
View File
@@ -0,0 +1,67 @@
/* C H A N _ M U L T . C
*
* Multiply specified columns of data by a given factor.
*
* Author -
* Carl J. Nuzman
*
* Source -
* The U. S. Army Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5068 USA
*
* Distribution Notice -
* Re-distribution of this software is restricted, as described in
* your "Statement of Terms and Conditions for the Release of
* The BRL-CAD Pacakge" agreement.
*
* Copyright Notice -
* This software is Copyright (C) 1993 by the United States Army
* in all countries except the USA. All rights reserved.
*/
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
int
main(argc,argv)
int argc;
char **argv;
{
double factor, temp;
int i,j,doit, of, count, val, *col_list;
if (argc < 4){
fprintf(stderr,"Usage: chan_mult factor num_columnss column [col ... ] < in.file > out.file\n");
return(-1);
}
sscanf(*(argv+1),"%lf",&factor);
sscanf(*(argv+2),"%d",&of);
col_list = (int *) calloc(argc-2,sizeof(int));
for (i=3;i<argc;i++){
sscanf(*(argv+i),"%d",col_list+(i-3));
}
count = 0;
while (!feof(stdin)){
val = scanf("%lf",&temp);
if (val<1)
;
else {
doit = 0;
for (j=0;j<argc-3;j++){
if (col_list[j]==count)
doit = 1;
}
if (doit)
printf("%.10g\t",temp*factor);
else
printf("%.10g\t",temp);
}
if ( count == (of-1))
printf("\n");
count = (count+1)%of;
}
return( 0 );
}
+70
View File
@@ -0,0 +1,70 @@
.TH CHAN_PERMUTE.C 1 BRL/CAD
.SH NAME
chan_permute - operate on columns of files.
.SH SYNOPSIS
.B chan_permute
.B -i infile1 id id ...
.B [-i infile2 id ...]
.B -o outfile1 id id ...
.B [-o outfile2 id ...]
.SH DESCRIPTION
This program mixes, matches, and merges ASCII files organized in
channels or columns. Each word, separated by whitespaces, should be less
than 40 characters long. The channels in each input file are specified
and then mapped to the desired channels in the output file(s). These are
the sort of things that can be done using
.I cut
and
.I paste,
but when
working on animation tables it's often nice to be able to do it in one
step.
.PP
.BR Infile s
are files to be read from,
.BR outfile s
are files to be written
to, and each
.B id
is a small positive integer identifying a channel. All of the
input
.BR id 's
should be distinct integers, or the results are not guaranteed.
.PP
.I Chan_permute
interprets
.B -i stdin
as standard input and
.B -o stdout
as
standard output.
.SH EXAMPLES
The command
.sp
chan_permute -i foo 0 1 2 -o stdout 2 1 0
.sp
reverses the order of foo's three columns and sends them to standard output.
.sp
.sp
The command
.sp
chan_permute -i file1 0 1 -i file2 2 3 -o file3 2 0 1 -o file4 3 0 1
.sp
creates file3 and file4, each containing one of the columns of file2
followed by both columns of file1.
.SH BUGS
A given file may be referenced
more than once for input, but may not be referenced for input and output
together or output and output together. In the latter case, the second
output reference overrides the other. The
.BR id 's
must be integers
somewhere between 0 and the number of arguments, inclusive.
.SH AUTHOR
Carl J. Nuzman
.SH COPYRIGHT
This software is Copyright (C) 1993 by the United States Army
in all countries except the USA. All rights reserved.
.SH "BUG REPORTS"
Reports of bugs or problems should be submitted via electronic
mail to <CAD@ARL.ARMY.MIL>.
+152
View File
@@ -0,0 +1,152 @@
/* C H A N _ P E R M U T E . C
*
* This program mixes, matches, and merges files organized in
* channels or columns.
* It's nothing cut and paste can't do, but sometimes it's nice to
* be able to do it in one step, especially when working with animation
* tables.
*Usage: channel -i infile1 id id id ... [-i infile2 ...] -o outfile1 id id ...
* [-o outfile2 ...]
*where infiles are files to be read from, outfiles are files to be written
*to, and each id is a small positive integer identifying a channel. All of the
*input id's should be distinct integers, or the results are not guaranteed.
*
* Author -
* Carl J. Nuzman
*
* Source -
* The U. S. Army Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5068 USA
*
* Distribution Notice -
* Re-distribution of this software is restricted, as described in
* your "Statement of Terms and Conditions for the Release of
* The BRL-CAD Pacakge" agreement.
*
* Copyright Notice -
* This software is Copyright (C) 1993 by the United States Army
* in all countries except the USA. All rights reserved.
*/
#include "conf.h"
#ifdef USE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#define MAXLEN 40
typedef char Word[MAXLEN];
struct unit {
FILE *file;
int channels;
short *list;
unsigned i_o; /*i=1 o=0*/
};
char ihead[] = "-i";
char ohead[] = "-o";
int
main(argc,argv)
int argc;
char **argv;
{
int i,j, maxlength,num_done;
int icount, ocount;
struct unit *x, *y;
Word *arrayd;
i=j=icount = ocount = maxlength = 0;
for(i=1;i<argc;i++){
if( !strncmp(argv[i],ihead,2) ){
j=0;
icount++;
}
else if( !strncmp(argv[i],ohead,2) ){
j=0;
ocount++;
}
else
maxlength = (++j>maxlength) ? j : maxlength;
}
y = (struct unit *) calloc(icount+ocount,sizeof(struct unit));
x = y - 1;
for(i=1;i<argc;i++){
if( !strncmp(argv[i],"-",1) ){
j=0;
x++;
x->list = (short *) calloc(maxlength,sizeof(short));
if (argv[i][1] == 'i'){
i++;
(x)->i_o = 1;
if ( ! strcmp(argv[i],"stdin") )
x->file = stdin;
else if ( !(x->file = fopen(argv[i],"r")) )
fprintf(stderr,"Channel: can't open %s\n",argv[i]);
}
else if (argv[i][1] == 'o'){
i++;
(x)->i_o = 0;
if ( ! strcmp(argv[i],"stdout") )
x->file = stdout;
else if ( !(x->file = fopen(argv[i],"w")) )
fprintf(stderr,"Channel: can't write to %s\n",argv[i]);
}
else{
fprintf(stderr,"Illegal option %c\n",argv[i][1]);
exit(-1);
}
}
else{
sscanf(argv[i],"%hd",x->list+(j++));
x->channels++;
}
}
arrayd = (Word *) calloc(argc,sizeof(Word));/*may use more memory than absolutely necessary*/
num_done = 0;
while(num_done < icount ){ /* go until all in files are done */
num_done = 0;
for (x=y;x<y+ocount+icount;x++){ /* do one line */
if(num_done >= icount)
;/*chill - all in files done */
else if (x->i_o == 1){
if(feof(x->file))
num_done += 1;
else
for(j=0;j<x->channels;j++)
fscanf(x->file,"%s ",arrayd[x->list[j]]);
}
else if (x->i_o == 0){
for(j=0;j<x->channels;j++)
fprintf(x->file,"%s\t",arrayd[x->list[j]]);
fprintf(x->file,"\n");
}
}
}
free(arrayd);
for (x=y;x<y+ocount+icount;x++){
free(x->list);
}
free(y);
exit(0);
}
int max(m,n) /*return greatest of n integers, unless one is greater than n*/
int m[],n;
{
int i,j;
j = 0;
for (i=0;i<n;i++){
j = (m[i]>j) ? m[i] : j;
}
return( (j>n) ? 0 : j );
}
+51
View File
@@ -0,0 +1,51 @@
This is awf, the Amazingly Workable Formatter -- a "nroff -man" or
(subset) "nroff -ms" clone written entirely in (old) awk.
It is slow and has many restrictions, but does a decent job on most
manual pages and simple -ms documents, and isn't subject to AT&T's
brain-damaged licensing that denies many System V users any text
formatter at all. It is also a text formatter that is simple enough
to be tinkered with, for people who want to experiment.
Type "make r" to run a regression test, formatting the manual page
(awf.1) and comparing it to a preformatted copy (awf.1.out). Type
"make install" to install it. Pathnames may need changing.
I don't know whether awf will run on 16-bit machines. Data requirements
are modest, but I fear the programs are probably big enough to run awk
out of space.
I can't believe I really wrote this.
Henry Spencer at U of Toronto Zoology
henry@zoo.toronto.edu utzoo!henry
13 July 1990
/*
* Copyright 1990 University of Toronto. All rights reserved.
* Written by Henry Spencer.
* This software is not subject to any license of the American Telephone
* and Telegraph Company or of the Regents of the University of California.
*
* Permission is granted to anyone to use this software for any purpose on
* any computer system, and to alter it and redistribute it freely, subject
* to the following restrictions:
*
* 1. The author is not responsible for the consequences of use of this
* software, no matter how awful, even if they arise from flaws in it.
*
* 2. The origin of this software must not be misrepresented, either by
* explicit claim or by omission. Since few users ever read sources,
* credits must appear in the documentation.
*
* 3. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software. Since few users
* ever read sources, credits must appear in the documentation.
*
* 4. This notice may not be removed or altered.
*/
As required by the above notice, you are informed that this software
has been slightly modified to become the formatter for the fallback
manual-page reading software for the BRL-CAD Package.
If you wish an unmodified copy of AWF, you should contact the original
author at the address above.
+35
View File
@@ -0,0 +1,35 @@
/*
* awf/Cakefile
*
* The actual formatter is located in "../brlman", because it needs to
* be installed in BINDIR.
*
* Note: The file "brlman/awf" needs to be modified when the definition of
* ETCDIR is changed.
*/
#include "../Cakefile.defs"
#define PRODUCTS common dev.dumb mac.man mac.ms \
pass1 pass2.base pass2.man pass2.ms pass3 \
AWF_COPYRIGHT
#define SRCDIR awf
#undef BINDIR
#define BINDIR ETCDIR
#undef BINPERM
#define BINPERM MANPERM
#define FILES /**/
#define SRCSUFF /**/
#define MANSECTION 1
#define STATIC_PRODUCTS PRODUCTS /* Force PRODUCTS into dist */
/*
* There is nothing to compile.
* The "install-prod" rule should install PRODUCTS,
* and "inst-dist" rule should take care of copying to distribution dir.
* Nothing else to do.
*/
all&:
@echo "SRCDIR: all done"
#include "../Cakefile.rules"
+212
View File
@@ -0,0 +1,212 @@
.\" Some of the stuff in this file is a bit contorted, because it's also
.\" the regression-test input.
.nr ES 5n
.de ES
.PP
.in +\\n(ESu
.nf
..
.de EE
.in -\\n(ESu
.fi
.PP
..
.de PT
.ie \\n(.$>1 .TP "\\$2"
.el .TP
.ie !'\\$1'' \\$1
.el \(bu
..
.ds Nr \fInroff\fR
.TH AWF 1 "13 July 1990"
.BY "U of Toronto"
.SH NAME
awf \- amazingly workable (text) formatter
.SH SYNOPSIS
.B awf
.BI \-m acros
[ file ] ...
.SH DESCRIPTION
.if t .tm OOPS -- AWF THINKS IT'S TROFF!!!
.I Awf
formats the text from the input \fIfile\fR(s)
(standard input if none)
in an imitation of
\*(Nr's style with the \fB\-man\fR or \fB\-ms\fR macro packages.
The
.BI \-m acro
option is mandatory and must be `\-man' or `\-ms'.
.PP
.I Awf
implements the following raw \*(Nr requests:
.LP
.\e" .ce .fi .in .ne .pl .sp
.ad .de .ft .it .nf .po .ta
.bp .ds .ie .ll .nr .ps .ti
.br .el .if .na .ns .rs .tm
.LP
and the following in-text codes:
.ES
\e$ \e% \e* \ec \ef \en \es
.EE
plus the full list of \*(Nr/\c
.I troff
special characters in
the original V7 \fItroff\fR manual.
.PP
Many restrictions are present; the behavior in general is a subset of
\*(Nr's. Of particular note are the following:
.IP \(bu 2
Point sizes do not exist;
.B .ps
and
.B \es
are ignored.
.PT
Conditionals implement only numeric comparisons on
.BR \en(.$ ,
string com\%par\%isons between a macro parameter and a literal,
and
.B n
(always true)
and
.BR t
(always false).
.PT
The implementation of strings is generally primitive.
.IP \(bu
Expressions in (e.g.)\&
.B .sp
are fairly general, but the
.BR | ,
.BR & ,
and
.BR :\&
operators do not exist, and the implementation of
.B \ew
requires that quote (') be used as the delimiter and
simply counts the characters inside (so that, e.g.,
\ew'\e(bu'
equals 4).
.P
White space at the beginning of lines,
and imbedded white space within lines, is dealt with properly.
Sentence terminators at ends of lines are understood to imply
extra space afterward in filled lines.
Tabs are im\%plemented crudely and not quite correctly, although
in most cases they work as expected.
Hyphenation is done only at explicit hyphens, em-dashes, and \*(Nr
discretionary hyphens.
.SH "MAN MACROS"
The
.B \-man
macro set implements the full V7 manual macros,
plus a few semi-random oddballs.
The full list is:
.ES
\&.B .DT .IP .P .RE .SM
\&.BI .HP .IR .PD .RI .TH
\&.BR .I .LP .PP .RS .TP
\&.BY .IB .NB .RB .SH .UC
.EE
.B .BY
and
.B .NB
each take a single string argument (respectively, an indi\%cation of
authorship and a note about the status of the manual page) and arrange
to place it in the page footer.
.SH "MS MACROS"
The
.B \-ms
macro set is a substantial subset of the V7 manuscript macros.
The implemented macros are:
.ES
\&.AB .CD .ID .ND .QP .RS .UL
\&.AE .DA .IP .NH .QS .SH .UX
\&.AI .DE .LD .NL .R .SM
\&.AU .DS .LG .PP .RE .TL
\&.B .I .LP .QE .RP .TP
.EE
Size changes are recognized but ignored, as are
.B .RP
and
.BR .ND .
.B .UL
just prints its argument in italics.
.BR .DS / .DE
does not do a keep,
nor do any of the other macros that normally imply keeps.
.PP
Assignments to the header/footer string variables are recognized and
implemented, but there is otherwise no control over header/footer
formatting.
The
.B DY
string variable is available.
The
.BR PD ,
.BR PI ,
and
.BR LL
number registers exist and can be changed.
.SH OUTPUT
The only output format supported by
.IR awf ,
in its distributed form,
is that appropriate to a dumb terminal,
using overprinting for italics (via underlining) and bold.
The \*(Nr special characters are printed as some vague approximation
(it's sometimes very vague) to their correct appearance.
.PP
.IR Awf 's
knowledge of the output device is established by a device file,
which is read before the user's input.
It is sought in
.IR awf 's
library directory, first as
.BI dev. term
(where \fIterm\fR is the value of the TERM environment variable)
and, failing that, as
.BR dev.dumb .
The device file
uses special internal commands
to set up resolution, special characters, fonts, etc.,
and more normal \*(Nr commands to set up page length etc.
.SH FILES
All in \fI/usr/lib/awf\fR (this can be overridden by the AWFLIB
environment variable):
.ta \w'pass2.base'u+((3n-1n)/2u)
.nf
common common device-independent initialization
dev.* device-specific initialization
mac.m* macro packages
pass1 macro substituter
pass2.base central formatter
pass2.m* macro-package-specific bits of formatter
pass3 line and page composer
.SH SEE ALSO
awk(1), nroff(1), man(7), ms(7)
.SH DIAGNOSTICS
.na
Unlike
.IR nroff ,
.I awf
complains whenever it sees unknown commands and macros.
All diagnostics (these and some internal ones) appear on standard error
at the end of the run.
.ad
.SH HISTORY
Written at University of Toronto by Henry Spencer,
more or less as a supplement to the C News project.
.LP
.ce 99
\(rh None of the above really want to admit it. \(lh
.ce 0
.SH BUGS
There are plenty, but what do you expect for a text formatter
written entirely in (old) \fIawk\fR?
.PP
The
.B \-ms
stuff has not been checked out very thoroughly.
+7
View File
@@ -0,0 +1,7 @@
.\" Common startup code, fully device-independent.
.\" --------------------------------
.fi
.ce 0
.ta +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5
.in 0
.ti 0
+154
View File
@@ -0,0 +1,154 @@
.\" Device-dependent but not macro-set-dependent definitions.
.\" --------------------------------
.\" overall formatting initialization
.\" 12 cpi horizontal exploits 80-column terminal well (6.5i@12 = 78)
.^r cpi 12 6
.\" call margin adjustment device-dependent for sake of some unusual cases
.ad
.\" page parameters
.pl 11i
.ll 6.5i
.po 0
.\" --------------------------------
.\" fonts, and their hyphens, last font change doubled to set up \fP
.^f R
.ft R
.^c hy 1 -
.^f I
.ft I
.^c hy 1 -
.^f B
.ft B
.^c hy 1 -\b-\b-
.ft R
.ft R
.\" --------------------------------
.\" definitions of nroff special characters
.\" The character definitions here operate on the "better ugly than invisible"
.\" principle, and try to approximate the character *somehow*. They were
.\" tuned for a Teletype 40 line printer, but should give vaguely plausible
.\" results on any overprinting ASCII device.
.\"
.\" first, things that nroff considered builtins
.^c \ 1 \\
.^c e 1 \\
.^c ' 1 '
.^c ` 1 `
.^c - 1 -
.\" some things seem to assume that \+ is like \-
.^c + 1 +
.\" we do not do backslash-space here, it can't be done with .^c, but the
.\" other forms of space we can do
.^c 0 1 "
.^c | 0
.^c ^ 0
.^c & 0
.\"
.\" and more normal characters
.\" note, the hyphenation logic knows about em
.^c em 2 --
.\" hy is a special case, see above
.^c bu 1 +\bo
.^c sq 2 []
.^c ru 1 _
.^c 12 3 1/2
.^c 14 3 1/4
.^c 34 3 3/4
.^c de 1 '\b`
.^c dg 1 -\b!
.^c fm 1 '
.^c ct 1 /\bc
.^c rg 3 (R)
.^c co 3 (c)
.^c pl 1 +
.^c mi 1 -
.^c eq 1 =
.^c ** 1 *
.^c sc 1 j\bf
.^c aa 1 '
.^c ga 1 `
.^c ul 1 _
.^c sl 1 /
.^c *a 1 <\ba
.^c *b 1 ,\bB
.^c *g 1 ,\by
.^c *d 1 S\bo
.^c *e 1 -\bc
.^c *z 1 ,\bL
.^c *y 1 ,\bn
.^c *h 1 -\b0
.^c *i 1 ,\bi
.^c *k 1 <\bK
.^c *l 1 \\\b>
.^c *m 1 ,\bu
.^c *n 1 ,\bv
.^c *c 1 ,\b3
.^c *o 1 o
.^c *p 1 -\bn
.^c *r 1 p
.^c *s 1 -\bo
.^c ts 1 s
.^c *t 1 ~\bt
.^c *u 1 u
.^c *f 1 /\bo
.^c *x 1 /\b\\
.^c *q 1 |\bu
.^c *w 1 u\bw
.^c *G 2 ~\b|~
.^c *D 2 _\b/_\b\\
.^c *H 1 -\bO
.^c *L 2 /\\
.^c *C 1 _\b-\b~
.^c *P 2 ~\b|~\b|
.^c *S 1 ~\b_\b>
.^c *U 1 Y
.^c *F 1 |\bO
.^c *Q 1 |\bU
.^c *W 2 _\b(_\b)
.^c sr 2 \\/
.^c rn 1 ~
.^c >= 1 _\b>
.^c <= 1 _\b<
.^c == 1 _\b=
.^c ~= 1 ~\b=
.^c ap 1 ~
.^c != 1 /\b=
.^c -> 2 ->
.^c <- 2 <-
.^c ua 1 |\b^
.^c da 1 |\bv
.^c mu 1 x
.^c di 1 -\b:
.^c +- 1 _\b+
.^c cu 1 U
.^c ca 3 (^)
.^c sb 2 (_\b~
.^c sp 2 _\b~)
.^c ib 2 (~\b_\b=
.^c ip 2 ~\b_\b=)
.^c if 2 oo
.^c pd 1 3\bo
.^c gr 1 ~\bV
.^c no 1 -
.^c is 1 '\b,\bI
.^c pt 2 oc
.^c es 1 /\bO
.^c mo 1 -\bC
.^c br 1 |
.^c dd 1 I\b|
.^c rh 1 =\b>
.^c lh 1 =\b<
.^c bs 4 (:-)
.^c or 1 |
.^c ci 1 O
.^c lt 1 ~\b(
.^c lb 1 _\b(
.^c rt 1 ~\b)
.^c rb 1 _\b)
.^c lk 1 -\b(
.^c rk 1 -\b)
.^c bv 1 |
.^c lf 1 _\b[
.^c rf 1 _\b]
.^c lc 1 ~\b[
.^c rc 1 ~\b]
+141
View File
@@ -0,0 +1,141 @@
.\"-----------------
.de TH
.ds LH "\\$1(\\$2)
.ds CH "Unix Programmer's Manual
.ds RH "\\$1(\\$2)
.ds LF "
.ds CF "\\$3
.ds RF "%
..
.\"-----------------
.de NB
.ds nb "\\$1
.lF
..
.\"-----------------
.de BY
.ds by "\\$1
.lF
..
.\"-----------------
.de UC
.BY "\\$1BSD"
..
.\"-----------------
.\" common initialization for headers and paragraphs: .In need
.de In
.ne \\$1
.sp \\n(PDu
.fi
.in \\n(inu
.ti 0
.it
.ft R
.ns
..
.\"-----------------
.de SH
.In 6
.in 0
.ft B
\&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
.ft R
.nr in 5n
.in \\n(inu
..
.\"-----------------
.de LP
.In 4
..
.\"-----------------
.de PP
.LP
..
.\"-----------------
.de P
.LP
..
.\"-----------------
.de HP
.In 4
.ti 0-\\n(tpu
..
.\"-----------------
.de TP
.In 4
.if \\n(.$>0 .nr tp \\$1n
.in \\n(inu+\\n(tpu
.ti 0-\\n(tpu
.it 1 tP
..
.\"-----------------
.de IP
.ie \\n(.$>1 .TP "\\$2"
.el .TP
\&\\$1
..
.\"-----------------
.de I
.ft I
.it 1 fP
.if \\n(.$>0 \&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
..
.\"-----------------
.de B
.ft B
.it 1 fP
.if \\n(.$>0 \&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
..
.\"-----------------
.de IR
\&\\fI\\$1\\fR\\$2\\fI\\$3\\fR\\$4\\fI\\$5\\fR\\$6\\fI\\$7\\fR\\$8\\fI\\$9\\fR
..
.\"-----------------
.de RI
\&\\$1\\fI\\$2\\fR\\$3\\fI\\$4\\fR\\$5\\fI\\$6\\fR\\$7\\fI\\$8\\fR\\$9
..
.\"-----------------
.de BR
\&\\fB\\$1\\fR\\$2\\fB\\$3\\fR\\$4\\fB\\$5\\fR\\$6\\fB\\$7\\fR\\$8\\fB\\$9\\fR
..
.\"-----------------
.de RB
\&\\$1\\fB\\$2\\fR\\$3\\fB\\$4\\fR\\$5\\fB\\$6\\fR\\$7\\fB\\$8\\fR\\$9
..
.\"-----------------
.de BI
\&\\fB\\$1\\fI\\$2\\fB\\$3\\fI\\$4\\fB\\$5\\fI\\$6\\fB\\$7\\fI\\$8\\fB\\$9\\fR
..
.\"-----------------
.de IB
\&\\fI\\$1\\fB\\$2\\fI\\$3\\fB\\$4\\fI\\$5\\fB\\$6\\fI\\$7\\fB\\$8\\fI\\$9\\fR
..
.\"-----------------
.de SM
.\" no-op
.if \\n(.$>0 \&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
..
.\"-----------------
.de DT
.ta +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5
..
.\"-----------------
.de RS
.in +5n
..
.\"-----------------
.de RE
.in -5n
..
.\"-----------------
.de PD
.ie \\n(.$=0 .nr PD 0.3v
.el .nr PD \\$1n
..
.\"-----------------
.\" misc. initialization
.nr tp 5n
.PD
.ds R \(rg
.ds S "
.ds Tm (TM)
+206
View File
@@ -0,0 +1,206 @@
.\"-----------------
.de R
.ie \\n(.$=0 .ft R
.el \\fR\\$1\\fP\\$2
..
.\"-----------------
.de I
.ie \\n(.$=0 .ft I
.el \\fI\\$1\\fP\\$2
..
.\"-----------------
.de B
.ie \\n(.$=0 .ft B
.el \\fB\\$1\\fP\\$2
..
.\"-----------------
.de UX
.\" old-fashioned capitalization -- I've never gotten used to the new one
\\$2Unix\\$1
..
.\"-----------------
.de DA
.ds DY "\\$1 \\$2 \\$3
.\" keep trailing spaces out of CF
.if \\n(.$=1 .ds CF "\\$1
.if \\n(.$=2 .ds CF "\\$1 \\$2
.if \\n(.$>2 .ds CF "\\$1 \\$2 \\$3
..
.\"-----------------
.de ND
.\" it's our default, ignore it
..
.\"-----------------
.de TL
.rs
.sp 5
.ft B
.ce 9999
..
.\"-----------------
.de AU
.sp 2
.ft R
..
.\"-----------------
.de AI
.sp
.ft R
..
.\"-----------------
.de AB
.sp 2
.ce 0
.ll -7n
.in +7n
..
.\"-----------------
.de AE
.sp
.ll
.in
..
.\"-----------------
.\" common initialization for headers and paragraphs: .In need extraspace
.de In
.ne \\$1
.sp \\n(Tsu
.nr Ts 0
.ie \\n(.$>1 .nr iN \\$2v
.el .nr iN 0
.sp \\n(PDu+\\n(iNu
.ce 0
.ft R
.in \\n(inu
.ll \\n(LLu
.ns
.fi
.ti 0
..
.\"-----------------
.de SH
.nr in 0
.In 6 1
.ft B
..
.\"-----------------
.de NH
.nr in 0
.In 6 1
.ft B
.\" punt to awk code to get the header numbering right
.nH \\$1
.\" and pick up the result
\&\\*(Nh
..
.\"-----------------
.de LP
.In 4
..
.\"-----------------
.de PP
.In 4
.ti \\n(PIu
..
.\"-----------------
.de TP
.In 4
.if \\n(.$>0 .nr tp \\$1n
.in \\n(inu+\\n(tpu
.ti 0-\\n(tpu
.it 1 tP
..
.\"-----------------
.de IP
.ie \\n(.$>1 .TP "\\$2"
.el .TP
\&\\$1
..
.\"-----------------
.de QP
.In 4
.in +5n
.ll -5n
..
.\"-----------------
.de QS
.nr in +5n
.nr LL -5n
.In 4
..
.\"-----------------
.de QE
.nr in -5n
.nr LL +5n
.In 4
..
.\"-----------------
.de DS
.In 5
.if '\\$1'C' .ce 9999
.if '\\$1'' .in +5n
.nf
..
.\"-----------------
.de CD
.In 5
.ce 9999
.nf
..
.\"-----------------
.de LD
.In 5
.nf
..
.\"-----------------
.de ID
.In 5
.in +5n
.nf
..
.\"-----------------
.de DE
.In 3
..
.\"-----------------
.de RS
.nr in +5n
.in \\n(inu
..
.\"-----------------
.de RE
.nr in -5n
.in \\n(inu
..
.\"-----------------
.de UL
\&\\fI$1\\fP
..
.\"-----------------
.de RP
..
.\"-----------------
.de LG
..
.\"-----------------
.de SM
..
.\"-----------------
.de NL
..
.\"-----------------
.\" the -ms accent strings
.ds ' "'\b
.ds ` "`\b
.ds : ":\b
.ds ^ "^\b
.ds ~ "~\b
.ds C "v\b
.ds , ",\b
.\" post-title spacing
.nr Ts 4v
.\" and parameter setup
.nr LL 6i
.ll \n(LLu
.nr PD 0.3v
.nr PI 5n
+212
View File
@@ -0,0 +1,212 @@
# first pass: macro expansion and .if
# We support macros, conditionals (of three quite limited forms), and macro
# argument substitution.
BEGIN {
curmacro = ""
macros[""] = 0 # just to make it an array
macrolen[""] = 0 # just to make it an array
macrotext[0] = "" # just to make it an array
args[""] = "" # just to make it an array
ntext = 1 # first slot in macrotext; cannot be 0
nroffset = 0 # offset between NR and "real" line numbers
inname = "?" # input filename
sp = 0 # stack "pointer" (number of stacked macros)
maxsp = 25 # limit on nesting depth
macrostack[sp] = "" # to make it an array
nleftstack[sp] = "" # to make it an array
ptrstack[sp] = "" # to make it an array
nargstack[sp] = "" # to make it an array
argstack[sp] = "" # to make it an array
condstack[sp] = "" # to make it an array
}
/^\.\^#/ { # filename and line no of next line: .^# no fn
nroffset = (NR+1) - $2
inname = $3
print
next
}
/^\.de/ { # macro start
curmacro = "." $2
macros[curmacro] = ntext
macrostart = ntext
next
}
curmacro != "" && $0 !~ /^\.\.$/ { # macro text - \\ becomes \
if ($0 !~ /\\/) # quick case, no backslashes
line = $0
else {
line = ""
for (n = 1; n <= length; n++) {
if (substr($0, n, 2) == "\\\\")
n++
line = line substr($0, n, 1)
}
}
macrotext[ntext++] = line
next
}
curmacro != "" && $0 ~ /^\.\.$/ { # macro end
macrolen[curmacro] = ntext - macrostart
curmacro = ""
print ".^#", NR - nroffset + 1, inname
next
}
$0 ~ /^\./ && ( macros[$1] != 0 || $0 ~ /^\.(i[ef]|el)/ ) {
# something that needs attention
print ".^=", NR - nroffset, inname
line = $0
nleft = 0
macro = "<none>"
nargs = 0
while (line != "") {
# conditionals; note that 1-n is !n (awk doesn't have !)
invert = 0
if (line ~ /^\.i[ef] !/)
invert = 1
prevcond = cond
cond = 0
if (line !~ /^\.(i[ef]|el)/) { # not conditional
cond = 1
iflen = 0
} else if (line ~ /^\.i[ef] !?\\n\(\.\$[<=>][0-9] /) {
# arithmetic comparison on arg count
iflen = length(".if .n(.$=x ") + invert
n = substr(line, iflen-1, 1) + 0
op = substr(line, iflen-2, 1)
if (op == "=" && nargs == n)
cond = 1
else if (op == "<" && nargs < n)
cond = 1
else if (op == ">" && nargs > n)
cond = 1
} else if (line ~ /^\.i[ef] !?'\\\$[0-9]'[^']*' /) {
# string equality on argument
iflen = length(".if '.$n'") + invert
n = substr(line, iflen-1, 1)+0
if (n <= nargs)
s1 = args[n]
else
s1 = ""
i = index(substr(line, iflen+1), "'")
s2 = substr(line, iflen+1, i-1)
iflen += i+1
if (s1 == s2)
cond = 1
} else if (line ~ /^\.i[ef] !?[nt] /) {
# nroff vs troff
iflen = length(".if n ") + invert
if (substr(line, iflen-1, 1) == "n")
cond = 1
} else if (line ~ /^\.el /) {
cond = 1 - prevcond
iflen = length(".el ")
} else {
line = ".tm unknown .if/.ie form: " line
cond = 1
iflen = 0
}
if (invert)
cond = 1 - cond
if (cond && iflen > 0) # trim true conditional off
line = substr(line, iflen+1)
# do argument substitution, if necessary
if (cond && line ~ /\\\$/) {
orig = line
line = ""
for (pos = index(orig, "\\$"); pos > 0; \
pos = index(orig, "\\$")) {
if (pos > 1)
line = line substr(orig, 1, pos-1)
c = substr(orig, pos+2, 1)
if (c ~ /[0-9]/ && c+0 <= nargs)
line = line args[c+0]
orig = substr(orig, pos+3)
}
line = line orig # the remnant
}
# is it an nroff command?
if (cond && line ~ /^\./) {
cmd = substr(line, 1, 3)
while (cmd ~ / $/)
cmd = substr(cmd, 1, length(cmd)-1)
} else
cmd = ""
# deal with it
if (!cond)
nop = 0 # nothing
else if (cmd == "" || macros[cmd] == 0)
print line # not a nested macro
else if (sp >= maxsp)
print ".tm macros nested too deeply (" sp " levels)"
else { # nesting
# stack old one
sp++
nleftstack[sp] = nleft
ptrstack[sp] = ptr
macrostack[sp] = macro
nargstack[sp] = nargs
condstack[sp] = cond
for (i = 1; i <= nargs; i++)
argstack[sp ":" i] = args[i]
# start new one, mostly pulling arguments apart
macro = cmd
nleft = macrolen[macro]
ptr = macros[macro]
cond = 0
argno = 1
pos = length(macro) + 1
for (;;) {
while (substr(line, pos, 1) ~ /[ \t]/)
pos++
if (pos > length(line))
break # NOTE BREAK OUT
arg = ""
if (substr(line, pos, 1) == "\"") {
pos++
while (substr(line, pos, 1) ~ /[^"]/) {
arg = arg substr(line, pos, 1)
pos++
}
pos++
} else
while (substr(line, pos, 1) ~ /[^ \t]/) {
arg = arg substr(line, pos, 1)
pos++
}
args[argno++] = arg
}
nargs = argno - 1
}
# clean up any completed macros
while (nleft <= 0 && sp > 0) {
nleft = nleftstack[sp]
ptr = ptrstack[sp]
macro = macrostack[sp]
nargs = nargstack[sp]
cond = condstack[sp]
for (i = 1; i <= nargs; i++)
args[i] = argstack[sp ":" i]
sp--
}
# finally, get next line
if (nleft > 0) {
line = macrotext[ptr++]
nleft--
} else
line = "" # signal loop to terminate
}
print ".^#", NR - nroffset + 1, inname
next
}
{
# it's ordinary
print
}
+587
View File
@@ -0,0 +1,587 @@
# second pass: interpretation of directives
# A macro-set-specific portion gets interpolated into this at the "#include"
# line. As a minimum, it must deal with .^b and .^e and with any input traps.
BEGIN {
# stuff for output to third pass
nobreak = -1
dobreak = -2
message = -3
OFS = "\t"
# special-character table; this one character needs to be hardcoded
chars[" "] = " " ; charwidths[" "] = 1
debug["e"] = 0 # just to make it an array
strings["a"] = "" # just to make it an array
numbers["a"] = 0 # just to make it an array
hyphens["a"] = "" # just to make it an array
hyphenwidths["a"] = "" # just to make it an array
# stuff for expression decoding
signfactor["+"] = 1
signfactor["-"] = -1
scale["i"] = 240
scale["c"] = 240*50/127
scale["P"] = 240/6
# we get m, n, and v when we see .^r
scale["p"] = 240/72
scale["u"] = 1
# stuff for basic parameters that just get passed to third pass
parms["in"] = 0 # just to make it an array
prevparms["in"] = 0 # just to make it an array
setcmd["ll"] = "linelen"
setcmd["in"] = "indent"
setcmd["ti"] = "tempindent"
setcmd["po"] = "pageoffset"
setcmd["pl"] = "pagelen"
# did last word end with \c ? (in which case, it's still in "word")
backc = 0
# stuff for error reporting
il = 0 # input line number
lockil = 0 # il is locked, we're inside a macro
inname = "?" # input filename
msg = message "\t" # later picks up filename etc.
# current input trap
afternext = ""
}
{
if (!lockil)
il++
msg = message "\t" inname "," il ": "
# fallthrough
}
/^[ \t]*$/ { # empty line
print dobreak, "space"
next
}
/^[ \t]/ { # line starting with white space
print dobreak, "flush"
print 0, "" # empty word
# fallthrough
}
/^[^.]/ { # text
# dispose of the easy case
if (font == "R" && $0 !~ /\\|\t|-| / && !backc && afternext == "") {
for (i = 1; i <= NF; i++)
print length($i), $i
if ($0 ~ /[.!?:]([)'"*]|])*$/)
print nobreak, "gap", 2
if (centering > 0) {
print dobreak, "center"
centering--
} else if (!fill)
print dobreak, "flush"
next
}
# the hard case, needs a character-by-character scan
s = $0 " " # the space flushes the last word
n = 1 # current position in s
inword = 0 # have we been processing a word?
period = "" # "." if this word ended a sentence
nsp = 0 # count of spaces seen so far
tabpos = 0 # which tab position was used last
while (n <= length(s)) {
c = substr(s, n, 1)
# handle state transitions
if (c == " " || c == "\t") {
if (inword) { # ends word
if (!backc) {
print wordlen, word
if (usedhyphen)
print nobreak, "nohyphen"
}
inword = 0
nsp = 0
}
} else {
if (!inword) { # begins word
if (!backc) {
word = ""
wordlen = 0
usedhyphen = 0
}
backc = 0
inword = 1
if (nsp > 1)
print nobreak, "gap", nsp
}
}
# deal with the character
if (c == " ") {
nsp++
if (n != length(s)) # not the trailing flusher
period = ""
} else if (c == "\t") {
# not really right, should be based on input position
# also, one space following tab gets ignored
tabpos++
if (tabpos <= ntabs)
print nobreak, "tabto", tabs[tabpos]
nsp = 0
period = ""
} else if (c == "-" && wordlen > 0) {
# hyphen within word
print wordlen, word, hyphenwidths[font]
print nobreak, "userhyphen", hyphens[font], hyphenwidths[font]
word = ""
wordlen = 0
period = ""
usedhyphen = 1
} else if (c != "\\") {
# ordinary character
if (font == "B")
word = word c "\b" c "\b" c
else if (font == "I" && c ~ /[a-zA-Z0-9]/)
word = word "_\b" c
else
word = word c
wordlen++
if (c ~ /[.!?:]/)
period = "."
else if (c !~ /([)'"*]|])/)
period = ""
} else { # backslash
n++
c = substr(s, n, 1)
if (c == "f") {
# font change
n++
code = substr(s, n, 1)
if (code == "(") {
n++
code = substr(s, n, 2)
n++
}
if (code == "P")
font = prevfont
else if (fontok[code] == "")
print msg "unknown font `" code "'"
else {
prevfont = font
font = code
}
} else if (c == "n") {
# number-register value
n++
code = substr(s, n, 1)
if (code == "(") {
n++
code = substr(s, n, 2)
n++
}
s = substr(s, 1, n) numbers[code] substr(s, n+1)
} else if (c == "s") {
# size change
n++
if (substr(s, n, 1) ~ /[0-9]/)
n++
# just ignore it
} else if (c == "c")
# word continuation
backc = 1
else if (c == "*") {
# string-variable value
n++
code = substr(s, n, 1)
if (code == "(") {
n++
code = substr(s, n, 2)
n++
}
s = substr(s, 1, n) strings[code] substr(s, n+1)
} else if (c == "%") {
# discretionary hyphen
if (wordlen > 0) {
print wordlen, word, hyphenwidths[font]
print nobreak, "hyphen", hyphens[font], hyphenwidths[font]
word = ""
wordlen = 0
usedhyphen = 1
}
} else if (c == "(" && substr(s, n+1, 2) == "em" && \
chars["em"] != "") {
# em-dash, special case due to hyphenation
n += 2
emw = charwidths["em"]
print wordlen, word, emw
print nobreak, "userhyphen", chars["em"], emw
word = ""
wordlen = 0
period = ""
usedhyphen = 1
} else {
# special-character name
code = c
if (code == "(") {
n++
code = substr(s, n, 2)
n++
}
word = word chars[code]
wordlen += charwidths[code]
period = ""
}
}
# on to the next character, at last
n++
}
# end-of-line processing
if (!backc) {
if (period == ".")
print nobreak, "gap", 2
if (centering > 0) {
print dobreak, "center"
centering--
} else if (!fill)
print dobreak, "flush"
}
# if no input trap, we're done
if (afternext == "")
next
# if there is an input trap, fall into the macro-dependent section
}
#
#
#
# at this point we plug in the macro-specific stuff, keyed on the next line
#include note that this is an awk comment
#
#
#
/^\.it/ { # plant an input trap, sort of
if (NF > 1 && $2 != 1)
print msg ".it first argument must be 1"
if (NF > 2)
afternext = afternext "," $3
else
afternext = ""
next
}
/^\.\^r cpi / { # set resolutions, in cpi: .^r cpi hor vert
scale["m"] = 240/$3
scale["n"] = 240/$3
scale["v"] = 240/$4
next
}
/^\.(ta|ll|in|ti|po|ne|sp|pl|nr)/ { # expression processing
# sort out default scale factor
if ($1 ~ /^\.(ne|sp|pl)/)
exprscale = "v"
else if ($1 ~ /^\.(nr)/)
exprscale = "u"
else
exprscale = "n"
# which argument should we start with?
offset = length($1) + 1
if ($1 == ".nr")
offset += length($2) + 1
# beginning of debugging message
if (debug["e"])
printf "%s ", msg substr($0, 1, offset)
# do the expressions
s = substr($0, offset+1)
n = 1
while (s != "") {
while (s ~ /^[ \t]/)
s = substr(s, 2)
# an initial sign is magic
ssign = ""
if (s ~ /^[+-]/) {
ssign = substr(s, 1, 1)
s = substr(s, 2)
}
s = "+" s # this is an un-magic addition operator
# process terms
sval = 0
while (s ~ /^([+*%)-]|\/)/) {
# figure out what it is and what it contributes
if (debug["e"] > 1)
print "s=`" s "'"
termop = substr(s, 1, 1)
s = substr(s, 2)
termscale = exprscale
if (termop == ")") {
if (debug["e"] > 1)
print "pop " valstack[vsp] " " opstack[vsp] " with " sval
termval = sval
sval = valstack[vsp]
termop = opstack[vsp]
vsp--
termscale = "u"
} else if (s ~ /^\(/) {
if (debug["e"] > 1)
print "push " sval " " termop
vsp++
valstack[vsp] = sval
opstack[vsp] = termop
sval = 0
termop = "+" # dummy op and value
termval = 0
s = "+" substr(s, 2)
} else if (s ~ /^\\w/) {
delim = substr(s, 3, 1)
s = substr(s, 4)
endp = index(s, delim)
if (endp == 0)
endp = length(s) + 1
termval = (endp - 1) * scale["n"] # crude
s = substr(s, endp+1)
} else if (s ~ /^\\n/) {
if (s ~ /^\\n\(/) {
code = substr(s, 4, 2)
s = substr(s, 6)
} else {
code = substr(s, 3, 1)
s = substr(s, 4)
}
termval = numbers[code]
} else if (s ~ /^[0-9.]/) {
for (endp = 1; endp <= length(s); endp++)
if (substr(s, endp, 1) !~ /[0-9.]/)
break
termval = substr(s, 1, endp-1) + 0
s = substr(s, endp)
}
# add it in, with scaling factor
c = substr(s, 1, 1)
if (scale[c] != "") {
termval *= scale[c]
s = substr(s, 2)
} else
termval *= scale[termscale]
if (termop == "+")
sval += termval
else if (termop == "-")
sval -= termval
else if (termop == "*")
sval *= termval
else if (termop == "/")
sval = int(sval) / int(termval)
else if (termop == "%")
sval = int(sval) % int(termval)
}
# remember the value, print if debugging
expr[n] = sval
exprsign[n] = ssign
iexpr[n] = signfactor[ssign] * sval # convenience
if (debug["e"])
printf "%s ", ssign "(" sval ")"
# proceed to next, skipping trash if necessary
while (s ~ /^[^ \t]/)
s = substr(s, 2)
n++
}
# final cleanup
nexprs = n - 1
if (debug["e"])
printf "\n"
# fallthrough
}
/^\.(ll|in|ti|po|pl)/ { # common code for set-parameter requests
# relies on expression processing, including setting of exprscale
name = substr($1, 2, 2)
n = parms[name]
if (nexprs == 0)
n = prevparms[name]
else if (exprsign[1] == "" || name == "ti")
n = expr[1] / scale[exprscale]
else
n += iexpr[1] / scale[exprscale]
prevparms[name] = parms[name]
parms[name] = int(n)
print dobreak, setcmd[name], parms[name]
next
}
/^\.nr/ {
# relies on expression processing
n = numbers[$2]
if (exprsign[1] == "")
n = expr[1]
else
n += iexpr[1]
numbers[$2] = int(n)
next
}
/^\.ne/ {
# relies on expression processing
print dobreak, "need", int(expr[1]/scale["v"] + 0.99)
next
}
/^\.sp/ {
# relies on expression processing
if (nexprs == 0)
i = 1
else
i = int(expr[1]/scale["v"] + 0.99)
for (; i > 0; i--)
print dobreak, "space"
next
}
/^\.ta/ {
# relies on expression processing
tabstop = 0
for (n = 1; n <= nexprs; n++) {
if (exprsign[n] == "")
tabstop = expr[n]
else
tabstop += iexpr[n]
tabs[n] = int(tabstop/scale["n"])
}
ntabs = nexprs
next
}
/^\.ft/ {
if (NF > 1)
code = $2
else
code = "P"
if (code == "P")
font = prevfont
else if (fontok[code] == "")
print msg "unknown font `" code "'"
else {
prevfont = font
font = code
}
next
}
/^\.br/ {
print dobreak, "flush"
next
}
/^\.ds/ {
# note, macro-set-specific code often looks at .ds as well
if ($3 !~ /^"/)
strings[$2] = $3
else
strings[$2] = substr($0, index($0, "\"")+1)
next
}
/^\.ns/ {
print nobreak, "nospace"
next
}
/^\.rs/ {
print nobreak, "yesspace"
next
}
/^\.ad/ {
print nobreak, "both"
next
}
/^\.na/ {
print nobreak, "left"
next
}
/^\.nf/ {
fill = 0
print dobreak, "flush"
next
}
/^\.fi/ {
fill = 1
print dobreak, "flush"
next
}
/^\.\^x/ { # direct errors to this file: .^x filename
print nobreak, "errsto", $2
next
}
/^\.\^c/ { # define character: .^c name width text
if ($4 ~ /^"/)
s = substr($0, index($0, "\"")+1)
else
s = $4
ns = ""
while ((n = index(s, "\\")) > 0) {
if (n > 1)
ns = ns substr(s, 1, n-1)
n++
c = substr(s, n, 1)
if (c == "\\")
ns = ns "\\"
else if (c == "b")
ns = ns "\b"
s = substr(s, n+1)
}
ns = ns s
if ($2 == "hy") {
hyphens[font] = ns
hyphenwidths[font] = $3
} else {
chars[$2] = ns
charwidths[$2] = $3
}
next
}
/^\.\^f/ { # this font is okay: .^f fontname
# someday, this might take font-change codes as further arguments
fontok[$2] = "yes"
next
}
/^\.tm/ {
print msg $0
next
}
/^\.ps/ {
# ignore
next
}
/^\.ce/ {
if (NF > 1)
centering = $2
else
centering = 1
next
}
/^\.bp/ {
print dobreak, "need", 999
next
}
/^\.\^d/ { # debug control: .^d debugvar value
debug[$2] = $3
next
}
/^\.\^#/ { # set line number of next line: .^# no file
il = $2 - 1
lockil = 0
inname = $3
next
}
/^\.\^=/ { # lock line number to value: .^= no file
il = $2
lockil = 1
inname = $3
next
}
/^\.\\"/ { # comment
next
}
/^\./ {
print msg "command `" $1 "' unsupported or unknown"
}
END {
print dobreak, "need", 999 # flush page
}
+33
View File
@@ -0,0 +1,33 @@
/^\.\^b/ { # initialization
print nobreak, "fph", 1
next
}
/^[^.]/ { # text line -- reached only for input traps
if (afternext ~ /,fP/)
font = prevfont
if (afternext ~ /,tP/)
print dobreak, "toindent"
afternext = ""
next
}
/^\.ds/ { # to catch special strings
if ($3 !~ /^"/)
v = $3
else
v = substr($0, index($0, "\"")+1)
if ($2 ~ /^[LCR][HF]$/)
print nobreak, $2, v
# fallthrough to normal .ds processing in macro-independent stuff
}
/^\.lF/ {
# special footer fiddling
if (strings["by"] != "" && strings["nb"] != "")
lf = strings["by"] "; " strings["nb"]
else
lf = strings["by"] strings["nb"]
print nobreak, "LF", lf
next
}
/^\.\^e/ { # finalization
next
}
+40
View File
@@ -0,0 +1,40 @@
/^\.\^b/ { # initialization
nhnos[1] = 0
next
}
/^[^.]/ { # text line -- reached only for input traps
if (afternext == ",tP")
print dobreak, "toindent"
afternext = ""
next
}
/^\.nH/ { # fooling around for numbered headings
no = 1
if (NF > 1)
no = $2
if (no == 0) {
nhnos[1] = 0
no = 1
}
nhnos[no]++
for (n in nhnos)
if (n > no)
nhnos[n] = 0
s = ""
for (n = 1; n <= no; n++)
s = s nhnos[n] "."
strings["Nh"] = s # result in string for macro to grab
next
}
/^\.ds/ { # to catch special strings
if ($3 !~ /^"/)
v = $3
else
v = substr($0, index($0, "\"")+1)
if ($2 ~ /^[LCR][HF]$/)
print nobreak, $2, v
# fallthrough to normal .ds processing in macro-independent stuff
}
/^\.\^e/ { # finalization
next
}
+332
View File
@@ -0,0 +1,332 @@
# third pass: setting lines and pages
# The input language of this pass is basically <width, word> pairs, where
# "word" may have imbedded strangeness (backspaces, etc.) for font changes
# and special characters. Zero width is not special. A third field may
# appear to indicate that this is a fragment of a word that can be
# hyphenated; the third field is the width of the hyphen that would have
# to be added if the line broke after this fragment.
# Negative widths denote special operations. -3 is an error message, the
# second field being the message. -1 and -2 are control messages to this
# pass, the difference being whether a break is implied or not. The second
# field is a message type string; more fields may appear as arguments. The
# semantics of control messages are often -- but not always! -- similar to
# those of troff commands. For example, "linelen" is .ll, but "center" is
# not semantically equivalent to .ce -- it is related but more primitive.
BEGIN {
# input and output details
FS = "\t"
nobreak = -1
dobreak = -2
message = -3
errs = "awf.errs" # default only, normally changed by "errsto"
# page setup -- some are defaults only, normally altered by pass 2
nextlineno = 1
thispageno = 1
topmargin = 5
botmargin = 5
ind = 0 # current indent
tmpind = 0
pageoffset = "" # string to emit at start of each line
nospacemode = 1
hdrs["CH"] = "- % -"
nop = split("LH,CH,RH,LF,CF,RF", hdrnames, ",")
fph = 0 # print header on first page?
fill = 1
adj = "both"
pagelen = 66
linelen = 78
# line-builder setup
line = "" # line so far, without padding
paddable = "" # x means corresp. char in "line" is paddable
thislinelen = -1 # -1 means nothing there
cont = " " # thing to append to continue line
contlen = 1
eol = "" # thing to append to break line
eollen = 0
padfrom = "R" # "L" or "R", alternating for river avoidance
# many spaces, so we can use substr to get any number we need
sps = " "
sps = sps sps sps sps sps sps sps sps sps sps
}
{
# process word, if any, causing a break if appropriate
if ($1 >= 0 && thislinelen < 0) { # word, and first on line
line = $2
paddable = substr(sps, 1, length($2))
thislinelen = $1
} else if ($1 >= 0 && thislinelen+contlen+$1+$3 <= linelen-ind-tmpind) {
# word, and it fits on line
line = line cont $2
if (cont == " ")
paddable = paddable "x"
else
paddable = paddable substr(sps, 1, length(cont))
paddable = paddable substr(sps, 1, length($2))
thislinelen += contlen + $1
} else if ($1 == nobreak || $1 == message)
nop = 0 # no attention (i.e. break) needed here
else if ($1 == dobreak && $2 == "need" && \
nextlineno + $3 < pagelen + 1 - botmargin)
nop = 0 # enough space is available, no action needed
else if ($1 == dobreak && $2 == "toindent" && \
ind + tmpind + thislinelen < ind) {
# move to indent position within line; there is room
n = ind - (ind + tmpind + thislinelen)
line = line substr(sps, 1, n)
# nothing before this is paddable
paddable = substr(sps, 1, length(line))
thislinelen += n
# prevent padding immediately after this point
cont = ""
contlen = 0
} else if (thislinelen >= 0 || ($1 == dobreak && $2 == "need")) {
# must emit output, either due to break or "need"
# if at top of page, header
if (nextlineno == 1) {
for (i = int((topmargin-1)/2); i > 0; i--) {
print ""
nextlineno++
}
for (hno in hdrnames) {
h = hdrnames[hno]
if (hdrs[h] ~ /%/) {
n = split(hdrs[h], t, "%")
thispagehdrs[h] = t[1] thispageno t[2]
} else
thispagehdrs[h] = hdrs[h]
}
if (fph || thispageno > 1) {
lh = thispagehdrs["LH"]
ch = thispagehdrs["CH"]
rh = thispagehdrs["RH"]
lsp = int((linelen - length(lh ch rh)) / 2)
rsp = linelen - length(lh ch rh) - lsp
print pageoffset lh substr(sps, 1, lsp) ch substr(sps, 1, rsp) rh
} else
print ""
nextlineno++
while (nextlineno <= topmargin) {
print ""
nextlineno++
}
}
# the current line
# first, add a trailing hyphen if any
line = line eol
paddable = paddable substr(sps, 1, length(eol))
thislinelen += eollen
# trim trailing spaces if any
while (line ~ / $/) {
line = substr(line, 1, length(line)-1)
paddable = substr(paddable, 1, length(line))
thislinelen--
}
# print it in a suitable way
if (line == "") # empty always prints as nothing
print ""
else if ($1 < 0 && $2 == "center") {
# center it
hsp = int((linelen - thislinelen) / 2)
if (hsp < 0)
hsp = 0
print pageoffset substr(sps, 1, ind+tmpind+hsp) line
} else if (adj == "left" || (adj == "both" && \
($1 < 0 || index(paddable, "x") == 0)))
# no right-margin adjustment (disabled, inappropriate
# (line ended by break), or impossible)
print pageoffset substr(sps, 1, ind+tmpind) line
else if (adj == "both") {
# hard case -- adjust right margin
# sanity check
if (length(paddable) != length(line)) # aieeeee
printf "awf: %f != %f!\n", length(paddable), \
length(line) >errs
# compute parameters
textlen = linelen - (ind+tmpind)
mustadd = textlen - thislinelen
npad = 0 # number of paddable spaces
for (tmp = paddable; (i = index(tmp, "x")) > 0; \
tmp = substr(tmp, i+1))
npad++
addatall = int(mustadd/npad) # all grow this much
spall = substr(sps, 1, addatall)
nmore = mustadd - addatall*npad # this many grow more
# build padded output text
out = substr(sps, 1, ind+tmpind)
padno = 0
while ((i = index(paddable, "x")) > 0) {
out = out substr(line, 1, i)
padno++
out = out spall
if (padfrom == "L") {
if (padno <= nmore)
out = out " "
} else {
if (padno > npad-nmore)
out = out " "
}
line = substr(line, i+1)
paddable = substr(paddable, i+1)
}
# print it, plus remnant not processed by loop
print pageoffset out line
# tidy up
if (padfrom == "L")
padfrom = "R"
else
padfrom = "L"
}
# tidy up after output line
nextlineno++
line = ""
paddable = ""
thislinelen = -1
tmpind = 0
nospacemode = 0
# if we broke from a "need", go to bottom of page
if ($1 == dobreak && $2 == "need")
while (nextlineno < pagelen + 1 - botmargin) {
print ""
nextlineno++
}
# footer, if at bottom of page
if (nextlineno >= pagelen + 1 - botmargin) {
for (i = int((botmargin-1)/2); i > 0; i--) {
print ""
nextlineno++
}
# header code prepared thispagehdrs
lf = thispagehdrs["LF"]
cf = thispagehdrs["CF"]
rf = thispagehdrs["RF"]
lsp = int((linelen - length(lf cf rf)) / 2)
rsp = linelen - length(lf cf rf) - lsp
print pageoffset lf substr(sps, 1, lsp) cf substr(sps, 1, rsp) rf
nextlineno++
while (nextlineno <= pagelen) {
print ""
nextlineno++
}
nextlineno = 1
thispageno++
# after page break, should not space unnecessarily,
# and should pad first line from right
nospacemode = 1
padfrom = "R"
}
# we are finally done with emitting output
# pick up input word, if any
if ($1 >= 0) {
line = $2
paddable = substr(sps, 1, length($2))
thislinelen = $1
}
}
# if we broke, next line should pad from right
if ($1 == dobreak)
padfrom = "R"
# cleanup and post-break command processing
if ($1 >= 0 || $2 == "nohyphen") {
# reset hyphenation trickery after each word (fragment)
cont = " "
contlen = 1
eol = ""
eollen = 0
} else if ($2 == "need" || $2 == "toindent")
nop = 0 # dealt with above
else if ($2 == "flush" || $2 == "center")
nop = 0 # exist only to cause break
else if ($1 == message)
print "awf: " $2 >errs
else if ($2 == "gap") {
# gap between last word and next one should be >= $3
if (thislinelen >= 0) {
line = line substr(sps, 1, $3-1)
paddable = paddable substr(sps, 1, $3-1)
thislinelen += $3-1
}
} else if ($2 == "tabto") {
# move to tab stop at $3
if (thislinelen < 0)
thislinelen = 0 # make line exist
n = $3 - thislinelen
if (n > 0) { # must emit some space
line = line substr(sps, 1, n)
# nothing before a tab is paddable
paddable = substr(sps, 1, length(line))
thislinelen += n
# suppress space following
cont = ""
contlen = 0
}
} else if ($2 == "errsto")
errs = $3
else if ($2 ~ /^[LCR][HF]$/)
hdrs[$2] = $3
else if ($2 == "fph")
fph = $3
else if ($2 == "space") {
if (!nospacemode) {
# generate an empty line, which will be flushed by
# the next word; NB we know "space" caused a flush
line = ""
paddable = ""
thislinelen = linelen + 1
nospacemode = 0
}
} else if ($2 == "left")
adj = "left"
else if ($2 == "both")
adj = "both"
else if ($2 == "indent")
ind = $3
else if ($2 == "tempindent")
tmpind = $3
else if ($2 == "linelen")
linelen = $3
else if ($2 == "pagelen")
pagelen = $3
else if ($2 == "nospace")
nospacemode = 1
else if ($2 == "yesspace")
nospacemode = 0
else if ($2 == "hyphen") {
# discretionary hyphen at this point
cont = ""
contlen = 0
eol = $3
eollen = $4
} else if ($2 == "userhyphen") {
# user-supplied hyphen at this point
cont = $3
contlen = $4
eol = $3
eollen = $4
} else if ($2 == "pageoffset")
pageoffset = substr(sps, 1, $3)
else
print "awf: URK -- INTERNAL OPCODE `" $2 "' UNKNOWN" >errs
}
END {
# second pass is supposed to fake a .ne to flush the last page
if (nextlineno != 1)
print "awf: last page not flushed!" >errs
}
+4
View File
@@ -0,0 +1,4 @@
@echo off
echo ---------- %1 ----------
cd %1
nmake /f makefile.vc /nologo %2
+5
View File
@@ -0,0 +1,5 @@
*.log
*.log.*
*.pix
*.pix.*
.cvsignore
+6 -5
View File
@@ -5,15 +5,12 @@
#define SRCDIR bench
#define PRODUCTS pixcmp
#define SRCSUFF .c
#define MANSECTION 9
/* #define MANSECTION 9 */
#define FILES pixcmp
#include "../Cakefile.defs"
/* These programs are not really for system-wide installation */
#define DONT_INSTALL 1
#ifdef NFS
/* Pick up any shell scripts needed */
%.sh: if exist ../SRCDIR/%.sh
@@ -26,12 +23,16 @@
clobber&: xxclober
@echo "About to wipe out all pictures and binary files in this directory"
@echo "Send SIGINT (typ. ^C) within 3 seconds to abort"
@sleep 5
@sleep 3
rm -f *.log.* *.pix.* # old versions
rm -f *.log *.pix # last try
#define clobber xxclober /* rename "clobber" in Cakefile.rules */
clean&:
@echo "Removing object files and pixcmp"
rm -f *.o pixcmp
pixcmp: OBJ
CC LDFLAGS -o pixcmp OBJ
+16 -6
View File
@@ -10,16 +10,18 @@ if test -f ../.lgt.$MACHINE/lgt
then
LGT=../.lgt.$MACHINE/lgt
DB=../.db.$MACHINE
LD_LIBRARY_PATH=../.libcursor.$MACHINE:../.libtermio.$MACHINE:../.libbu.$MACHINE:../.libbn.$MACHINE:../.librt.$MACHINE:../.libfb.$MACHINE:../.libpkg.$MACHINE:../.libsysv.$MACHINE:$LD_LIBRARY_PATH
else
if test -f ../lgt/lgt
then
LGT=../lgt/lgt
DB=../db
else
echo "Can't find LGT"
exit 1
fi
LGT=../lgt/lgt
DB=../db
LD_LIBRARY_PATH=../libcursor:../libtermio:../libbu:../libbn:../librt:../libfb:../libpkg:../libsysv:$LD_LIBRARY_PATH
fi
export LD_LIBRARY_PATH
CMP=./pixcmp
if test ! -f $CMP
@@ -134,15 +136,23 @@ fi
./script2 < /dev/null &&
./script3 < /dev/null || { echo "Script test failed."; exit 1; }
FAIL=0
for i in 1 2 3
do
if ${CMP} ../pix/lgt${i}.pix lgt${i}a.pix
then :;
else echo "Test $i A failed."; exit 1
else echo "Test $i A failed."; FAIL=1
fi
if ${CMP} ../pix/lgt${i}.pix lgt${i}b.pix
then :;
else echo "Test $i B failed."; exit 1
else echo "Test $i B failed."; FAIL=1
fi
done
echo "Tested OK."
if test "$FAIL" -eq 0
then
echo "LGT Tested OK."
exit 0
fi
echo "*** LGT does NOT work on this platform ***"
exit 2
+17 -8
View File
@@ -21,9 +21,18 @@ HOST="$1"
NOTE1="$2"
NOTE2="$3"
NEW_FILES="moss.log world.log star.log bldg391.log m35.log"
NEW_FILES="moss.log world.log star.log bldg391.log m35.log sphflake.log"
REF_FILES="../pix/moss.log ../pix/world.log ../pix/star.log \
../pix/bldg391.log ../pix/m35.log"
../pix/bldg391.log ../pix/m35.log ../pix/sphflake.log"
for i in $NEW_FILES $REF_FILES
do
if test ! -f $i
then
echo "${NAME}: file $i does not exist, aborting"
exit 1
fi
done
# Use TR to convert newlines to tabs.
VGRREF=`grep RTFM $REF_FILES | \
@@ -35,14 +44,14 @@ CURVALS=`grep RTFM $NEW_FILES | \
RATIO_LIST=""
# Trick: Force args $1 through $5 to the numbers in $CURVALS
# Trick: Force args $1 through $6 to the numbers in $CURVALS
# This should be "set -- $CURVALS", but 4.2BSD /bin/sh can't handle it,
# and CURVALS are all positive (ie, no leading dashes), so this is safe.
set $CURVALS
while test $# != 5
do echo "${NAME}: Warning, only $# times found, using zeros"
CURVALS="$CURVALS 0"
while test $# -lt 6
do echo "${NAME}: Warning, only $# times found, adding a zero."
CURVALS="${CURVALS}0 "
set $CURVALS
done
@@ -56,8 +65,8 @@ do
done
# The number of plus signs must be one less than the number of elements.
MEAN_ABS=`echo 2k $CURVALS ++++ 5/ p | dc`
MEAN_REL=`echo 2k $RATIO_LIST ++++ 5/ p | dc`
MEAN_ABS=`echo 2k $CURVALS +++++ 6/ p | dc`
MEAN_REL=`echo 2k $RATIO_LIST +++++ 6/ p | dc`
# Note: Both RATIO_LIST and CURVALS have an extra trailing tab.
# The question mark is for the mean field
+10 -2
View File
@@ -23,10 +23,17 @@
* All rights reserved.
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
static const char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include "conf.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
long matching;
long off1;
@@ -34,6 +41,7 @@ long offmany;
char usage[] = "Usage: pixcmp f1.pix f2.pix\n";
int
main(argc, argv)
char **argv;
{
@@ -108,7 +116,7 @@ char **argv;
}
}
fprintf(stderr,
"pixcmp bytes: %7d matching, %7d off by 1, %7d off by many\n",
"pixcmp bytes: %8ld matching, %8ld off by 1, %8ld off by many\n",
matching, off1, offmany );
/* If files were of different lengths, that is an error */
+30 -2
View File
@@ -1,8 +1,36 @@
#!/bin/sh
export PATH || (echo "This isn't sh."; sh $0 $*; kill $$)
eval `machinetype.sh -b` # sets MACHINE, UNIXTYPE, HAS_TCP
if test -f ../.rt.$MACHINE/rt
then
RT=../.rt.$MACHINE/rt
DB=../.db.$MACHINE
LD_LIBRARY_PATH=../.libbu.$MACHINE:../.libbn.$MACHINE:../.librt.$MACHINE:../.libfb.$MACHINE:../.libpkg.$MACHINE:../.libsysv.$MACHINE:$LD_LIBRARY_PATH
else
if test ! -f ../rt/rt
then
echo "Can't find RT"
exit 1
fi
RT=../rt/rt
DB=../db
LD_LIBRARY_PATH=../libbu:../libbn:../librt:../libfb:../libpkg:../libsysv:$LD_LIBRARY_PATH
fi
export LD_LIBRARY_PATH
# Alliant NFS hack
if test x${MACHINE} = xfx
then
cp ${RT} /tmp/rt
RT=/tmp/rt
fi
# WARNING THIS IS A REAL CPU HOG
../rt/rt -p90 -f1024 -H3 -M $*\
if test -f cube.pix; then mv -f cube.pix cube.pix.$$; fi
if test -f cube.log; then mv -f cube.log cube.log.$$; fi
$RT -p90 -f1024 -H3 -M $*\
-o cube.pix\
../db/cube.g\
$DB/cube.g\
'all.g' \
2> cube.log\
<<EOF
+8 -2
View File
@@ -9,17 +9,20 @@ eval `machinetype.sh -b` # sets MACHINE, UNIXTYPE, HAS_TCP
if test -f ../.util.$MACHINE/pixdiff
then
PIXDIFF=../.util.$MACHINE/pixdiff
PIX_FB=../.util.$MACHINE/pix-fb
PIX_FB=../.fb.$MACHINE/pix-fb
LD_LIBRARY_PATH=../.libbu.$MACHINE:../.libbn.$MACHINE:../.librt.$MACHINE:../.libfb.$MACHINE:../.libpkg.$MACHINE:../.libsysv.$MACHINE:$LD_LIBRARY_PATH
else
if test -f ../util/pixdiff
then
PIXDIFF=../util/pixdiff
PIX_FB=../util/pix-fb
PIX_FB=../fb/pix-fb
else
echo "Can't find pixdiff"
exit 1
fi
LD_LIBRARY_PATH=../libbu:../libbn:../librt:../libfb:../libpkg:../libsysv:$LD_LIBRARY_PATH
fi
export LD_LIBRARY_PATH
# Alliant NFS hack
if test x${MACHINE} = xfx
@@ -44,3 +47,6 @@ ${PIXDIFF} ../pix/bldg391.pix bldg391.pix | ${PIX_FB}
echo +++++ m35.pix
${PIXDIFF} ../pix/m35.pix m35.pix | ${PIX_FB}
echo +++++ sphflake.pix
${PIXDIFF} ../pix/sphflake.pix sphflake.pix | ${PIX_FB}
+141 -13
View File
@@ -2,33 +2,100 @@
# A Shell script to run the BRL-CAD Benchmark Test
# @(#)$Header$ (BRL)
# set RT, DB, and/or CMP environment variables to override default locations
echo "B R L - C A D B E N C H M A R K"
echo "================================="
# Ensure /bin/sh
export PATH || (echo "This isn't sh."; sh $0 $*; kill $$)
eval `machinetype.sh -b` # sets MACHINE, UNIXTYPE, HAS_TCP
if test -f ../.rt.$MACHINE/rt
echo Looking for RT...
# find RT (environment variable overrides)
if test "x${RT}" = "x"
then
RT=../.rt.$MACHINE/rt
DB=../.db.$MACHINE
else
if test -f ../rt/rt
echo ...checking for NFS or local build...
# check for NFS build
if test -x ../.rt.$MACHINE/rt
then
echo ...found NFS build
RT=../.rt.$MACHINE/rt
if test x${DB} != x ; then DB=../.db.$MACHINE ; fi
LD_LIBRARY_PATH=../.libbu.$MACHINE:../.libbn.$MACHINE:../.liboptical.$MACHINE:../.libitcl3.2.$MACHINE:../.libtcl8.3.$MACHINE:../.librt.$MACHINE:../.libfb.$MACHINE:../.libpkg.$MACHINE:../.libsysv.$MACHINE:$LD_LIBRARY_PATH
# check for local build
elif test -f ../rt/rt
then
echo ...found local build
RT=../rt/rt
DB=../db
else
echo "Can't find RT"
exit 1
if test x${DB} != x ; then DB=../db ; fi
LD_LIBRARY_PATH=../libbu:../libbn:../liboptical:../libitcl3.2:../libtcl8.3:../librt:../libfb:../libpkg:../libsysv:$LD_LIBRARY_PATH
fi
fi
CMP=./pixcmp
if test ! -f $CMP
echo Looking for geometry database directory...
# find geometry database directory if we do not already know where it is
# DB environment variable overrides
if test "x${DB}" = "x"
then
cake pixcmp
echo ...checking for NFS or local build...
# check for NFS build
if test -f ../.db.$MACHINE/sphflake.g
then
echo ...found NFS build
DB=../.db.$MACHINE
LD_LIBRARY_PATH=../.libbu.$MACHINE:../.libbn.$MACHINE:../.liboptical.$MACHINE:../.libitcl3.2.$MACHINE:../.libtcl8.3.$MACHINE:../.librt.$MACHINE:../.libfb.$MACHINE:../.libpkg.$MACHINE:../.libsysv.$MACHINE:$LD_LIBRARY_PATH
# check for local build
elif test -f ../db/sphflake.g
then
echo ...found local build
DB=../db
LD_LIBRARY_PATH=../libbu:../libbn:../liboptical:../libitcl3.2:../libtcl8.3:../librt:../libfb:../libpkg:../libsysv:$LD_LIBRARY_PATH
fi
fi
echo Checking for pixel comparison utility...
# find pixel comparison utility
# CMP environment variable overrides
if test "x${CMP}" = "x"
then
echo ...checking for NFS of local build...
if test -x ../.bench.$MACHINE/pixcmp
then
echo ...found NFS build
CMP=../.bench.$MACHINE/pixcmp
elif test -x ./pixcmp
then
echo ...found local build
CMP=./pixcmp
else
echo ...need to build pixcmp
cake >& /dev/null
if test "x$?" = "x0"
then
echo ...building pixcmp with cake
cake pixcmp
else
if test "x${CC}" = "x"
then
CC=gcc
$CC >& /dev/null
if ! test "x$?" = "x1"
then
CC=cc
fi
fi
fi
echo ...building pixcmp with $CC
$CC -o pixcmp -I../h pixcmp.c
CMP=./pixcmp
fi
fi
# Alliant NFS hack
if test x${MACHINE} = xfx
if test "x${MACHINE}" = "xfx"
then
cp ${RT} /tmp/rt
cp ${CMP} /tmp/pixcmp
@@ -36,6 +103,33 @@ then
CMP=/tmp/pixcmp
fi
# print results or choke
if test "x${RT}" = "x"
then
echo "ERROR: Could not find RT"
exit 1
else
echo "Using [$RT] for RT"
fi
if test "x${DB}" = "x"
then
echo "ERROR: Could not find database directory"
exit 1
else
echo "Using [$DB] for DB"
fi
if test "x${CMP}" = "x"
then
echo "ERROR: Could not find pixel comparison utility"
exit 1
else
echo "Using [$CMP] for CMP"
fi
export LD_LIBRARY_PATH
echo
# Run the tests
echo +++++ moss
@@ -56,6 +150,7 @@ viewrot -5.735764503e-01 8.191520572e-01 0.000000000e+00
start 0;
end;
EOF
if test -f gmon.out; then mv -f gmon.out gmon.moss.out; fi
${CMP} ../pix/moss.pix moss.pix
if test $? = 0
then
@@ -82,6 +177,7 @@ viewrot -5.735764503e-01 8.191520572e-01 0.000000000e+00
start 0;
end;
EOF
if test -f gmon.out; then mv -f gmon.out gmon.world.out; fi
${CMP} ../pix/world.pix world.pix
if test $? = 0
then
@@ -107,6 +203,7 @@ viewrot -6.733560560e-01 6.130643360e-01 4.132114880e-01 0.000000000e+00
start 0;
end;
EOF
if test -f gmon.out; then mv -f gmon.out gmon.star.out; fi
${CMP} ../pix/star.pix star.pix
if test $? = 0
then
@@ -133,6 +230,7 @@ viewrot -5.735764503e-01 8.191520572e-01 0.000000000e+00
start 0;
end;
EOF
if test -f gmon.out; then mv -f gmon.out gmon.bldg391.out; fi
${CMP} ../pix/bldg391.pix bldg391.pix
if test $? = 0
then
@@ -158,6 +256,7 @@ viewrot -5.527838919e-01 8.332423558e-01 1.171090926e-02 0.000000000e+00
start 0;
end;
EOF
if test -f gmon.out; then mv -f gmon.out gmon.m35.out; fi
${CMP} ../pix/m35.pix m35.pix
if test $? = 0
then
@@ -166,6 +265,31 @@ else
echo m35.pix: WRONG WRONG WRONG WRONG WRONG WRONG
fi
echo +++++ sphflake
if test -f sphflake.pix; then mv -f sphflake.pix sphflake.pix.$$; fi
if test -f sphflake.log; then mv -f sphflake.log sphflake.log.$$; fi
time $RT -B -M -s512 $* \
-o sphflake.pix \
$DB/sphflake.g \
"scene.r" \
2> sphflake.log \
<< EOF
viewsize 2.556283261452611e+04;
orientation 4.406810841785839e-01 4.005093234738861e-01 5.226451688385938e-01 6.101102288499644e-01;
eye_pt 2.418500583758302e+04 -3.328563644344796e+03 8.489926952850350e+03;
start 0;
end;
EOF
if test -f gmon.out; then mv -f gmon.out gmon.sphflake.out; fi
${CMP} ../pix/sphflake.pix sphflake.pix
if test $? = 0
then
echo sphflake.pix: answers are RIGHT
else
echo sphflake.pix: WRONG WRONG WRONG WRONG WRONG WRONG
fi
echo
echo Testing complete, check times against reference files in ../pix/.
@@ -175,3 +299,7 @@ else HOST=`uname -n`
fi
sh ../bench/perf.sh "$HOST" "`date`" "$*" >> summary
+19 -4
View File
@@ -11,16 +11,18 @@ if test -f ../.rt.$MACHINE/rt
then
RT=../.rt.$MACHINE/rt
DB=../.db.$MACHINE
LD_LIBRARY_PATH=../.libbu.$MACHINE:../.libbn.$MACHINE:../.librt.$MACHINE:../.libfb.$MACHINE:../.libpkg.$MACHINE:../.libsysv.$MACHINE:$LD_LIBRARY_PATH
else
if test -f ../rt/rt
if test ! -f ../rt/rt
then
RT=../rt/rt
DB=../db
else
echo "Can't find RT"
exit 1
fi
RT=../rt/rt
DB=../db
LD_LIBRARY_PATH=../libbu:../libbn:../librt:../libfb:../libpkg:../libsysv:$LD_LIBRARY_PATH
fi
export LD_LIBRARY_PATH
CMP=./pixcmp
if test ! -f $CMP
@@ -116,3 +118,16 @@ viewrot -5.527838919e-01 8.332423558e-01 1.171090926e-02 0.000000000e+00
start 0;
end;
EOF
echo +++++ sphflake
time $RT -B -M -s512 $* \
$DB/sphflake.g scene.r \
<< EOF
viewsize 2.556283261452611e+04;
orientation 4.406810841785839e-01 4.005093234738861e-01 5.226451688385938e-01 6.101102288499644e-01;
eye_pt 2.418500583758302e+04 -3.328563644344796e+03 8.489926952850350e+03;
start 0;
end;
EOF
+26
View File
@@ -0,0 +1,26 @@
/*
* brlman/Cakefile
*
* Note: The file "awf" needs to know where ../awf/Cakefile put the
* pieces (ETCDIR by default).
*/
#include "../Cakefile.defs"
#define PRODUCTS awf brlman
#define SRCDIR brlman
#define FILES /**/
#define SRCSUFF /**/
#define MANSECTION 1
#define STATIC_PRODUCTS PRODUCTS /* Force PRODUCTS into dist */
/*
* There is nothing to compile.
* The "install-prod" rule should install PRODUCTS,
* and "inst-dist" rule shoudl take care of copying to distribution dir.
* Nothing else to do.
*/
all&:
@echo "SRCDIR: all done"
#include "../Cakefile.rules"
Executable
+61
View File
@@ -0,0 +1,61 @@
#! /bin/sh
eval `machinetype.sh -v` # BRL mod: sets $BASEDIR
PATH=/bin:/usr/bin ; export PATH
# AWFLIB is where the pieces live
AWFLIB=${AWFLIB-$BASEDIR/etc} # BRL mod
tmp=/tmp/awp$$ # tempfile for building pass 2
errs=/tmp/awe$$ # error messages (awk can't send to stderr)
case "$1" in
-ms) mac=ms ;;
-man) mac=man ;;
*) echo "$0: must specify -ms or -man" >&2
exit 2
;;
esac
shift
dev="$AWFLIB/dev.$TERM"
if test ! -r $dev
then
dev="$AWFLIB/dev.dumb"
fi
trap "rm -f $tmp $errs ; exit 0" 0 1 2
# build the full, macro-set-dependent, pass-2 awk program
(
sed -n '1,/^#include/p' $AWFLIB/pass2.base
cat $AWFLIB/pass2.$mac
sed -n '/^#include/,$p' $AWFLIB/pass2.base
) >$tmp
# do it
(
echo ".^x $errs"
echo ".^b"
echo ".^# 1 <prolog>"
cat $dev $AWFLIB/common $AWFLIB/mac.$mac
if test " $*" = " "
then
echo ".^# 1 <stdin>"
cat
else
for f
do
echo ".^# 1 $f"
cat $f
done
fi
echo ".^e"
) | awk -f $AWFLIB/pass1 | awk -f $tmp | awk -f $AWFLIB/pass3
# error messages, if any
if test -s $errs
then
cat $errs >&2
exit 1
else
exit 0
fi
Executable
+54
View File
@@ -0,0 +1,54 @@
#!/bin/sh
# B R L M A N
#
# A substitute for the "man" command for those systems that do not
# have NROFF. Henry Spencer's "nroff -man" replacement called AWF
# is used instead.
#
# Michael John Muuss, BRL, 23-June-1991.
# Public Domain, Distribution Unlimited
#
# @(#) $Header$ (BRL)
if test $# -lt 1
then
echo "Usage: $0 command"
echo " To obtain help about that command"
exit 1
fi
# Use MANPAGER, else use PAGER, else use "more" command.
MORE="more -s -f"
if test "$PAGER" != ""
then
MORE="${PAGER}"
fi
if test "${MANPAGER}" != ""
then
MORE="${MANPAGER}"
fi
eval `machinetype.sh -v` # sets $BASEDIR
# Ensure that MANPATH is set and has BRL-CAD materials listed first.
MANPATH=${BASEDIR}/man:${MANPATH}
PATH_ELEMENTS=`echo ${MANPATH} | sed 's/^://
s/:://g
s/:$//
s/:\\.:/:/g
s/:/ /g'`
for PLACE in ${PATH_ELEMENTS}
do
PATTERN="${PLACE}/man?/$1.?"
TRY=`eval echo ${PATTERN}`
if test "${TRY}" != "${PATTERN}"
then
# Found something(s), format it/them
echo ${TRY}
awf -man ${TRY} | ${MORE}
fi
done
exit 0
+43
View File
@@ -0,0 +1,43 @@
.TH BRLMAN 1 BRL/CAD
.SH NAME
brlman \- display manual pages for BRL-CAD software
.SH SYNOPSIS
.B brlman
title
.SH DESCRIPTION
.I Brlman
provides a substitute for the
.I man
command for those systems that do not
have
.I nroff.
Henry Spencer's
.I nroff -man
replacement called
.I awf
is used instead.
.I Brlman
uses the environment variable
.I MANPATH
to determine where to search for the manual pages (
.I /usr/brlcad/man
is the default). The pager used is taken from the environment variable
.I MANPAGER
or, if that is nor set
.I PAGER
is used. The default is to use the
.I more -s -f
command.
.SH "SEE ALSO"
awf(1)
.SH AUTHOR
Michael John Muuss
.SH SOURCE
SECAD/VLD Computing Consortium, Bldg 394
.br
The U. S. Army Ballistic Research Laboratory
.br
Aberdeen Proving Ground, Maryland 21005
.SH "BUG REPORTS"
Reports of bugs or problems should be submitted via electronic
mail to <CAD@ARL.ARMY.MIL>.
+33
View File
@@ -0,0 +1,33 @@
/*
* btclsh/Cakefile
*
*/
#define CONFIGDEFS BTCLSH_CONFIG
#define SRCDIR bwish
#define PRODUCTS btclsh
#if 0
#define STATIC_PRODUCTS btclsh.tcl
#endif
#define SRCSUFF .c
#define MANSECTION 1
#define FILES main input tcl cmd
#include "../Cakefile.defs"
#include "../Cakefile.prog"
#if HAS_TCP
# define COMPLETE_LIBES \
LIBPKG LIBWDB LIBRT LIBBN LIBBU LIBBU_LIBES LIBTERMIO BTCLSH_LIBES LIBES
#else
# define COMPLETE_LIBES \
LIBWDB LIBRT LIBBN LIBBU LIBBU_LIBES LIBTERMIO BTCLSH_LIBES LIBES
#endif
btclsh: OBJ LIBRT_DEP LIBBN_DEP LIBBU_DEP LIBWDB_DEP LIBTCL_DEP
sh ../sh/newvers.sh version "BrlCad Tclsh (BTCLSH)"
CC CFLAGS -c vers.c
CC -o btclsh LDFLAGS OBJ COMPLETE_LIBES vers.o
#include "../Cakefile.rules"
+19 -16
View File
@@ -9,7 +9,10 @@
$Header$ (BRL)
*/
#define CONFIGDEFS LGT_CONFIG -I. /* -DDEBUG */
/* Remove the following line if you have BRLCAD 4.0 or later. */
/* #define LIBFB_LIBES /**/
#define CONFIGDEFS LGT_CONFIG -I. -U_POSIX_SOURCE /*-DDEBUG*/
#define SRCDIR burst
#define PRODUCTS burst
@@ -17,36 +20,36 @@
#define MANSECTION 1
#define FILES burst error fb glob grid gridrotate idents\
paint plot prnt trie ui\
Hm HmGetc HmGlob Sc Tc
Hm HmGetc HmGlob Sc
#include "../Cakefile.defs"
#include "../Cakefile.prog"
/* Explicit composition of each product */
PRODUCTS: OBJ
CC LDFLAGS -o burst OBJ LIB_PRE''LIBRT RT_LIBES LIB_PRE''LIBFB LIBTERMLIB LIBES -ltermlib -lm
PRODUCTS: OBJ LIBRT_DEP LIBBN_DEP LIBFB_DEP LIBBU_DEP LIBTERMIO_DEP
CC LDFLAGS -o burst OBJ LIBRT LIBBN LIBBU LIBBU_LIBES LIBTERMIO LIBTERMLIB LIBFB LIBFB_LIBES LIBES -lm
all&: PRODUCTS
test&: all tfiles/ktank.g
./burst -b < tfiles/ktank.in
@if test $? -ne 0 \
then echo "Test failed."; exit 1 \
test&: ../.burst.MTYPE/burst tfiles/ktank.g
../.burst.MTYPE/burst -b < tfiles/ktank.in
@if test $? -ne 0 \\
then echo "Test failed."; exit 1 \\
fi
diff tfiles/ktank.burst tfiles/ktank.burst.bak
@if test $? -ne 0 \
then echo "Test failed."; exit 1 \
diff tfiles/ktank.burst tfiles/ktank.burst.bak4.0
@if test $? -ne 0 \\
then echo "Test failed."; exit 1 \\
fi
diff tfiles/ktank.shotlines tfiles/ktank.shotlines.bak
@if test $? -ne 0 \
then echo "Test failed."; exit 1 \
diff tfiles/ktank.shotlines tfiles/ktank.shotlines.bak4.0
@if test $? -ne 0 \\
then echo "Test failed."; exit 1 \\
fi
@echo "Tested OK."
untest&:
rm -f tfiles/ktank.burst tfiles/ktank.shotlines tfiles/ktank.plot \
rm -f tfiles/ktank.burst tfiles/ktank.shotlines tfiles/ktank.plot \\
tfiles/ktank.pix tfiles/ktank.g tfiles/ktank.log
tfiles/ktank.g:
asc2g < tfiles/ktank.asc > tfiles/ktank.g
asc2g < ../burst/tfiles/ktank.asc > tfiles/ktank.g
#include "../Cakefile.rules"
+24 -77
View File
@@ -12,7 +12,7 @@
*/
/*LINTLIBRARY*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
static const char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#ifndef DEBUG
@@ -25,10 +25,13 @@ static char RCSid[] = "@(#)$Header$ (BRL)";
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include "./Sc.h"
#include "./Hm.h"
#include "./Mm.h"
#define ErLog rt_log
#include "./extern.h"
#define ErLog brst_log
#if __STDC__
extern void exit( int s );
extern unsigned alarm( unsigned s );
@@ -37,6 +40,14 @@ extern void exit();
extern unsigned alarm();
#endif
#ifndef _POSIX_SOURCE
#if __STDC__
extern FILE *fdopen(int, const char *);
#else
extern FILE *fdopen();
#endif
#endif
#define HmDEBUG false
#ifndef Max
@@ -148,10 +159,10 @@ register HmItem *itemp;
{
(void) ErLog( "\t\t\ttext=\"%s\"\n", itemp->text );
(void) ErLog( "\t\t\thelp=\"%s\"\n", itemp->help == (char *) NULL ? "(null)" : itemp->help );
(void) ErLog( "\t\t\tnext=0x%x\n", (int) itemp->next );
(void) ErLog( "\t\t\tdfn=0x%x\n", (int) itemp->dfn );
(void) ErLog( "\t\t\tbfn=0x%x\n", (int) itemp->bfn );
(void) ErLog( "\t\t\thfn=0x%x\n", (int) itemp->hfn );
(void) ErLog( "\t\t\tnext=0x%x\n", itemp->next );
(void) ErLog( "\t\t\tdfn=0x%x\n", itemp->dfn );
(void) ErLog( "\t\t\tbfn=0x%x\n", itemp->bfn );
(void) ErLog( "\t\t\thfn=0x%x\n", itemp->hfn );
(void) ErLog( "\t\t\tdata=%d\n", itemp->data );
(void) ErLog( "\t\t\t----\n" );
}
@@ -171,7 +182,7 @@ HmPrntMenu( HmMenu *menup )
HmPrntMenu( menup )
HmMenu *menup;
#endif
{ register HmWindow *win;
{
(void) ErLog( "\tHmPrntMenu( 0x%x )\n", menup );
(void) ErLog( "\t\tgenerator=0x%x\n", menup->generator );
(void) ErLog( "\t\tprevtop=%d\n", menup->prevtop );
@@ -317,7 +328,6 @@ int flag;
return;
if( itemp->text[0] & 0200 ) /* right-justified */
{ register int i;
char errbuf[81];
label_len--;
for( i = 0; i < width - label_len; i++ )
*p++ = itemp->text[0] & 0177;
@@ -393,7 +403,7 @@ int flag;
*/
STATIC void
#if __STDC__
HmPutBorder( register HmWindow *win, register row, char mark )
HmPutBorder( register HmWindow *win, register int row, char mark )
#else
HmPutBorder( win, row, mark )
register HmWindow *win;
@@ -504,7 +514,7 @@ HmWindow *win;
*/
STATIC HmWindow *
#if __STDC__
HmInWin( register x, register y, register HmWindow *win )
HmInWin( register int x, register int y, register HmWindow *win )
#else
HmInWin( x, y, win )
register int x, y;
@@ -770,30 +780,6 @@ HmRedraw()
return;
}
#if ! defined( BSD ) && ! defined( sun ) && ! defined( sgi )
#include <sys/jioctl.h>
#endif
#include <signal.h>
/*
void alarmfunc( int sig )
Do nothing on receipt of SIGALRM. NOTE: this is not the same
as setting SIGALRM to SIG_IGN.
*/
/*ARGSUSED*/
void
#if __STDC__
alarmfunc( int sig )
#else
alarmfunc( sig )
int sig;
#endif
{
(void) signal( SIGALRM, alarmfunc );
return;
}
/*
void HmTtySet( void )
@@ -859,9 +845,8 @@ HmInit( x, y, maxvis )
int x, y;
int maxvis;
#endif
{ extern char *getenv();
char *term = getenv( "TERM" );
if( (HmTtyFd = open( "/dev/tty", O_RDONLY )) == NULL
{
if( (HmTtyFd = open( "/dev/tty", O_RDONLY )) == (-1)
|| (HmTtyFp = fdopen( HmTtyFd, "r" )) == NULL
)
{
@@ -873,45 +858,7 @@ int maxvis;
HmLftMenu = x;
HmTopMenu = y;
HmMaxVis = maxvis;
#if ! defined( BSD ) && ! defined( sun ) && ! defined( sgi )
/* In case we are running MPX and MYX on a DMD, use "editor ptr"
to make menu selections. */
if( term != (char *) NULL && strncmp( term, "tty5620", 7 ) == 0 )
{ /* We have a DMD. */
#ifdef XT_JMPX /* DAG -- temporary dual mpx/layers support */
if( ioctl( HmTtyFd, JMPX, 0 ) != -1
|| ioctl( HmTtyFd, XT_JMPX, 0 ) != -1
)
{
#else
if( ioctl( HmTtyFd, JMPX, 0 ) != -1 )
{
#endif
/* We are running MPX. */
char input[12];
register int i;
void (*oalarmfunc)();
TcClrEcho( HmTtyFd );
TcSetCbreak( HmTtyFd );
(void) ScMvCursor( HmLftMenu, HmTopMenu );
(void) fputs( "\033[?1Z", stdout );
(void) fflush( stdout );
oalarmfunc = signal( SIGALRM, alarmfunc );
(void) alarm( 1 );
(void) fgets( input, 12, stdin );
(void) alarm( 0 );
(void) signal( SIGALRM, oalarmfunc );
HmMyxflag = true;
for( i = 0; i < 11; i++ )
if( input[i] != '0' && input[i] != '1' )
{
HmMyxflag = false;
break;
}
TcResetTty( HmTtyFd );
}
}
#endif /* sun */
return true;
}
@@ -1092,7 +1039,7 @@ HmMenu *menup; /* -> first HmItem in array. */
/* If generator function is provided, dynamically allocate the
menu items.
*/
if( dynamic = menup->item == (HmItem *) NULL )
if( (dynamic = (menup->item == (HmItem *) NULL) ))
{ register int i;
register HmItem *gitemp;
HmLList llhead, **listp;
+2 -1
View File
@@ -7,9 +7,10 @@
$Header$ (BRL)
*/
#if ! defined( lint )
static char RCSid[] = "@(#)$Header$ (BRL)";
static const char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
#include <signal.h>
#include "./burst.h"
#include "./Hm.h"
/*LINTLIBRARY*/
+1 -1
View File
@@ -8,7 +8,7 @@
*/
/*LINTLIBRARY*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
static const char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
FILE *HmTtyFp = NULL; /* read keyboard, not stdin */
+2 -2
View File
@@ -8,8 +8,8 @@
*/
/* Emulate MUVES Mm package using malloc. */
#if __STDC__
extern char *malloc( unsigned n );
extern char *strcpy( char *s1, char *s2 );
#include <stdlib.h>
#include <string.h>
#else
extern char *malloc();
extern char *strcpy();
+28 -24
View File
@@ -9,15 +9,17 @@
*/
/*LINTLIBRARY*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
static const char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include "conf.h"
#include <stdio.h>
#ifdef BSD
#ifdef USE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#ifdef SYSV
#include <string.h>
#endif
#ifndef cray
#if defined( VLDSYSV )
#include <sys/_ioctl.h>
@@ -29,20 +31,22 @@ static char RCSid[] = "@(#)$Header$ (BRL)";
#include "./Sc.h"
/* Externals from termlib(3). */
#if _STDC_
#if __STDC__
extern char *tgoto( char *cm, int destcol, int destline );
extern char *tgetstr( char *id, char **area );
extern int tgetent( char *bp, char *name );
extern int tgetnum( char *id );
#else
extern char *tgoto();
extern char *tgetstr();
extern int tgetent();
extern int tgetnum();
#endif
extern int tputs();
/* Externals from the C library. */
#if _STDC_
#if __STDC__
extern char *getenv( char *s );
extern char *strncpy( char *a, char *b, int n );
#else
extern char *getenv();
extern char *strncpy();
@@ -87,7 +91,7 @@ int ScLI, /* Number of lines on screen. */
*/
static void
#if _STDC_
#if __STDC__
ScLoadTP( void )
#else
ScLoadTP()
@@ -119,7 +123,7 @@ ScLoadTP()
Get the terminal control strings.
*/
static void
#if _STDC_
#if __STDC__
ScLoadTCS( void )
#else
ScLoadTCS()
@@ -154,7 +158,7 @@ ScLoadTCS()
*/
int
#if _STDC_
#if __STDC__
PutChr( char c )
#else
PutChr( c )
@@ -181,7 +185,7 @@ char c;
there is a problem in retrieving the corresponding termcap entry.
*/
bool
#if _STDC_
#if __STDC__
ScInit( FILE *fp )
#else
ScInit( fp )
@@ -225,7 +229,7 @@ FILE *fp;
*/
bool
#if _STDC_
#if __STDC__
ScClrEOL( void )
#else
ScClrEOL()
@@ -244,7 +248,7 @@ ScClrEOL()
*/
bool
#if _STDC_
#if __STDC__
ScClrScrlReg( void )
#else
ScClrScrlReg()
@@ -263,7 +267,7 @@ ScClrScrlReg()
*/
bool
#if _STDC_
#if __STDC__
ScClrStandout( void )
#else
ScClrStandout()
@@ -281,7 +285,7 @@ ScClrStandout()
*/
bool
#if _STDC_
#if __STDC__
ScClrText( void )
#else
ScClrText()
@@ -300,7 +304,7 @@ ScClrText()
*/
bool
#if _STDC_
#if __STDC__
ScInsertLn( void )
#else
ScInsertLn()
@@ -319,7 +323,7 @@ ScInsertLn()
*/
bool
#if _STDC_
#if __STDC__
ScDeleteLn( void )
#else
ScDeleteLn()
@@ -338,7 +342,7 @@ ScDeleteLn()
*/
bool
#if _STDC_
#if __STDC__
ScDnScroll( void )
#else
ScDnScroll()
@@ -357,7 +361,7 @@ ScDnScroll()
*/
bool
#if _STDC_
#if __STDC__
ScHmCursor( void )
#else
ScHmCursor()
@@ -377,7 +381,7 @@ ScHmCursor()
*/
bool
#if _STDC_
#if __STDC__
ScMvCursor( int x, int y )
#else
ScMvCursor( x, y )
@@ -400,7 +404,7 @@ int x, y;
*/
bool
#if _STDC_
#if __STDC__
ScSetScrlReg( int top, int btm )
#else
ScSetScrlReg( top, btm )
@@ -420,7 +424,7 @@ int top, btm;
*/
bool
#if _STDC_
#if __STDC__
ScSetStandout( void )
#else
ScSetStandout()
@@ -439,7 +443,7 @@ ScSetStandout()
*/
bool
#if _STDC_
#if __STDC__
ScUpScroll( void )
#else
ScUpScroll()
+2 -1
View File
@@ -24,7 +24,8 @@
**/
#ifndef Sc_H_INCLUDE
#define Sc_H_INCLUDE
#include "burst.h"
#include "./burst.h"
#include "./Tc.h"
/**
bool ScInit( FILE *fp )
+32 -19
View File
@@ -1,4 +1,6 @@
/*
XXX Outdated : should not be used
SCCS id: %Z% %M% %I%
Modified: %G% at %U%
Retrieved: %H% at %T%
@@ -9,9 +11,12 @@
Aberdeen Proving Ground
Maryland 21005-5066
*/
#if 0
/*LINTLIBRARY*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
static const char RCSid[] = "@(#)$Header$ (BRL)";
static char sccsTag[] = "%Z% %M% %I%, modified %G% at %U%, archive %P%";
#endif
@@ -19,29 +24,35 @@ static char sccsTag[] = "%Z% %M% %I%, modified %G% at %U%, archive %P%";
#include <fcntl.h>
#ifdef SYSV
/**#ifndef TANDEM /* USG derivatives */
/**#ifndef TANDEM */
/* USG derivatives */
#include <termio.h>
#include <memory.h>
#ifndef _NFILE
#define _NFILE 32
#endif _NFILE
#endif /* _NFILE */
static struct termio save_tio[_NFILE], curr_tio[_NFILE];
#endif SYSV
#endif /* SYSV */
#ifdef BSD
#include <sys/ioctl.h>
#ifdef HAVE_IOCTL_COMPAT_H
#include <sys/ioctl_compat.h>
#endif
#ifndef _NFILE
#define _NFILE 32
#endif _NFILE
/****#ifdef TANDEM /* 7th Edition derivatives */
#endif /* _NFILE */
/****#ifdef TANDEM */
/* 7th Edition derivatives */
#define TCSETA TIOCSETP
#define TCGETA TIOCGETP
#ifndef XTABS
#define XTABS (TAB1 | TAB2)
#endif XTABS
#endif /* XTABS */
static struct sgttyb save_tio[_NFILE], curr_tio[_NFILE];
#endif BSD
#endif /* BSD */
void TcSaveTty(), TcResetTty();
void TcSetCbreak(), TcClrCbreak();
@@ -59,7 +70,7 @@ static void copy_Tio();
Clear CBREAK mode, for file descriptor "fd".
*/
void
#if _STDC_
#if __STDC__
TcClrCbreak( int fd )
#else
TcClrCbreak( fd )
@@ -85,7 +96,7 @@ int fd;
Set CBREAK mode, "fd".
*/
void
#if _STDC_
#if __STDC__
TcSetCbreak( int fd )
#else
TcSetCbreak( fd )
@@ -134,7 +145,7 @@ int fd;
Set raw mode, "fd".
*/
void
#if _STDC_
#if __STDC__
TcSetRaw( int fd )
#else
TcSetRaw( fd )
@@ -161,7 +172,7 @@ int fd;
Set echo mode, "fd".
*/
void
#if _STDC_
#if __STDC__
TcSetEcho( int fd )
#else
TcSetEcho( fd )
@@ -183,7 +194,7 @@ int fd;
Clear echo mode, "fd".
*/
void
#if _STDC_
#if __STDC__
TcClrEcho( int fd )
#else
TcClrEcho( fd )
@@ -205,7 +216,7 @@ int fd;
Turn on tab expansion, "fd".
*/
void
#if _STDC_
#if __STDC__
TcSetTabs( int fd )
#else
TcSetTabs( fd )
@@ -229,7 +240,7 @@ int fd;
Turn off tab expansion, "fd".
*/
void
#if _STDC_
#if __STDC__
TcClrTabs( int fd )
#else
TcClrTabs( fd )
@@ -253,7 +264,7 @@ int fd;
Turn on "Hang up on last close", "fd".
*/
void
#if _STDC_
#if __STDC__
TcSetHUPCL( int fd )
#else
TcSetHUPCL( fd )
@@ -277,7 +288,7 @@ int fd;
Turn off CR/LF mapping, "fd".
*/
void
#if _STDC_
#if __STDC__
TcClrCRNL( int fd )
#else
TcClrCRNL( fd )
@@ -300,7 +311,7 @@ TcClrCRNL( fd )
Get and save terminal parameters, "fd".
*/
void
#if _STDC_
#if __STDC__
TcSaveTty( int fd )
#else
TcSaveTty( fd )
@@ -319,7 +330,7 @@ int fd;
TcSaveTty() was called for "fd".
*/
void
#if _STDC_
#if __STDC__
TcResetTty( int fd )
#else
TcResetTty( fd )
@@ -382,3 +393,5 @@ struct termio *tio_ptr;
#endif
return;
}
#endif
+21
View File
@@ -12,6 +12,8 @@
*/
/**
<Tc.h> -- MUVES "Tc" (terminal control) package definitions
Rewritten to use BRL-CAD's libtermio
**/
/**
@@ -23,6 +25,8 @@
#ifndef Tc_H_INCLUDE
#define Tc_H_INCLUDE
#if 0
/**
All of these functions take effect on the stream specified
@@ -88,6 +92,23 @@ extern void TcSetRaw();
extern void TcSetTabs();
#endif
#else
#define TcClrCRNL clr_CRNL
#define TcClrCbreak clr_Cbreak
#define TcClrEcho clr_Echo
#define TcClrRaw clr_Raw
#define TcClrTabs clr_Tabs
#define TcResetTty reset_Tty
#define TcSaveTty save_Tty
#define TcSetCbreak set_Cbreak
#define TcSetEcho set_Echo
#define TcSetHUPCL set_HUPCL
#define TcSetRaw set_Raw
#define TcSetTabs set_Tabs
#endif
#endif /* Tc_H_INCLUDE */
+8 -11
View File
@@ -5,7 +5,7 @@
Maryland 21005-5066
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
static const char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#ifndef DEBUG
@@ -16,7 +16,6 @@ static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <assert.h>
#include <stdio.h>
#include <signal.h>
@@ -133,8 +132,6 @@ int argc;
char **argv;
#endif
{ register int c;
extern int optind;
extern char *optarg;
/* Parse options. */
while( (c = getopt( argc, argv, "b" )) != EOF )
{
@@ -169,12 +166,12 @@ FILE *fp;
{ Func *cmdfunc;
if( (cmdfunc = getTrie( cmdname, cmdtrie )) == NULL )
{ register int i, len = strlen( cmdname );
rt_log( "ERROR -- command syntax:\n" );
rt_log( "\t%s\n", cmdbuf );
rt_log( "\t" );
brst_log( "ERROR -- command syntax:\n" );
brst_log( "\t%s\n", cmdbuf );
brst_log( "\t" );
for( i = 0; i < len; i++ )
rt_log( " " );
rt_log( "^\n" );
brst_log( " " );
brst_log( "^\n" );
}
else
if( strcmp( cmdname, CMD_COMMENT ) == 0 )
@@ -240,9 +237,9 @@ char *argv[];
readBatchInput( stdin );
if( tty )
(void) HmHit( mainhmenu );
exitCleanly( EXIT_SUCCESS );
exitCleanly( BURST_EXIT_SUCCESS );
clean: (void) unlink( tmpfname );
death: return EXIT_FAILURE;
death: return BURST_EXIT_FAILURE;
}
/*
+2 -2
View File
@@ -3,7 +3,7 @@ Shotline file output format from burst program:
record type: 1
description: header line for each aspect
ICD reference: Line Number 1, Figure 19.
format: '1',2(1x,f8.4),5(1x,f7.2),1x,6a
format: '1',1x,f9.4,1x,f8.4,5(1x,f7.2),1x,6a
data: attack azimuth in degrees
attack elevation in degrees
shotline separation
@@ -37,7 +37,7 @@ Burst Point Library output format from burst program:
record type: 1
description: header line for each aspect
ICD reference: Line Number 1, Figure 20.
format: '1',2(1x,f8.4),1x,f5.2,1x,f10.2,1x,6a,1x,f9.6
format: '1',1x,f9.4,1x,f8.4,1x,f5.2,1x,f10.2,1x,6a,1x,f9.6
data: attack azimuth in degrees
attack elevation in degrees
burst distance
+10 -34
View File
@@ -9,6 +9,11 @@
#ifndef INCL_BURST
#define INCL_BURST
/* NSIG not always defined in <signal.h> */
#ifndef NSIG
#define NSIG 64
#endif
/* Some useful stuff from Doug Gwyn's std.h. */
/* Extended data types */
typedef int bool; /* Boolean data */
@@ -33,11 +38,11 @@ typedef char *pointer; /* generic pointer */
#define signed /* nothing */ /* ANSI C type specifier */
#define volatile /* nothing */ /* ANSI C type qualifier */
#endif
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#ifndef BURST_EXIT_SUCCESS
#define BURST_EXIT_SUCCESS 0
#endif
#ifndef EXIT_FAILURE
#define EXIT_FAILURE 1
#ifndef BURST_EXIT_FAILURE
#define BURST_EXIT_FAILURE 1
#endif
#define DEGRAD 57.2957795130823208767981548141051703324054724665642
@@ -201,37 +206,8 @@ typedef char *pointer; /* generic pointer */
#define OutsideAir(rp) ((rp)->reg_aircode == OUTSIDE_AIR)
#define InsideAir(rp) (Air(rp)&& !OutsideAir(rp))
#define Check_Iflip( _pp, _normal, _rdir )\
{ fastf_t f;\
if( _pp->pt_inflip )\
{\
ScaleVec( _normal, -1.0 );\
_pp->pt_inflip = 0;\
}\
f = Dot( _rdir, _normal );\
if( f >= 0.0 )\
{\
ScaleVec( _normal, -1.0 );\
rt_log( "Fixed flipped entry normal\n" );\
}\
}
#define Check_Oflip( _pp, _normal, _rdir )\
{ fastf_t f;\
if( _pp->pt_outflip )\
{\
ScaleVec( _normal, -1.0 );\
_pp->pt_outflip = 0;\
}\
f = Dot( _rdir, _normal );\
if( f <= 0.0 )\
{\
ScaleVec( _normal, -1.0 );\
rt_log( "Fixed flipped exit normal\n" );\
}\
}
#define Malloc_Bomb( _bytes_ ) \
rt_log( "\"%s\"(%d) : allocation of %d bytes failed.\n",\
brst_log( "\"%s\"(%d) : allocation of %d bytes failed.\n",\
__FILE__, __LINE__, _bytes_ )
#define Swap_Doubles( a_, b_ ) \
+39 -17
View File
@@ -5,7 +5,7 @@
Maryland 21005-5066
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
static const char RCSid[] = "@(#)$Header$ (BRL)";
#endif
/*
* E R R O R
@@ -14,14 +14,14 @@ static char RCSid[] = "@(#)$Header$ (BRL)";
*
* Functions -
* rt_bomb Called upon fatal RT library error.
* rt_log Called to log RT library events.
* brst_log Called to log RT library events.
* fb_log Called to log FB library events.
*
* Idea originated by Mike John Muuss
*/
#include <stdio.h>
#include <varargs.h>
#include <signal.h>
#include "./Sc.h"
#include "./extern.h"
@@ -34,25 +34,33 @@ void
rt_bomb(str)
char *str;
{
rt_log( "%s (librt.a) : Fatal error, aborting!\n", str );
brst_log( "%s (librt.a) : Fatal error, aborting!\n", str );
(void) fflush( stdout );
(void) abort(); /* Should dump. */
exit(12);
/* exit(12); XXX - this shouldn't be needed */
}
/*
* R T _ L O G
* B R S T _ L O G
*
* Log an RT library event
*/
/* VARARGS */
void
rt_log( va_alist )
#if defined(HAVE_STDARG_H)
brst_log( char *fmt, ... )
{
va_list ap;
va_start( ap, fmt );
#else
brst_log( va_alist )
va_dcl
{ register char *format; /* picked up by va_arg() */
va_list ap;
{
register char *fmt; /* picked up by va_arg() */
va_list ap;
va_start( ap );
format = va_arg( ap, char * );
fmt = va_arg( ap, char * );
#endif
if( tty && (errfile[0] == '\0' || ! strcmp( errfile, "/dev/tty" )) )
{
TcClrTabs( HmTtyFd );
@@ -62,7 +70,7 @@ va_dcl
(void) ScDeleteLn();
(void) ScMvCursor( 1, SCROLL_BTM );
(void) ScClrEOL();
(void) vprintf( format, ap );
(void) vprintf( fmt, ap );
}
else
if( ScSetScrlReg( SCROLL_TOP, SCROLL_BTM+1 ) )
@@ -72,13 +80,13 @@ va_dcl
(void) ScClrEOL();
/* Work around for problem with vprintf(): it doesn't
cause the screen to scroll, don't know why. */
(void) vsprintf( buf, format, ap );
(void) vsprintf( buf, fmt, ap );
/* Newline will cause double scroll. */
p = buf+strlen(buf)-1;
if( *p == '\n' )
*p = '\0'; /* clobber newline */
(void) puts( buf );
/*(void) vprintf( format, ap );*/
/*(void) vprintf( fmt, ap );*/
(void) ScMvCursor( 1, SCROLL_BTM+1 );
(void) ScClrScrlReg();
}
@@ -97,7 +105,7 @@ va_dcl
}
else
{
(void) vfprintf( stderr, format, ap );
(void) vfprintf( stderr, fmt, ap );
}
va_end( ap );
}
@@ -107,11 +115,25 @@ va_dcl
*
* Log an FB library event
*/
/* VARARGS */
/*VARARGS*/
void
#if __STDC__
fb_log(char *fmt, ...)
#else
fb_log( va_alist )
va_dcl
#endif
{
(void) rt_log( va_alist );
return;
#if ! __STDC__
register char *fmt;
#endif
va_list ap;
#if __STDC__
va_start( ap, fmt );
#else
va_start( ap );
fmt = va_arg( ap, char * );
#endif
(void) brst_log( fmt, ap );
va_end( ap );
}
+52 -15
View File
@@ -7,6 +7,18 @@
$Header$ (BRL)
*/
#include "conf.h"
#if defined(HAVE_STDARG_H)
# include <stdarg.h>
#else
#include <varargs.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include "machine.h"
#include "fb.h"
@@ -16,21 +28,21 @@
#include "./Hm.h"
/* External functions from C library. */
#ifdef __STDC__
#if (__STDC__ && ! apollo) || (sgi && mips && BRLCAD4_0)
#include <stdlib.h>
extern pointer sbrk( int );
#else
extern char *fgets();
extern char *getenv();
extern char *malloc();
extern char *tmpnam();
extern pointer sbrk();
#endif
#ifdef SYSV
extern long lrand48();
#else
#if !defined(linux)
extern long random();
#endif
#endif
/* External variables from termlib. */
extern char *CS, *DL;
@@ -40,6 +52,8 @@ extern int CO, LI;
extern Colors *findColors();
extern Func *getTrie();
extern Trie *addTrie();
extern bool chkEntryNorm();
extern bool chkExitNorm();
extern bool closFbDevice();
extern bool imageInit();
extern bool initUi();
@@ -48,11 +62,12 @@ extern bool findIdents();
extern bool readColors();
extern bool readIdents();
extern int notify();
extern int round();
extern int roundToInt();
extern void closeUi();
extern void colorPartition();
extern void exitCleanly();
extern void freeIdents();
extern void getRtHitNorm();
extern void gridInit();
extern void gridModel();
extern void gridToFb();
@@ -68,6 +83,7 @@ extern void plotRay();
extern void prntAspectInit();
extern void prntBurstHdr();
extern void prntCellIdent();
extern void prntDbgPartitions();
extern void prntFiringCoords();
extern void prntFusingComp();
extern void prntGridOffsets();
@@ -75,12 +91,33 @@ extern void prntIdents();
extern void prntPhantom();
extern void prntRayHeader();
extern void prntRayIntersect();
extern void prntScr();
extern void prntTimer();
extern void prompt();
extern void readCmdFile();
extern void rt_log();
#if defined(HAVE_STDARG_H)
extern void prntScr( char *, ...);
extern void brst_log( char *, ... );
#else
extern void brst_log();
extern void prntScr();
#endif
extern void warning();
extern void prntUsage();
extern void clr_Tabs();
extern void prntShieldComp();
extern void qFree();
extern void prntRegionHdr();
extern int qAdd();
extern void prntSeg();
extern void gridRotate();
extern void HmBanner();
extern void spallInit();
extern void readBatchInput();
extern void set_Cbreak();
extern void clr_Echo();
extern void clr_Tabs();
extern void reset_Tty();
extern void save_Tty();
#if STD_SIGNAL_DECLS
extern void (*norml_sig)(), (*abort_sig)();
@@ -106,15 +143,15 @@ extern HmMenu *mainhmenu;
extern Ids airids;
extern Ids armorids;
extern Ids critids;
extern RGBpixel *pixgrid;
extern RGBpixel pixaxis;
extern RGBpixel pixbkgr;
extern RGBpixel pixbhit;
extern RGBpixel pixblack;
extern RGBpixel pixcrit;
extern RGBpixel pixghit;
extern RGBpixel pixmiss;
extern RGBpixel pixtarg;
extern unsigned char *pixgrid;
extern unsigned char pixaxis[3];
extern unsigned char pixbkgr[3];
extern unsigned char pixbhit[3];
extern unsigned char pixblack[3];
extern unsigned char pixcrit[3];
extern unsigned char pixghit[3];
extern unsigned char pixmiss[3];
extern unsigned char pixtarg[3];
extern Trie *cmdtrie;
extern bool batchmode;
+17 -17
View File
@@ -5,11 +5,12 @@
Maryland 21005-5066
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
static const char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <signal.h>
#include "fb.h"
#include "./burst.h"
#include "./ascii.h"
@@ -71,17 +72,16 @@ char *devname;
goto safe_exit;
}
if( ( (fbiop != FBIO_NULL && fb_getwidth( fbiop ) != devwid)
|| pixgrid == NULL
)
&& (pixgrid = (RGBpixel *) malloc( sizeof(RGBpixel)*devwid ))
== (RGBpixel *) NULL )
|| pixgrid == NULL)
&& (pixgrid = (unsigned char *) calloc( devwid*3, sizeof(unsigned char) ))
== (unsigned char *) NULL )
{
prntScr( "Memory allocation of %d bytes failed.",
sizeof(RGBpixel)*devwid );
ret = false;
goto safe_exit;
prntScr( "Memory allocation of %d bytes failed.",
sizeof(unsigned char)*devwid );
ret = false;
goto safe_exit;
}
(void) memset( (char *) pixgrid, NUL, sizeof(RGBpixel)*devwid );
(void) memset( (char *) pixgrid, NUL, sizeof(unsigned char)*devwid*3 );
if( fbiop != FBIO_NULL )
{
#if SGI_WINCLOSE_BUG
@@ -100,17 +100,17 @@ char *devname;
}
}
if( (fbiop = fb_open( devname, devwid, devhgt )) == NULL )
fbiop = fb_open( devname, devwid, devhgt );
if( fbiop == NULL )
{
ret = false;
goto safe_exit;
}
else
if( fb_clear( fbiop, pixblack ) == -1
|| notify( "Zooming", NOTIFY_APPEND ),
fb_zoom( fbiop, 1, 1 ) == -1
|| notify( "Windowing", NOTIFY_DELETE ),
fb_window( fbiop, devwid/2, devhgt/2 ) == -1
else if( fb_clear( fbiop, pixblack ) == -1
|| (notify( "Zooming", NOTIFY_APPEND ),
fb_zoom( fbiop, 1, 1 ) == -1)
|| (notify( "Windowing", NOTIFY_DELETE ),
fb_window( fbiop, devwid/2, devhgt/2 ) == -1)
)
{
ret = false;
+11 -10
View File
@@ -5,9 +5,10 @@
Maryland 21005-5066
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
static const char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
#include <signal.h>
#include "machine.h"
#include "vmath.h"
#include "fb.h"
@@ -29,15 +30,15 @@ HmMenu *mainhmenu;
Ids airids; /* burst air idents */
Ids armorids; /* burst armor idents */
Ids critids; /* critical component idents */
RGBpixel *pixgrid;
RGBpixel pixaxis = { 255, 0, 0 }; /* grid axis */
RGBpixel pixbhit = { 200, 255, 200 }; /* burst ray hit non-critical comps */
RGBpixel pixbkgr = { 150, 100, 255 }; /* outside grid */
RGBpixel pixblack = { 0, 0, 0 }; /* black */
RGBpixel pixcrit = { 255, 200, 200 }; /* burst ray hit critical component */
RGBpixel pixghit = { 255, 0, 255 }; /* ground burst */
RGBpixel pixmiss = { 200, 200, 200 }; /* shot missed target */
RGBpixel pixtarg = { 255, 255, 255 }; /* shot hit target */
unsigned char *pixgrid;
unsigned char pixaxis[3] = { 255, 0, 0 }; /* grid axis */
unsigned char pixbhit[3] = { 200, 255, 200 }; /* burst ray hit non-critical comps */
unsigned char pixbkgr[3] = { 150, 100, 255 }; /* outside grid */
unsigned char pixblack[3] = { 0, 0, 0 }; /* black */
unsigned char pixcrit[3] = { 255, 200, 200 }; /* burst ray hit critical component */
unsigned char pixghit[3] = { 255, 0, 255 }; /* ground burst */
unsigned char pixmiss[3] = { 200, 200, 200 }; /* shot missed target */
unsigned char pixtarg[3] = { 255, 255, 255 }; /* shot hit target */
Trie *cmdtrie = NULL;
bool batchmode = false; /* are we processing batch input now */
+340 -130
View File
@@ -5,7 +5,7 @@
Maryland 21005-5066
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
static const char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#ifndef DEBUG
@@ -23,9 +23,12 @@ static char RCSid[] = "@(#)$Header$ (BRL)";
#include <math.h>
#include "machine.h"
#include "bu.h"
#include "vmath.h"
#include "bn.h"
#include "raytrace.h"
#include "fb.h"
#include "plot3.h"
#include "./vecmath.h"
#include "./ascii.h"
@@ -84,7 +87,7 @@ int type;
if( plotfile[0] == NUL )
return;
assert( plotfp != NULL );
RES_ACQUIRE( &rt_g.res_syscall );
bu_semaphore_acquire( BU_SEM_SYSCALL );
switch( type )
{
case C_CRIT :
@@ -120,10 +123,10 @@ int type;
);
break;
default :
rt_log( "colorPartition: bad type %d.\n", type );
brst_log( "colorPartition: bad type %d.\n", type );
break;
}
RES_RELEASE( &rt_g.res_syscall );
bu_semaphore_release( BU_SEM_SYSCALL );
return;
}
@@ -150,10 +153,12 @@ doBursts()
break;
ag.a_level = 0; /* initialize recursion level */
plotGrid( burstpoint );
prntBurstHdr( burstpoint, viewdir );
if( ! burstPoint( &ag, zaxis, burstpoint ) )
{
/* fatal error in application routine */
rt_log( "Fatal error: raytracing aborted.\n" );
brst_log( "Fatal error: raytracing aborted.\n" );
return false;
}
if( ! TSTBIT(firemode,FM_FILE) )
@@ -201,13 +206,17 @@ register struct partition *pt_headp;
critical components were encountered.
*/
STATIC int
f_BurstHit( ap, pt_headp )
f_BurstHit( ap, pt_headp, segp )
struct application *ap;
struct partition *pt_headp;
{ Pt_Queue *qshield = PT_Q_NULL;
register struct partition *cpp, *spp;
register int nbar;
register int ncrit = 0;
struct seg *segp;
{ Pt_Queue *qshield = PT_Q_NULL;
register struct partition *cpp, *spp;
register int nbar;
register int ncrit = 0;
#ifdef VDEBUG
prntDbgPartitions( ap, pt_headp, "f_BurstHit: initial partitions" );
#endif
/* Find first barrier in front of the burst point. */
for( spp = pt_headp->pt_forw;
spp != pt_headp
@@ -224,7 +233,7 @@ struct partition *pt_headp;
if( Air( regp ) )
continue; /* Air doesn't matter here. */
if( findIdents( regp->reg_regionid, &critids ) )
{
{ fastf_t entrynorm[3], exitnorm[3];
if( ncrit == 0 )
prntRayHeader( ap->a_ray.r_dir, viewdir,
ap->a_user );
@@ -235,13 +244,14 @@ struct partition *pt_headp;
/* Output critical component intersection;
prntRegionHdr fills in hit entry/exit normals. */
prntRegionHdr( ap, pt_headp, cpp );
prntRegionHdr( ap, pt_headp, cpp, entrynorm, exitnorm );
colorPartition( regp, C_CRIT );
plotPartition( cpp->pt_inhit, cpp->pt_outhit,
rayp, regp );
if( fbfile[0] != NUL && ncrit == 0 )
/* first hit on critical component */
lgtModel( ap, cpp, cpp->pt_inhit, rayp );
lgtModel( ap, cpp, cpp->pt_inhit, rayp,
entrynorm );
ncrit++;
}
else
@@ -263,61 +273,117 @@ struct partition *pt_headp;
return ncrit;
}
/*
int f_HushOverlap( struct application *ap, struct partition *pp,
struct region *reg1, struct region *reg2 )
struct region *reg1, struct region *reg2,
struct partition *pheadp )
Do not report diagnostics about individual overlaps, but keep count
of significant ones (at least as thick as OVERLAP_TOL).
Some of this code is from librt/bool.c:rt_defoverlap() for
consistency of which region is picked.
Returns -
0 to eliminate partition with overlap entirely
1 to retain partition in output list, claimed by reg1
2 to retain partition in output list, claimed by reg2
*/
/*ARGSUSED*/
STATIC int
f_HushOverlap( ap, pp, reg1, reg2 )
struct application *ap;
struct partition *pp;
struct region *reg1, *reg2;
{ fastf_t depth = pp->pt_outhit->hit_dist -
pp->pt_inhit->hit_dist;
if( depth < OVERLAP_TOL )
return 1;
noverlaps++;
return 1;
f_HushOverlap( ap, pp, reg1, reg2, pheadp )
struct application *ap;
struct partition *pp;
struct region *reg1, *reg2;
struct partition *pheadp;
{ fastf_t depth;
#ifdef BRLCAD4_0
RT_CHECK_PT(pp);
#endif
depth = pp->pt_outhit->hit_dist - pp->pt_inhit->hit_dist;
if( depth >= OVERLAP_TOL )
noverlaps++;
/* Apply heuristics as to which region should claim partition. */
if( reg1->reg_aircode != 0 )
/* reg1 was air, replace with reg2 */
return 2;
if( pp->pt_back != pheadp )
{ /* Repeat a prev region, if that is a choice */
if( pp->pt_back->pt_regionp == reg1 )
return 1;
if( pp->pt_back->pt_regionp == reg2 )
return 2;
}
/* To provide some consistency from ray to ray, use lowest bit # */
if( reg1->reg_bit < reg2->reg_bit )
return 1;
return 2;
}
/*
int f_Overlap( struct application *ap, struct partition *pp,
struct region *reg1, struct region *reg2 )
struct region *reg1, struct region *reg2,
struct partition *pheadp )
Do report diagnostics and keep count of individual overlaps
that are at least as thick as OVERLAP_TOL.
Some of this code is from librt/bool.c:rt_defoverlap() for
consistency of which region is picked.
Returns -
0 to eliminate partition with overlap entirely
1 to retain partition in output list, claimed by reg1
2 to retain partition in output list, claimed by reg2
*/
/*ARGSUSED*/
STATIC int
f_Overlap( ap, pp, reg1, reg2 )
struct application *ap;
struct partition *pp;
struct region *reg1, *reg2;
{ point_t pt;
fastf_t depth = pp->pt_outhit->hit_dist -
pp->pt_inhit->hit_dist;
if( depth < OVERLAP_TOL )
return 1;
VJOIN1( pt, ap->a_ray.r_pt, pp->pt_inhit->hit_dist,
ap->a_ray.r_dir );
rt_log( "OVERLAP:\n" );
rt_log( "reg=%s isol=%s,\n",
reg1->reg_name, pp->pt_inseg->seg_stp->st_name
);
rt_log( "reg=%s osol=%s,\n",
reg2->reg_name, pp->pt_outseg->seg_stp->st_name
);
rt_log( "depth %.2fmm at (%g,%g,%g) x%d y%d lvl%d purpose=%s\n",
depth,
pt[X], pt[Y], pt[Z],
ap->a_x, ap->a_y, ap->a_level, ap->a_purpose
);
noverlaps++;
return 1;
f_Overlap( ap, pp, reg1, reg2, pheadp )
struct application *ap;
struct partition *pp;
struct region *reg1, *reg2;
struct partition *pheadp;
{ fastf_t depth;
point_t pt;
#ifdef BRLCAD4_0
RT_CHECK_PT(pp);
#endif
depth = pp->pt_outhit->hit_dist - pp->pt_inhit->hit_dist;
if( depth >= OVERLAP_TOL )
{
noverlaps++;
VJOIN1( pt, ap->a_ray.r_pt, pp->pt_inhit->hit_dist,
ap->a_ray.r_dir );
brst_log( "OVERLAP:\n" );
brst_log( "reg=%s isol=%s,\n",
reg1->reg_name, pp->pt_inseg->seg_stp->st_name
);
brst_log( "reg=%s osol=%s,\n",
reg2->reg_name, pp->pt_outseg->seg_stp->st_name
);
brst_log( "depth %.2fmm at (%g,%g,%g) x%d y%d lvl%d purpose=%s\n",
depth,
pt[X], pt[Y], pt[Z],
ap->a_x, ap->a_y, ap->a_level, ap->a_purpose
);
}
/* Apply heuristics as to which region should claim partition. */
if( reg1->reg_aircode != 0 )
/* reg1 was air, replace with reg2 */
return 2;
if( pp->pt_back != pheadp )
{ /* Repeat a prev region, if that is a choice */
if( pp->pt_back->pt_regionp == reg1 )
return 1;
if( pp->pt_back->pt_regionp == reg2 )
return 2;
}
/* To provide some consistency from ray to ray, use lowest bit # */
if( reg1->reg_bit < reg2->reg_bit )
return 1;
return 2;
}
/*
@@ -333,15 +399,17 @@ struct region *reg1, *reg2;
handed to rt_shootray() by burstRay(). Otherwise, true is returned.
*/
STATIC int
f_ShotHit( ap, pt_headp )
f_ShotHit( ap, pt_headp, segp )
struct application *ap;
struct partition *pt_headp;
struct seg *segp;
{ register struct partition *pp;
struct partition *bp = PT_NULL;
struct partition *bp = PT_NULL;
fastf_t burstnorm[3]; /* normal at burst point */
#if DEBUG_GRID
rt_log( "f_ShotHit\n" );
brst_log( "f_ShotHit\n" );
for( pp = pt_headp->pt_forw; pp != pt_headp; pp = pp->pt_forw )
rt_log( "\tregion is '%s',\tid=%d\taircode=%d\n",
brst_log( "\tregion is '%s',\tid=%d\taircode=%d\n",
pp->pt_regionp->reg_name,
(int) pp->pt_regionp->reg_regionid,
(int) pp->pt_regionp->reg_aircode );
@@ -390,16 +458,16 @@ struct partition *pt_headp;
if( np != pt_headp )
{
#if DEBUG_GRID
rt_log( "\tprocessing region '%s',\tid=%d\taircode=%d\n",
brst_log( "\tprocessing region '%s',\tid=%d\taircode=%d\n",
pp->pt_regionp->reg_name,
(int) pp->pt_regionp->reg_regionid,
(int) pp->pt_regionp->reg_aircode );
rt_log( "\tcheck for voids\n" );
brst_log( "\tcheck for voids\n" );
#endif
los = np->pt_inhit->hit_dist -
pp->pt_outhit->hit_dist;
#if DEBUG_GRID
rt_log( "\tlos=%g tolerance=%g\n",
brst_log( "\tlos=%g tolerance=%g\n",
los, LOS_TOL );
#endif
voidflag = ( los > LOS_TOL );
@@ -408,7 +476,7 @@ struct partition *pt_headp;
if( OutsideAir( np->pt_regionp ) )
{
#if DEBUG_GRID
rt_log( "\t\toutside air\n" );
brst_log( "\t\toutside air\n" );
#endif
if( voidflag )
{
@@ -442,7 +510,7 @@ struct partition *pt_headp;
if( np != pt_headp && InsideAir( np->pt_regionp ) )
{
#if DEBUG_GRID
rt_log( "\tmerging inside airs\n" );
brst_log( "\tmerging inside airs\n" );
#endif
for( cp = np->pt_forw;
cp != pt_headp;
@@ -467,7 +535,7 @@ struct partition *pt_headp;
/* If adjacent partitions are the same air, extend
the first on to include them. */
#if DEBUG_GRID
rt_log( "\tphantom armor before internal air\n" );
brst_log( "\tphantom armor before internal air\n" );
#endif
for( cp = np; cp != pt_headp; cp = cp->pt_forw )
{
@@ -489,37 +557,54 @@ struct partition *pt_headp;
}
else
if( ! Air( regp ) ) /* If we have a component, output it. */
{
{ fastf_t entrynorm[3]; /* normal at entry */
fastf_t exitnorm[3]; /* normal at exit */
/* Get entry normal. */
getRtHitNorm( pp->pt_inhit, pp->pt_inseg->seg_stp,
&ap->a_ray, (bool) pp->pt_inflip, entrynorm );
(void) chkEntryNorm( pp, &ap->a_ray, entrynorm,
"shotline entry normal" );
/* Get exit normal. */
getRtHitNorm( pp->pt_outhit, pp->pt_outseg->seg_stp,
&ap->a_ray, (bool) pp->pt_outflip, exitnorm );
(void) chkExitNorm( pp, &ap->a_ray, exitnorm,
"shotline exit normal" );
#if DEBUG_GRID
rt_log( "\twe have a component\n" );
brst_log( "\twe have a component\n" );
#endif
/* In the case of fragmenting munitions, a hit on any
component will cause a burst point. */
if( bp == PT_NULL && bdist > 0.0 )
{
bp = pp; /* register exterior burst */
CopyVec( burstnorm, exitnorm );
}
/* If there is a void, output 01 air as space. */
if( voidflag )
{
#if DEBUG_GRID
rt_log( "\t\tthere is a void, %s\n",
brst_log( "\t\tthere is a void, %s\n",
"so outputting 01 air" );
#endif
if( bp == PT_NULL && ! reqburstair
&& findIdents( regp->reg_regionid,
&armorids ) )
/* Bursting on armor/void (ouchh). */
{ /* Bursting on armor/void (ouchh). */
bp = pp;
prntSeg( ap, pp, OUTSIDE_AIR );
CopyVec( burstnorm, exitnorm );
}
prntSeg( ap, pp, OUTSIDE_AIR,
entrynorm, exitnorm, pp == bp );
}
else
/* If air expicitly follows, output space code. */
if( np != pt_headp && Air( nregp ) )
{ fastf_t slos = np->pt_outhit->hit_dist -
np->pt_inhit->hit_dist;
{
/* Check for interior burst point. */
#if DEBUG_GRID
rt_log( "\t\texplicit air follows\n" );
brst_log( "\t\texplicit air follows\n" );
#endif
if( bp == PT_NULL && bdist <= 0.0
&& findIdents( regp->reg_regionid,
@@ -528,24 +613,29 @@ struct partition *pt_headp;
|| findIdents( nregp->reg_aircode,
&airids ))
)
{
bp = pp; /* register interior burst */
prntSeg( ap, pp, nregp->reg_aircode );
CopyVec( burstnorm, exitnorm );
}
prntSeg( ap, pp, nregp->reg_aircode,
entrynorm, exitnorm, pp == bp );
}
else
if( np == pt_headp )
{
/* Last component gets 09 air. */
#if DEBUG_GRID
rt_log( "\t\tlast component\n" );
brst_log( "\t\tlast component\n" );
#endif
prntSeg( ap, pp, EXIT_AIR );
prntSeg( ap, pp, EXIT_AIR,
entrynorm, exitnorm, pp == bp );
}
else
/* No air follows component. */
if( SameCmp( regp, nregp ) )
{
#if DEBUG_GRID
rt_log( "\t\tmerging adjacent components\n" );
brst_log( "\t\tmerging adjacent components\n" );
#endif
/* Merge adjacent components with same
idents. */
@@ -557,9 +647,11 @@ struct partition *pt_headp;
else
{
#if DEBUG_GRID
rt_log( "\t\tdifferent component follows\n" );
brst_log( "\t\tdifferent component follows\n" );
#endif
prntSeg( ap, pp, 0 ); /* component follows */
prntSeg( ap, pp, 0,
entrynorm, exitnorm, pp == bp );
/* component follows */
}
}
/* Check for adjacency of differing airs, implicit or
@@ -567,7 +659,7 @@ struct partition *pt_headp;
if( InsideAir( regp ) )
{
#if DEBUG_GRID
rt_log( "\tcheck for adjacency of differing airs; inside air\n" );
brst_log( "\tcheck for adjacency of differing airs; inside air\n" );
#endif
/* Inside air followed by implicit outside air. */
if( voidflag )
@@ -577,7 +669,7 @@ struct partition *pt_headp;
if( np != pt_headp )
{
#if DEBUG_GRID
rt_log( "\tcheck next partition for adjacency\n" );
brst_log( "\tcheck next partition for adjacency\n" );
#endif
/* See if inside air follows impl. outside air. */
if( voidflag && InsideAir( nregp ) )
@@ -585,7 +677,7 @@ struct partition *pt_headp;
np->pt_outhit->hit_dist -
np->pt_inhit->hit_dist;
#if DEBUG_GRID
rt_log( "\t\tinside air follows impl. outside air\n" );
brst_log( "\t\tinside air follows impl. outside air\n" );
#endif
prntPhantom( np->pt_inhit, nregp->reg_aircode,
slos );
@@ -600,7 +692,7 @@ struct partition *pt_headp;
{ fastf_t slos = np->pt_outhit->hit_dist -
np->pt_inhit->hit_dist;
#if DEBUG_GRID
rt_log( "\t\tdiffering airs are adjacent\n" );
brst_log( "\t\tdiffering airs are adjacent\n" );
#endif
prntPhantom( np->pt_inhit,
(int) nregp->reg_aircode,
@@ -611,7 +703,7 @@ struct partition *pt_headp;
if( np == pt_headp && InsideAir( regp ) )
{
#if DEBUG_GRID
rt_log( "\tinternal air last hit\n" );
brst_log( "\tinternal air last hit\n" );
#endif
prntPhantom( pp->pt_outhit, EXIT_AIR, 0.0 );
}
@@ -621,8 +713,6 @@ struct partition *pt_headp;
if( bp != PT_NULL )
{ fastf_t burstpt[3];
register struct hit *ohitp;
register struct soltab *stp;
/* This is a burst point, calculate coordinates. */
if( bdist > 0.0 )
{ /* Exterior burst point (i.e. case-fragmenting
@@ -648,16 +738,132 @@ struct partition *pt_headp;
if( nspallrays < 1 )
return true;
/* fill in hit point and normal */
stp = bp->pt_outseg->seg_stp;
ohitp = bp->pt_outhit;
RT_HIT_NORM( ohitp, stp, &(ap->a_ray) );
Check_Oflip( bp, ohitp->hit_normal, ap->a_ray.r_dir );
return burstPoint( ap, ohitp->hit_normal, burstpt );
return burstPoint( ap, burstnorm, burstpt );
}
return true;
}
/*
void getRtHitNorm( struct hit *hitp, struct soltab *stp,
struct xray *rayp, bool flipped, fastf_t normvec[3] )
Fill normal and hit point into hit struct and if the flipped
flag is set, reverse the normal. Return a private copy of the
flipped normal in normvec. NOTE: the normal placed in the hit
struct should not be modified (ie reversed) by the application
because it can be instanced by other solids.
*/
void
getRtHitNorm( hitp, stp, rayp, flipped, normvec )
struct hit *hitp;
struct soltab *stp;
struct xray *rayp;
bool flipped;
fastf_t normvec[3];
{
RT_HIT_NORMAL( normvec, hitp, stp, rayp, flipped );
}
bool
chkEntryNorm( pp, rayp, normvec, purpose )
struct partition *pp;
struct xray *rayp;
fastf_t normvec[3];
char *purpose;
{ fastf_t f;
static int flipct = 0;
static int totalct = 0;
struct soltab *stp = pp->pt_inseg->seg_stp;
bool ret = true;
totalct++;
/* Dot product of ray direction with normal *should* be negative. */
f = Dot( rayp->r_dir, normvec );
if( NearZero( f ) )
{
#ifdef DEBUG
brst_log( "chkEntryNorm: near 90 degree obliquity.\n" );
brst_log( "\tPnt %g,%g,%g\n\tDir %g,%g,%g\n\tNorm %g,%g,%g.\n",
rayp->r_pt[X], rayp->r_pt[Y], rayp->r_pt[Z],
rayp->r_dir[X], rayp->r_dir[Y], rayp->r_dir[Z],
normvec[X], normvec[Y], normvec[Z] );
#endif
ret = false;
}
if( f > 0.0 )
{
flipct++;
brst_log( "Fixed flipped entry normal:\n" );
brst_log( "\tregion \"%s\" solid \"%s\" type %d \"%s\".\n",
pp->pt_regionp->reg_name, stp->st_name,
stp->st_id, purpose );
#ifdef DEBUG
brst_log( "\tPnt %g,%g,%g\n\tDir %g,%g,%g\n\tNorm %g,%g,%g.\n",
rayp->r_pt[X], rayp->r_pt[Y], rayp->r_pt[Z],
rayp->r_dir[X], rayp->r_dir[Y], rayp->r_dir[Z],
normvec[X], normvec[Y], normvec[Z] );
brst_log( "\tDist %g Hit Pnt %g,%g,%g\n",
pp->pt_inhit->hit_dist,
pp->pt_inhit->hit_point[X],
pp->pt_inhit->hit_point[Y],
pp->pt_inhit->hit_point[Z] );
brst_log( "\t%d of %d normals flipped.\n", flipct, totalct );
#endif
ScaleVec( normvec, -1.0 );
ret = false;
}
return ret;
}
bool
chkExitNorm( pp, rayp, normvec, purpose )
struct partition *pp;
struct xray *rayp;
fastf_t normvec[3];
char *purpose;
{ fastf_t f;
static int flipct = 0;
static int totalct = 0;
struct soltab *stp = pp->pt_outseg->seg_stp;
bool ret = true;
totalct++;
/* Dot product of ray direction with normal *should* be positive. */
f = Dot( rayp->r_dir, normvec );
if( NearZero( f ) )
{
#ifdef DEBUG
brst_log( "chkExitNorm: near 90 degree obliquity.\n" );
brst_log( "\tPnt %g,%g,%g\n\tDir %g,%g,%g\n\tNorm %g,%g,%g.\n",
rayp->r_pt[X], rayp->r_pt[Y], rayp->r_pt[Z],
rayp->r_dir[X], rayp->r_dir[Y], rayp->r_dir[Z],
normvec[X], normvec[Y], normvec[Z] );
#endif
ret = false;
}
if( f < 0.0 )
{
flipct++;
brst_log( "Fixed flipped exit normal:\n" );
brst_log( "\tregion \"%s\" solid \"%s\" type %d \"%s\".\n",
pp->pt_regionp->reg_name, stp->st_name,
stp->st_id, purpose );
#ifdef DEBUG
brst_log( "\tPnt %g,%g,%g\n\tDir %g,%g,%g\n\tNorm %g,%g,%g.\n",
rayp->r_pt[X], rayp->r_pt[Y], rayp->r_pt[Z],
rayp->r_dir[X], rayp->r_dir[Y], rayp->r_dir[Z],
normvec[X], normvec[Y], normvec[Z] );
brst_log( "\tDist %g Hit Pnt %g,%g,%g\n",
pp->pt_outhit->hit_dist,
pp->pt_outhit->hit_point[X],
pp->pt_outhit->hit_point[Y],
pp->pt_outhit->hit_point[Z] );
brst_log( "\t%d of %d normals flipped.\n", flipct, totalct );
#endif
ScaleVec( normvec, -1.0 );
ret = false;
}
return ret;
}
/*
int f_ShotMiss( register struct application *ap )
@@ -703,7 +909,7 @@ register struct application *ap;
else
if( bdist < 0.0 )
{ /* interior burst not implemented in ground */
rt_log( "User error: %s %s.\n",
brst_log( "User error: %s %s.\n",
"negative burst distance can not be",
"specified with ground plane bursting"
);
@@ -713,7 +919,10 @@ register struct application *ap;
/* else bdist == 0.0, no adjustment necessary */
/* only burst if nspallrays greater than zero */
if( nspallrays > 0 )
{
prntBurstHdr( hitpoint, viewdir );
return burstPoint( ap, zaxis, hitpoint );
}
else
return true;
}
@@ -826,25 +1035,25 @@ gridInit()
#if DEBUG_SHOT
if( TSTBIT(firemode,FM_BURST) )
rt_log( "gridInit: reading burst points.\n" );
brst_log( "gridInit: reading burst points.\n" );
else {
if( TSTBIT(firemode,FM_SHOT) )
rt_log( "gridInit: shooting discrete shots.\n" );
brst_log( "gridInit: shooting discrete shots.\n" );
else
rt_log( "gridInit: shooting %s.\n",
brst_log( "gridInit: shooting %s.\n",
TSTBIT(firemode,FM_PART) ?
"partial envelope" : "full envelope" );
}
if( TSTBIT(firemode,FM_BURST) || TSTBIT(firemode,FM_SHOT) )
{
rt_log( "gridInit: reading %s coordinates from %s.\n",
brst_log( "gridInit: reading %s coordinates from %s.\n",
TSTBIT(firemode,FM_3DIM) ? "3-d" : "2-d",
TSTBIT(firemode,FM_FILE) ? "file" : "command stream" );
}
else
if( TSTBIT(firemode,FM_FILE) || TSTBIT(firemode,FM_3DIM) )
rt_log( "BUG: insane combination of fire mode bits:0x%x\n",
brst_log( "BUG: insane combination of fire mode bits:0x%x\n",
firemode );
if( TSTBIT(firemode,FM_BURST) || shotburst )
nriplevels = 1;
@@ -856,7 +1065,7 @@ gridInit()
"Ground bursting directive ignored: %s.\n",
"only relevant if bursting along shotline" );
warning( scrbuf );
rt_log( scrbuf );
brst_log( scrbuf );
}
#endif
/* compute grid unit vectors */
@@ -867,7 +1076,7 @@ gridInit()
fastf_t sinpitch = sin( pitch );
fastf_t xdeltavec[3], ydeltavec[3];
#if DEBUG_SHOT
rt_log( "gridInit: canting warhead\n" );
brst_log( "gridInit: canting warhead\n" );
#endif
cantwarhead = true;
Scale2Vec( gridhor, negsinyaw, xdeltavec );
@@ -1004,9 +1213,9 @@ gridInit()
gridyfin++;
}
#if DEBUG_SHOT
rt_log( "gridInit: xorg,xfin,yorg,yfin=%d,%d,%d,%d\n",
brst_log( "gridInit: xorg,xfin,yorg,yfin=%d,%d,%d,%d\n",
gridxorg, gridxfin, gridyorg, gridyfin );
rt_log( "gridInit: left,right,down,up=%g,%g,%g,%g\n",
brst_log( "gridInit: left,right,down,up=%g,%g,%g,%g\n",
gridlf, gridrt, griddn, gridup );
#endif
@@ -1047,6 +1256,7 @@ gridModel()
{
ag.a_onehit = false;
ag.a_overlap = reportoverlaps ? f_Overlap : f_HushOverlap;
ag.a_logoverlap = rt_silent_logoverlap;
ag.a_rt_i = rtip;
if( ! TSTBIT(firemode,FM_BURST) )
{ /* set up for shotlines */
@@ -1070,11 +1280,12 @@ gridModel()
rt_prep_timer();
notify( "Raytracing", NOTIFY_ERASE );
if( TSTBIT(firemode,FM_BURST) )
if( TSTBIT(firemode,FM_BURST) ) {
if( ! doBursts() )
return;
else
goto endvu;
}
/* get starting and ending shot number */
currshot = 0;
@@ -1125,7 +1336,7 @@ gridShot()
if( rt_shootray( &a ) == -1 && fatalerror )
{
/* fatal error in application routine */
rt_log( "Fatal error: raytracing aborted.\n" );
brst_log( "Fatal error: raytracing aborted.\n" );
return false;
}
if( ! TSTBIT(firemode,FM_FILE) && TSTBIT(firemode,FM_SHOT) )
@@ -1139,7 +1350,8 @@ gridShot()
/*
void lgtModel( register struct application *ap, struct partition *pp,
struct hit *hitp, struct xray *rayp )
struct hit *hitp, struct xray *rayp,
fastf_t surfnorm[3] )
This routine is a simple lighting model which places RGB coefficients
(0 to 1) in ap->a_color based on the cosine of the angle between
@@ -1149,13 +1361,14 @@ gridShot()
space.
*/
STATIC void
lgtModel( ap, pp, hitp, rayp )
lgtModel( ap, pp, hitp, rayp, surfnorm )
register struct application *ap;
struct partition *pp;
struct hit *hitp;
struct xray *rayp;
fastf_t surfnorm[3];
{ Colors *colorp;
fastf_t intensity = -Dot( viewdir, hitp->hit_normal );
fastf_t intensity = -Dot( viewdir, surfnorm );
if( intensity < 0.0 )
intensity = -intensity;
@@ -1164,9 +1377,9 @@ struct xray *rayp;
!= COLORS_NULL
)
{
ap->a_color[RED] = colorp->c_rgb[RED]/255.0;
ap->a_color[GRN] = colorp->c_rgb[GRN]/255.0;
ap->a_color[BLU] = colorp->c_rgb[BLU]/255.0;
ap->a_color[RED] = (fastf_t)colorp->c_rgb[RED]/255.0;
ap->a_color[GRN] = (fastf_t)colorp->c_rgb[GRN]/255.0;
ap->a_color[BLU] = (fastf_t)colorp->c_rgb[BLU]/255.0;
}
else
ap->a_color[RED] =
@@ -1174,7 +1387,6 @@ struct xray *rayp;
ap->a_color[BLU] = 1.0;
ScaleVec( ap->a_color, intensity );
ap->a_cumlen = hitp->hit_dist;
return;
}
/*
@@ -1226,7 +1438,7 @@ register fastf_t *vec;
{
if( items != EOF )
{
rt_log( "Fatal error: %d burst coordinates read.\n",
brst_log( "Fatal error: %d burst coordinates read.\n",
items );
fatalerror = true;
return false;
@@ -1269,7 +1481,7 @@ register fastf_t *vec;
{
if( items != EOF )
{
rt_log( "Fatal error: only %d firing coordinates read.\n", items );
brst_log( "Fatal error: only %d firing coordinates read.\n", items );
fatalerror = true;
return false;
}
@@ -1296,7 +1508,7 @@ register fastf_t *vec;
{
if( items != EOF )
{
rt_log( "Fatal error: %d firing coordinates read.\n", items );
brst_log( "Fatal error: %d firing coordinates read.\n", items );
fatalerror = true;
return false;
}
@@ -1312,19 +1524,18 @@ register fastf_t *vec;
}
else
{
rt_log( "BUG: readShot called with bad firemode.\n" );
brst_log( "BUG: readShot called with bad firemode.\n" );
return false;
}
return true;
}
/*
int round( fastf_t f )
int roundToInt( fastf_t f )
RETURN CODES: the nearest integer to f.
*/
int
round( f )
int roundToInt( f )
fastf_t f;
{ register int a;
a = f;
@@ -1360,7 +1571,7 @@ spallInit()
delta = 0.0;
phiinc = 0.0;
raysolidangle = 0.0;
rt_log( "%d sampling rays\n", spallct );
brst_log( "%d sampling rays\n", spallct );
return;
}
@@ -1385,9 +1596,9 @@ spallInit()
spallct++;
}
raysolidangle = theta / spallct;
rt_log( "Solid angle of sampling cone = %g\n", theta );
rt_log( "Solid angle per sampling ray = %g\n", raysolidangle );
rt_log( "%d sampling rays\n", spallct );
brst_log( "Solid angle of sampling cone = %g\n", theta );
brst_log( "Solid angle per sampling ray = %g\n", raysolidangle );
brst_log( "%d sampling rays\n", spallct );
return;
}
@@ -1437,8 +1648,6 @@ register fastf_t *bpt; /* burst point coordinates */
}
CopyVec( a_burst.a_ray.r_pt, bpt );
/* prntBurstHdr( bpt ); XXX print something about burst point? */
comphi = 0.0; /* Initialize global for concurrent access. */
/* SERIAL case -- one CPU does all the work. */
@@ -1451,7 +1660,6 @@ burstRay()
threads of execution. */
struct application a_spall;
fastf_t phi;
fastf_t nrings = conehfangle / phiinc;
bool hitcrit = false;
a_spall = a_burst;
a_spall.a_resource = RESOURCE_NULL;
@@ -1460,11 +1668,11 @@ burstRay()
fastf_t gamma, gammainc, gammalast;
register int done;
int m;
RES_ACQUIRE( &rt_g.res_worker );
bu_semaphore_acquire( RT_SEM_WORKER );
phi = comphi;
comphi += phiinc;
done = phi > conehfangle;
RES_RELEASE( &rt_g.res_worker );
bu_semaphore_release( RT_SEM_WORKER );
if( done )
break;
sinphi = sin( phi );
@@ -1477,14 +1685,14 @@ burstRay()
spallVec( a_burst.a_ray.r_dir, a_spall.a_ray.r_dir,
phi, gamma );
plotRay( &a_spall.a_ray );
RES_ACQUIRE( &rt_g.res_worker );
bu_semaphore_acquire( RT_SEM_WORKER );
a_spall.a_user = a_burst.a_user++;
RES_RELEASE( &rt_g.res_worker );
bu_semaphore_release( RT_SEM_WORKER );
if( (ncrit = rt_shootray( &a_spall )) == -1
&& fatalerror )
{
/* Fatal error in application routine. */
rt_log( "Error: ray tracing aborted.\n" );
brst_log( "Error: ray tracing aborted.\n" );
return false;
}
if( fbfile[0] != NUL && ncrit > 0 )
@@ -1494,9 +1702,9 @@ burstRay()
}
if( histfile[0] != NUL )
{
RES_ACQUIRE( &rt_g.res_syscall );
bu_semaphore_acquire( BU_SEM_SYSCALL );
(void) fprintf( histfp, "%d\n", ncrit );
RES_RELEASE( &rt_g.res_syscall );
bu_semaphore_release( BU_SEM_SYSCALL );
}
}
}
@@ -1577,6 +1785,7 @@ int sig;
#endif
}
#if 0
/* i p o w ( )
Integer exponent pow() function.
Returns d to the nth power.
@@ -1592,18 +1801,19 @@ register int n;
result *= d;
return result;
}
#endif
/* v i e w _ p i x ( ) */
STATIC void
view_pix( ap )
register struct application *ap;
{
RES_ACQUIRE( &rt_g.res_syscall );
bu_semaphore_acquire( BU_SEM_SYSCALL );
if( ! TSTBIT(firemode,FM_BURST) )
prntGridOffsets( ap->a_x, ap->a_y );
if( tty )
prntTimer( NULL );
RES_RELEASE( &rt_g.res_syscall );
bu_semaphore_release( BU_SEM_SYSCALL );
return;
}
@@ -1623,7 +1833,7 @@ view_end()
(void) fflush( shotlnfp );
prntTimer( "view" );
if( noverlaps > 0 )
rt_log( "%d overlaps detected over %g mm thick.\n",
brst_log( "%d overlaps detected over %g mm thick.\n",
noverlaps, OVERLAP_TOL );
return;
}

Some files were not shown because too many files have changed in this diff Show More