PLIB 1.8.5+ r2173 from http://plib.svn.sourceforge.net/svnroot/plib/trunk
@@ -0,0 +1,2 @@
|
||||
Exposer was written by Steve Baker.
|
||||
|
||||
@@ -0,0 +1,340 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
ExPoser Change Log.
|
||||
===================
|
||||
|
||||
ExPoser v0.0.1 (July 21st 2001)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
* Most bugs now removed.
|
||||
|
||||
* Can load in 'scenery'
|
||||
|
||||
* Better example models.
|
||||
|
||||
ExPoser v0.0.0 (June 17th 2001)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
* First release.
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, a file
|
||||
`config.cache' that saves the results of its tests to speed up
|
||||
reconfiguring, and a file `config.log' containing compiler output
|
||||
(useful mainly for debugging `configure').
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If at some point `config.cache'
|
||||
contains results you don't want to keep, you may remove or edit it.
|
||||
|
||||
The file `configure.in' is used to create `configure' by a program
|
||||
called `autoconf'. You only need `configure.in' if you want to change
|
||||
it or regenerate `configure' using a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. You can give `configure'
|
||||
initial values for variables by setting them in the environment. Using
|
||||
a Bourne-compatible shell, you can do that on the command line like
|
||||
this:
|
||||
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
|
||||
|
||||
Or on systems that have the `env' program, you can do it like this:
|
||||
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not supports the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a time
|
||||
in the source code directory. After you have installed the package for
|
||||
one architecture, use `make distclean' before reconfiguring for another
|
||||
architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PATH'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||
PATH as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=PATH' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' can not figure out
|
||||
automatically, but needs to determine by the type of host the package
|
||||
will run on. Usually `configure' can figure that out, but if it prints
|
||||
a message saying it can not guess the host type, give it the
|
||||
`--host=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name with three fields:
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the host type.
|
||||
|
||||
If you are building compiler tools for cross-compiling, you can also
|
||||
use the `--target=TYPE' option to select the type of system they will
|
||||
produce code for and the `--build=TYPE' option to select the type of
|
||||
system on which you are compiling the package.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Operation Controls
|
||||
==================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Use and save the results of the tests in FILE instead of
|
||||
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
|
||||
debugging `configure'.
|
||||
|
||||
`--help'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`--version'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options.
|
||||
@@ -0,0 +1,4 @@
|
||||
SUBDIRS = src data doc
|
||||
|
||||
EXTRA_DIST = autogen.sh README exposer.dsw
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
ExPoser 3D.
|
||||
~~~~~~~~~~~
|
||||
by Steve Baker
|
||||
<sjbaker1@airmail.net>
|
||||
|
||||
INSTALLATION:
|
||||
|
||||
Installation instructions are pretty basic,
|
||||
and are covered in the documentation directory 'doc'.
|
||||
|
||||
OpenGL (or Mesa)
|
||||
GLUT (the GL Utility Toolkit)
|
||||
PLIB (which can be obtained from one of:
|
||||
http://plib.sourceforge.net
|
||||
|
||||
Once that is done, it should be a simple matter of changing
|
||||
to the directory where all this stuff is unpacked and type:
|
||||
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
However, you might want to check the full documentation -
|
||||
especially if you need to install Mesa/GLIDE/GLUT before
|
||||
you can start.
|
||||
|
||||
All documents are in HTML - so view them with your web browser.
|
||||
|
||||
LICENSE:
|
||||
|
||||
This software is released under the provisions of
|
||||
the GNU General Public License (GPL) which can be
|
||||
found in the file 'COPYING' in the current directory.
|
||||
|
||||
DIRECTORY STRUCTURE:
|
||||
|
||||
src -- Where the source code lives.
|
||||
|
||||
data -- This contains all kinds of miscellaneous data
|
||||
files to test with.
|
||||
|
||||
doc -- Documentation - all in HTML
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
|
||||
OSTYPE=`uname -s`
|
||||
|
||||
AMFLAGS="--add-missing"
|
||||
if test "$OSTYPE" = "IRIX" -o "$OSTYPE" = "IRIX64"; then
|
||||
AMFLAGS=$AMFLAGS" --include-deps";
|
||||
fi
|
||||
|
||||
echo "Running aclocal"
|
||||
aclocal
|
||||
echo "Running automake"
|
||||
automake $AMFLAGS
|
||||
echo "Running autoconf"
|
||||
autoconf
|
||||
|
||||
echo "======================================"
|
||||
echo "Now you are ready to run './configure'"
|
||||
echo "======================================"
|
||||
@@ -0,0 +1,167 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT(src/exposer.cxx)
|
||||
AM_INIT_AUTOMAKE(exposer, 0.2.0)
|
||||
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AC_PROG_CXX
|
||||
AC_PROG_CXXCPP
|
||||
AC_PROG_INSTALL
|
||||
|
||||
plib_suffix="-lplibjs -lplibsl -lplibssgaux -lplibssg -lplibpuaux -lplibpu -lplibfnt -lplibsg -lplibul"
|
||||
|
||||
AC_LANG_CPLUSPLUS
|
||||
|
||||
|
||||
dnl Command line arguments.
|
||||
|
||||
dnl Don't use AC_HELP_STRING here as old versions of autoconf do not
|
||||
dnl understand it.
|
||||
AC_ARG_WITH(GL,
|
||||
[ --with-GL=DIR set the prefix directory where GL resides],
|
||||
GL_PREFIX=$withval, GL_PREFIX=auto)
|
||||
|
||||
if test "x$GL_PREFIX" != "xauto"; then
|
||||
LDFLAGS="$LDFLAGS -L$GL_PREFIX/lib"
|
||||
CPPFLAGS="$CPPFLAGS -I$GL_PREFIX/include"
|
||||
fi
|
||||
|
||||
|
||||
dnl Checks for library functions.
|
||||
dnl check for OpenGL related libraries
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
case "${host}" in
|
||||
*-*-cygwin* | *-*-mingw32*)
|
||||
dnl CygWin under Windoze.
|
||||
|
||||
LIBS="$LIBS -lwinmm -lglut32 -lglu32 -lopengl32 -luser32 -lgdi32"
|
||||
;;
|
||||
*-apple-darwin*)
|
||||
dnl Mac OS X
|
||||
|
||||
LIBS="$LIBS -framework GLUT -lobjc -framework OpenGL -framework Carbon"
|
||||
;;
|
||||
*)
|
||||
dnl Check for X11
|
||||
|
||||
AC_PATH_XTRA
|
||||
|
||||
LDFLAGS="$LDFLAGS $X_LIBS"
|
||||
|
||||
LIBS="$LIBS $X_PRE_LIBS -lXi -lXmu -lXext -lX11 $X_EXTRA_LIBS -lm"
|
||||
|
||||
dnl =========================================================
|
||||
dnl if test "x$x_includes" != "x"; then
|
||||
dnl CPPFLAGS="$CPPFLAGS -I$x_includes"
|
||||
dnl fi
|
||||
dnl =========================================================
|
||||
|
||||
dnl Reasonable stuff non-windoze variants ... :-)
|
||||
|
||||
AC_CHECK_LIB(GL, glNewList)
|
||||
if test "x$ac_cv_lib_GL_glNewList" = "xno" ; then
|
||||
dnl if no GL, check for MesaGL
|
||||
AC_CHECK_LIB(MesaGL, glNewList,,
|
||||
AC_MSG_ERROR([could not find working GL library]))
|
||||
fi
|
||||
|
||||
AC_CHECK_LIB(GLU, gluLookAt)
|
||||
if test "x$ac_cv_lib_GLU_gluLookAt" = "xno" ; then
|
||||
dnl if no GLU, check for MesaGLU
|
||||
AC_CHECK_LIB(MesaGLU, gluLookAt,,
|
||||
AC_MSG_ERROR([could not find working GLU library]))
|
||||
fi
|
||||
|
||||
dnl check for glut...or freeglut
|
||||
AC_CHECK_LIB(freeglut, glutGetModifiers)
|
||||
if test "x$ac_cv_lib_freeglut_glutGetModifiers" = "xno" ; then
|
||||
dnl if no freeglut, check for Real GLUT
|
||||
AC_CHECK_LIB(glut, glutGetModifiers,,
|
||||
AC_MSG_ERROR([could not find working GLUT library]))
|
||||
fi
|
||||
|
||||
AC_CHECK_LIB(dl, dlclose)
|
||||
|
||||
dnl Check SGI audio library
|
||||
AC_CHECK_LIB(audio, ALopenport, SND_LIBS="-laudio")
|
||||
;;
|
||||
esac
|
||||
|
||||
dnl Check PLIB library
|
||||
AC_CHECK_LIB(plibul, ulInit, true,
|
||||
AC_MSG_ERROR([there seems to be a problem with the PLIB libraries]))
|
||||
|
||||
LIBS="$plib_suffix $LIBS"
|
||||
|
||||
|
||||
dnl Checks for header files.
|
||||
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADER(windows.h, AC_DEFINE(WIN32))
|
||||
|
||||
case "${host}" in
|
||||
*-*-cygwin* | *-*-mingw32*)
|
||||
dnl CygWin under Windoze.
|
||||
|
||||
AC_CHECK_HEADERS(GL/gl.h GL/glu.h,,
|
||||
AC_MSG_ERROR([OpenGL header files not found]))
|
||||
|
||||
AC_CHECK_HEADER(GL/glut.h, AC_DEFINE(GLUT_IS_PRESENT),
|
||||
AC_MSG_ERROR([GLUT header file not found]))
|
||||
;;
|
||||
*-apple-darwin*)
|
||||
dnl Mac OS X
|
||||
|
||||
AC_CHECK_HEADERS(OpenGL/gl.h OpenGL/glu.h,,
|
||||
AC_MSG_ERROR([OpenGL header files not found]))
|
||||
|
||||
AC_CHECK_HEADER(GLUT/glut.h, AC_DEFINE(GLUT_IS_PRESENT),
|
||||
AC_MSG_ERROR([GLUT header file not found]))
|
||||
;;
|
||||
*)
|
||||
AC_CHECK_HEADERS(GL/gl.h GL/glu.h,,
|
||||
AC_MSG_ERROR([OpenGL header files not found]))
|
||||
|
||||
if test "x$ac_cv_lib_freeglut_glutGetModifiers" = "xyes"; then
|
||||
AC_CHECK_HEADER(GL/freeglut.h, AC_DEFINE(FREEGLUT_IS_PRESENT),
|
||||
AC_MSG_ERROR([freeglut header file not found]))
|
||||
else
|
||||
AC_CHECK_HEADER(GL/glut.h, AC_DEFINE(GLUT_IS_PRESENT),
|
||||
AC_MSG_ERROR([GLUT header file not found]))
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_CHECK_HEADER(plib/ul.h,, AC_MSG_ERROR([PLIB header files not found]))
|
||||
|
||||
|
||||
dnl Warning flags
|
||||
WFLAG="-Wall"
|
||||
case "$host" in
|
||||
mips-sgi-irix*)
|
||||
if test "x$CXX" = "xCC"; then
|
||||
WFLAG="-fullwarn";
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
if test "x$CXX" = "xicpc" || test "x$CXX" = "xicc"; then
|
||||
WFLAG="-w1"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
CFLAGS="$CFLAGS $WFLAG"
|
||||
CXXFLAGS="$CXXFLAGS $WFLAG"
|
||||
|
||||
|
||||
AC_OUTPUT( Makefile \
|
||||
data/Makefile \
|
||||
doc/Makefile \
|
||||
src/Makefile \
|
||||
)
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
pkgdatadir = $(datadir)/games/@PACKAGE@/data
|
||||
|
||||
pkgdata_DATA = $(wildcard *.rgb *.ac *.bones)
|
||||
|
||||
EXTRA_DIST = $(pkgdata_DATA)
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
NUMBONES=24 NUMEVENTS=5 MAXTIME=3.392857 Z_OFFSET=0 SPEED=0
|
||||
BONE "Tongue" HP.
|
||||
BONE "WholeDog" H..
|
||||
BONE "Nose" ...
|
||||
BONE "Head" HPR
|
||||
BONE "Body" H..
|
||||
BONE "Tail" HP.
|
||||
BONE "LeftEar" ..R
|
||||
BONE "RightEar" ..R
|
||||
BONE "FrLfShoulder" ...
|
||||
BONE "FrRtShoulder" ...
|
||||
BONE "BkLfHip" ...
|
||||
BONE "BkRtHip" ...
|
||||
BONE "FrLfLeg" .P.
|
||||
BONE "FrLfKnee" .P.
|
||||
BONE "FrLfFoot" HP.
|
||||
BONE "FrRtLeg" .P.
|
||||
BONE "FrRtKnee" .P.
|
||||
BONE "FrRtFoot" HP.
|
||||
BONE "BkLfLeg" .P.
|
||||
BONE "BkLfKnee" .P.
|
||||
BONE "BkLfFoot" .P.
|
||||
BONE "BkRtLeg" HPR
|
||||
BONE "BkRtKnee" .P.
|
||||
BONE "BkRtFoot" .P.
|
||||
EVENT 0.000000 24 (0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(-8,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,14,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
EVENT 0.502870 24 (0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(-8,0,0)
|
||||
(11,-23,0)
|
||||
(0,0,0)
|
||||
(-28,-10,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,14,0)
|
||||
(0,-24,0)
|
||||
(21,-18,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
EVENT 1.005740 24 (0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(-8,0,0)
|
||||
(0,-30,0)
|
||||
(0,0,0)
|
||||
(-52,-10,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,14,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
EVENT 2.005421 24 (0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(-8,0,0)
|
||||
(51,0,0)
|
||||
(0,0,0)
|
||||
(51,-10,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,14,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
EVENT 3.000000 24 (0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(-8,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,14,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
@@ -0,0 +1,38 @@
|
||||
NUMBONES=18 NUMEVENTS=1 MAXTIME=10.000000 Z_OFFSET=-0.002791 SPEED=0.000000
|
||||
BONE "Human" HPR
|
||||
BONE "RtShoulder" HPR
|
||||
BONE "RtArm" HPR
|
||||
BONE "RtElbow" HPR
|
||||
BONE "RtWrist" HPR
|
||||
BONE "LfShoulder" HPR
|
||||
BONE "LfArm" HPR
|
||||
BONE "LfElbow" HPR
|
||||
BONE "LfWrist" HPR
|
||||
BONE "Neck" HPR
|
||||
BONE "Head" HPR
|
||||
BONE "Waist" HPR
|
||||
BONE "RtHip" .P.
|
||||
BONE "RtKnee" .P.
|
||||
BONE "RtAnkle" .P.
|
||||
BONE "LfHip" .P.
|
||||
BONE "LfKnee" .P.
|
||||
BONE "LfAnkle" .P.
|
||||
EVENT 0.000000 18 (0.000000,0.000000,0.000000)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
@@ -0,0 +1,133 @@
|
||||
NUMBONES=18 NUMEVENTS=6 MAXTIME=1.474031 Z_OFFSET=-0.002791 SPEED=0.000000
|
||||
BONE "Human" HPR
|
||||
BONE "RtShoulder" ...
|
||||
BONE "RtArm" HPR
|
||||
BONE "RtElbow" HPR
|
||||
BONE "RtWrist" HPR
|
||||
BONE "LfShoulder" ...
|
||||
BONE "LfArm" HPR
|
||||
BONE "LfElbow" HPR
|
||||
BONE "LfWrist" HPR
|
||||
BONE "Neck" HPR
|
||||
BONE "Head" HPR
|
||||
BONE "Waist" HPR
|
||||
BONE "RtHip" HP.
|
||||
BONE "RtKnee" .P.
|
||||
BONE "RtAnkle" .P.
|
||||
BONE "LfHip" .P.
|
||||
BONE "LfKnee" .P.
|
||||
BONE "LfAnkle" .P.
|
||||
EVENT 0.000000 18 (0.000000,0.000000,0.000000)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,71)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,-64)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
EVENT 0.150392 18 (0.000000,-0.462963,0.000000)
|
||||
(0,-11,0)
|
||||
(0,0,0)
|
||||
(0,38,68)
|
||||
(31,0,-4)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,32,-52)
|
||||
(0,-2,-57)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,-34,0)
|
||||
(0,30,0)
|
||||
(0,18,0)
|
||||
(0,0,0)
|
||||
(0,-21,0)
|
||||
(0,15,0)
|
||||
(0,0,0)
|
||||
(0,-17,0)
|
||||
EVENT 0.299477 18 (0.000000,-0.648148,-0.462963)
|
||||
(0,41,0)
|
||||
(0,0,0)
|
||||
(0,22,28)
|
||||
(75,0,-4)
|
||||
(87,0,-3)
|
||||
(0,0,0)
|
||||
(0,71,-32)
|
||||
(0,22,-15)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,20,0)
|
||||
(0,10,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,-21,0)
|
||||
(0,4,0)
|
||||
(0,0,0)
|
||||
(0,-17,0)
|
||||
EVENT 0.451177 18 (0.000000,-0.787037,-1.157408)
|
||||
(0,90,0)
|
||||
(0,0,0)
|
||||
(40,-43,22)
|
||||
(135,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,11,0)
|
||||
(0,-19,0)
|
||||
(0,-45,0)
|
||||
(0,4,0)
|
||||
(0,0,0)
|
||||
(0,-17,0)
|
||||
EVENT 0.681740 18 (0.000000,-0.787037,-1.157408)
|
||||
(0,90,0)
|
||||
(0,0,0)
|
||||
(15,-59,22)
|
||||
(19,-21,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,-42,0)
|
||||
(0,0,0)
|
||||
(0,-41,0)
|
||||
(0,0,0)
|
||||
(30,-20,0)
|
||||
(0,0,0)
|
||||
(0,16,0)
|
||||
(0,-19,0)
|
||||
(0,-45,0)
|
||||
(0,8,0)
|
||||
(0,-4,0)
|
||||
(0,-17,0)
|
||||
EVENT 0.994971 18 (0.000000,-0.787037,-1.157408)
|
||||
(0,90,0)
|
||||
(0,0,0)
|
||||
(15,-59,22)
|
||||
(19,-21,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,-42,0)
|
||||
(0,0,0)
|
||||
(0,-41,0)
|
||||
(0,0,0)
|
||||
(61,-20,0)
|
||||
(0,0,0)
|
||||
(25,0,0)
|
||||
(0,0,0)
|
||||
(0,-21,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,-12,0)
|
||||
@@ -0,0 +1,171 @@
|
||||
NUMBONES=18 NUMEVENTS=8 MAXTIME=1.402956 Z_OFFSET=-0.002791 SPEED=1.400000
|
||||
BONE "Human" HPR
|
||||
BONE "RtShoulder" ...
|
||||
BONE "RtArm" HPR
|
||||
BONE "RtElbow" HPR
|
||||
BONE "RtWrist" HPR
|
||||
BONE "LfShoulder" ...
|
||||
BONE "LfArm" HPR
|
||||
BONE "LfElbow" HPR
|
||||
BONE "LfWrist" HPR
|
||||
BONE "Neck" HPR
|
||||
BONE "Head" HPR
|
||||
BONE "Waist" HPR
|
||||
BONE "RtHip" .P.
|
||||
BONE "RtKnee" .P.
|
||||
BONE "RtAnkle" .P.
|
||||
BONE "LfHip" .P.
|
||||
BONE "LfKnee" .P.
|
||||
BONE "LfAnkle" .P.
|
||||
EVENT 0.000000 18 (0.000000,0.000000,0.000000)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,-24,69)
|
||||
(19,0,0)
|
||||
(18,0,0)
|
||||
(0,0,0)
|
||||
(0,14,-73)
|
||||
(-21,0,-4)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,-28,0)
|
||||
(0,0,0)
|
||||
(0,10,0)
|
||||
(0,26,0)
|
||||
(0,-20,0)
|
||||
(0,0,0)
|
||||
EVENT 0.195412 18 (0.000000,0.000000,0.000000)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,-11,69)
|
||||
(19,0,0)
|
||||
(18,0,0)
|
||||
(0,0,0)
|
||||
(0,-11,-73)
|
||||
(-21,0,-4)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,5,0)
|
||||
(0,-57,0)
|
||||
(0,-21,0)
|
||||
(0,11,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
EVENT 0.400845 18 (0.000000,0.000000,0.000000)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,9,69)
|
||||
(19,0,0)
|
||||
(18,0,0)
|
||||
(0,0,0)
|
||||
(0,-30,-73)
|
||||
(-21,0,-4)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,29,0)
|
||||
(0,-60,0)
|
||||
(0,-4,0)
|
||||
(0,-4,0)
|
||||
(0,-9,0)
|
||||
(0,14,0)
|
||||
EVENT 0.598762 18 (0.000000,0.000000,0.000000)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,18,69)
|
||||
(34,-5,0)
|
||||
(18,0,0)
|
||||
(0,0,0)
|
||||
(0,-45,-73)
|
||||
(-21,0,-4)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,22,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,-24,0)
|
||||
(0,-9,0)
|
||||
(0,5,0)
|
||||
EVENT 0.801689 18 (0.000000,0.000000,0.000000)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,9,69)
|
||||
(23,-5,0)
|
||||
(21,0,0)
|
||||
(0,0,0)
|
||||
(0,-33,-73)
|
||||
(-21,0,-4)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,10,0)
|
||||
(0,-9,0)
|
||||
(0,-45,0)
|
||||
(0,-16,0)
|
||||
EVENT 1.004617 18 (0.000000,0.000000,0.000000)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,-8,69)
|
||||
(23,-5,0)
|
||||
(21,0,0)
|
||||
(0,0,0)
|
||||
(0,-23,-73)
|
||||
(-21,0,-4)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,-16,0)
|
||||
(0,0,0)
|
||||
(0,25,0)
|
||||
(0,38,0)
|
||||
(0,-53,0)
|
||||
(0,18,0)
|
||||
EVENT 1.200028 18 (0.000000,0.000000,0.000000)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,-12,69)
|
||||
(0,5,0)
|
||||
(15,0,0)
|
||||
(0,0,0)
|
||||
(0,0,-73)
|
||||
(-21,0,-4)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,-23,0)
|
||||
(0,0,0)
|
||||
(0,9,0)
|
||||
(0,20,0)
|
||||
(0,0,0)
|
||||
(0,-8,0)
|
||||
EVENT 1.402956 18 (0.000000,0.000000,0.000000)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,-24,69)
|
||||
(19,0,0)
|
||||
(18,0,0)
|
||||
(0,0,0)
|
||||
(0,15,-73)
|
||||
(-21,0,-4)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,0,0)
|
||||
(0,-28,0)
|
||||
(0,0,0)
|
||||
(0,10,0)
|
||||
(0,26,0)
|
||||
(0,-19,0)
|
||||
(0,0,0)
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
pkgdatadir = $(datadir)/games/@PACKAGE@/doc
|
||||
|
||||
pkgdata_DATA = $(wildcard *.*)
|
||||
|
||||
EXTRA_DIST = $(pkgdata_DATA)
|
||||
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
@@ -0,0 +1,451 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<TITLE>Exposer Home Page</TITLE>
|
||||
</HEAD>
|
||||
<BODY text="#B5A642" link="#8FFF8F" vlink="#18A515" alink="#20336B" bgcolor="#005000" background="../../../doc/marble.png">
|
||||
|
||||
<TABLE>
|
||||
<TR>
|
||||
<TD>
|
||||
<IMG SRC="exposer_logo.png" ALT="Exposer Logo" width=127 height=39>
|
||||
<br>
|
||||
</TD>
|
||||
<TD>
|
||||
<center>
|
||||
<H1>
|
||||
<FONT SIZE=9>E</FONT><FONT SIZE=5>X</FONT><FONT SIZE=9>P</FONT><FONT SIZE=5>OSER:</FONT>
|
||||
<FONT SIZE=9>A</FONT>
|
||||
<FONT SIZE=9>T</FONT><FONT SIZE=5>OOL FOR</FONT>
|
||||
<FONT SIZE=9>A</FONT><FONT SIZE=5>NIMATING</FONT>
|
||||
<FONT SIZE=9>PLIB</FONT>
|
||||
<FONT SIZE=9>C</FONT><FONT SIZE=5>RITTERS.</FONT>
|
||||
</H1>
|
||||
</center>
|
||||
</TD>
|
||||
<TD>
|
||||
<ul>
|
||||
The foot bone's connected to the leg bone,<br>
|
||||
The leg bone's connected to the knee bone,<br>
|
||||
The knee bone's connected to the thigh bone,<br>
|
||||
The thigh bone's connected to the back bone,<br>
|
||||
The back bone's connected to the neck bone,<br>
|
||||
The neck bone's connected to the head bone,<br>
|
||||
Oh, hear the word of the Lord!<br>
|
||||
<br>
|
||||
-- Unknown (but incompetent) anatomist.
|
||||
</ul>
|
||||
<center>
|
||||
<A href="http://sourceforge.net">
|
||||
<IMG src="http://sourceforge.net/sflogo.php?group_id=382&type=1" width="88" height="31" border="0" ALT="Sourceforge Logo"></A>
|
||||
</center>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
|
||||
<H1>Introduction.</H1>
|
||||
Exposer is a tool to allow you to perform fairly complex animations
|
||||
of complex creatures with relative ease using the
|
||||
<A HREF="http://plib.sf.net"> PLIB Scene Graph API</A>. Naturally,
|
||||
Exposer is written using PLIB and generates output in several forms
|
||||
that PLIB programs will find useful.
|
||||
<p>
|
||||
Exposer is totally unrelated to the Windows program 'poser'. The
|
||||
name 'exposer' relates to the fact that this program used to be
|
||||
called 'poser' until I heard of the existance of a Windows program
|
||||
of the same name. This is therefore the ex-Poser program.
|
||||
<p>
|
||||
Exposer has a complex (but very powerful) GUI - you <b>WILL</b> need to
|
||||
read this manual in order to take advantage of it.
|
||||
<H2>Licensing.</H2>
|
||||
Exposer is OpenSource software, issued under the terms of the
|
||||
GNU Public License (GPL).
|
||||
<H2>Installing and Running Exposer</H2>
|
||||
Download ExPoser from the PLIB site:
|
||||
<A HREF="http://plib.sf.net/dist/exposer-0.0.1.tar.gz">
|
||||
http://plib.sf.net/dist/exposer-0.0.1.tar.gz</A>
|
||||
<p>
|
||||
Next, unpack the tarball containing the Exposer sources:
|
||||
<pre>
|
||||
|
||||
tar xzvf exposer-0.0.1.tar.gz
|
||||
|
||||
</pre>
|
||||
Then run the usual:
|
||||
<pre>
|
||||
|
||||
./configure ; make
|
||||
|
||||
</pre>
|
||||
(And you can optionally run 'make install' if you wish to fully
|
||||
install the program rather than running it out of the installation
|
||||
directory).
|
||||
<p>
|
||||
Then to run the program (without installing it) you could type
|
||||
something like:
|
||||
<pre>
|
||||
|
||||
src/exposer
|
||||
|
||||
</pre>
|
||||
The program will prompt you to enter a 3D model file - the
|
||||
ones in data with the extension '.ac' will do for starters.
|
||||
<p>
|
||||
Exposer can read any format that the PLIB library supports
|
||||
that can contain both line and polygon objects.
|
||||
|
||||
<H2>So What Does It Do.</H2>
|
||||
Well, right now, not a lot. The idea is that you can take an
|
||||
arbitary polygonal model (typically of a person or animal of
|
||||
some kind) and with minimal additional modelling effort be able
|
||||
to animate it in your game or other interactive application.
|
||||
<p>
|
||||
The technique that exposer uses is 'skin and bones' animation
|
||||
where the polygons of the model form the creatures 'skin' and
|
||||
you model a set of line primitives inside the creature to make
|
||||
a crude skeleton (the 'bones') much like the armature that a
|
||||
sculptor would use.
|
||||
<p>
|
||||
Exposer therefore separates out the polygons and the lines in the
|
||||
model you load (because your game will only be using the polygons)
|
||||
and uses the lines to form a hierarchical structure of matrix
|
||||
transformations. Exposer then assigns each vertex in the
|
||||
skin to one of the bones (possibly more than one in the future)
|
||||
according to distance - and then moves each vertex in accordance
|
||||
with the matrix of the bone to which it's attached.
|
||||
<p>
|
||||
Exposer can optionally display each bone as a coloured cuboid and
|
||||
provides a Heading/Pitch/Roll dial for each of them - but typically,
|
||||
you'll only want to view the 'skin' - and that's the default.
|
||||
By playing
|
||||
with the coloured dials, you can move the bones in any way you like and
|
||||
the skin will try to follow that movement as smoothly as possible.
|
||||
<p>
|
||||
One important issue is how the lines are assembled into a bone
|
||||
heirarchy. Firstly, exactly ONE of the lines in the original
|
||||
model must be painted RED. This bone is special because it's
|
||||
the root of the bone hierarchy. Typically, this will be a
|
||||
bone in the spine of a human or other mammal - but you might
|
||||
choose it to be something else. You can "Make the Tail Wag
|
||||
the Dog" by making the tailbone be the red one!
|
||||
<p>
|
||||
Once the program has found that red 'root' bone, it looks
|
||||
for other lines that have one or other of their vertices
|
||||
touching the root bone. Other lines can connect to the
|
||||
root somewhere other than at the ends of that red line,
|
||||
but your non-root bones MUST connect to it at their ends.
|
||||
<p>
|
||||
The program allows a 1% tolerance on this positioning so
|
||||
bones don't have to be EXACTLY touching - but they do have
|
||||
to be VERY close.
|
||||
<p>
|
||||
So, now we have the root bone and some other bones connected
|
||||
to it - and now the program proceeds to expand out the
|
||||
skeleton by treating all of the newly connected bones as
|
||||
'root' and proceeding recursively from there.
|
||||
<p>
|
||||
In a sense, it's like reading the lines of the song at
|
||||
the top of this page backwards:
|
||||
<pre>
|
||||
The back bone's...the RED bone,
|
||||
The thigh bone's connected to the back bone,
|
||||
The knee bone's connected to the thigh bone,
|
||||
The leg bone's connected to the knee bone,
|
||||
The foot bone's connected to the leg bone
|
||||
</pre>
|
||||
...although if it were me, I'd want a pelvis-bone and for
|
||||
the sake of graphics, there wouldn't need to be a knee bone.
|
||||
<p>
|
||||
So, that's more or less it.
|
||||
|
||||
<H2>Controls.</H2>
|
||||
Having loaded your first model, you'll see something like this:
|
||||
<br>
|
||||
<center><IMG SRC="exposer.png" ALT="ExPoser screenshot" width=400 height=300></center>
|
||||
<br>
|
||||
The rather nice shade of green is my favorite colour. If
|
||||
you prefer shock-pink...bad luck - that's what source code
|
||||
is for! The 3D model sits in the middle of the screen with
|
||||
the GUI widgets floating in front of it.
|
||||
<p>
|
||||
There is an optional black and white chequerboard 'floor'.
|
||||
<p>
|
||||
Let's go through the GUI controls piece by piece:
|
||||
|
||||
<H3>The Menu Bar.</H3>
|
||||
In the top-left, there is a pretty standard menu bar,
|
||||
<br>
|
||||
<center><IMG SRC="menu.png" ALT="Menu Bar" width=136 height=36></center>
|
||||
<br>
|
||||
The 'File' menu allows you to replace the model you are
|
||||
working on with another, it also allows you to load
|
||||
and save 'bone' files - which contain everything you
|
||||
create in Exposer. Generally, these Bone files have
|
||||
the same filename as the 3D model but with the extension
|
||||
".bones". Exposer will fill that filename into the
|
||||
file selector box - so you probably only have to hit "OK"
|
||||
to load and save.
|
||||
<p>
|
||||
The 'View' menu lets you zoom into and out of the 'timeline'
|
||||
which we'll come to later. The 'Time' menu has other
|
||||
'timeline' operations.
|
||||
|
||||
<H3>The Bone Dials</H3>
|
||||
To the left of the window are the bone dials - each coloured
|
||||
row of GUI widgets represents one of the bones in your model.
|
||||
<br>
|
||||
<center><IMG SRC="bone.png" ALT="Bone Dials" width=225 height=60></center>
|
||||
<br>
|
||||
The button marked 'X' resets all of the angles of the bone
|
||||
to zero - which will always be how your model was posed when
|
||||
you created it. The 'H', 'P' and 'R' buttons let you freeze
|
||||
and hide any of the three dials that you don't want to use
|
||||
for that particular bone. This is useful for joints like
|
||||
your elbow that can only flex in one degree of freedom.
|
||||
<p>
|
||||
The three dials represent the heading, pitch and roll
|
||||
angles of the joint at the end of that bone nearest the
|
||||
top of the bone connection hierarchy.
|
||||
<p>
|
||||
The rectangular area above the 'X/H/P/R' buttons can
|
||||
be used to enter a short text string to identify the
|
||||
bone. These strings are saved when you write out the
|
||||
bone data and your application program might want to
|
||||
read them to help identify what's what.
|
||||
<p>
|
||||
If you have more bones than will conveniently fit on the
|
||||
screen, the scroll-bar to the left of the bone widgets
|
||||
will allow you to scroll them up and down.
|
||||
|
||||
<H3>The Body Translators</H3>
|
||||
Just below the meny bar, there are three sliders with
|
||||
text display/entry areas that allow you to bodily
|
||||
translate your model.
|
||||
<br>
|
||||
<center><IMG SRC="translate.png" ALT="Body Translators" width=226 height=74></center>
|
||||
<br>
|
||||
You should generally use this
|
||||
for things like adding 'bounce' to a character's walk
|
||||
sequence - it's not advisable to try to position your
|
||||
character within it's world using this feature.
|
||||
|
||||
<H3>View Control</H3>
|
||||
In the bottom-left corner of the screen are some
|
||||
view controls. These can be used anytime to change
|
||||
the view you have of the model - but they don't change
|
||||
any actual data in the model or it's bones.
|
||||
<br>
|
||||
<center><IMG SRC="viewer.png" ALT="View Controls" width=198 height=63></center>
|
||||
<br>
|
||||
You can also use the 'Zoom' slider to move the model
|
||||
closer or further away, and there are buttons marked
|
||||
'Skin', 'Bones' and 'Floor' that let you toggle the display of
|
||||
each of those things - so you can see just the skin,
|
||||
just the bones or both (Or neither if you are
|
||||
particularly perverse!) - with or without the floor
|
||||
plane. The initial default is to show just the skin.
|
||||
<p>
|
||||
The 'Pan' and 'Tilt' dials allow you to move your
|
||||
eyepoint around the model to view it from all sides
|
||||
as it animates.
|
||||
|
||||
<H3>VCR Controls</H3>
|
||||
In the bottom-right corner of the screen, there
|
||||
are some VCR-like controls to play the animation,
|
||||
pause it, play in reverse and to play at triple-speed
|
||||
in forward or reverse.
|
||||
<br>
|
||||
<center><IMG SRC="vcr.png" ALT="VCR Controls" width=233 height=44></center>
|
||||
<br>
|
||||
You cannot adjust any joint angles in the model when
|
||||
the animation is playing - so be sure to press the
|
||||
downward arrow (STOP!) when you want to do editing.
|
||||
<p>
|
||||
There is a control to make the ground translate
|
||||
along at a specified speed (in OpenGL-units-per-second).
|
||||
This is useful if (for example) you want to animate
|
||||
a running character that's you'll be moving at two
|
||||
meters per second in your game. You need to move
|
||||
the legs so that the feet move along at the same
|
||||
speed as the ground or else it'll look like
|
||||
'moonwalking'. Set the VCR's ground speed to match
|
||||
the speed in the game and you'll be able to see if
|
||||
the animation is going to work.
|
||||
|
||||
<H3>The TimeLine</H3>
|
||||
This is a large rectangle taking up most of the bottom
|
||||
edge of the screen:
|
||||
<br>
|
||||
<center><IMG SRC="timeline.png" ALT="TimeLine" width=130 height=102></center>
|
||||
<br>
|
||||
It has a number of functions, it starts up as a view
|
||||
of a 10 second animation. Seconds are indicated by
|
||||
the long tickmarks, tenth seconds by the short ones.
|
||||
You can zoom into or out of the view or reset to seeing
|
||||
the entire timeline using the 'View' menu in the menubar.
|
||||
<p>
|
||||
If you are zoomed into the timeline, a slider will appear
|
||||
to allow you to scroll it left and right.
|
||||
<p>
|
||||
Magenta lines that extend across the full height of
|
||||
the timeline indicate "events" - each event is a point
|
||||
in time at which you have set the bone joint angles.
|
||||
You can add an event by selecting 'Add an Event' in
|
||||
the 'Time' menu and then clicking somewhere onto the
|
||||
timeline to position it. One they are positioned, you
|
||||
can click and drag events up and down the timeline to
|
||||
change when they happen.
|
||||
<p>
|
||||
To change an event, click on it and it'll flash to
|
||||
indicate that you have it selected. Then you can
|
||||
adjust it using the bone dials. A common problem
|
||||
is to try to edit a position without selecting it
|
||||
first - make sure that the event is flashing on
|
||||
the timeline.
|
||||
<p>
|
||||
Various operations on the 'selected' event are
|
||||
available from the 'Time' menu.
|
||||
<p>
|
||||
You can also select a 'region' by left-clicking
|
||||
on one end and right-clicking on the other. The
|
||||
current region is highlighted in yellow. There
|
||||
are operations that operate on the current region
|
||||
in the 'Time' menu.
|
||||
<p>
|
||||
Wherever you click the left button on the timeline,
|
||||
the model will move to that position - and the bone
|
||||
dials will follow. You can drag the mouse up and
|
||||
down the timeline to replay the animation at whatever
|
||||
speed you move the mouse. However, to get a 'realistic'
|
||||
playback speed, use the single arrows on the VCR
|
||||
menu.
|
||||
<p>
|
||||
Remember though that you can only EDIT the position
|
||||
of the model on a selected event.
|
||||
|
||||
<H3>Menu Operations on the Timeline.</H3>
|
||||
The 'Time' menu allows you to add an event,
|
||||
delete the selected event, delete ALL the events
|
||||
in the 'region' that you have highlighted,
|
||||
or delete the section of time in the 'region' -
|
||||
compressing up the rest of the timeline to fit.
|
||||
Finally, you can add more time to the timeline
|
||||
so that you can create animations that are longer
|
||||
than the ten seconds initially provided.
|
||||
|
||||
<H2>The Exposer ".bones" file format.</H2>
|
||||
This is a very simple ASCII text file - however
|
||||
the parser for it is VERY crude at this stage.
|
||||
<p>
|
||||
The first line of the file is:
|
||||
<pre>
|
||||
|
||||
NUMBONES=17 NUMEVENTS=7 MAXTIME=10.0000 Z_OFFSET=1.3 SPEED=0.3
|
||||
|
||||
</pre>
|
||||
So there are 17 bones, 7 events - and the
|
||||
duration of the animation is ten seconds.
|
||||
<p>
|
||||
The Z_OFFSET is advice to the application about the
|
||||
height of the origin of the model above the lowest
|
||||
point on the model in it's default pose.
|
||||
<p>
|
||||
SPEED is the speed set on the VCR 'Ground Speed'
|
||||
control - which the application can use to tell
|
||||
at what speed the character should move forwards
|
||||
in order to make the animation look right.
|
||||
<p>
|
||||
Then follows the bones - one per line:
|
||||
<pre>
|
||||
|
||||
BONE "bone-name" HPR
|
||||
|
||||
</pre>
|
||||
The 'bone-name' is the string you entered beside the
|
||||
bone dials. The 'HPR' part sets which axes are frozen.
|
||||
(in this case, none of them...the frozen axis letters
|
||||
are replaced by dots).
|
||||
<p>
|
||||
After all the bones come the events. For each event
|
||||
there is a header line:
|
||||
<pre>
|
||||
|
||||
EVENT 3.0000 17 (0.000,0.000,0.000)
|
||||
|
||||
</pre>
|
||||
The first number is the time (in seconds) at which the
|
||||
event occurred, the second number is the number of bones
|
||||
that are affected by this event. Currently this must be
|
||||
the same as 'NUMBONES'. The coordinate in parentheses is
|
||||
the body-translation of the model from the origin at this
|
||||
moment in time.
|
||||
<p>
|
||||
After the event header, there is one line per bone
|
||||
containing the three joint angles in degrees for
|
||||
that bone at that time:
|
||||
<pre>
|
||||
|
||||
(90,45,37)
|
||||
|
||||
</pre>
|
||||
That's it! However, as I said - the parser is 'brittle'
|
||||
and very intolerant of errors - edit the file at your
|
||||
own peril!
|
||||
|
||||
<H2>Support Programs.</H2>
|
||||
|
||||
In the ExPoser directory, you'll also find a short
|
||||
program called 'merge_bones' - this takes a number
|
||||
of '.bones' files (listed in order on the command line)
|
||||
and concatenates them end-to-end - placing the results
|
||||
in the file 'out.bones'.
|
||||
<p>
|
||||
On stdout, it lists the header from each of the component
|
||||
files. It is (of course) necessary that the '.bones'
|
||||
files originated from the same 3D model - merge_bones
|
||||
checks that things are consistant and warns of errors.
|
||||
|
||||
|
||||
<H2>Some Advice</H2>
|
||||
Bones don't necessarily have to be placed where the
|
||||
bones would be in an anatomically correct version of
|
||||
the critter. In the example 'dog.ac' file, there is
|
||||
a tongue-bone and two ear-bones - and there are no ribs,
|
||||
spinal vertibrae, etc.
|
||||
<p>
|
||||
You'll also probably need to hop back and forth between
|
||||
your modeller and exposer to position the bones how you
|
||||
want them. You'll find on occasions that the algorithm
|
||||
that causes exposer to attach a skin vertex to the nearest
|
||||
bone will sometimes result in part of a character's stomach
|
||||
being attached to their hand or something. If that happens
|
||||
then you might try adding some lateral bones
|
||||
in the stomach to ensure that there is always one attached
|
||||
to the spine that's closer to the skin than the hand is.
|
||||
<p>
|
||||
Artists should be encouraged to model the character in
|
||||
a position with their legs wide apart and their arms
|
||||
fully outstretched to minimise this kind of problem.
|
||||
<p>
|
||||
It is normal to model the character facing down the
|
||||
positive Y axis - facing away from the camera.
|
||||
<p>
|
||||
Using the axis freeze buttons to isolate only those
|
||||
axes through which a real joint can rotate is very
|
||||
useful. A human elbow joint can really only
|
||||
rotate through one axis and turning off the other two is
|
||||
helpful.
|
||||
<p>
|
||||
You can also use Exposer for things other than animals.
|
||||
You could model plants bending in a heavy wind - or
|
||||
even flexible things like flags or clothing.
|
||||
|
||||
<hr>
|
||||
<ADDRESS>
|
||||
<A HREF="http://www.sjbaker.org">
|
||||
Steve J. Baker.</A>
|
||||
<<A HREF="mailto:sjbaker1@airmail.net">sjbaker1@airmail.net</A>>
|
||||
</ADDRESS>
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
After Width: | Height: | Size: 329 B |
|
After Width: | Height: | Size: 365 B |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "exposer"=.\src\exposer.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# src/
|
||||
|
||||
bindir=$(prefix)/games
|
||||
|
||||
bin_PROGRAMS = exposer merge_tweens
|
||||
|
||||
exposer_SOURCES = \
|
||||
exposer.cxx exposer.h \
|
||||
floor.cxx floor.h \
|
||||
vertices.cxx vertices.h \
|
||||
boneGUI.cxx boneGUI.h \
|
||||
load_save.cxx load_save.h \
|
||||
timebox.cxx timebox.h \
|
||||
bones.cxx bones.h \
|
||||
event.cxx event.h \
|
||||
model.cxx model.h
|
||||
|
||||
merge_tweens_SOURCES = \
|
||||
merge_tweens.cxx merge_tweens.h
|
||||
|
||||
EXTRA_DIST = exposer.dsp
|
||||
|
||||
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
This file is part of ExPoser - A Tool for Animating PLIB Critters.
|
||||
Copyright (C) 2001 Steve Baker
|
||||
|
||||
ExPoser is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ExPoser is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ExPoser; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: boneGUI.cxx 2100 2006-11-03 22:31:54Z fayjf $
|
||||
*/
|
||||
|
||||
|
||||
#include "exposer.h"
|
||||
|
||||
static puSlider *XtranslateSlider ;
|
||||
static puSlider *YtranslateSlider ;
|
||||
static puSlider *ZtranslateSlider ;
|
||||
static puInput *XtranslateInput ;
|
||||
static puInput *YtranslateInput ;
|
||||
static puInput *ZtranslateInput ;
|
||||
|
||||
|
||||
static void jointHeadingCB ( puObject *ob )
|
||||
{
|
||||
Bone *bone = (Bone *) (ob->getUserData()) ;
|
||||
float a ; ob -> getValue ( & a ) ;
|
||||
|
||||
bone->setAngle ( 0, a * 360.0f - 180.0f ) ;
|
||||
setShowAngle ( a * 360.0f - 180.0f ) ;
|
||||
}
|
||||
|
||||
|
||||
static void jointPitchCB ( puObject *ob )
|
||||
{
|
||||
Bone *bone = (Bone *) (ob->getUserData()) ;
|
||||
float a ; ob -> getValue ( & a ) ;
|
||||
|
||||
bone->setAngle ( 1, a * 360.0f - 180.0f ) ;
|
||||
setShowAngle ( a * 360.0f - 180.0f ) ;
|
||||
}
|
||||
|
||||
|
||||
static void jointRollCB ( puObject *ob )
|
||||
{
|
||||
Bone *bone = (Bone *) (ob->getUserData()) ;
|
||||
float a ; ob -> getValue ( & a ) ;
|
||||
|
||||
bone->setAngle ( 2, a * 360.0f - 180.0f ) ;
|
||||
setShowAngle ( a * 360.0f - 180.0f ) ;
|
||||
}
|
||||
|
||||
|
||||
void hide_headingCB ( puObject *ob )
|
||||
{
|
||||
Bone *bone = (Bone *) (ob->getUserData()) ;
|
||||
|
||||
if ( ob -> getValue () )
|
||||
bone -> sh -> hide () ;
|
||||
else
|
||||
bone -> sh -> reveal () ;
|
||||
}
|
||||
|
||||
|
||||
void hide_pitchCB ( puObject *ob )
|
||||
{
|
||||
Bone *bone = (Bone *) (ob->getUserData()) ;
|
||||
|
||||
if ( ob -> getValue () )
|
||||
bone -> sp -> hide () ;
|
||||
else
|
||||
bone -> sp -> reveal () ;
|
||||
}
|
||||
|
||||
void hide_rollCB ( puObject *ob )
|
||||
{
|
||||
Bone *bone = (Bone *) (ob->getUserData()) ;
|
||||
|
||||
if ( ob -> getValue () )
|
||||
bone -> sr -> hide () ;
|
||||
else
|
||||
bone -> sr -> reveal () ;
|
||||
}
|
||||
|
||||
|
||||
static void resetCB ( puObject *ob )
|
||||
{
|
||||
Bone *bone = (Bone *) (ob->getUserData()) ;
|
||||
|
||||
bone -> setAngles ( 0, 0, 0 ) ;
|
||||
}
|
||||
|
||||
|
||||
void syncTranslators ( sgVec3 trans )
|
||||
{
|
||||
XtranslateSlider -> setValue ( trans [ 0 ] / 5.0f + 0.5f ) ;
|
||||
YtranslateSlider -> setValue ( trans [ 1 ] / 5.0f + 0.5f ) ;
|
||||
ZtranslateSlider -> setValue ( trans [ 2 ] / 5.0f + 0.5f ) ;
|
||||
|
||||
if ( ! XtranslateInput -> isAcceptingInput () )
|
||||
XtranslateInput -> setValue ( trans [ 0 ] ) ;
|
||||
if ( ! YtranslateInput -> isAcceptingInput () )
|
||||
YtranslateInput -> setValue ( trans [ 1 ] ) ;
|
||||
if ( ! ZtranslateInput -> isAcceptingInput () )
|
||||
ZtranslateInput -> setValue ( trans [ 2 ] ) ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void currTranslateTxtXCB ( puObject *sl )
|
||||
{
|
||||
float v = sl -> getFloatValue () ;
|
||||
|
||||
if ( eventList->getCurrentEvent() == NULL ) return ;
|
||||
|
||||
sgVec3 xyz ;
|
||||
|
||||
eventList->getCurrentEvent() -> getTranslate ( xyz ) ;
|
||||
xyz [ 0 ] = v ;
|
||||
eventList->getCurrentEvent() -> setTranslate ( xyz ) ;
|
||||
|
||||
syncTranslators ( xyz ) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void currTranslateTxtYCB ( puObject *sl )
|
||||
{
|
||||
float v = sl -> getFloatValue () ;
|
||||
|
||||
if ( eventList->getCurrentEvent() == NULL ) return ;
|
||||
|
||||
sgVec3 xyz ;
|
||||
|
||||
eventList->getCurrentEvent() -> getTranslate ( xyz ) ;
|
||||
xyz [ 1 ] = v ;
|
||||
eventList->getCurrentEvent() -> setTranslate ( xyz ) ;
|
||||
|
||||
syncTranslators ( xyz ) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void currTranslateTxtZCB ( puObject *sl )
|
||||
{
|
||||
float v = sl -> getFloatValue () ;
|
||||
|
||||
if ( eventList->getCurrentEvent() == NULL ) return ;
|
||||
|
||||
sgVec3 xyz ;
|
||||
|
||||
eventList->getCurrentEvent() -> getTranslate ( xyz ) ;
|
||||
xyz [ 2 ] = v ;
|
||||
eventList->getCurrentEvent() -> setTranslate ( xyz ) ;
|
||||
|
||||
syncTranslators ( xyz ) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void currTranslateXCB ( puObject *sl )
|
||||
{
|
||||
float v = (((puSlider *)sl) -> getFloatValue () - 0.5f ) * 5.0f ;
|
||||
|
||||
if ( eventList->getCurrentEvent() == NULL ) return ;
|
||||
|
||||
sgVec3 xyz ;
|
||||
|
||||
eventList->getCurrentEvent() -> getTranslate ( xyz ) ;
|
||||
xyz [ 0 ] = v ;
|
||||
eventList->getCurrentEvent() -> setTranslate ( xyz ) ;
|
||||
|
||||
syncTranslators ( xyz ) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void currTranslateYCB ( puObject *sl )
|
||||
{
|
||||
float v = (((puSlider *)sl) -> getFloatValue () - 0.5f ) * 5.0f ;
|
||||
|
||||
if ( eventList->getCurrentEvent() == NULL ) return ;
|
||||
|
||||
sgVec3 xyz ;
|
||||
|
||||
eventList->getCurrentEvent() -> getTranslate ( xyz ) ;
|
||||
xyz [ 1 ] = v ;
|
||||
eventList->getCurrentEvent() -> setTranslate ( xyz ) ;
|
||||
|
||||
syncTranslators ( xyz ) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void currTranslateZCB ( puObject *sl )
|
||||
{
|
||||
float v = (((puSlider *)sl) -> getFloatValue () - 0.5f ) * 5.0f ;
|
||||
|
||||
if ( eventList->getCurrentEvent() == NULL ) return ;
|
||||
|
||||
sgVec3 xyz ;
|
||||
|
||||
eventList->getCurrentEvent() -> getTranslate ( xyz ) ;
|
||||
xyz [ 2 ] = v ;
|
||||
eventList->getCurrentEvent() -> setTranslate ( xyz ) ;
|
||||
|
||||
syncTranslators ( xyz ) ;
|
||||
}
|
||||
|
||||
|
||||
void initBoneGUI ()
|
||||
{
|
||||
puText *message ;
|
||||
|
||||
ZtranslateInput = new puInput ( 5, 485, 80, 505 ) ;
|
||||
ZtranslateInput -> setCallback ( currTranslateTxtZCB ) ;
|
||||
|
||||
ZtranslateSlider = new puSlider ( 80, 485, 120, FALSE ) ;
|
||||
ZtranslateSlider -> setCBMode ( PUSLIDER_DELTA ) ;
|
||||
ZtranslateSlider -> setDelta ( 0.01f ) ;
|
||||
ZtranslateSlider -> setCallback ( currTranslateZCB ) ;
|
||||
message = new puText ( 205,485 ) ; message->setLabel ( "Z" ) ;
|
||||
|
||||
YtranslateInput = new puInput ( 5, 505, 80, 525 ) ;
|
||||
YtranslateInput -> setCallback ( currTranslateTxtYCB ) ;
|
||||
|
||||
YtranslateSlider = new puSlider ( 80, 505, 120, FALSE ) ;
|
||||
YtranslateSlider -> setCBMode ( PUSLIDER_DELTA ) ;
|
||||
YtranslateSlider -> setDelta ( 0.01f ) ;
|
||||
YtranslateSlider -> setCallback ( currTranslateYCB ) ;
|
||||
message = new puText ( 205,505 ) ; message->setLabel ( "Y" ) ;
|
||||
|
||||
XtranslateInput = new puInput ( 5, 525, 80, 545 ) ;
|
||||
XtranslateInput -> setCallback ( currTranslateTxtXCB ) ;
|
||||
|
||||
XtranslateSlider = new puSlider ( 80, 525, 120, FALSE ) ;
|
||||
XtranslateSlider -> setCBMode ( PUSLIDER_DELTA ) ;
|
||||
XtranslateSlider -> setDelta ( 0.01f ) ;
|
||||
XtranslateSlider -> setCallback ( currTranslateXCB ) ;
|
||||
message = new puText ( 205,525 ) ; message->setLabel ( "X" ) ;
|
||||
}
|
||||
|
||||
|
||||
void Bone::createJoint ()
|
||||
{
|
||||
widget = new puGroup ( 0, 0 ) ;
|
||||
rs = new puOneShot ( 0, 0, "x" ) ;
|
||||
hb = new puButton (20, 0, "H" ) ;
|
||||
pb = new puButton (40, 0, "P" ) ;
|
||||
rb = new puButton (60, 0, "R" ) ;
|
||||
sh = new puDial ( 80, 0, 40 ) ;
|
||||
sp = new puDial ( 120, 0, 40 ) ;
|
||||
sr = new puDial ( 160, 0, 40 ) ;
|
||||
na = new puInput ( 0,20,80,40 ) ;
|
||||
|
||||
na->setUserData ( this ) ;
|
||||
na->setColourScheme ( colour[0], colour[1], colour[2], 0.5f ) ;
|
||||
|
||||
rs->setUserData ( this ) ;
|
||||
rs->setCallback ( resetCB ) ;
|
||||
rs->setColourScheme ( colour[0], colour[1], colour[2], 0.5f ) ;
|
||||
|
||||
hb->setUserData ( this ) ;
|
||||
hb->setCallback ( hide_headingCB ) ;
|
||||
hb->setColourScheme ( colour[0], colour[1], colour[2], 0.5f ) ;
|
||||
|
||||
pb->setUserData ( this ) ;
|
||||
pb->setCallback ( hide_pitchCB ) ;
|
||||
pb->setColourScheme ( colour[0], colour[1], colour[2], 0.5f ) ;
|
||||
|
||||
rb->setUserData ( this ) ;
|
||||
rb->setCallback ( hide_rollCB ) ;
|
||||
rb->setColourScheme ( colour[0], colour[1], colour[2], 0.5f ) ;
|
||||
|
||||
sh->setUserData ( this ) ;
|
||||
sh->setValue ( 0.5f ) ;
|
||||
sh->setCallback ( jointHeadingCB ) ;
|
||||
sh->setColourScheme ( colour[0], colour[1], colour[2], 0.5f ) ;
|
||||
|
||||
sp->setUserData ( this ) ;
|
||||
sp->setValue ( 0.5f ) ;
|
||||
sp->setCallback ( jointPitchCB ) ;
|
||||
sp->setColourScheme ( colour[0], colour[1], colour[2], 0.5f ) ;
|
||||
|
||||
sr->setUserData ( this ) ;
|
||||
sr->setValue ( 0.5f ) ;
|
||||
sr->setCallback ( jointRollCB ) ;
|
||||
sr->setColourScheme ( colour[0], colour[1], colour[2], 0.5f ) ;
|
||||
|
||||
widget -> close () ;
|
||||
widget -> hide () ;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
This file is part of ExPoser - A Tool for Animating PLIB Critters.
|
||||
Copyright (C) 2001 Steve Baker
|
||||
|
||||
ExPoser is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ExPoser is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ExPoser; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: boneGUI.h 1425 2002-08-17 23:58:38Z ude $
|
||||
*/
|
||||
|
||||
|
||||
void hide_headingCB ( puObject *ob ) ;
|
||||
void hide_pitchCB ( puObject *ob ) ;
|
||||
void hide_rollCB ( puObject *ob ) ;
|
||||
|
||||
void syncTranslators ( sgVec3 trans ) ;
|
||||
void initBoneGUI () ;
|
||||
|
||||
|
||||
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
This file is part of ExPoser - A Tool for Animating PLIB Critters.
|
||||
Copyright (C) 2001 Steve Baker
|
||||
|
||||
ExPoser is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ExPoser is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ExPoser; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: bones.cxx 2100 2006-11-03 22:31:54Z fayjf $
|
||||
*/
|
||||
|
||||
|
||||
#include "exposer.h"
|
||||
|
||||
static sgVec3 curr_translate = { 0.0f, 0.0f, 0.0f } ;
|
||||
|
||||
static ssgSimpleState *boneState = NULL ;
|
||||
static Bone *bone = NULL ;
|
||||
|
||||
ssgSimpleState *getBoneState () { return boneState ; }
|
||||
float *getCurrTranslate () { return curr_translate ; }
|
||||
Bone *getBone ( int i ) { return & ( bone [ i ] ) ; }
|
||||
|
||||
|
||||
void init_bones ()
|
||||
{
|
||||
if ( bone == NULL )
|
||||
bone = new Bone [ 1000 ] ;
|
||||
|
||||
sgZeroVec3 ( curr_translate ) ;
|
||||
}
|
||||
|
||||
|
||||
Bone::Bone ()
|
||||
{
|
||||
parent = -1 ;
|
||||
}
|
||||
|
||||
|
||||
void Bone::read ( FILE *fd )
|
||||
{
|
||||
char name [ PUSTRING_MAX ] ;
|
||||
char shb, spb, srb ;
|
||||
|
||||
fscanf ( fd, "BONE \"%s %c%c%c\n",
|
||||
name, & shb, & spb, & srb ) ;
|
||||
|
||||
if ( name[strlen(name)-1] == '\"' )
|
||||
name[strlen(name)-1] = '\0' ;
|
||||
|
||||
na -> setValue ( name ) ;
|
||||
hb -> setValue ( (shb == 'H') ? 0 : 1 ) ;
|
||||
pb -> setValue ( (spb == 'P') ? 0 : 1 ) ;
|
||||
rb -> setValue ( (srb == 'R') ? 0 : 1 ) ;
|
||||
|
||||
hide_headingCB ( hb ) ;
|
||||
hide_pitchCB ( pb ) ;
|
||||
hide_rollCB ( rb ) ;
|
||||
}
|
||||
|
||||
|
||||
void Bone::write ( FILE *fd )
|
||||
{
|
||||
fprintf ( fd, "BONE \"%s\" %c%c%c\n",
|
||||
na->getStringValue(),
|
||||
hb->getValue() ? '.' : 'H',
|
||||
pb->getValue() ? '.' : 'P',
|
||||
rb->getValue() ? '.' : 'R' ) ;
|
||||
}
|
||||
|
||||
|
||||
void Bone::setAngles ( float h, float p, float r )
|
||||
{
|
||||
sgVec3 hpr ;
|
||||
sgSetVec3 ( hpr, h, p, r ) ;
|
||||
setAngles ( hpr ) ;
|
||||
}
|
||||
|
||||
|
||||
void Bone::setAngle ( int which, float a )
|
||||
{
|
||||
getXForm() -> hpr [ which ] = a ;
|
||||
setAngles ( getXForm() -> hpr ) ;
|
||||
}
|
||||
|
||||
|
||||
void Bone::setAngles ( sgVec3 src )
|
||||
{
|
||||
sgCopyVec3 ( getXForm() -> hpr, src ) ;
|
||||
}
|
||||
|
||||
|
||||
float *Bone::getDialAngles ()
|
||||
{
|
||||
static sgVec3 dst ;
|
||||
dst[0] = sh -> getFloatValue () * 360.0f - 180.0f ;
|
||||
dst[1] = sp -> getFloatValue () * 360.0f - 180.0f ;
|
||||
dst[2] = sr -> getFloatValue () * 360.0f - 180.0f ;
|
||||
return dst ;
|
||||
}
|
||||
|
||||
|
||||
sgCoord *Bone::getXForm ( Event *prev, Event *next, float lerptime )
|
||||
{
|
||||
static sgCoord c ;
|
||||
|
||||
sgCoord *coord0 = prev->getBoneCoord ( id ) ;
|
||||
sgCoord *coord1 = next->getBoneCoord ( id ) ;
|
||||
|
||||
sgCopyVec3 ( c.xyz, xlate ) ;
|
||||
|
||||
sgLerpAnglesVec3 ( c.hpr, coord0->hpr, coord1->hpr, lerptime ) ;
|
||||
|
||||
sh -> setValue ( (c.hpr[0] + 180.0f) / 360.0f ) ;
|
||||
sp -> setValue ( (c.hpr[1] + 180.0f) / 360.0f ) ;
|
||||
sr -> setValue ( (c.hpr[2] + 180.0f) / 360.0f ) ;
|
||||
|
||||
return & c ;
|
||||
}
|
||||
|
||||
|
||||
sgCoord *Bone::getXForm ()
|
||||
{
|
||||
if ( eventList->getCurrentEvent() != NULL )
|
||||
{
|
||||
sgCoord *coord = eventList->getCurrentEvent()->getBoneCoord ( id ) ;
|
||||
sgCopyVec3 ( coord->xyz, xlate ) ;
|
||||
return coord ;
|
||||
}
|
||||
|
||||
static sgCoord coord ;
|
||||
sgZeroCoord ( & coord ) ;
|
||||
sgCopyVec3 ( coord.xyz, xlate ) ;
|
||||
return &coord ;
|
||||
}
|
||||
|
||||
|
||||
void Bone::computeTransform ( Event *prev, Event *next, float t )
|
||||
{
|
||||
effector -> setTransform ( getXForm( prev, next, t ) ) ;
|
||||
}
|
||||
|
||||
|
||||
void Bone::transform ( sgVec3 dst, sgVec3 src )
|
||||
{
|
||||
sgXformPnt3 ( dst, src, netMatrix ) ;
|
||||
sgAddVec3 ( dst, curr_translate ) ;
|
||||
}
|
||||
|
||||
|
||||
void Bone::swapEnds()
|
||||
{
|
||||
sgVec3 tmp ;
|
||||
|
||||
/* Swap vertices so that vx0 is always the root. */
|
||||
|
||||
sgCopyVec3 ( tmp, vx[0] ) ;
|
||||
sgCopyVec3 ( vx[0], vx[1] ) ;
|
||||
sgCopyVec3 ( vx[1], tmp ) ;
|
||||
|
||||
sgCopyVec3 ( tmp, orig_vx[0] ) ;
|
||||
sgCopyVec3 ( orig_vx[0], orig_vx[1] ) ;
|
||||
sgCopyVec3 ( orig_vx[1], tmp ) ;
|
||||
}
|
||||
|
||||
|
||||
void Bone::init ( ssgLeaf *l, sgMat4 newmat, short vv[2], int ident )
|
||||
{
|
||||
parent = -1 ;
|
||||
sgCopyVec3 ( vx [ 0 ], l -> getVertex ( vv[0] ) ) ;
|
||||
sgCopyVec3 ( vx [ 1 ], l -> getVertex ( vv[1] ) ) ;
|
||||
sgXformPnt3 ( vx [ 0 ], newmat ) ;
|
||||
sgXformPnt3 ( vx [ 1 ], newmat ) ;
|
||||
|
||||
sgCopyVec3 ( orig_vx [ 0 ], vx [ 0 ] ) ;
|
||||
sgCopyVec3 ( orig_vx [ 1 ], vx [ 1 ] ) ;
|
||||
|
||||
id = ident ;
|
||||
if ( sgEqualVec3 ( vx [ 0 ], vx [ 1 ] ) )
|
||||
fprintf ( stderr, "exposer: Zero length bone found.\n" ) ;
|
||||
}
|
||||
|
||||
|
||||
void Bone::print ( FILE *fd, int which )
|
||||
{
|
||||
fprintf ( fd, "Bone %d: vx (%f,%f,%f) -> (%f,%f,%f) Parent = %d\n",
|
||||
which,
|
||||
vx[0][0],vx[0][1],vx[0][2],
|
||||
vx[1][0],vx[1][1],vx[1][2],
|
||||
parent ) ;
|
||||
}
|
||||
|
||||
|
||||
#define NUM_COLOURS 13
|
||||
|
||||
static sgVec4 colourTable [] =
|
||||
{
|
||||
{ 1, 0, 0, 0.3f }, { 0, 1, 0, 0.3f }, { 0, 0, 1, 0.3f },
|
||||
{ 1, 1, 0, 0.3f }, { 1, 0, 1, 0.3f }, { 0, 1, 1, 0.3f },
|
||||
|
||||
{ 0.5f, 0.5f, 0.5f, 0.3f },
|
||||
|
||||
{ 1, 0.5f, 0.5f, 0.3f }, { 0.5f, 1 , 0.5f, 0.3f }, { 0.5f, 0.5f, 1, 0.3f },
|
||||
{ 1, 1 , 0.5f, 0.3f }, { 1 , 0.5f, 1 , 0.3f }, { 0.5f, 1, 1, 0.3f }
|
||||
} ;
|
||||
|
||||
|
||||
ssgBranch *Bone::generateGeometry ( int root )
|
||||
{
|
||||
static int nextColIndex = 0 ;
|
||||
|
||||
ssgTransform *b = new ssgTransform ;
|
||||
|
||||
b -> setUserData ( this ) ;
|
||||
effector = b ;
|
||||
sgZeroVec3 ( getXForm()->hpr ) ;
|
||||
sgCopyVec3 ( xlate, vx[0] ) ;
|
||||
sgZeroVec3 ( vx[0] ) ;
|
||||
sgSubVec3 ( vx[1], xlate ) ;
|
||||
|
||||
sgMat4 mat ;
|
||||
sgMakeCoordMat4 ( mat, getXForm() ) ;
|
||||
b -> setTransform ( mat ) ;
|
||||
|
||||
offsetChildBones ( root, xlate ) ;
|
||||
|
||||
sgCopyVec4 ( colour, colourTable[nextColIndex] ) ;
|
||||
|
||||
createJoint () ;
|
||||
|
||||
ssgaCube *shape = new ssgaCube () ;
|
||||
sgVec3 org ; sgCopyVec3 ( org, vx[1] ) ;
|
||||
sgVec3 siz ; sgCopyVec3 ( siz, vx[1] ) ;
|
||||
|
||||
sgScaleVec3 ( org, 0.5 ) ;
|
||||
|
||||
siz[0] = (float)fabs ( siz[0] ) ; if ( siz[0] <= 0.1f ) siz [ 0 ] = 0.1f ;
|
||||
siz[1] = (float)fabs ( siz[1] ) ; if ( siz[1] <= 0.1f ) siz [ 1 ] = 0.1f ;
|
||||
siz[2] = (float)fabs ( siz[2] ) ; if ( siz[2] <= 0.1f ) siz [ 2 ] = 0.1f ;
|
||||
|
||||
if ( boneState == NULL )
|
||||
{
|
||||
boneState = new ssgSimpleState () ;
|
||||
boneState -> setColourMaterial ( GL_AMBIENT_AND_DIFFUSE ) ;
|
||||
boneState -> setMaterial ( GL_SPECULAR, 0, 0, 0, 1 ) ;
|
||||
boneState -> setMaterial ( GL_EMISSION, 0, 0, 0, 1 ) ;
|
||||
boneState -> enable ( GL_BLEND ) ;
|
||||
}
|
||||
|
||||
shape -> setCenter ( org ) ;
|
||||
shape -> setSize ( siz ) ;
|
||||
shape -> setColour ( colourTable[nextColIndex] ) ;
|
||||
shape -> setKidState ( boneState ) ;
|
||||
|
||||
nextColIndex = ( nextColIndex + 1 ) % NUM_COLOURS ;
|
||||
|
||||
b -> addKid ( shape ) ;
|
||||
|
||||
for ( int i = 0 ; i < getNumBones() ; i++ )
|
||||
if ( i != root && getBone(i)->parent == root )
|
||||
b -> addKid ( getBone(i)->generateGeometry ( i ) ) ;
|
||||
|
||||
return b ;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
This file is part of ExPoser - A Tool for Animating PLIB Critters.
|
||||
Copyright (C) 2001 Steve Baker
|
||||
|
||||
ExPoser is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ExPoser is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ExPoser; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: bones.h 1425 2002-08-17 23:58:38Z ude $
|
||||
*/
|
||||
|
||||
|
||||
#define ROOT_BONE 9999
|
||||
|
||||
class Bone : public ssgBase
|
||||
{
|
||||
public:
|
||||
int id ;
|
||||
int parent ;
|
||||
ssgTransform *effector ;
|
||||
|
||||
sgVec3 xlate ;
|
||||
sgMat4 netMatrix ;
|
||||
|
||||
sgVec3 vx [ 2 ] ; /* Relative to joint */
|
||||
sgVec3 orig_vx [ 2 ] ; /* Absolute */
|
||||
|
||||
puGroup *widget ;
|
||||
puOneShot *rs ;
|
||||
puButton *hb ;
|
||||
puButton *pb ;
|
||||
puButton *rb ;
|
||||
puDial *sh ;
|
||||
puDial *sp ;
|
||||
puDial *sr ;
|
||||
puInput *na ;
|
||||
sgVec4 colour ;
|
||||
Bone () ;
|
||||
|
||||
void read ( FILE *fd ) ;
|
||||
void write ( FILE *fd ) ;
|
||||
void createJoint () ;
|
||||
|
||||
void computeTransform ( Event *prev, Event *next, float tim ) ;
|
||||
|
||||
void setAngle ( int which, float a ) ;
|
||||
void setAngles ( float h, float p, float r ) ;
|
||||
void setAngles ( sgVec3 a ) ;
|
||||
|
||||
float *getXYZ () { return xlate ; }
|
||||
|
||||
float *getDialAngles () ;
|
||||
|
||||
sgCoord *getXForm ( Event *prev, Event *next, float tim ) ;
|
||||
sgCoord *getXForm () ;
|
||||
|
||||
void transform ( sgVec3 dst, sgVec3 src ) ;
|
||||
void swapEnds() ;
|
||||
void init ( ssgLeaf *l, sgMat4 newmat, short vv[2], int id ) ;
|
||||
void print ( FILE *fd, int which ) ;
|
||||
ssgBranch *generateGeometry ( int root ) ;
|
||||
} ;
|
||||
|
||||
|
||||
void init_bones () ;
|
||||
void setShowAngle ( float a ) ;
|
||||
|
||||
float *getCurrTranslate () ;
|
||||
Bone *getBone ( int i ) ;
|
||||
|
||||
ssgSimpleState *getBoneState () ;
|
||||
|
||||
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
This file is part of ExPoser - A Tool for Animating PLIB Critters.
|
||||
Copyright (C) 2001 Steve Baker
|
||||
|
||||
ExPoser is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ExPoser is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ExPoser; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: event.cxx 2100 2006-11-03 22:31:54Z fayjf $
|
||||
*/
|
||||
|
||||
|
||||
#include "exposer.h"
|
||||
|
||||
|
||||
void EventList::read ( int nevents, FILE *fd )
|
||||
{
|
||||
for ( int i = 0 ; i < nevents ; i++ )
|
||||
{
|
||||
Event *e = new Event ( getNumBones(), (float) i ) ;
|
||||
e -> read ( fd ) ;
|
||||
addEvent ( e ) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EventList::write ( FILE *fd )
|
||||
{
|
||||
for ( int i = 0 ; i < getNumEvents () ; i++ )
|
||||
getEvent ( i ) -> write ( fd ) ;
|
||||
}
|
||||
|
||||
|
||||
void EventList::moveEvent ( Event *e, float new_time )
|
||||
{
|
||||
removeEvent ( e ) ;
|
||||
e -> setTime ( new_time ) ;
|
||||
addEvent ( e ) ;
|
||||
}
|
||||
|
||||
|
||||
void EventList::newEvent ( float t )
|
||||
{
|
||||
if ( getNumBones () <= 0 )
|
||||
return ;
|
||||
|
||||
setCurrentEvent ( new Event ( getNumBones (), t ) ) ;
|
||||
addEvent ( getCurrentEvent () ) ;
|
||||
}
|
||||
|
||||
|
||||
void EventList::deleteEvent ( Event *e )
|
||||
{
|
||||
if ( e == NULL )
|
||||
return ;
|
||||
|
||||
if ( e == curr_event )
|
||||
curr_event = NULL ;
|
||||
|
||||
removeEvent ( e ) ;
|
||||
delete e ;
|
||||
}
|
||||
|
||||
|
||||
void EventList::compressEventsBetween ( float t1, float t2 )
|
||||
{
|
||||
deleteEventsBetween ( t1, t2 ) ;
|
||||
|
||||
for ( int i = 0 ; i < getNumEvents() ; i++ )
|
||||
{
|
||||
Event *ev = getEvent ( i ) ;
|
||||
|
||||
float t = ev -> getTime () ;
|
||||
|
||||
if ( t > t1 || t > t2 )
|
||||
ev -> setTime ( t - (float)fabs(t1-t2) ) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int EventList::getNumEventsBetween ( float t1, float t2 )
|
||||
{
|
||||
int nevents = 0 ;
|
||||
|
||||
for ( int i = 0 ; i < getNumEvents() ; i++ )
|
||||
{
|
||||
float t = getEvent ( i ) -> getTime () ;
|
||||
|
||||
if ( ( t1 < t2 && t >= t1 && t <= t2 ) ||
|
||||
( t2 < t1 && t >= t2 && t <= t1 ) )
|
||||
nevents++ ;
|
||||
}
|
||||
|
||||
return nevents ;
|
||||
}
|
||||
|
||||
|
||||
int EventList::getEventsBetween ( float t1, float t2, Event ***elist )
|
||||
{
|
||||
int nevents = getNumEventsBetween ( t1, t2 ) ;
|
||||
|
||||
if ( nevents == 0 )
|
||||
{
|
||||
elist = NULL ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/* Make a list of the events */
|
||||
|
||||
*elist = new Event* [ nevents ] ;
|
||||
|
||||
nevents = 0 ;
|
||||
|
||||
for ( int i = 0 ; i < getNumEvents() ; i++ )
|
||||
{
|
||||
Event *ev = getEvent ( i ) ;
|
||||
float t = ev -> getTime () ;
|
||||
|
||||
if ( ( t1 < t2 && t >= t1 && t <= t2 ) ||
|
||||
( t2 < t1 && t >= t2 && t <= t1 ) )
|
||||
(*elist) [ nevents++ ] = ev ;
|
||||
}
|
||||
|
||||
return nevents ;
|
||||
}
|
||||
|
||||
|
||||
void EventList::deleteEventsBetween ( float t1, float t2 )
|
||||
{
|
||||
int found_one = FALSE ;
|
||||
|
||||
do
|
||||
{
|
||||
found_one = FALSE ;
|
||||
|
||||
for ( int i = 0 ; i < getNumEvents() && ! found_one ; i++ )
|
||||
{
|
||||
Event *ev = getEvent ( i ) ;
|
||||
|
||||
float t = ev -> getTime () ;
|
||||
|
||||
if ( ( t1 < t2 && t >= t1 && t <= t2 ) ||
|
||||
( t2 < t1 && t >= t2 && t <= t1 ) )
|
||||
{
|
||||
deleteEvent ( ev ) ;
|
||||
found_one = TRUE ;
|
||||
}
|
||||
}
|
||||
|
||||
} while ( found_one ) ;
|
||||
}
|
||||
|
||||
|
||||
void EventList::reverseEventsBetween ( float t1, float t2 )
|
||||
{
|
||||
/* Make a list of the events */
|
||||
|
||||
Event **elist ;
|
||||
int nevents = getEventsBetween ( t1, t2, &elist ) ;
|
||||
|
||||
if ( nevents == 0 )
|
||||
return ;
|
||||
|
||||
/* Reverse their order */
|
||||
|
||||
for ( int i = 0 ; i < nevents ; i++ )
|
||||
{
|
||||
Event *ev = elist [ i ] ;
|
||||
|
||||
removeEvent ( ev ) ;
|
||||
|
||||
float t = ev -> getTime () ;
|
||||
|
||||
if ( t1 > t2 )
|
||||
t = t1 - ( t - t2 ) ;
|
||||
else
|
||||
t = t2 - ( t - t1 ) ;
|
||||
|
||||
ev -> setTime ( t ) ;
|
||||
|
||||
addEvent ( ev ) ;
|
||||
}
|
||||
|
||||
delete [] elist ;
|
||||
}
|
||||
|
||||
|
||||
void EventList::addEvent ( Event *e )
|
||||
{
|
||||
/*
|
||||
Keep list in time-increasing order.
|
||||
*/
|
||||
|
||||
for ( int i = 0 ; i < getNumEvents() ; i++ )
|
||||
if ( e -> getTime() < getEvent(i)->getTime() )
|
||||
{
|
||||
addEntityBefore ( i, e ) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
addEntity ( e ) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Event *EventList::findNearestEvent ( float t, float tolerance )
|
||||
{
|
||||
int nearest = -1 ;
|
||||
float min = FLT_MAX ;
|
||||
|
||||
for ( int i = 0 ; i < getNumEvents() ; i++ )
|
||||
{
|
||||
float t2 = getEvent(i)->getTime() ;
|
||||
float diff = (float) fabs ( t - t2 ) ;
|
||||
|
||||
if ( diff < min )
|
||||
{
|
||||
min = diff ;
|
||||
nearest = i ;
|
||||
}
|
||||
}
|
||||
|
||||
return ( nearest >= 0 && min < tolerance ) ? getEvent ( nearest ) : NULL ;
|
||||
}
|
||||
|
||||
|
||||
void EventList::deleteAll ()
|
||||
{
|
||||
while ( getNumEvents() > 0 )
|
||||
deleteEvent ( getEvent ( 0 ) ) ;
|
||||
}
|
||||
|
||||
|
||||
EventList::EventList ()
|
||||
{
|
||||
curr_event = NULL ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Event::Event ( int n, float t )
|
||||
{
|
||||
time = t ;
|
||||
nbones = n ;
|
||||
bone_angles = new sgCoord [ n ] ;
|
||||
|
||||
sgCopyVec3 ( translate, getCurrTranslate() ) ;
|
||||
|
||||
for ( int i = 0 ; i < n ; i++ )
|
||||
{
|
||||
sgCopyVec3 ( bone_angles [ i ] . hpr, getBone(i)->getDialAngles() ) ;
|
||||
sgCopyVec3 ( bone_angles [ i ] . xyz, getBone(i)->getXYZ() ) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Event::read ( FILE *fd )
|
||||
{
|
||||
fscanf ( fd, "EVENT %f %d (%f,%f,%f)\n", &time, &nbones,
|
||||
&translate[0], &translate[1], &translate[2] ) ;
|
||||
|
||||
for ( int i = 0 ; i < nbones ; i++ )
|
||||
{
|
||||
int ssh, ssp, ssr ;
|
||||
|
||||
fscanf ( fd, " (%d,%d,%d)\n", & ssh, & ssp, & ssr ) ;
|
||||
|
||||
sgSetVec3 ( bone_angles [ i ] . hpr, (float)ssh, (float)ssp, (float)ssr ) ;
|
||||
sgCopyVec3 ( bone_angles [ i ] . xyz, getBone(i)->getXYZ() ) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Event::write ( FILE *fd )
|
||||
{
|
||||
fprintf ( fd, "EVENT %f %d (%f,%f,%f)\n", time, nbones,
|
||||
translate[0], translate[1], translate[2] ) ;
|
||||
|
||||
for ( int i = 0 ; i < nbones ; i++ )
|
||||
{
|
||||
fprintf ( fd, " (%d,%d,%d)\n",
|
||||
(int) bone_angles [ i ] . hpr[0],
|
||||
(int) bone_angles [ i ] . hpr[1],
|
||||
(int) bone_angles [ i ] . hpr[2] ) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
This file is part of ExPoser - A Tool for Animating PLIB Critters.
|
||||
Copyright (C) 2001 Steve Baker
|
||||
|
||||
ExPoser is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ExPoser is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ExPoser; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: event.h 1425 2002-08-17 23:58:38Z ude $
|
||||
*/
|
||||
|
||||
|
||||
class Event
|
||||
{
|
||||
float time ;
|
||||
int nbones ;
|
||||
sgCoord *bone_angles ;
|
||||
sgVec3 translate ;
|
||||
|
||||
public:
|
||||
|
||||
Event ( int n, float t ) ;
|
||||
~Event () { delete [] bone_angles ; }
|
||||
|
||||
void read ( FILE *fd ) ;
|
||||
void write ( FILE *fd ) ;
|
||||
|
||||
void setTranslate ( sgVec3 tra ) { sgCopyVec3 ( translate, tra ) ; }
|
||||
void getTranslate ( sgVec3 tra ) { sgCopyVec3 ( tra, translate ) ; }
|
||||
|
||||
void setBoneAngles ( int n, sgVec3 angles )
|
||||
{
|
||||
if ( n < nbones )
|
||||
sgCopyVec3 ( bone_angles[n].hpr, angles ) ;
|
||||
}
|
||||
|
||||
void getBoneAngles ( int n, sgVec3 angles )
|
||||
{
|
||||
if ( n < nbones )
|
||||
sgCopyVec3 ( angles, bone_angles[n].hpr ) ;
|
||||
else
|
||||
sgZeroVec3 ( angles ) ;
|
||||
}
|
||||
|
||||
sgCoord *getBoneCoord ( int n ) { return & ( bone_angles [ n ] ) ; }
|
||||
|
||||
void setTime ( float t ) { time = t ; }
|
||||
float getTime () { return time ; }
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class EventList : public ulList
|
||||
{
|
||||
Event *curr_event ;
|
||||
|
||||
public:
|
||||
|
||||
EventList () ;
|
||||
|
||||
int getNumEvents () { return getNumEntities () ; }
|
||||
|
||||
void addEvent ( Event *e ) ;
|
||||
void newEvent ( float t ) ;
|
||||
Event *findNearestEvent ( float t, float tolerance ) ;
|
||||
|
||||
void moveEvent ( Event *e, float new_time ) ;
|
||||
void removeEvent ( Event *e ) { removeEntity ( e ) ; }
|
||||
void setCurrentEvent ( Event *ev ) { curr_event = ev ; }
|
||||
Event *getEvent ( int i ) { return (Event *) getEntity ( i ) ; }
|
||||
void deleteEvent ( Event *e ) ;
|
||||
void deleteAll () ;
|
||||
|
||||
Event *getCurrentEvent () { return curr_event ; }
|
||||
void deleteCurrentEvent() { deleteEvent ( curr_event ) ; }
|
||||
|
||||
int getNumEventsBetween ( float t1, float t2 ) ;
|
||||
int getEventsBetween ( float t1, float t2, Event ***elist ) ;
|
||||
void reverseEventsBetween ( float t1, float t2 ) ;
|
||||
void deleteEventsBetween ( float t1, float t2 ) ;
|
||||
void compressEventsBetween( float t1, float t2 ) ;
|
||||
|
||||
void write ( FILE *fd ) ;
|
||||
void read ( int nevents, FILE *fd ) ;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,480 @@
|
||||
/*
|
||||
This file is part of ExPoser - A Tool for Animating PLIB Critters.
|
||||
Copyright (C) 2001 Steve Baker
|
||||
|
||||
ExPoser is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ExPoser is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ExPoser; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: exposer.cxx 2100 2006-11-03 22:31:54Z fayjf $
|
||||
*/
|
||||
|
||||
|
||||
#include "exposer.h"
|
||||
|
||||
static int curr_button = 0 ;
|
||||
static int scroll_controllers = 0 ;
|
||||
|
||||
EventList * eventList = NULL ;
|
||||
TimeBox * timebox = NULL ;
|
||||
Floor * ground = NULL ;
|
||||
ssgRoot * skinScene = NULL ;
|
||||
ssgRoot *tweenScene = NULL ;
|
||||
ssgRoot * boneScene = NULL ;
|
||||
ssgRoot *sceneScene = NULL ;
|
||||
|
||||
static puText *message ;
|
||||
static puButton *hideBones ;
|
||||
static puButton *hideSkin ;
|
||||
static puButton *hideGround ;
|
||||
static puButton *hideScene ;
|
||||
static puSlider *scroller ;
|
||||
static puMenuBar *menuBar ;
|
||||
|
||||
static puSlider *rangeSlider ;
|
||||
static puDial * panSlider ;
|
||||
static puDial * tiltSlider ;
|
||||
|
||||
static puInput *show_angle ;
|
||||
|
||||
static void save_60th_CB ( puObject * ) { setTweenInterval ( 1.0f/60.0f ) ; }
|
||||
static void save_30th_CB ( puObject * ) { setTweenInterval ( 1.0f/30.0f ) ; }
|
||||
static void save_20th_CB ( puObject * ) { setTweenInterval ( 1.0f/20.0f ) ; }
|
||||
static void save_15th_CB ( puObject * ) { setTweenInterval ( 1.0f/15.0f ) ; }
|
||||
static void save_10th_CB ( puObject * ) { setTweenInterval ( 1.0f/10.0f ) ; }
|
||||
static void save_8th_CB ( puObject * ) { setTweenInterval ( 1.0f/ 8.0f ) ; }
|
||||
static void save_4th_CB ( puObject * ) { setTweenInterval ( 1.0f/ 4.0f ) ; }
|
||||
static void save_2th_CB ( puObject * ) { setTweenInterval ( 1.0f/ 2.0f ) ; }
|
||||
static void save_1th_CB ( puObject * ) { setTweenInterval ( 1.0f ) ; }
|
||||
|
||||
void setShowAngle ( float a )
|
||||
{
|
||||
show_angle -> setValue ( a ) ;
|
||||
show_angle -> rejectInput () ;
|
||||
}
|
||||
|
||||
|
||||
static void update_eye_motion ()
|
||||
{
|
||||
float r ; rangeSlider -> getValue ( & r ) ; r *= 100.0f ; r += 2.0f ;
|
||||
float h ; panSlider -> getValue ( & h ) ; h *= 360.0f ; h += 180.0f ;
|
||||
float p ; tiltSlider -> getValue ( & p ) ; p *= 360.0f ; p += 180.0f ;
|
||||
|
||||
sgMat4 mat ;
|
||||
sgVec3 vec ;
|
||||
|
||||
sgMakeCoordMat4 ( mat, 0, 0, 0, h, p, 0 ) ;
|
||||
sgSetVec3 ( vec, 0, r * 20, 0 ) ;
|
||||
sgXformPnt3 ( vec, mat ) ;
|
||||
sgNegateVec3 ( vec ) ;
|
||||
sgCopyVec3 ( mat[3], vec ) ;
|
||||
ssgSetCamera ( mat ) ;
|
||||
transformModel ( boneScene, timebox->getCursorTime () ) ;
|
||||
}
|
||||
|
||||
|
||||
static void reshape ( int w, int h )
|
||||
{
|
||||
glViewport ( 0, 0, w, h ) ;
|
||||
ssgSetFOV ( 60.0f, 60.0f * (float) h / (float) w ) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void specialfn ( int key, int, int )
|
||||
{
|
||||
puKeyboard ( key + PU_KEY_GLUT_SPECIAL_OFFSET, PU_DOWN ) ;
|
||||
}
|
||||
|
||||
|
||||
static void keyfn ( unsigned char key, int, int )
|
||||
{
|
||||
puKeyboard ( key, PU_DOWN ) ;
|
||||
}
|
||||
|
||||
|
||||
static void passmotionfn ( int x, int y )
|
||||
{
|
||||
puMouse ( x, y ) ;
|
||||
}
|
||||
|
||||
|
||||
static void motionfn ( int x, int y )
|
||||
{
|
||||
puMouse ( x, y ) ;
|
||||
timebox->updateEventQueue ( curr_button, x, y, FALSE ) ;
|
||||
}
|
||||
|
||||
|
||||
static void mousefn ( int button, int updown, int x, int y )
|
||||
{
|
||||
puMouse ( button, updown, x, y ) ;
|
||||
|
||||
curr_button = button ;
|
||||
timebox->updateEventQueue ( curr_button, x, y, updown == PU_DOWN ) ;
|
||||
}
|
||||
|
||||
|
||||
static void scrollerCB ( puObject *ob )
|
||||
{
|
||||
scroll_controllers = (int)(((float)getNumBones()) * ob -> getFloatValue ()) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void exitCB ( puObject *ob )
|
||||
{
|
||||
if ( ob -> getValue () )
|
||||
exit ( 1 ) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
CALLBACK FUNCTIONS FOR GUI.
|
||||
*/
|
||||
|
||||
static void deleteEventCB ( puObject * ) { timebox -> deleteEvent () ; }
|
||||
static void addNewEventCB ( puObject * ) { timebox -> addNewEvent () ; }
|
||||
static void reverseRegionCB ( puObject * ) { timebox -> reverseRegion () ; }
|
||||
// static void deleteAllCB ( puObject * ) { timebox -> deleteAll () ; }
|
||||
static void deleteRegionCB ( puObject * ) { timebox -> deleteRegion () ; }
|
||||
static void deleteRegionAndCompressCB ( puObject * )
|
||||
{ timebox -> deleteRegionAndCompress () ; }
|
||||
|
||||
static void zoom_nrm_CB ( puObject * ) { timebox -> setZoom ( 1.0f ) ; }
|
||||
static void zoom_in_CB ( puObject * ) { timebox -> setZoom (
|
||||
timebox -> getZoom () * 1.5f ) ; }
|
||||
static void zoom_out_CB ( puObject * ) { float scale = timebox->getZoom() / 1.5f ;
|
||||
timebox -> setZoom ( ( scale <= 1.0f ) ? 1.0f : scale ) ; }
|
||||
|
||||
static void add_1_CB ( puObject * ) {timebox->setMaxTime(timebox->getMaxTime()+1.0f);}
|
||||
static void add_2_CB ( puObject * ) {timebox->setMaxTime(timebox->getMaxTime()+2.0f);}
|
||||
static void add_5_CB ( puObject * ) {timebox->setMaxTime(timebox->getMaxTime()+5.0f);}
|
||||
|
||||
static void opaqueBones ()
|
||||
{
|
||||
if ( getBoneState() != NULL )
|
||||
getBoneState() -> disable ( GL_BLEND ) ;
|
||||
}
|
||||
|
||||
|
||||
static void blendBones ()
|
||||
{
|
||||
if ( getBoneState() != NULL )
|
||||
getBoneState() -> enable ( GL_BLEND ) ;
|
||||
}
|
||||
|
||||
|
||||
/* GLUT callbacks */
|
||||
|
||||
static void redraw ()
|
||||
{
|
||||
int i ;
|
||||
|
||||
timebox->updateVCR () ;
|
||||
|
||||
update_eye_motion () ;
|
||||
|
||||
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
|
||||
glEnable ( GL_DEPTH_TEST ) ;
|
||||
|
||||
if ( ! hideScene -> getValue () && sceneScene != NULL )
|
||||
ssgCullAndDraw ( sceneScene ) ;
|
||||
|
||||
if ( ! hideGround -> getValue () )
|
||||
ground -> draw () ;
|
||||
|
||||
if ( ! hideSkin -> getValue () )
|
||||
{
|
||||
ssgCullAndDraw ( skinScene ) ;
|
||||
blendBones () ;
|
||||
}
|
||||
else
|
||||
opaqueBones () ;
|
||||
|
||||
if ( ! hideBones -> getValue () )
|
||||
{
|
||||
glClear ( GL_DEPTH_BUFFER_BIT ) ;
|
||||
ssgCullAndDraw ( boneScene ) ;
|
||||
}
|
||||
|
||||
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
|
||||
glAlphaFunc ( GL_GREATER, 0.1f ) ;
|
||||
glEnable ( GL_BLEND ) ;
|
||||
glDisable ( GL_DEPTH_TEST ) ;
|
||||
|
||||
for ( i = 0 ; i < getNumBones() ; i++ )
|
||||
getBone ( i ) -> widget -> hide () ;
|
||||
|
||||
for ( i = 0 ; i < 10 && i+scroll_controllers < getNumBones() ; i++ )
|
||||
{
|
||||
getBone ( i + scroll_controllers ) -> widget -> setPosition ( 24, 70+i*40);
|
||||
|
||||
if ( eventList -> getCurrentEvent() == NULL )
|
||||
{
|
||||
getBone ( i + scroll_controllers ) -> widget -> reveal () ;
|
||||
getBone ( i + scroll_controllers ) -> widget -> greyOut () ;
|
||||
}
|
||||
else
|
||||
{
|
||||
getBone ( i + scroll_controllers ) -> widget -> reveal () ;
|
||||
getBone ( i + scroll_controllers ) -> widget -> activate () ;
|
||||
}
|
||||
}
|
||||
|
||||
puDisplay () ;
|
||||
|
||||
timebox -> draw () ;
|
||||
|
||||
glutPostRedisplay () ;
|
||||
glutSwapBuffers () ;
|
||||
}
|
||||
|
||||
|
||||
/* Menu bar entries: */
|
||||
|
||||
static char *file_submenu [] = { "Exit",
|
||||
"------------",
|
||||
"Save Tweened Model As...",
|
||||
"Save Bones As...",
|
||||
"Load Bones",
|
||||
"Load Scenery",
|
||||
"Load Model",
|
||||
NULL } ;
|
||||
|
||||
static puCallback file_submenu_cb [] = { exitCB,
|
||||
NULL,
|
||||
twsaveCB,
|
||||
bnsaveCB,
|
||||
bnloadCB,
|
||||
scloadCB,
|
||||
loadCB,
|
||||
NULL } ;
|
||||
|
||||
static char *view_submenu [] = { "Zoom Timeline In",
|
||||
"Zoom Timeline Out",
|
||||
"Zoom Timeline 1:1",
|
||||
NULL } ;
|
||||
|
||||
static puCallback view_submenu_cb [] = { zoom_in_CB,
|
||||
zoom_out_CB,
|
||||
zoom_nrm_CB,
|
||||
NULL } ;
|
||||
|
||||
static char *pref_submenu [] = { "1/60th second",
|
||||
"1/30th second",
|
||||
"1/20th second",
|
||||
"1/15th second",
|
||||
"1/10th second",
|
||||
"eighth second",
|
||||
"quarter second",
|
||||
"half second",
|
||||
"second",
|
||||
"Save a tween bank every...",
|
||||
NULL } ;
|
||||
|
||||
static puCallback pref_submenu_cb [] = { save_60th_CB,
|
||||
save_30th_CB,
|
||||
save_20th_CB,
|
||||
save_15th_CB,
|
||||
save_10th_CB,
|
||||
save_8th_CB,
|
||||
save_4th_CB,
|
||||
save_2th_CB,
|
||||
save_1th_CB,
|
||||
NULL,
|
||||
NULL } ;
|
||||
|
||||
static char *time_submenu [] = { "Add 5 seconds",
|
||||
"Add 2 seconds",
|
||||
"Add 1 second",
|
||||
"------------",
|
||||
"Reverse region",
|
||||
"Delete region & compress",
|
||||
"Delete region",
|
||||
"Delete selected event",
|
||||
"Add new event",
|
||||
NULL } ;
|
||||
|
||||
static puCallback time_submenu_cb [] = { add_5_CB,
|
||||
add_2_CB,
|
||||
add_1_CB,
|
||||
NULL,
|
||||
reverseRegionCB,
|
||||
deleteRegionAndCompressCB,
|
||||
deleteRegionCB,
|
||||
deleteEventCB,
|
||||
addNewEventCB,
|
||||
NULL } ;
|
||||
|
||||
|
||||
static void init_graphics ()
|
||||
{
|
||||
int fake_argc = 1 ;
|
||||
char *fake_argv[3] ;
|
||||
|
||||
fake_argv[0] = "ExPoser" ;
|
||||
fake_argv[1] = "ExPoser - Skin and Bones animation for PLIB." ;
|
||||
fake_argv[2] = NULL ;
|
||||
|
||||
/* Initialise GLUT */
|
||||
|
||||
glutInitWindowPosition ( 0, 0 ) ;
|
||||
glutInitWindowSize ( 800, 600 ) ;
|
||||
glutInit ( &fake_argc, fake_argv ) ;
|
||||
glutInitDisplayMode ( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ) ;
|
||||
glutCreateWindow ( fake_argv[1] ) ;
|
||||
glutDisplayFunc ( redraw ) ;
|
||||
glutReshapeFunc ( reshape ) ;
|
||||
glutKeyboardFunc ( keyfn ) ;
|
||||
glutSpecialFunc ( specialfn ) ;
|
||||
glutMouseFunc ( mousefn ) ;
|
||||
glutMotionFunc ( motionfn ) ;
|
||||
glutPassiveMotionFunc ( passmotionfn ) ;
|
||||
|
||||
/* Initialise SSG & PUI */
|
||||
|
||||
ssgInit () ;
|
||||
puInit () ;
|
||||
puSetDefaultStyle ( PUSTYLE_SMALL_SHADED ) ;
|
||||
puSetDefaultFonts ( PUFONT_HELVETICA_10, PUFONT_HELVETICA_10 ) ;
|
||||
|
||||
/* Some basic OpenGL setup */
|
||||
|
||||
glClearColor ( 0.2f, 0.5f, 0.2f, 1.0f ) ;
|
||||
ssgSetFOV ( 60.0f, 0.0f ) ;
|
||||
ssgSetNearFar ( 0.1f, 700.0f ) ;
|
||||
|
||||
/* Set up the Sun. */
|
||||
|
||||
sgVec3 sunposn ;
|
||||
sgSetVec3 ( sunposn, 0.2f, 0.5f, 0.5f ) ;
|
||||
ssgGetLight ( 0 ) -> setPosition ( sunposn ) ;
|
||||
|
||||
/* GUI setup. */
|
||||
|
||||
timebox = new TimeBox ( eventList ) ;
|
||||
ground = new Floor () ;
|
||||
|
||||
menuBar = new puMenuBar () ;
|
||||
{
|
||||
menuBar -> add_submenu ( "File", file_submenu, file_submenu_cb ) ;
|
||||
menuBar -> add_submenu ( "View", view_submenu, view_submenu_cb ) ;
|
||||
menuBar -> add_submenu ( "Time", time_submenu, time_submenu_cb ) ;
|
||||
menuBar -> add_submenu ( "SavePrefs", pref_submenu, pref_submenu_cb ) ;
|
||||
}
|
||||
menuBar -> close () ;
|
||||
|
||||
show_angle = new puInput ( 5, 560, 80, 580 ) ;
|
||||
show_angle -> setValue ( "" ) ;
|
||||
show_angle -> rejectInput () ;
|
||||
message = new puText ( 80, 560 ) ;
|
||||
message -> setLabel ( "Angle" ) ;
|
||||
|
||||
scroller = new puSlider ( 5, 70, 400, TRUE ) ;
|
||||
scroller -> setCBMode ( PUSLIDER_DELTA ) ;
|
||||
scroller -> setDelta ( 0.01f ) ;
|
||||
scroller -> setCallback ( scrollerCB ) ;
|
||||
|
||||
panSlider = new puDial ( 0, 0, 40 ) ;
|
||||
panSlider -> setCBMode ( PUSLIDER_DELTA ) ;
|
||||
panSlider -> setDelta ( 0.01f ) ;
|
||||
panSlider -> setValue ( 0.5f ) ;
|
||||
message = new puText ( 0, 40 ) ;
|
||||
message -> setColour ( PUCOL_LABEL, 0.7f,0.65f,0.26f,1 ) ;
|
||||
message -> setLabel ( "Pan" ) ;
|
||||
|
||||
tiltSlider = new puDial ( 40, 0, 40 ) ;
|
||||
tiltSlider -> setCBMode ( PUSLIDER_DELTA ) ;
|
||||
tiltSlider -> setDelta ( 0.01f ) ;
|
||||
tiltSlider -> setValue ( 0.5f ) ;
|
||||
message = new puText ( 40, 40 ) ;
|
||||
message -> setColour ( PUCOL_LABEL, 0.7f,0.65f,0.26f,1 ) ;
|
||||
message -> setLabel ( "Tilt" ) ;
|
||||
|
||||
hideBones = new puButton ( 80, 0, "Bones" ) ;
|
||||
hideBones -> setValue ( TRUE ) ;
|
||||
hideSkin = new puButton ( 119, 0, "Skin" ) ;
|
||||
hideSkin -> setValue ( FALSE ) ;
|
||||
hideGround = new puButton ( 149, 0, "Floor" ) ;
|
||||
hideGround -> setValue ( FALSE ) ;
|
||||
hideScene = new puButton ( 183, 0, "Scene" ) ;
|
||||
hideScene -> setValue ( FALSE ) ;
|
||||
|
||||
rangeSlider = new puSlider ( 80, 20, 141, FALSE ) ;
|
||||
rangeSlider -> setCBMode ( PUSLIDER_DELTA ) ;
|
||||
rangeSlider -> setDelta ( 0.01f ) ;
|
||||
message = new puText ( 80, 40 ) ;
|
||||
message -> setColour ( PUCOL_LABEL, 0.7f,0.65f,0.26f,1 ) ;
|
||||
message -> setLabel ( "Zoom" ) ;
|
||||
}
|
||||
|
||||
|
||||
static void init_database ()
|
||||
{
|
||||
skinScene = new ssgRoot ;
|
||||
boneScene = new ssgRoot ;
|
||||
}
|
||||
|
||||
|
||||
static void help ()
|
||||
{
|
||||
fprintf ( stderr, "\n" ) ;
|
||||
fprintf ( stderr, "exposer: Interactive Usage -\n" ) ;
|
||||
fprintf ( stderr, " exposer\n\n" ) ;
|
||||
fprintf ( stderr, " ...or...\n\n" ) ;
|
||||
fprintf ( stderr, "exposer: Batch Tweenfile generation Usage -\n" ) ;
|
||||
fprintf ( stderr, " exposer -f framerate modelfile bonefile tweenfile\n" );
|
||||
fprintf ( stderr, "\n" ) ;
|
||||
}
|
||||
|
||||
|
||||
int main ( int argc, char **argv )
|
||||
{
|
||||
eventList = new EventList ;
|
||||
|
||||
init_graphics () ;
|
||||
init_database () ;
|
||||
init_bones () ;
|
||||
initBoneGUI () ;
|
||||
|
||||
/* Interactive? */
|
||||
|
||||
if ( argc <= 1 )
|
||||
{
|
||||
loadCB ( NULL ) ;
|
||||
|
||||
glutPostRedisplay () ;
|
||||
glutMainLoop () ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
if ( argc != 6 || strcmp ( argv [ 1 ], "-f" ) != 0 ||
|
||||
atof ( argv [ 2 ] ) > 100.0f || atof ( argv[2] ) < 0.1f )
|
||||
{
|
||||
help () ;
|
||||
return 1 ;
|
||||
}
|
||||
|
||||
setTweenInterval ( 1.0f / (float)atof ( argv [ 2 ] ) ) ;
|
||||
loadFile ( argv [ 3 ], FALSE ) ;
|
||||
loadBoneFile ( argv [ 4 ], FALSE ) ;
|
||||
saveTweenFile ( argv [ 5 ], FALSE ) ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
# Microsoft Developer Studio Project File - Name="exposer" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=exposer - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "exposer.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "exposer.mak" CFG="exposer - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "exposer - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "exposer - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "exposer - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib sg.lib ssg.lib ssgAux.lib fnt.lib pui.lib puAux.lib ul.lib opengl32.lib glu32.lib glut32.lib Winmm.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\.."
|
||||
|
||||
!ELSEIF "$(CFG)" == "exposer - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\.." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib sg_d.lib ssg_d.lib ssgAux_d.lib fnt_d.lib pui_d.lib puAux_d.lib ul_d.lib opengl32.lib glu32.lib glut32.lib Winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\.."
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "exposer - Win32 Release"
|
||||
# Name "exposer - Win32 Debug"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\boneGUI.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\boneGUI.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bones.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bones.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\event.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\event.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\exposer.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\exposer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\floor.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\floor.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\load_save.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\load_save.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\model.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\model.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\timebox.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\timebox.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vertices.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\vertices.h
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
This file is part of ExPoser - A Tool for Animating PLIB Critters.
|
||||
Copyright (C) 2001 Steve Baker
|
||||
|
||||
ExPoser is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ExPoser is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ExPoser; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: exposer.h 1528 2002-09-01 07:10:09Z ude $
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#ifdef FREEGLUT_IS_PRESENT
|
||||
# include <GL/freeglut.h>
|
||||
#else
|
||||
# ifdef __APPLE__
|
||||
# include <GLUT/glut.h>
|
||||
# else
|
||||
# include <GL/glut.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <plib/pu.h>
|
||||
#include <plib/ssgAux.h>
|
||||
|
||||
#include "event.h"
|
||||
#include "model.h"
|
||||
#include "bones.h"
|
||||
#include "boneGUI.h"
|
||||
#include "vertices.h"
|
||||
#include "timebox.h"
|
||||
#include "floor.h"
|
||||
#include "load_save.h"
|
||||
|
||||
extern EventList * eventList ;
|
||||
extern TimeBox * timebox ;
|
||||
extern Floor * ground ;
|
||||
extern ssgRoot * skinScene ;
|
||||
extern ssgRoot *tweenScene ;
|
||||
extern ssgRoot * boneScene ;
|
||||
extern ssgRoot *sceneScene ;
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
This file is part of ExPoser - A Tool for Animating PLIB Critters.
|
||||
Copyright (C) 2001 Steve Baker
|
||||
|
||||
ExPoser is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ExPoser is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ExPoser; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: floor.cxx 1425 2002-08-17 23:58:38Z ude $
|
||||
*/
|
||||
|
||||
|
||||
#include "exposer.h"
|
||||
|
||||
static unsigned char Texture0 [] =
|
||||
{
|
||||
0, 0, 0, 0, 255, 255, 255, 255,
|
||||
0, 0, 0, 0, 255, 255, 255, 255,
|
||||
0, 0, 0, 0, 255, 255, 255, 255,
|
||||
0, 0, 0, 0, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 0, 0, 0, 0,
|
||||
255, 255, 255, 255, 0, 0, 0, 0,
|
||||
255, 255, 255, 255, 0, 0, 0, 0,
|
||||
255, 255, 255, 255, 0, 0, 0, 0
|
||||
} ;
|
||||
|
||||
static unsigned char Texture1 [] =
|
||||
{
|
||||
0, 0, 255, 255,
|
||||
0, 0, 255, 255,
|
||||
255, 255, 0, 0,
|
||||
255, 255, 0, 0
|
||||
} ;
|
||||
|
||||
static unsigned char Texture2 [] =
|
||||
{
|
||||
0, 255,
|
||||
255, 0
|
||||
} ;
|
||||
|
||||
static unsigned char Texture3 [] =
|
||||
{
|
||||
127
|
||||
} ;
|
||||
|
||||
|
||||
void Floor::draw ()
|
||||
{
|
||||
glMatrixMode ( GL_PROJECTION) ; _ssgCurrentContext->loadProjectionMatrix() ;
|
||||
glMatrixMode ( GL_MODELVIEW ) ; _ssgCurrentContext->loadModelviewMatrix () ;
|
||||
|
||||
glDisable ( GL_LIGHTING ) ;
|
||||
glEnable ( GL_TEXTURE_2D ) ;
|
||||
glEnable ( GL_CULL_FACE ) ;
|
||||
glBindTexture ( GL_TEXTURE_2D, texhandle ) ;
|
||||
glColor4f ( 1.0f, 1.0f, 1.0f, 1.0f ) ;
|
||||
|
||||
glBegin ( GL_QUADS ) ;
|
||||
glTexCoord2f ( -30.0f, timebox->getGroundPosition() - 30.0f ) ;
|
||||
glVertex3f ( -30.0f, -30.0f, z_coord ) ;
|
||||
glTexCoord2f ( 30.0f, timebox->getGroundPosition() - 30.0f ) ;
|
||||
glVertex3f ( 30.0f, -30.0f, z_coord ) ;
|
||||
glTexCoord2f ( 30.0f, timebox->getGroundPosition() + 30.0f ) ;
|
||||
glVertex3f ( 30.0f, 30.0f, z_coord ) ;
|
||||
glTexCoord2f ( -30.0f, timebox->getGroundPosition() + 30.0f ) ;
|
||||
glVertex3f ( -30.0f, 30.0f, z_coord ) ;
|
||||
glEnd () ;
|
||||
|
||||
glDisable ( GL_TEXTURE_2D ) ;
|
||||
glEnable ( GL_LIGHTING ) ;
|
||||
}
|
||||
|
||||
|
||||
Floor::Floor ()
|
||||
{
|
||||
glGenTextures ( 1, & texhandle ) ;
|
||||
|
||||
glBindTexture ( GL_TEXTURE_2D, texhandle ) ;
|
||||
glTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ;
|
||||
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ) ;
|
||||
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
GL_LINEAR_MIPMAP_LINEAR ) ;
|
||||
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ) ;
|
||||
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ) ;
|
||||
glTexImage2D ( GL_TEXTURE_2D, 0, 1, 8, 8,
|
||||
FALSE, GL_LUMINANCE, GL_UNSIGNED_BYTE, Texture0 ) ;
|
||||
glTexImage2D ( GL_TEXTURE_2D, 1, 1, 4, 4,
|
||||
FALSE, GL_LUMINANCE, GL_UNSIGNED_BYTE, Texture1 ) ;
|
||||
glTexImage2D ( GL_TEXTURE_2D, 2, 1, 2, 2,
|
||||
FALSE, GL_LUMINANCE, GL_UNSIGNED_BYTE, Texture2 ) ;
|
||||
glTexImage2D ( GL_TEXTURE_2D, 3, 1, 1, 1,
|
||||
FALSE, GL_LUMINANCE, GL_UNSIGNED_BYTE, Texture3 ) ;
|
||||
glBindTexture ( GL_TEXTURE_2D, 0 ) ;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
This file is part of ExPoser - A Tool for Animating PLIB Critters.
|
||||
Copyright (C) 2001 Steve Baker
|
||||
|
||||
ExPoser is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ExPoser is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ExPoser; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: floor.h 1425 2002-08-17 23:58:38Z ude $
|
||||
*/
|
||||
|
||||
|
||||
class Floor
|
||||
{
|
||||
unsigned int texhandle ;
|
||||
float z_coord ;
|
||||
|
||||
public:
|
||||
|
||||
void setZcoord ( float z ) { z_coord = z ; }
|
||||
float getZcoord () { return z_coord ; }
|
||||
|
||||
void draw () ;
|
||||
Floor () ;
|
||||
} ;
|
||||
|
||||
|
||||
@@ -0,0 +1,621 @@
|
||||
/*
|
||||
This file is part of ExPoser - A Tool for Animating PLIB Critters.
|
||||
Copyright (C) 2001 Steve Baker
|
||||
|
||||
ExPoser is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ExPoser is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ExPoser; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: load_save.cxx 2078 2006-04-13 16:22:38Z bram $
|
||||
*/
|
||||
|
||||
#include <plib/puAux.h>
|
||||
|
||||
#include "exposer.h"
|
||||
|
||||
#define FILE_SELECTOR_ARGS (640-320)/2,(480-270)/2,320,270,1
|
||||
|
||||
|
||||
static float tweeninterval = 1.0f/8.0f ;
|
||||
|
||||
void setTweenInterval ( float t ) { tweeninterval = t ; }
|
||||
float getTweenInterval () { return tweeninterval ; }
|
||||
|
||||
|
||||
static puaFileSelector *file_selector = NULL ;
|
||||
|
||||
|
||||
static char lastModelFilePath [ PUSTRING_MAX ] ;
|
||||
static char lastModelFileName [ PUSTRING_MAX ] ;
|
||||
|
||||
static void dismissDialogCB ( puObject * ) ;
|
||||
|
||||
static puButton *dialog_button = NULL ;
|
||||
|
||||
|
||||
static void initDialog ()
|
||||
{
|
||||
if ( dialog_button != NULL )
|
||||
return ;
|
||||
|
||||
dialog_button = new puButton ( 250, 240, "" ) ;
|
||||
dialog_button -> setSize ( 400, 40 ) ;
|
||||
dialog_button -> setLegendFont ( PUFONT_TIMES_ROMAN_24 ) ;
|
||||
dialog_button -> setCallback ( dismissDialogCB ) ;
|
||||
dialog_button -> setColorScheme ( 1, 1, 0, 1 ) ;
|
||||
dialog_button -> hide () ;
|
||||
}
|
||||
|
||||
|
||||
static void dismissDialogCB ( puObject * )
|
||||
{
|
||||
initDialog () ;
|
||||
dialog_button -> hide () ;
|
||||
}
|
||||
|
||||
|
||||
static void dialog ( const char *msg, float r, float g, float b )
|
||||
{
|
||||
initDialog () ;
|
||||
dialog_button -> setLegend ( msg ) ;
|
||||
dialog_button -> setColorScheme ( r, g, b, 1 ) ;
|
||||
dialog_button -> reveal () ;
|
||||
}
|
||||
|
||||
|
||||
static void twsavepickfn ( puObject * )
|
||||
{
|
||||
char path [ PUSTRING_MAX ] ;
|
||||
|
||||
file_selector -> getValue ( path ) ;
|
||||
|
||||
if ( path [ 0 ] == '\0' )
|
||||
{
|
||||
puDeleteObject ( file_selector ) ;
|
||||
file_selector = NULL ;
|
||||
|
||||
dialog ( "FAILED TO SAVE TWEENED MODEL!", 1, 0, 0 ) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
saveTweenFile ( path, TRUE ) ;
|
||||
}
|
||||
|
||||
|
||||
void saveTweenFile ( char *path, int interactive )
|
||||
{
|
||||
char orig_path [ PUSTRING_MAX ] ;
|
||||
char fname [ PUSTRING_MAX ] ;
|
||||
char *p = NULL ;
|
||||
int i ;
|
||||
|
||||
strcpy ( orig_path, path ) ;
|
||||
|
||||
for ( i = strlen(path) ; i >= 0 ; i-- )
|
||||
if ( path[i] == '/' || path[i] == '\\' )
|
||||
{
|
||||
p = & ( path[i+1] ) ;
|
||||
path[i] = '\0' ;
|
||||
break ;
|
||||
}
|
||||
|
||||
if ( p == NULL )
|
||||
{
|
||||
ssgModelPath ( "." ) ;
|
||||
if ( getenv ( "EXPOSER_TEXTURE_PATH" ) != NULL )
|
||||
ssgTexturePath ( getenv ( "EXPOSER_TEXTURE_PATH" ) ) ;
|
||||
else
|
||||
ssgTexturePath ( "." ) ;
|
||||
strcpy ( fname, path ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
ssgModelPath ( path ) ;
|
||||
if ( getenv ( "EXPOSER_TEXTURE_PATH" ) != NULL )
|
||||
ssgTexturePath ( getenv ( "EXPOSER_TEXTURE_PATH" ) ) ;
|
||||
else
|
||||
ssgTexturePath ( path ) ;
|
||||
strcpy ( fname, p ) ;
|
||||
}
|
||||
|
||||
/* SAVE THE TWEENED MODEL */
|
||||
|
||||
if ( orig_path[0] == '\0' )
|
||||
{
|
||||
if ( interactive )
|
||||
{
|
||||
puDeleteObject ( file_selector ) ;
|
||||
file_selector = NULL ;
|
||||
dialog ( "FAILED TO SAVE TWEENED MODEL!", 1, 0, 0 ) ;
|
||||
return ;
|
||||
}
|
||||
else
|
||||
{
|
||||
perror ( "saveTween:" ) ;
|
||||
exit ( 1 ) ;
|
||||
}
|
||||
}
|
||||
|
||||
tweenScene = (ssgRoot *) makeTweenCopy ( skinScene ) ;
|
||||
|
||||
for ( i = 0 ; i <= (int)( timebox->getMaxTime() / tweeninterval ) ; i++ )
|
||||
{
|
||||
if ( i != 0 )
|
||||
addTweenBank ( tweenScene ) ;
|
||||
|
||||
transformModel ( boneScene, (float) i * tweeninterval ) ;
|
||||
makeTweenCopy ( tweenScene, skinScene ) ;
|
||||
}
|
||||
|
||||
if ( ! ssgSave ( orig_path, tweenScene ) )
|
||||
{
|
||||
if ( interactive )
|
||||
{
|
||||
puDeleteObject ( file_selector ) ;
|
||||
file_selector = NULL ;
|
||||
dialog ( "FAILED TO SAVE TWEENED MODEL!", 1, 0, 0 ) ;
|
||||
return ;
|
||||
}
|
||||
else
|
||||
{
|
||||
perror ( "saveTween:" ) ;
|
||||
exit ( 1 ) ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( interactive )
|
||||
{
|
||||
puDeleteObject ( file_selector ) ;
|
||||
file_selector = NULL ;
|
||||
dialog ( "TWEENED MODEL WAS SAVED OK.", 1, 1, 0 ) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void bnsavepickfn ( puObject * )
|
||||
{
|
||||
char path [ PUSTRING_MAX ] ;
|
||||
char fname [ PUSTRING_MAX ] ;
|
||||
|
||||
file_selector -> getValue ( path ) ;
|
||||
|
||||
if ( path [ 0 ] == '\0' )
|
||||
{
|
||||
puDeleteObject ( file_selector ) ;
|
||||
file_selector = NULL ;
|
||||
|
||||
dialog ( "FAILED TO SAVE BONES!", 1, 0, 0 ) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
char *p = NULL ;
|
||||
int i ;
|
||||
|
||||
for ( i = strlen(path) ; i >= 0 ; i-- )
|
||||
if ( path[i] == '/' || path[i] == '\\' )
|
||||
{
|
||||
p = & ( path[i+1] ) ;
|
||||
path[i] = '\0' ;
|
||||
break ;
|
||||
}
|
||||
|
||||
if ( p == NULL )
|
||||
{
|
||||
ssgModelPath ( "." ) ;
|
||||
if ( getenv ( "EXPOSER_TEXTURE_PATH" ) != NULL )
|
||||
ssgTexturePath ( getenv ( "EXPOSER_TEXTURE_PATH" ) ) ;
|
||||
else
|
||||
ssgTexturePath ( "." ) ;
|
||||
strcpy ( fname, path ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
ssgModelPath ( path ) ;
|
||||
if ( getenv ( "EXPOSER_TEXTURE_PATH" ) != NULL )
|
||||
ssgTexturePath ( getenv ( "EXPOSER_TEXTURE_PATH" ) ) ;
|
||||
else
|
||||
ssgTexturePath ( path ) ;
|
||||
strcpy ( fname, p ) ;
|
||||
}
|
||||
|
||||
/* SAVE THE BONES */
|
||||
|
||||
if ( file_selector->getStringValue()[0] == '\0' )
|
||||
{
|
||||
puDeleteObject ( file_selector ) ;
|
||||
file_selector = NULL ;
|
||||
dialog ( "FAILED TO SAVE BONES!", 1, 0, 0 ) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
FILE *fd = fopen ( file_selector->getStringValue(), "wa" ) ;
|
||||
|
||||
puDeleteObject ( file_selector ) ;
|
||||
file_selector = NULL ;
|
||||
|
||||
if ( fd == NULL )
|
||||
{
|
||||
dialog ( "FAILED TO SAVE BONES!", 1, 0, 0 ) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
fprintf ( fd, "NUMBONES=%d NUMEVENTS=%d MAXTIME=%f Z_OFFSET=%f SPEED=%f\n",
|
||||
getNumBones(), eventList->getNumEvents(), timebox->getMaxTime (),
|
||||
-ground->getZcoord(), timebox->getGroundSpeed() ) ;
|
||||
|
||||
for ( i = 0 ; i < getNumBones () ; i++ )
|
||||
getBone ( i ) -> write ( fd ) ;
|
||||
|
||||
eventList -> write ( fd ) ;
|
||||
|
||||
fclose ( fd ) ;
|
||||
dialog ( "BONES WERE SAVED OK.", 1, 1, 0 ) ;
|
||||
}
|
||||
|
||||
|
||||
static void bnpickfn ( puObject * )
|
||||
{
|
||||
char path [ PUSTRING_MAX ] ;
|
||||
|
||||
file_selector -> getValue ( path ) ;
|
||||
|
||||
if ( path [ 0 ] == '\0' )
|
||||
{
|
||||
puDeleteObject ( file_selector ) ;
|
||||
file_selector = NULL ;
|
||||
return ;
|
||||
}
|
||||
|
||||
loadBoneFile ( path, TRUE ) ;
|
||||
}
|
||||
|
||||
void loadBoneFile ( char *path, int interactive )
|
||||
{
|
||||
char orig_path [ PUSTRING_MAX ] ;
|
||||
char fname [ PUSTRING_MAX ] ;
|
||||
char *p = NULL ;
|
||||
int i ;
|
||||
|
||||
strcpy ( orig_path, path ) ;
|
||||
|
||||
for ( i = strlen(path) ; i >= 0 ; i-- )
|
||||
if ( path[i] == '/' || path[i] == '\\' )
|
||||
{
|
||||
p = & ( path[i+1] ) ;
|
||||
path[i] = '\0' ;
|
||||
break ;
|
||||
}
|
||||
|
||||
if ( p == NULL )
|
||||
{
|
||||
ssgModelPath ( "." ) ;
|
||||
if ( getenv ( "EXPOSER_TEXTURE_PATH" ) != NULL )
|
||||
ssgTexturePath ( getenv ( "EXPOSER_TEXTURE_PATH" ) ) ;
|
||||
else
|
||||
ssgTexturePath ( "." ) ;
|
||||
strcpy ( fname, path ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
ssgModelPath ( path ) ;
|
||||
if ( getenv ( "EXPOSER_TEXTURE_PATH" ) != NULL )
|
||||
ssgTexturePath ( getenv ( "EXPOSER_TEXTURE_PATH" ) ) ;
|
||||
else
|
||||
ssgTexturePath ( path ) ;
|
||||
strcpy ( fname, p ) ;
|
||||
}
|
||||
|
||||
/* LOAD THE BONES */
|
||||
|
||||
if ( orig_path[0] == '\0' )
|
||||
{
|
||||
if ( interactive )
|
||||
{
|
||||
puDeleteObject ( file_selector ) ;
|
||||
file_selector = NULL ;
|
||||
return ;
|
||||
}
|
||||
else
|
||||
{
|
||||
perror ( "loadBones:" ) ;
|
||||
exit ( 1 ) ;
|
||||
}
|
||||
}
|
||||
|
||||
FILE *fd = fopen ( orig_path, "ra" ) ;
|
||||
|
||||
if ( fd == NULL )
|
||||
{
|
||||
if ( interactive )
|
||||
{
|
||||
puDeleteObject ( file_selector ) ;
|
||||
file_selector = NULL ;
|
||||
return ;
|
||||
}
|
||||
else
|
||||
{
|
||||
perror ( "loadBones:" ) ;
|
||||
exit ( 1 ) ;
|
||||
}
|
||||
}
|
||||
|
||||
timebox->deleteAll () ;
|
||||
|
||||
int numbones, numevents ;
|
||||
float floor_z_coord, maxtime, new_ground_speed ;
|
||||
|
||||
fscanf ( fd,
|
||||
"NUMBONES=%d NUMEVENTS=%d MAXTIME=%f Z_OFFSET=%f SPEED=%f\n",
|
||||
&numbones, &numevents,
|
||||
&maxtime, &floor_z_coord, &new_ground_speed ) ;
|
||||
|
||||
|
||||
/* Don't use the floor_z_coord from the file. */
|
||||
/* ground -> setZcoord ( floor_z_coord ) ; */
|
||||
|
||||
timebox->setMaxTime ( maxtime ) ;
|
||||
timebox->setGroundSpeed ( new_ground_speed ) ;
|
||||
|
||||
if ( numbones != getNumBones () )
|
||||
{
|
||||
fprintf ( stderr,
|
||||
"Number of bones in model (%d) doesn't agree with number in bones file (%d)!\n", getNumBones (), numbones ) ;
|
||||
exit ( 1 ) ;
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < getNumBones () ; i++ )
|
||||
getBone ( i ) -> read ( fd ) ;
|
||||
|
||||
eventList -> read ( numevents, fd ) ;
|
||||
|
||||
fclose ( fd ) ;
|
||||
|
||||
if ( interactive )
|
||||
{
|
||||
puDeleteObject ( file_selector ) ;
|
||||
file_selector = NULL ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void scpickfn ( puObject * )
|
||||
{
|
||||
char path [ PUSTRING_MAX ] ;
|
||||
char fname [ PUSTRING_MAX ] ;
|
||||
|
||||
file_selector -> getValue ( path ) ;
|
||||
|
||||
puDeleteObject ( file_selector ) ;
|
||||
file_selector = NULL ;
|
||||
|
||||
if ( path [ 0 ] == '\0' )
|
||||
return ;
|
||||
|
||||
if ( strlen ( path ) >= 6 && strcmp(&path[strlen(path)-6], ".bones" ) == 0 )
|
||||
{
|
||||
fprintf ( stderr, "I think you tried to load a BONES file as 3D model.\n");
|
||||
fprintf ( stderr, "Try again!\n");
|
||||
scloadCB ( NULL ) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
char *p = NULL ;
|
||||
|
||||
for ( int i = strlen(path) ; i >= 0 ; i-- )
|
||||
if ( path[i] == '/' || path[i] == '\\' )
|
||||
{
|
||||
p = & ( path[i+1] ) ;
|
||||
path[i] = '\0' ;
|
||||
break ;
|
||||
}
|
||||
|
||||
if ( p == NULL )
|
||||
{
|
||||
ssgModelPath ( "." ) ;
|
||||
|
||||
if ( getenv ( "EXPOSER_TEXTURE_PATH" ) != NULL )
|
||||
ssgTexturePath ( getenv ( "EXPOSER_TEXTURE_PATH" ) ) ;
|
||||
else
|
||||
ssgTexturePath ( "." ) ;
|
||||
strcpy ( fname, path ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
ssgModelPath ( path ) ;
|
||||
|
||||
if ( getenv ( "EXPOSER_TEXTURE_PATH" ) != NULL )
|
||||
ssgTexturePath ( getenv ( "EXPOSER_TEXTURE_PATH" ) ) ;
|
||||
else
|
||||
ssgTexturePath ( path ) ;
|
||||
|
||||
strcpy ( fname, p ) ;
|
||||
}
|
||||
|
||||
delete sceneScene ;
|
||||
sceneScene = new ssgRoot ;
|
||||
sceneScene -> addKid ( ssgLoad ( fname, NULL ) ) ;
|
||||
}
|
||||
|
||||
|
||||
static void pickfn ( puObject * )
|
||||
{
|
||||
char path [ PUSTRING_MAX ] ;
|
||||
|
||||
file_selector -> getValue ( path ) ;
|
||||
|
||||
puDeleteObject ( file_selector ) ;
|
||||
file_selector = NULL ;
|
||||
|
||||
if ( path [ 0 ] == '\0' )
|
||||
return ;
|
||||
|
||||
if ( strlen ( path ) >= 6 && strcmp(&path[strlen(path)-6], ".bones" ) == 0 )
|
||||
{
|
||||
fprintf ( stderr, "I think you tried to load a BONES file as 3D model.\n");
|
||||
fprintf ( stderr, "Try again!\n");
|
||||
loadCB ( NULL ) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
loadFile ( path, TRUE ) ;
|
||||
}
|
||||
|
||||
void loadFile ( char *path, int interactive )
|
||||
{
|
||||
char fname [ PUSTRING_MAX ] ;
|
||||
char *p = NULL ;
|
||||
|
||||
for ( int i = strlen(path) ; i >= 0 ; i-- )
|
||||
if ( path[i] == '/' || path[i] == '\\' )
|
||||
{
|
||||
p = & ( path[i+1] ) ;
|
||||
path[i] = '\0' ;
|
||||
break ;
|
||||
}
|
||||
|
||||
if ( p == NULL )
|
||||
{
|
||||
ssgModelPath ( "." ) ;
|
||||
if ( getenv ( "EXPOSER_TEXTURE_PATH" ) != NULL )
|
||||
ssgTexturePath ( getenv ( "EXPOSER_TEXTURE_PATH" ) ) ;
|
||||
else
|
||||
ssgTexturePath ( "." ) ;
|
||||
strcpy ( fname, path ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
ssgModelPath ( path ) ;
|
||||
if ( getenv ( "EXPOSER_TEXTURE_PATH" ) != NULL )
|
||||
ssgTexturePath ( getenv ( "EXPOSER_TEXTURE_PATH" ) ) ;
|
||||
else
|
||||
ssgTexturePath ( path ) ;
|
||||
strcpy ( fname, p ) ;
|
||||
}
|
||||
|
||||
strcpy ( lastModelFilePath, path ) ;
|
||||
strcpy ( lastModelFileName, fname ) ;
|
||||
|
||||
skinScene -> addKid ( ssgLoad ( fname, NULL ) ) ;
|
||||
ssgFlatten ( skinScene -> getKid ( 0 ) ) ;
|
||||
ssgStripify ( skinScene -> getKid ( 0 ) ) ;
|
||||
boneScene -> addKid ( extractBones ( skinScene ) ) ;
|
||||
|
||||
extractVertices ( skinScene ) ;
|
||||
timebox->deleteAll () ;
|
||||
|
||||
eventList -> newEvent ( 0.0f ) ;
|
||||
|
||||
ground -> setZcoord ( getLowestVertexZ () ) ;
|
||||
}
|
||||
|
||||
|
||||
void twsaveCB ( puObject * )
|
||||
{
|
||||
if ( file_selector == NULL )
|
||||
{
|
||||
file_selector = new puaFileSelector ( FILE_SELECTOR_ARGS,
|
||||
lastModelFilePath, "Save Tweened Model As..." ) ;
|
||||
file_selector -> setCallback ( twsavepickfn ) ;
|
||||
|
||||
char guess_fname [ PUSTRING_MAX ] ;
|
||||
strcpy ( guess_fname, lastModelFileName ) ;
|
||||
|
||||
for ( int i = strlen ( guess_fname ) ; i >= 0 ; i-- )
|
||||
if ( guess_fname [ i ] == '.' )
|
||||
{
|
||||
guess_fname[i] = '\0' ;
|
||||
break ;
|
||||
}
|
||||
|
||||
strcat ( guess_fname, "_tweened.ssg" ) ;
|
||||
file_selector -> setInitialValue ( guess_fname ) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void bnsaveCB ( puObject * )
|
||||
{
|
||||
if ( file_selector == NULL )
|
||||
{
|
||||
file_selector = new puaFileSelector ( FILE_SELECTOR_ARGS,
|
||||
lastModelFilePath, "Save Bones As..." ) ;
|
||||
file_selector -> setCallback ( bnsavepickfn ) ;
|
||||
|
||||
char guess_fname [ PUSTRING_MAX ] ;
|
||||
strcpy ( guess_fname, lastModelFileName ) ;
|
||||
|
||||
for ( int i = strlen ( guess_fname ) ; i >= 0 ; i-- )
|
||||
if ( guess_fname [ i ] == '.' )
|
||||
{
|
||||
guess_fname[i] = '\0' ;
|
||||
break ;
|
||||
}
|
||||
|
||||
strcat ( guess_fname, ".bones" ) ;
|
||||
file_selector -> setInitialValue ( guess_fname ) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void bnloadCB ( puObject * )
|
||||
{
|
||||
if ( file_selector == NULL )
|
||||
{
|
||||
file_selector = new puaFileSelector ( FILE_SELECTOR_ARGS,
|
||||
lastModelFilePath, "Load Bones from..." ) ;
|
||||
file_selector -> setCallback ( bnpickfn ) ;
|
||||
|
||||
/* Guess an initial filename from the model filename */
|
||||
|
||||
char guess_fname [ PUSTRING_MAX ] ;
|
||||
strcpy ( guess_fname, lastModelFileName ) ;
|
||||
|
||||
for ( int i = strlen ( guess_fname ) ; i >= 0 ; i-- )
|
||||
if ( guess_fname [ i ] == '.' )
|
||||
{
|
||||
guess_fname[i] = '\0' ;
|
||||
break ;
|
||||
}
|
||||
|
||||
strcat ( guess_fname, ".bones" ) ;
|
||||
file_selector -> setInitialValue ( guess_fname ) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void scloadCB ( puObject * )
|
||||
{
|
||||
if ( file_selector == NULL )
|
||||
{
|
||||
file_selector = new puaFileSelector ( FILE_SELECTOR_ARGS,
|
||||
"", "Load Scenery from..." ) ;
|
||||
file_selector -> setCallback ( scpickfn ) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void loadCB ( puObject * )
|
||||
{
|
||||
if ( file_selector == NULL )
|
||||
{
|
||||
file_selector = new puaFileSelector ( FILE_SELECTOR_ARGS,
|
||||
"", "Load Model from..." ) ;
|
||||
file_selector -> setCallback ( pickfn ) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
This file is part of ExPoser - A Tool for Animating PLIB Critters.
|
||||
Copyright (C) 2001 Steve Baker
|
||||
|
||||
ExPoser is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ExPoser is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ExPoser; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: load_save.h 1425 2002-08-17 23:58:38Z ude $
|
||||
*/
|
||||
|
||||
|
||||
void loadCB ( puObject * ) ;
|
||||
void scloadCB ( puObject * ) ;
|
||||
void bnloadCB ( puObject * ) ;
|
||||
void bnsaveCB ( puObject * ) ;
|
||||
void twsaveCB ( puObject * ) ;
|
||||
|
||||
void loadFile ( char *fname, int interactive ) ;
|
||||
void loadBoneFile ( char *fname, int interactive ) ;
|
||||
void saveTweenFile ( char *fname, int interactive ) ;
|
||||
|
||||
void setTweenInterval ( float t ) ;
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
merge_tweens - Merges multiple '.bones' files written from ExPoser
|
||||
Copyright (C) 2001 Steve Baker
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: merge_tweens.cxx 1425 2002-08-17 23:58:38Z ude $
|
||||
*/
|
||||
|
||||
|
||||
#include "merge_tweens.h"
|
||||
|
||||
static void help ()
|
||||
{
|
||||
fprintf ( stderr, "\n\n" ) ;
|
||||
fprintf ( stderr, "merge_tweens: Usage -\n\n" ) ;
|
||||
fprintf ( stderr, " merge_tweens file.bones ...\n" ) ;
|
||||
fprintf ( stderr, "\n" ) ;
|
||||
fprintf ( stderr, "Merges multiple '.bones' files written from ExPoser\n" ) ;
|
||||
fprintf ( stderr, "into a single animation sequence (stored in 'out.bones').\n" ) ;
|
||||
fprintf ( stderr, "\n" ) ;
|
||||
fprintf ( stderr, "Bones files must be compatible (same number of joints\n" );
|
||||
fprintf ( stderr, "in same order, etc).\n" ) ;
|
||||
fprintf ( stderr, "\n" ) ;
|
||||
}
|
||||
|
||||
|
||||
static int numBones = 0 ;
|
||||
static int totalEvents = 0 ;
|
||||
static float totalTime = 0.0f ;
|
||||
static float floor_z = 0.0f ;
|
||||
static float ground_speed = 0.0f ;
|
||||
|
||||
int main ( int argc, char **argv )
|
||||
{
|
||||
if ( argc < 2 )
|
||||
{
|
||||
help () ;
|
||||
exit ( 1 ) ;
|
||||
}
|
||||
|
||||
/*
|
||||
First Pass - add up times - do error checking.
|
||||
*/
|
||||
|
||||
totalEvents = 0 ;
|
||||
totalTime = 0.0f ;
|
||||
|
||||
int i ;
|
||||
|
||||
for ( i = 1 ; i < argc ; i++ )
|
||||
{
|
||||
FILE *fd = fopen ( argv[i], "ra" ) ;
|
||||
|
||||
int bones, numevents ;
|
||||
float new_floor_z, maxtime, new_ground_speed ;
|
||||
|
||||
fscanf ( fd, "NUMBONES=%d NUMEVENTS=%d MAXTIME=%f Z_OFFSET=%f SPEED=%f\n",
|
||||
&bones, &numevents, &maxtime, &new_floor_z, &new_ground_speed ) ;
|
||||
|
||||
printf (
|
||||
"%2d) %s: NUMBONES=%d NUMEVENTS=%d MAXTIME=%f Z_OFFSET=%f SPEED=%f\n",
|
||||
i, argv[i], bones, numevents, maxtime, new_floor_z, new_ground_speed ) ;
|
||||
|
||||
totalEvents += numevents ;
|
||||
totalTime += maxtime ;
|
||||
|
||||
if ( i == 1 )
|
||||
{
|
||||
numBones = bones ;
|
||||
floor_z = new_floor_z ;
|
||||
ground_speed = new_ground_speed ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( numBones != bones )
|
||||
{
|
||||
fprintf ( stderr,
|
||||
"merge_bones: FATAL - Number of bones must be the same across files.\n" ) ;
|
||||
exit ( 1 ) ;
|
||||
}
|
||||
|
||||
if ( floor_z != new_floor_z )
|
||||
{
|
||||
fprintf ( stderr,
|
||||
"merge_bones: WARNING - Floor Z is not the same across files.\n" ) ;
|
||||
}
|
||||
|
||||
if ( ground_speed != new_ground_speed )
|
||||
{
|
||||
fprintf ( stderr,
|
||||
"merge_bones: WARNING - Ground speed is not the same across files.\n");
|
||||
}
|
||||
}
|
||||
|
||||
fclose ( fd ) ;
|
||||
}
|
||||
|
||||
/*
|
||||
Pass TWO : Write out composite file.
|
||||
*/
|
||||
|
||||
FILE *out_fd = fopen ( "out.bones", "wa" ) ;
|
||||
|
||||
float nextTime = 0.0f ;
|
||||
|
||||
for ( i = 1 ; i < argc ; i++ )
|
||||
{
|
||||
FILE *fd = fopen ( argv[i], "ra" ) ;
|
||||
|
||||
int bones, numevents ;
|
||||
float new_floor_z, maxtime, new_ground_speed ;
|
||||
|
||||
fscanf ( fd, "NUMBONES=%d NUMEVENTS=%d MAXTIME=%f Z_OFFSET=%f SPEED=%f\n",
|
||||
&bones, &numevents, &maxtime, &new_floor_z, &new_ground_speed ) ;
|
||||
|
||||
if ( i == 1 )
|
||||
{
|
||||
fprintf ( out_fd,
|
||||
"NUMBONES=%d NUMEVENTS=%d MAXTIME=%f Z_OFFSET=%f SPEED=%f\n",
|
||||
numBones, totalEvents, totalTime, floor_z, ground_speed ) ;
|
||||
|
||||
for ( int j = 0 ; j < numBones ; j++ )
|
||||
{
|
||||
char s [ 1000 ] ;
|
||||
fgets ( s, 1000, fd ) ;
|
||||
fprintf ( out_fd, "%s", s ) ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( int j = 0 ; j < numBones ; j++ )
|
||||
{
|
||||
char s [ 1000 ] ;
|
||||
fgets ( s, 1000, fd ) ;
|
||||
}
|
||||
}
|
||||
|
||||
for ( int j = 0 ; j < numevents ; j++ )
|
||||
{
|
||||
float t, x, y, z ;
|
||||
int nb ;
|
||||
|
||||
fscanf ( fd, "EVENT %f %d (%f,%f,%f)\n", &t, &nb, &x, &y, &z ) ;
|
||||
fprintf ( out_fd, "EVENT %f %d (%f,%f,%f)\n", t+nextTime, nb, x, y, z ) ;
|
||||
|
||||
for ( int k = 0 ; k < nb ; k++ )
|
||||
{
|
||||
int xx, yy, zz ;
|
||||
fscanf ( fd, " (%d,%d,%d)\n", &xx, &yy, &zz ) ;
|
||||
fprintf ( out_fd, " (%d,%d,%d)\n", xx, yy, zz ) ;
|
||||
}
|
||||
}
|
||||
|
||||
nextTime += maxtime ;
|
||||
fclose ( fd ) ;
|
||||
}
|
||||
|
||||
fclose ( out_fd ) ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
# Microsoft Developer Studio Project File - Name="merge_tweens" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=merge_tweens - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "merge_tweens.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "merge_tweens.mak" CFG="exposer - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "merge_tweens - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "merge_tweens - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "merge_tweens - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "merge_tweens - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\.." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\.."
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "merge_tweens - Win32 Release"
|
||||
# Name "merge_tweens - Win32 Debug"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\merge_tweens.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\merge_tweens.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
# End Project
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
@@ -0,0 +1,465 @@
|
||||
/*
|
||||
This file is part of ExPoser - A Tool for Animating PLIB Critters.
|
||||
Copyright (C) 2001 Steve Baker
|
||||
|
||||
ExPoser is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ExPoser is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ExPoser; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: model.cxx 1425 2002-08-17 23:58:38Z ude $
|
||||
*/
|
||||
|
||||
|
||||
#include "exposer.h"
|
||||
|
||||
static int rootBone = -1 ;
|
||||
static int nextBone = 0 ;
|
||||
|
||||
int getNumBones () { return nextBone ; }
|
||||
|
||||
static void findChildBones ( int root )
|
||||
{
|
||||
float *v0 = getBone ( root ) -> vx[0] ;
|
||||
float *v1 = getBone ( root ) -> vx[1] ;
|
||||
|
||||
/*
|
||||
Compute parametric equation.
|
||||
*/
|
||||
|
||||
sgVec3 vec ;
|
||||
float len ;
|
||||
int i ;
|
||||
|
||||
sgSubVec3 ( vec, v1, v0 ) ;
|
||||
len = sgLengthVec3 ( vec ) ;
|
||||
sgScaleVec3 ( vec, 1.0f/len ) ;
|
||||
|
||||
for ( i = 0 ; i < getNumBones() ; i++ )
|
||||
{
|
||||
/*******************************
|
||||
If this bone already has a parent
|
||||
then we are done.
|
||||
********************************/
|
||||
|
||||
if ( getBone(i)->parent >= 0 )
|
||||
continue ;
|
||||
|
||||
/*******************************
|
||||
Test vertex zero of the daughter
|
||||
bone against the parent bone.
|
||||
********************************/
|
||||
|
||||
float *vi0 = getBone(i)-> vx[0] ;
|
||||
float *vi1 = getBone(i)-> vx[1] ;
|
||||
sgVec3 vec_i ;
|
||||
float len_i ;
|
||||
|
||||
sgSubVec3 ( vec_i, vi0, v0 ) ;
|
||||
len_i = sgLengthVec3 ( vec_i ) ;
|
||||
|
||||
if ( len_i <= 0.01 ) /* Close to vertex 0 of parent? */
|
||||
{
|
||||
getBone(i)-> parent = root ;
|
||||
continue ;
|
||||
}
|
||||
|
||||
sgScaleVec3 ( vec_i, 1.0f/len_i ) ;
|
||||
|
||||
/* Somewhere between vertex 0 and vertex 1 of parent? */
|
||||
|
||||
if ( sgDistanceSquaredVec3 ( vec, vec_i ) <= 0.001 && len_i <= len * 1.01 )
|
||||
{
|
||||
getBone(i)-> parent = root ;
|
||||
continue ;
|
||||
}
|
||||
|
||||
/*******************************
|
||||
Test vertex one of the daughter
|
||||
bone against the parent bone.
|
||||
********************************/
|
||||
|
||||
sgSubVec3 ( vec_i, vi1, v0 ) ;
|
||||
len_i = sgLengthVec3 ( vec_i ) ;
|
||||
|
||||
if ( len_i <= 0.01 ) /* Close to vertex 0 of parent? */
|
||||
{
|
||||
getBone(i)->parent = root ;
|
||||
getBone(i)->swapEnds () ;
|
||||
continue ;
|
||||
}
|
||||
|
||||
sgScaleVec3 ( vec_i, 1.0f/len_i ) ;
|
||||
|
||||
/* Somewhere between vertex 0 and vertex 1 of parent? */
|
||||
|
||||
if ( sgDistanceSquaredVec3 ( vec, vec_i ) <= 0.001 && len_i <= len * 1.01 )
|
||||
{
|
||||
getBone(i)->parent = root ;
|
||||
getBone(i)->swapEnds () ;
|
||||
continue ;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************
|
||||
Recursively search any new child nodes we found.
|
||||
****************************************************/
|
||||
|
||||
for ( i = 0 ; i < getNumBones() ; i++ )
|
||||
if ( i != root && getBone(i)->parent == root ) /* If Parented by this root node */
|
||||
findChildBones ( i ) ; /* Recurse downwards. */
|
||||
}
|
||||
|
||||
|
||||
void addTweenBank ( ssgBranch *root )
|
||||
{
|
||||
if ( root == NULL )
|
||||
return ;
|
||||
|
||||
for ( int i = 0 ; i < root -> getNumKids () ; i++ )
|
||||
{
|
||||
ssgEntity *e = root -> getKid ( i ) ;
|
||||
|
||||
if ( e -> isAKindOf ( ssgTypeBranch() ) )
|
||||
addTweenBank ( (ssgBranch *)e ) ;
|
||||
else
|
||||
if ( e -> isAKindOf ( ssgTypeTween() ) )
|
||||
{
|
||||
ssgTween *tween = (ssgTween *) e ;
|
||||
|
||||
ssgVertexArray *v1 = new ssgVertexArray ;
|
||||
|
||||
for ( int ii = 0 ; ii < tween -> getNumVertices () ; ii++ )
|
||||
v1 -> add ( tween -> getVertex ( ii ) ) ;
|
||||
|
||||
tween -> newBank ( v1, NULL, NULL, NULL ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void makeTweenCopy ( ssgBranch *dst, ssgBranch *src )
|
||||
{
|
||||
for ( int i = 0 ; i < src -> getNumKids () ; i++ )
|
||||
{
|
||||
ssgEntity *s = src -> getKid ( i ) ;
|
||||
ssgEntity *d = dst -> getKid ( i ) ;
|
||||
|
||||
if ( s -> isAKindOf ( ssgTypeBranch() ) )
|
||||
makeTweenCopy ( (ssgBranch *)d, (ssgBranch *)s ) ;
|
||||
else
|
||||
{
|
||||
ssgLeaf *ls = (ssgLeaf *) s ;
|
||||
ssgLeaf *ld = (ssgLeaf *) d ;
|
||||
|
||||
for ( int ii = 0 ; ii < ls -> getNumVertices () ; ii++ )
|
||||
sgCopyVec3 ( ld->getVertex(ii), ls->getVertex(ii) ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void tweenify ( ssgBranch *root )
|
||||
{
|
||||
for ( int i = 0 ; i < root -> getNumKids () ; i++ )
|
||||
{
|
||||
ssgEntity *e = root -> getKid ( i ) ;
|
||||
|
||||
if ( e -> isAKindOf ( ssgTypeBranch() ) )
|
||||
tweenify ( (ssgBranch *)e ) ;
|
||||
else
|
||||
{
|
||||
ssgLeaf *l = (ssgLeaf *) e ;
|
||||
|
||||
ssgVertexArray *v0 = new ssgVertexArray ;
|
||||
ssgNormalArray *n0 = new ssgNormalArray ;
|
||||
ssgTexCoordArray *t0 = new ssgTexCoordArray ;
|
||||
ssgColourArray *c0 = new ssgColourArray ;
|
||||
|
||||
for ( int ii = 0 ; ii < l -> getNumVertices () ; ii++ )
|
||||
{
|
||||
v0 -> add ( l -> getVertex ( ii ) ) ;
|
||||
n0 -> add ( l -> getNormal ( ii ) ) ;
|
||||
t0 -> add ( l -> getTexCoord ( ii ) ) ;
|
||||
c0 -> add ( l -> getColour ( ii ) ) ;
|
||||
}
|
||||
|
||||
ssgTween *tween = new ssgTween ( l -> getPrimitiveType () ) ;
|
||||
|
||||
tween -> setState ( l -> getState () ) ;
|
||||
tween -> newBank ( v0, n0, t0, c0 ) ;
|
||||
|
||||
root -> replaceKid ( l, tween ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ssgEntity *makeTweenCopy ( ssgEntity *root )
|
||||
{
|
||||
if ( root == NULL )
|
||||
return NULL ;
|
||||
|
||||
ssgEntity *res = (ssgEntity *) ( root -> clone ( SSG_CLONE_RECURSIVE |
|
||||
SSG_CLONE_GEOMETRY ) ) ;
|
||||
tweenify ( (ssgBranch *) res ) ;
|
||||
|
||||
return res ;
|
||||
}
|
||||
|
||||
|
||||
static void walkBones ( ssgBranch *root, sgMat4 mat )
|
||||
{
|
||||
if ( root == NULL )
|
||||
return ;
|
||||
|
||||
sgMat4 newmat ;
|
||||
|
||||
if ( root -> isAKindOf ( ssgTypeTransform() ) )
|
||||
{
|
||||
sgMat4 tmp ;
|
||||
|
||||
((ssgTransform *)root)-> getTransform ( tmp ) ;
|
||||
sgMultMat4 ( newmat, mat, tmp ) ;
|
||||
}
|
||||
else
|
||||
sgCopyMat4 ( newmat, mat ) ;
|
||||
|
||||
for ( int i = 0 ; i < root -> getNumKids () ; i++ )
|
||||
{
|
||||
ssgEntity *e = root -> getKid ( i ) ;
|
||||
|
||||
if ( e -> isAKindOf ( ssgTypeBranch() ) )
|
||||
walkBones ( (ssgBranch *)e, newmat ) ;
|
||||
else
|
||||
{
|
||||
ssgLeaf *l = (ssgLeaf *) e ;
|
||||
|
||||
if ( l -> getPrimitiveType () == GL_LINES ||
|
||||
l -> getPrimitiveType () == GL_LINE_LOOP ||
|
||||
l -> getPrimitiveType () == GL_LINE_STRIP )
|
||||
{
|
||||
for ( int ll = 0 ; ll < l->getNumLines() ; ll++ )
|
||||
{
|
||||
short vv [ 2 ] ;
|
||||
|
||||
l -> getLine ( ll, & vv[0], & vv[1] ) ;
|
||||
|
||||
getBone ( getNumBones() ) -> init ( l, newmat, vv,
|
||||
getNumBones() ) ;
|
||||
|
||||
/*
|
||||
Is this line red?
|
||||
If so, it's the 'root' line.
|
||||
*/
|
||||
|
||||
float *col = l -> getColour ( vv[0] ) ;
|
||||
|
||||
if ( l -> getState () != NULL &&
|
||||
l -> getState () -> isAKindOf ( ssgTypeSimpleState () ) )
|
||||
{
|
||||
ssgSimpleState *ss = (ssgSimpleState *)( l -> getState () ) ;
|
||||
|
||||
if ( ss -> getColourMaterial () != GL_DIFFUSE &&
|
||||
ss -> getColourMaterial () != GL_AMBIENT_AND_DIFFUSE )
|
||||
{
|
||||
col = ss -> getMaterial ( GL_DIFFUSE ) ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( col [ 0 ] > 0.75 && col [ 1 ] < 0.25 && col [ 2 ] < 0.25 )
|
||||
{
|
||||
if ( rootBone != -1 )
|
||||
rootBone = -2 ;
|
||||
else
|
||||
rootBone = getNumBones() ;
|
||||
}
|
||||
|
||||
nextBone++ ;
|
||||
}
|
||||
|
||||
root -> removeKid ( e ) ;
|
||||
i-- ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void offsetChildBones ( int root, sgVec3 v )
|
||||
{
|
||||
for ( int i = 0 ; i < getNumBones() ; i++ )
|
||||
if ( getBone(i)->parent == root )
|
||||
{
|
||||
sgSubVec3 ( getBone(i)->vx[0], v ) ;
|
||||
sgSubVec3 ( getBone(i)->vx[1], v ) ;
|
||||
offsetChildBones ( i, v ) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ssgBranch *extractBones ( ssgBranch *root )
|
||||
{
|
||||
sgMat4 mat ;
|
||||
|
||||
nextBone = 0 ;
|
||||
rootBone = -1 ;
|
||||
|
||||
sgMakeIdentMat4 ( mat ) ;
|
||||
walkBones ( root, mat ) ;
|
||||
|
||||
if ( rootBone == -1 )
|
||||
{
|
||||
fprintf ( stderr, "exposer: ERROR - No 'root' bone found?!?\n" ) ;
|
||||
fprintf ( stderr, "exposer: (Exactly one 'bone' line should be RED).\n" ) ;
|
||||
exit ( 1 ) ;
|
||||
}
|
||||
|
||||
if ( rootBone == -2 )
|
||||
{
|
||||
fprintf ( stderr, "exposer: ERROR - Multiple 'root' bones found?!?\n" ) ;
|
||||
fprintf ( stderr, "exposer: (Only one 'bone' line should be RED).\n" ) ;
|
||||
exit ( 1 ) ;
|
||||
}
|
||||
|
||||
fprintf ( stderr, "exposer: %d bones found, rootBone is number %d.\n",
|
||||
getNumBones(), rootBone ) ;
|
||||
|
||||
getBone(rootBone)->parent = ROOT_BONE ;
|
||||
|
||||
findChildBones ( rootBone ) ;
|
||||
|
||||
int disconnected = 0 ;
|
||||
|
||||
for ( int i = 0 ; i < getNumBones() ; i++ )
|
||||
if ( getBone(i)->parent < 0 )
|
||||
disconnected++ ;
|
||||
|
||||
if ( disconnected > 0 )
|
||||
{
|
||||
fprintf ( stderr,
|
||||
"exposer: ERROR - %d bones are not connected to the 'root' bone.\n",
|
||||
disconnected ) ;
|
||||
fprintf ( stderr,
|
||||
"exposer: (The root bone line should be RED. All other bones\n" ) ;
|
||||
fprintf ( stderr,
|
||||
"exposer: should either touch the root bone - or touch some\n" ) ;
|
||||
fprintf ( stderr,
|
||||
"exposer: other bone that is connected to the root bone so that\n");
|
||||
fprintf ( stderr,
|
||||
"exposer: all the bones form one continuously connected\n" ) ;
|
||||
fprintf ( stderr,
|
||||
"exposer: skeleton.)\n" ) ;
|
||||
exit ( 1 ) ;
|
||||
}
|
||||
|
||||
|
||||
ssgBranch *res = getBone ( rootBone ) -> generateGeometry ( rootBone ) ;
|
||||
|
||||
return res ;
|
||||
}
|
||||
|
||||
|
||||
static void walkTransforms ( ssgBranch *root, sgMat4 mat )
|
||||
{
|
||||
if ( root == NULL )
|
||||
return ;
|
||||
|
||||
sgMat4 newmat ;
|
||||
|
||||
if ( root -> isAKindOf ( ssgTypeTransform() ) )
|
||||
{
|
||||
sgMat4 tmp ;
|
||||
|
||||
((ssgTransform *)root)-> getTransform ( tmp ) ;
|
||||
sgMultMat4 ( newmat, mat, tmp ) ;
|
||||
|
||||
Bone *bo = (Bone *)(((ssgTransform *)root)-> getUserData ()) ;
|
||||
sgCopyMat4 ( bo -> netMatrix, newmat ) ;
|
||||
}
|
||||
else
|
||||
sgCopyMat4 ( newmat, mat ) ;
|
||||
|
||||
for ( int i = 0 ; i < root -> getNumKids () ; i++ )
|
||||
{
|
||||
ssgEntity *e = root -> getKid ( i ) ;
|
||||
|
||||
if ( e -> isAKindOf ( ssgTypeBranch () ) )
|
||||
walkTransforms ( (ssgBranch *) e, newmat ) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void transformModel ( ssgBranch *boneRoot, float tim )
|
||||
{
|
||||
if ( eventList->getNumEvents () < 1 )
|
||||
return ;
|
||||
|
||||
Event *prev = eventList->getEvent ( 0 ) ;
|
||||
Event *next = prev ;
|
||||
|
||||
if ( eventList->getCurrentEvent() != NULL )
|
||||
{
|
||||
prev = next = eventList->getCurrentEvent() ;
|
||||
tim = eventList->getCurrentEvent() -> getTime () ;
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( int i = 1 ; i < eventList->getNumEvents () ; i++ )
|
||||
{
|
||||
Event *ev = eventList->getEvent ( i ) ;
|
||||
float t = ev -> getTime () ;
|
||||
|
||||
if ( t < tim )
|
||||
next = prev = ev ;
|
||||
else
|
||||
{
|
||||
next = ev ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float lerptime = 0.0f ;
|
||||
|
||||
if ( next->getTime() - prev->getTime() >= 0.01 )
|
||||
{
|
||||
lerptime = tim - prev->getTime() ;
|
||||
lerptime /= (next->getTime() - prev->getTime()) ;
|
||||
}
|
||||
|
||||
sgVec3 ptra ; prev->getTranslate(ptra) ;
|
||||
sgVec3 ntra ; next->getTranslate(ntra) ;
|
||||
|
||||
sgLerpVec3 ( getCurrTranslate(), ptra, ntra, lerptime ) ;
|
||||
|
||||
syncTranslators ( getCurrTranslate() ) ;
|
||||
|
||||
int i ;
|
||||
|
||||
for ( i = 0 ; i < getNumBones () ; i++ )
|
||||
getBone ( i ) -> computeTransform ( prev, next, lerptime ) ;
|
||||
|
||||
sgMat4 mat ;
|
||||
|
||||
sgMakeIdentMat4 ( mat ) ;
|
||||
|
||||
walkTransforms ( (ssgBranch *) boneRoot, mat ) ;
|
||||
|
||||
transformVertices () ;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
This file is part of ExPoser - A Tool for Animating PLIB Critters.
|
||||
Copyright (C) 2001 Steve Baker
|
||||
|
||||
ExPoser is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ExPoser is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ExPoser; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: model.h 1425 2002-08-17 23:58:38Z ude $
|
||||
*/
|
||||
|
||||
|
||||
ssgBranch *extractBones ( ssgBranch *root ) ;
|
||||
ssgEntity *makeTweenCopy ( ssgEntity *root ) ;
|
||||
void extractVertices ( ssgBranch *root ) ;
|
||||
void transformModel ( ssgBranch *boneRoot, float tim ) ;
|
||||
void makeTweenCopy ( ssgBranch *dest, ssgBranch *src ) ;
|
||||
void addTweenBank ( ssgBranch *root ) ;
|
||||
void offsetChildBones ( int root, sgVec3 v ) ;
|
||||
|
||||
float getLowestVertexZ () ;
|
||||
|
||||
int getNumBones () ;
|
||||
|
||||
@@ -0,0 +1,386 @@
|
||||
/*
|
||||
This file is part of ExPoser - A Tool for Animating PLIB Critters.
|
||||
Copyright (C) 2001 Steve Baker
|
||||
|
||||
ExPoser is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ExPoser is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ExPoser; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: timebox.cxx 2100 2006-11-03 22:31:54Z fayjf $
|
||||
*/
|
||||
|
||||
|
||||
#include "exposer.h"
|
||||
|
||||
#define MODE_ADD 0
|
||||
#define MODE_SELECT 1
|
||||
|
||||
#define TIMEBOX_LEFT 230.0f
|
||||
#define TIMEBOX_RIGHT 790.0f
|
||||
#define TIMEBOX_TOP 100.0f
|
||||
#define TIMEBOX_BOTTOM 10.0f
|
||||
#define TIMEBOX_WIDTH (TIMEBOX_RIGHT-TIMEBOX_LEFT)
|
||||
#define TIMEBOX_INITIAL_DURATION 10.0f /* Seconds */
|
||||
|
||||
/* GUI callback functions. */
|
||||
|
||||
static void vcr_fastReverse ( puObject *ob )
|
||||
{
|
||||
TimeBox *timebox = (TimeBox *) ob -> getUserData () ;
|
||||
timebox -> setReplaySpeed (-3.0f);
|
||||
}
|
||||
|
||||
static void vcr_reverse ( puObject *ob )
|
||||
{
|
||||
TimeBox *timebox = (TimeBox *) ob -> getUserData () ;
|
||||
timebox -> setReplaySpeed (-1.0f);
|
||||
}
|
||||
|
||||
static void vcr_stop ( puObject *ob )
|
||||
{
|
||||
TimeBox *timebox = (TimeBox *) ob -> getUserData () ;
|
||||
timebox -> setReplaySpeed ( 0.0f);
|
||||
}
|
||||
|
||||
static void vcr_play ( puObject *ob )
|
||||
{
|
||||
TimeBox *timebox = (TimeBox *) ob -> getUserData () ;
|
||||
timebox -> setReplaySpeed ( 1.0f);
|
||||
}
|
||||
|
||||
static void vcr_fastPlay ( puObject *ob )
|
||||
{
|
||||
TimeBox *timebox = (TimeBox *) ob -> getUserData () ;
|
||||
timebox -> setReplaySpeed ( 3.0f);
|
||||
}
|
||||
|
||||
static void vcr_groundSpeed ( puObject *ob )
|
||||
{
|
||||
TimeBox *timebox = (TimeBox *) ob -> getUserData () ;
|
||||
timebox -> setGroundSpeed ( ob -> getFloatValue () ) ;
|
||||
}
|
||||
|
||||
|
||||
static void timescrollerCB ( puObject *ob )
|
||||
{
|
||||
TimeBox *timebox = (TimeBox *) ob -> getUserData () ;
|
||||
|
||||
timebox -> setScroll ( ob -> getFloatValue () *
|
||||
( timebox -> getMaxTime() -
|
||||
TIMEBOX_WIDTH / timebox -> second () ) ) ;
|
||||
}
|
||||
|
||||
|
||||
float TimeBox::second ()
|
||||
{
|
||||
return scale * TIMEBOX_WIDTH / maxtime ;
|
||||
}
|
||||
|
||||
|
||||
void TimeBox::deleteRegionAndCompress ()
|
||||
{
|
||||
eventList -> compressEventsBetween ( lcursor, rcursor ) ;
|
||||
|
||||
maxtime -= (float)fabs(lcursor-rcursor) ;
|
||||
|
||||
if ( lcursor > rcursor )
|
||||
lcursor = rcursor ;
|
||||
else
|
||||
rcursor = lcursor ;
|
||||
}
|
||||
|
||||
|
||||
void TimeBox::addNewEvent ()
|
||||
{
|
||||
if ( getNumBones() <= 0 )
|
||||
return ;
|
||||
|
||||
eventList->setCurrentEvent ( NULL ) ;
|
||||
event_mode = MODE_ADD ;
|
||||
}
|
||||
|
||||
|
||||
void TimeBox::updateVCR ()
|
||||
{
|
||||
static ulClock timer ;
|
||||
|
||||
timer.update () ;
|
||||
|
||||
if ( replay_speed != 0.0f )
|
||||
{
|
||||
float delta_t = replay_speed * (float)timer.getDeltaTime () ;
|
||||
|
||||
lcursor += delta_t ;
|
||||
|
||||
if ( lcursor < 0.0f )
|
||||
lcursor = maxtime ;
|
||||
|
||||
if ( lcursor > maxtime )
|
||||
lcursor = 0.0f ;
|
||||
}
|
||||
|
||||
ground_position = lcursor * ground_speed ;
|
||||
}
|
||||
|
||||
|
||||
void TimeBox::draw ()
|
||||
{
|
||||
int w = puGetWindowWidth () ;
|
||||
int h = puGetWindowHeight () ;
|
||||
|
||||
glPushAttrib ( GL_ENABLE_BIT | GL_TRANSFORM_BIT | GL_LIGHTING_BIT ) ;
|
||||
|
||||
glDisable ( GL_LIGHTING ) ;
|
||||
glDisable ( GL_FOG ) ;
|
||||
glDisable ( GL_TEXTURE_2D ) ;
|
||||
glDisable ( GL_DEPTH_TEST ) ;
|
||||
glDisable ( GL_CULL_FACE ) ;
|
||||
|
||||
glViewport ( 0, 0, w, h ) ;
|
||||
glMatrixMode ( GL_PROJECTION ) ;
|
||||
glPushMatrix () ;
|
||||
glLoadIdentity () ;
|
||||
gluOrtho2D ( 0, w, 0, h ) ;
|
||||
glMatrixMode ( GL_MODELVIEW ) ;
|
||||
glPushMatrix () ;
|
||||
glLoadIdentity () ;
|
||||
|
||||
glColor4f ( 0.8f, 0.8f, 0.8f, 1.0f ) ;
|
||||
glBegin ( GL_LINE_LOOP ) ;
|
||||
glVertex2f ( TIMEBOX_LEFT , TIMEBOX_BOTTOM ) ;
|
||||
glVertex2f ( TIMEBOX_RIGHT, TIMEBOX_BOTTOM ) ;
|
||||
glVertex2f ( TIMEBOX_RIGHT, TIMEBOX_TOP ) ;
|
||||
glVertex2f ( TIMEBOX_LEFT , TIMEBOX_TOP ) ;
|
||||
glEnd () ;
|
||||
|
||||
int nseconds = (int)floor(TIMEBOX_WIDTH / second () ) ;
|
||||
int ntenthseconds = (int)floor(TIMEBOX_WIDTH*10.0f / second () ) ;
|
||||
int tenthsecondoffset = (int)( (start*10.0f -
|
||||
floor(start*10.0f))
|
||||
* second () / 10.0f ) ;
|
||||
int secondoffset = (int)( (start -
|
||||
floor(start))
|
||||
* second () ) ;
|
||||
int i ;
|
||||
|
||||
glBegin ( GL_LINES ) ;
|
||||
|
||||
for ( i = 0 ; i < ntenthseconds ; i++ )
|
||||
{
|
||||
float x = TIMEBOX_LEFT + tenthsecondoffset +
|
||||
(float) i * second () / 10.0f ;
|
||||
|
||||
glVertex2f ( x, TIMEBOX_BOTTOM ) ;
|
||||
glVertex2f ( x, TIMEBOX_TOP/3.0f ) ;
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < nseconds ; i++ )
|
||||
{
|
||||
float x = TIMEBOX_LEFT + secondoffset +
|
||||
(float) i * second () ;
|
||||
|
||||
glVertex2f ( x, TIMEBOX_BOTTOM ) ;
|
||||
glVertex2f ( x, TIMEBOX_TOP/2.0f ) ;
|
||||
}
|
||||
|
||||
glEnd () ;
|
||||
|
||||
float tlcursor = ( lcursor - start ) * second () ;
|
||||
float trcursor = ( rcursor - start ) * second () ;
|
||||
|
||||
tlcursor = (tlcursor < 0.0f ) ? 0.0f :
|
||||
(tlcursor > TIMEBOX_WIDTH) ? TIMEBOX_WIDTH : tlcursor ;
|
||||
|
||||
trcursor = (trcursor < 0.0f ) ? 0.0f :
|
||||
(trcursor > TIMEBOX_WIDTH) ? TIMEBOX_WIDTH : trcursor ;
|
||||
|
||||
if ( tlcursor != trcursor )
|
||||
{
|
||||
glColor4f ( 1.0f, 1.0f, 0.0f, 0.2f ) ;
|
||||
glBegin ( GL_QUADS ) ;
|
||||
glVertex2f ( TIMEBOX_LEFT + tlcursor, TIMEBOX_BOTTOM ) ;
|
||||
glVertex2f ( TIMEBOX_LEFT + tlcursor, TIMEBOX_TOP ) ;
|
||||
glVertex2f ( TIMEBOX_LEFT + trcursor, TIMEBOX_TOP ) ;
|
||||
glVertex2f ( TIMEBOX_LEFT + trcursor, TIMEBOX_BOTTOM ) ;
|
||||
glEnd () ;
|
||||
}
|
||||
|
||||
glColor4f ( 0.0f, 0.0f, 0.0f, 1.0f ) ;
|
||||
|
||||
glBegin ( GL_LINES ) ;
|
||||
glVertex2f ( TIMEBOX_LEFT + trcursor, TIMEBOX_BOTTOM ) ;
|
||||
glVertex2f ( TIMEBOX_LEFT + trcursor, TIMEBOX_TOP ) ;
|
||||
glEnd () ;
|
||||
|
||||
glColor4f ( 1.0f, 0.0f, 0.0f, 1.0f ) ;
|
||||
|
||||
glBegin ( GL_LINES ) ;
|
||||
glVertex2f ( TIMEBOX_LEFT + tlcursor, TIMEBOX_BOTTOM ) ;
|
||||
glVertex2f ( TIMEBOX_LEFT + tlcursor, TIMEBOX_TOP ) ;
|
||||
glEnd () ;
|
||||
|
||||
float t ;
|
||||
|
||||
glColor4f ( 1.0f, 0.0f, 1.0f, 1.0f ) ;
|
||||
|
||||
glBegin ( GL_LINES ) ;
|
||||
|
||||
for ( i = 0 ; i < eventList->getNumEvents() ; i++ )
|
||||
{
|
||||
t = eventList->getEvent(i) -> getTime () ;
|
||||
|
||||
t = ( t - start ) * second () ;
|
||||
|
||||
if ( t >= 0.0f && t <= TIMEBOX_WIDTH )
|
||||
{
|
||||
glVertex2f ( TIMEBOX_LEFT + t, TIMEBOX_TOP/3.0f ) ;
|
||||
glVertex2f ( TIMEBOX_LEFT + t, TIMEBOX_TOP ) ;
|
||||
}
|
||||
}
|
||||
glEnd () ;
|
||||
|
||||
if ( eventList->getCurrentEvent() != NULL )
|
||||
{
|
||||
t = eventList->getCurrentEvent() -> getTime () ;
|
||||
|
||||
t = ( t - start ) * second () ;
|
||||
|
||||
if ( t >= 0.0f && t <= TIMEBOX_WIDTH )
|
||||
{
|
||||
static ulClock flasher ;
|
||||
flasher.update () ;
|
||||
|
||||
if ( (int)(flasher.getAbsTime()*3.0f) & 1 )
|
||||
glColor4f ( 1.0f, 0.0f, 1.0f, 1.0f ) ;
|
||||
else
|
||||
glColor4f ( 0.0f, 1.0f, 0.0f, 1.0f ) ;
|
||||
glBegin ( GL_LINES ) ;
|
||||
glVertex2f ( TIMEBOX_LEFT + t, TIMEBOX_TOP/3.0f ) ;
|
||||
glVertex2f ( TIMEBOX_LEFT + t, TIMEBOX_TOP ) ;
|
||||
glEnd () ;
|
||||
}
|
||||
}
|
||||
|
||||
glMatrixMode ( GL_PROJECTION ) ;
|
||||
glPopMatrix () ;
|
||||
glMatrixMode ( GL_MODELVIEW ) ;
|
||||
glPopMatrix () ;
|
||||
glPopAttrib () ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void TimeBox::updateEventQueue ( int button, int x, int y, int new_click )
|
||||
{
|
||||
y = puGetWindowHeight () - y ;
|
||||
|
||||
/*
|
||||
Allow user to click a little outside the box so
|
||||
we can make it easier to get the ends exactly.
|
||||
*/
|
||||
|
||||
if ( x > TIMEBOX_LEFT - 20 && x < TIMEBOX_RIGHT + 20 &&
|
||||
y > TIMEBOX_BOTTOM && y < TIMEBOX_TOP )
|
||||
{
|
||||
float c = (float)(x - TIMEBOX_LEFT) ;
|
||||
|
||||
if ( c < 0.0f ) c = 0.0f ;
|
||||
if ( c > TIMEBOX_WIDTH ) c = TIMEBOX_WIDTH ;
|
||||
|
||||
c /= second () ;
|
||||
c += start ;
|
||||
|
||||
if ( button == PU_RIGHT_BUTTON )
|
||||
rcursor = c ;
|
||||
else
|
||||
if ( button == PU_LEFT_BUTTON )
|
||||
{
|
||||
rcursor = lcursor = c ;
|
||||
|
||||
if ( new_click )
|
||||
{
|
||||
if ( event_mode == MODE_ADD )
|
||||
eventList -> newEvent ( lcursor ) ;
|
||||
else
|
||||
eventList -> setCurrentEvent (
|
||||
eventList -> findNearestEvent ( lcursor, 10.0f/second () ) ) ;
|
||||
|
||||
event_mode = MODE_SELECT ;
|
||||
}
|
||||
else
|
||||
if ( eventList->getCurrentEvent() != NULL )
|
||||
eventList->moveEvent ( eventList->getCurrentEvent(), lcursor ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TimeBox::init ()
|
||||
{
|
||||
event_mode = MODE_SELECT ;
|
||||
|
||||
maxtime = TIMEBOX_INITIAL_DURATION ;
|
||||
scale = 1.0f ;
|
||||
start = 0.0f ;
|
||||
|
||||
lcursor = 0.0f ;
|
||||
rcursor = 0.0f ;
|
||||
|
||||
replay_speed = 0.0f ;
|
||||
ground_speed = 0.0f ;
|
||||
ground_position = 0.0f ;
|
||||
|
||||
timescroller = new puSlider ( (int)TIMEBOX_LEFT, (int)TIMEBOX_TOP+5,
|
||||
570-(int)TIMEBOX_LEFT, FALSE ) ;
|
||||
timescroller -> setCBMode ( PUSLIDER_DELTA ) ;
|
||||
timescroller -> setDelta ( 0.01f ) ;
|
||||
timescroller -> setCallback ( timescrollerCB ) ;
|
||||
timescroller -> setUserData ( this ) ;
|
||||
timescroller -> hide () ;
|
||||
|
||||
puText *message ;
|
||||
puOneShot *oneshot ;
|
||||
puGroup *vcr = new puGroup ( 579, (int)TIMEBOX_TOP + 5 ) ;
|
||||
|
||||
oneshot = new puArrowButton ( 0, 0, 30, 30, PUARROW_FASTLEFT ) ;
|
||||
oneshot -> setCallback ( vcr_fastReverse ) ;
|
||||
oneshot -> setUserData ( this ) ;
|
||||
oneshot = new puArrowButton ( 30, 0, 60, 30, PUARROW_LEFT ) ;
|
||||
oneshot -> setCallback ( vcr_reverse ) ;
|
||||
oneshot -> setUserData ( this ) ;
|
||||
oneshot = new puArrowButton ( 60, 0, 90, 30, PUARROW_DOWN ) ;
|
||||
oneshot -> setCallback ( vcr_stop ) ;
|
||||
oneshot -> setUserData ( this ) ;
|
||||
oneshot = new puArrowButton ( 90, 0,120, 30, PUARROW_RIGHT ) ;
|
||||
oneshot -> setCallback ( vcr_play ) ;
|
||||
oneshot -> setUserData ( this ) ;
|
||||
oneshot = new puArrowButton (120, 0,150, 30, PUARROW_FASTRIGHT ) ;
|
||||
oneshot -> setCallback ( vcr_fastPlay ) ;
|
||||
oneshot -> setUserData ( this ) ;
|
||||
|
||||
ground_speed_input = new puInput ( 150, 0, 200, 20 ) ;
|
||||
ground_speed_input -> setCallback ( vcr_groundSpeed ) ;
|
||||
ground_speed_input -> setValue ( "0.0" ) ;
|
||||
ground_speed_input -> setUserData ( this ) ;
|
||||
|
||||
message = new puText ( 150, 20 ) ;
|
||||
message -> setColour ( PUCOL_LABEL, 0.7f,0.65f,0.26f,1 ) ;
|
||||
message -> setLabel ( "GrndSpeed" ) ;
|
||||
|
||||
vcr -> close () ;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
This file is part of ExPoser - A Tool for Animating PLIB Critters.
|
||||
Copyright (C) 2001 Steve Baker
|
||||
|
||||
ExPoser is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ExPoser is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ExPoser; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: timebox.h 1425 2002-08-17 23:58:38Z ude $
|
||||
*/
|
||||
|
||||
|
||||
class TimeBox
|
||||
{
|
||||
int event_mode ;
|
||||
|
||||
float maxtime ;
|
||||
float scale ;
|
||||
float start ;
|
||||
float lcursor ;
|
||||
float rcursor ;
|
||||
|
||||
EventList *eventList ;
|
||||
puSlider *timescroller ;
|
||||
puInput *ground_speed_input ;
|
||||
|
||||
float replay_speed ;
|
||||
float ground_speed ;
|
||||
float ground_position ;
|
||||
|
||||
void init () ;
|
||||
|
||||
public:
|
||||
|
||||
void setReplaySpeed ( float spd )
|
||||
{
|
||||
replay_speed = spd ;
|
||||
eventList->setCurrentEvent ( NULL ) ;
|
||||
}
|
||||
|
||||
void draw () ;
|
||||
|
||||
void updateEventQueue ( int button, int x, int y, int new_click ) ;
|
||||
void updateVCR () ;
|
||||
|
||||
TimeBox ( EventList *el ) { eventList = el ; init () ; }
|
||||
|
||||
float second () ;
|
||||
|
||||
float getCursorTime () { return lcursor ; }
|
||||
|
||||
void setMaxTime ( float t ) { maxtime = t ; }
|
||||
float getMaxTime () { return maxtime ; }
|
||||
|
||||
|
||||
void setGroundSpeed ( float t )
|
||||
{
|
||||
ground_speed = t ;
|
||||
ground_speed_input -> setValue ( ground_speed ) ;
|
||||
}
|
||||
float getGroundSpeed () { return ground_speed ; }
|
||||
|
||||
void setGroundPosition ( float t ) { ground_position = t ; }
|
||||
float getGroundPosition () { return ground_position ; }
|
||||
|
||||
void setScroll ( float z ) { start = z ; }
|
||||
float getScroll () { return start ; }
|
||||
|
||||
void setZoom ( float z )
|
||||
{
|
||||
scale = z ;
|
||||
|
||||
if ( scale == 1.0f )
|
||||
timescroller -> hide () ;
|
||||
else
|
||||
timescroller -> reveal () ;
|
||||
}
|
||||
float getZoom () { return scale ; }
|
||||
|
||||
void reverseRegion ()
|
||||
{
|
||||
eventList -> reverseEventsBetween ( lcursor, rcursor ) ;
|
||||
}
|
||||
|
||||
void deleteAll ()
|
||||
{
|
||||
eventList -> deleteAll () ;
|
||||
lcursor = rcursor = 0.0f ;
|
||||
}
|
||||
|
||||
void deleteRegion ()
|
||||
{
|
||||
eventList -> deleteEventsBetween ( lcursor, rcursor ) ;
|
||||
}
|
||||
|
||||
void deleteEvent ()
|
||||
{
|
||||
eventList -> deleteCurrentEvent () ;
|
||||
}
|
||||
|
||||
void deleteRegionAndCompress () ;
|
||||
void addNewEvent () ;
|
||||
} ;
|
||||
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
This file is part of ExPoser - A Tool for Animating PLIB Critters.
|
||||
Copyright (C) 2001 Steve Baker
|
||||
|
||||
ExPoser is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ExPoser is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ExPoser; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: vertices.cxx 1425 2002-08-17 23:58:38Z ude $
|
||||
*/
|
||||
|
||||
|
||||
#include "exposer.h"
|
||||
|
||||
|
||||
class Vertex
|
||||
{
|
||||
public:
|
||||
|
||||
int boneID ;
|
||||
sgVec3 rel_vx ;
|
||||
float *vx ;
|
||||
|
||||
int getBoneID () { return boneID ; }
|
||||
} ;
|
||||
|
||||
|
||||
static int nextVertex = 0 ;
|
||||
|
||||
#define MAX_VERTICES (64*1024)
|
||||
|
||||
static Vertex vertex [ MAX_VERTICES ] ;
|
||||
|
||||
|
||||
|
||||
static int getNumVertices () { return nextVertex ; }
|
||||
|
||||
|
||||
static void addVertex ( sgVec3 v )
|
||||
{
|
||||
vertex [ nextVertex ] . vx = v ;
|
||||
sgCopyVec3 ( vertex [ nextVertex ] . rel_vx, v ) ;
|
||||
|
||||
nextVertex++ ;
|
||||
}
|
||||
|
||||
|
||||
static void initVertices ()
|
||||
{
|
||||
nextVertex = 0 ;
|
||||
}
|
||||
|
||||
|
||||
static void walkVertices ( ssgBranch *root, sgMat4 mat )
|
||||
{
|
||||
if ( root == NULL )
|
||||
return ;
|
||||
|
||||
sgMat4 newmat ;
|
||||
|
||||
if ( root -> isAKindOf ( ssgTypeTransform() ) )
|
||||
{
|
||||
sgMat4 tmp ;
|
||||
|
||||
((ssgTransform *)root)-> getTransform ( tmp ) ;
|
||||
sgMultMat4 ( newmat, mat, tmp ) ;
|
||||
|
||||
sgMakeIdentMat4 ( tmp ) ;
|
||||
((ssgTransform *)root)-> setTransform ( tmp ) ;
|
||||
}
|
||||
else
|
||||
sgCopyMat4 ( newmat, mat ) ;
|
||||
|
||||
for ( int i = 0 ; i < root -> getNumKids () ; i++ )
|
||||
{
|
||||
ssgEntity *e = root -> getKid ( i ) ;
|
||||
|
||||
if ( e -> isAKindOf ( ssgTypeBranch() ) )
|
||||
walkVertices ( (ssgBranch *)e, newmat ) ;
|
||||
else
|
||||
{
|
||||
ssgLeaf *l = (ssgLeaf *) e ;
|
||||
|
||||
for ( int ll = 0 ; ll < l->getNumVertices() ; ll++ )
|
||||
{
|
||||
float *v = l -> getVertex ( ll ) ;
|
||||
int vv = -1 ;
|
||||
|
||||
for ( int j = 0 ; j < getNumVertices() ; j++ )
|
||||
if ( v == vertex [ j ] . vx )
|
||||
{
|
||||
vv = j ;
|
||||
break ;
|
||||
}
|
||||
|
||||
if ( vv < 0 )
|
||||
{
|
||||
sgXformPnt3 ( v, mat ) ;
|
||||
addVertex ( v ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void extractVertices ( ssgBranch *root )
|
||||
{
|
||||
sgMat4 mat ;
|
||||
|
||||
initVertices () ;
|
||||
|
||||
/*
|
||||
Walk the model - making a list of all of the
|
||||
unique vertices - flattening the model's transforms
|
||||
as we go.
|
||||
*/
|
||||
|
||||
sgMakeIdentMat4 ( mat ) ;
|
||||
walkVertices ( root, mat ) ;
|
||||
|
||||
/*
|
||||
Now find the nearest bone to each vertex and
|
||||
compute it's position relative to the root of
|
||||
that bone.
|
||||
*/
|
||||
|
||||
for ( int i = 0 ; i < getNumVertices() ; i++ )
|
||||
{
|
||||
float min = FLT_MAX ;
|
||||
|
||||
for ( int j = 0 ; j < getNumBones() ; j++ )
|
||||
{
|
||||
sgLineSegment3 ls ;
|
||||
sgCopyVec3 ( ls.a, getBone(j)->orig_vx[0] ) ;
|
||||
sgCopyVec3 ( ls.b, getBone(j)->orig_vx[1] ) ;
|
||||
|
||||
float d = sgDistSquaredToLineSegmentVec3 ( ls, vertex[i].vx ) ;
|
||||
|
||||
if ( d < min )
|
||||
{
|
||||
min = d ;
|
||||
vertex[i].boneID = j ;
|
||||
}
|
||||
}
|
||||
|
||||
sgSubVec3 ( vertex[i].rel_vx,
|
||||
vertex[i].vx,
|
||||
getBone(vertex[i].boneID)->orig_vx[0] ) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float getLowestVertexZ ()
|
||||
{
|
||||
float lowest = FLT_MAX ;
|
||||
|
||||
for ( int i = 0 ; i < getNumVertices() ; i++ )
|
||||
{
|
||||
float v = vertex[i].vx [ 2 ] ;
|
||||
|
||||
if ( v < lowest )
|
||||
lowest = v ;
|
||||
}
|
||||
|
||||
return lowest ;
|
||||
}
|
||||
|
||||
|
||||
void transformVertices ()
|
||||
{
|
||||
for ( int i = 0 ; i < getNumVertices () ; i++ )
|
||||
getBone ( vertex[i].getBoneID() ) -> transform ( vertex[i].vx,
|
||||
vertex[i].rel_vx ) ;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
This file is part of ExPoser - A Tool for Animating PLIB Critters.
|
||||
Copyright (C) 2001 Steve Baker
|
||||
|
||||
ExPoser is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ExPoser is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ExPoser; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id: vertices.h 1425 2002-08-17 23:58:38Z ude $
|
||||
*/
|
||||
|
||||
|
||||
void extractVertices ( ssgBranch *root ) ;
|
||||
float getLowestVertexZ () ;
|
||||
void transformVertices () ;
|
||||
|
||||